# MemeStudio API Reference ## Base URL - Development: `http://localhost:3001/studio` - Production: `https://119.91.211.52/studio` ## Authentication All endpoints except `/api/auth/*` require a valid session cookie: - `better-auth.session_token` (HTTP) - `__Secure-better-auth.session_token` (HTTPS) Error response if unauthorized: `{ error: 'Unauthorized' }` (401) --- ## Authentication Endpoints ### POST /api/auth/sign-in/email Sign in with email and password. **Request:** ```json { "email": "admin@example.com", "password": "password123" } ``` **Response:** ```json { "user": { "id": "uuid", "email": "admin@example.com", "name": "Admin", "emailVerified": true }, "session": { "id": "session_id", "expiresAt": "2024-04-14T10:00:00Z", "token": "session_token" } } ``` --- ### POST /api/auth/sign-out Sign out and invalidate session. **Response:** ```json { "success": true } ``` --- ## Levels API ### GET /api/levels Get all levels, sorted by sortOrder. **Response:** ```json [ { "id": "uuid", "imageUrl": "https://bucket.myqcloud.com/mini_game/images/...", "answer": "答案文本", "hint1": "提示1", "hint2": "提示2", "hint3": "提示3", "sortOrder": 1, "createdAt": "2024-04-01T10:00:00Z", "updatedAt": "2024-04-01T10:00:00Z" } ] ``` --- ### POST /api/levels Create a new level. sortOrder is auto-calculated as max+1. **Request:** ```json { "imageUrl": "https://bucket.myqcloud.com/mini_game/images/...", "answer": "答案", "hint1": "提示1", "hint2": "提示2", "hint3": "提示3" } ``` **Response:** Level object (201 Created) **Validation:** - `imageUrl` and `answer` are required - Returns 400 if missing required fields --- ### PUT /api/levels Update a level. **Request:** ```json { "id": "uuid", "imageUrl": "...", "answer": "新答案", "hint1": "...", "hint2": "...", "hint3": "..." } ``` **Response:** Updated Level object **Validation:** - `id` is required - Other fields are optional (only provided fields are updated) --- ### DELETE /api/levels?id= Delete a level. **Response:** ```json { "success": true } ``` --- ## Levels Reorder API ### PUT /api/levels/reorder Batch update sort order for multiple levels (atomic transaction). **Request:** ```json { "orders": [ { "id": "uuid1", "sortOrder": 1 }, { "id": "uuid2", "sortOrder": 2 }, { "id": "uuid3", "sortOrder": 3 } ] } ``` **Response:** ```json { "success": true } ``` **Validation:** - `orders` must be an array of objects with `id` and `sortOrder` --- ## Admin Users API ### GET /api/users Get all admin users, sorted by createdAt DESC. **Response:** ```json [ { "id": "uuid", "email": "admin@example.com", "emailVerified": true, "name": "Admin Name", "image": null, "createdAt": "2024-04-01T10:00:00Z", "updatedAt": "2024-04-01T10:00:00Z" } ] ``` --- ### POST /api/users Create a new admin user. **Request:** ```json { "email": "newadmin@example.com", "password": "securepassword123", "name": "New Admin" } ``` **Response:** User object (201 Created) **Validation:** - `email` and `password` are required - `email` must be unique (returns 400 if already exists: "该邮箱已被注册") - Password is automatically hashed using Better Auth's hashPassword --- ### PUT /api/users Update a user. **Request:** ```json { "id": "uuid", "email": "newemail@example.com", "password": "newpassword123", "name": "Updated Name" } ``` **Response:** Updated User object **Validation:** - `id` is required - Email must be unique across other users (returns 400 if taken: "该邮箱已被其他用户使用") - If `password` is provided, it's hashed and Account record is updated --- ### DELETE /api/users?id= Delete a user. **Response:** ```json { "success": true } ``` **Validation:** - `id` is required - Cannot delete yourself (returns 400: "不能删除自己的账户") - Cascading delete removes all sessions and accounts --- ## WeChat Users API ### GET /api/wx-users?search=&page=<1>&limit=<20> Get WeChat users with pagination and search. **Query Parameters:** - `search` (optional): Search in nickname or openid (contains search) - `page` (optional, default 1): Page number - `limit` (optional, default 20): Items per page **Response:** ```json { "users": [ { "id": "uuid", "openid": "oABCDEF123456", "nickname": "用户昵称", "avatarUrl": "https://...", "points": 100, "createdAt": "2024-04-01T10:00:00Z", "updatedAt": "2024-04-01T10:00:00Z" } ], "meta": { "total": 150, "page": 1, "limit": 20, "totalPages": 8 } } ``` --- ### GET /api/wx-users/ Get a specific WeChat user with their level progress. **Response:** ```json { "id": "uuid", "openid": "oABCDEF123456", "nickname": "用户昵称", "avatarUrl": "https://...", "points": 100, "sessionKey": "...", "createdAt": "2024-04-01T10:00:00Z", "updatedAt": "2024-04-01T10:00:00Z", "levelProgress": [ { "id": "progress_uuid", "userId": "uuid", "levelId": "uuid", "completedAt": "2024-04-02T15:30:00Z", "level": { "id": "uuid", "answer": "答案" } } ] } ``` --- ### DELETE /api/wx-users/level-progress Delete multiple level progress records (batch). **Request:** ```json { "ids": [ "progress_uuid1", "progress_uuid2", "progress_uuid3" ] } ``` **Response:** ```json { "deleted": 3 } ``` **Validation:** - `ids` must be a non-empty array of strings - Returns 400 if validation fails --- ## Tencent COS API ### GET /api/cos/temp-key Get temporary credentials for uploading images to COS. **Response:** ```json { "credentials": { "tmpSecretId": "AKIA...", "tmpSecretKey": "...", "sessionToken": "..." }, "startTime": 1712000000, "expiredTime": 1712001800, "bucket": "mybucket-1234567890", "region": "ap-guangzhou" } ``` **Details:** - Credentials are valid for 30 minutes (1800 seconds) - Limited to upload to `mini_game/images/*` directory - Use returned `bucket` and `region` for upload configuration - Browser should upload directly to COS using these credentials (S3-compatible API) --- ## Error Handling ### Standard Error Response ```json { "error": "Error message" } ``` ### HTTP Status Codes - `200`: Success - `201`: Created - `400`: Bad Request (validation error) - `401`: Unauthorized (no session) - `404`: Not Found (resource doesn't exist) - `500`: Server Error --- ## Implementation Notes ### Session Validation Pattern ```typescript const session = await auth.api.getSession({ headers: request.headers }) if (!session) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) } ``` ### Pagination Pattern - `skip = (page - 1) * limit` - `totalPages = Math.ceil(total / limit)` ### Transaction Pattern (Multi-step operations) ```typescript await prisma.$transaction(async (tx) => { // Multiple database operations in atomic transaction }) ``` ### Error Handling Pattern All endpoints log errors to console and return appropriate status codes. --- ## Testing with cURL ### Sign In ```bash curl -X POST http://localhost:3001/studio/api/auth/sign-in/email \ -H "Content-Type: application/json" \ -d '{"email":"admin@example.com","password":"admin123456"}' \ -c cookies.txt ``` ### Get Levels (with session cookie) ```bash curl http://localhost:3001/studio/api/levels \ -b cookies.txt ``` ### Create Level ```bash curl -X POST http://localhost:3001/studio/api/levels \ -H "Content-Type: application/json" \ -b cookies.txt \ -d '{ "imageUrl":"https://bucket.myqcloud.com/mini_game/images/test.jpg", "answer":"答案", "hint1":"提示1", "hint2":"提示2", "hint3":"提示3" }' ``` --- ## Environment Variables Required for API ``` DATABASE_URL=mysql://user:pass@host:port/dbname BETTER_AUTH_SECRET=<32+ chars> BETTER_AUTH_URL=http://localhost:3001 NEXT_PUBLIC_APP_URL=http://localhost:3001 NEXT_PUBLIC_BASE_PATH=/studio COS_SECRET_ID= COS_SECRET_KEY= COS_BUCKET=bucket-name COS_REGION=ap-guangzhou COS_APPID= ```