Files
MemeStudio/API_REFERENCE.md
2026-05-01 08:44:56 +08:00

453 lines
8.0 KiB
Markdown

# 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=<levelId>
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=<userId>
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=<text>&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/<userId>
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=<tencent secret>
COS_SECRET_KEY=<tencent secret>
COS_BUCKET=bucket-name
COS_REGION=ap-guangzhou
COS_APPID=<tencent app id>
```