docs: 交叉检查修复文档疏漏与不一致

- 修复 api.md 修改密码接口混入注册场景的 409 错误
- 补充 api.md WebSocket 示例缺失的 quality_supervisor running 消息
- 补充 api.md 注册接口格式校验错误响应、缓存接口详细说明
- 补充 frontend.md Task 接口缺失的 error 字段
- 补充 frontend.md 错误处理章节(API 错误、WebSocket 断连、加载状态)
- frontend.md 风格键表改为引用 style-keys.md,消除重复
- async-tasks.md 去重/文件存储改为引用 database.md,消除重复
- backend.md ER 图改为引用 database.md,消除重复
- 补充 backend.md 目录结构中缺失的 auth/project handler 和 user model
- 补充 backend.md 缓存层设计说明
- 补充 database.md GEN2D_SERVER_PORT 环境变量和迁移文件归属说明
- 补充 multi-agent-pipeline.md 到 backend.md 和 async-tasks.md 的交叉引用
- 补充 async-tasks.md 超时控制说明
This commit is contained in:
2026-05-24 10:47:00 +08:00
parent 5a6bcaffaf
commit f4c1a10403
6 changed files with 102 additions and 37 deletions
+44 -5
View File
@@ -93,6 +93,16 @@ Token 通过登录接口获取,过期时间由 `GEN2D_JWT_EXPIRE` 控制(默
}
```
错误响应:
| 场景 | code | message |
|------|------|---------|
| 用户名格式不合法(非 3-64 字符或含特殊字符) | 400 | 用户名格式不合法 |
| 密码长度不足 | 400 | 密码长度不能少于 8 位 |
| 邮箱格式不合法 | 400 | 邮箱格式不正确 |
| 用户名已存在 | 409 | 用户名已被注册 |
| 邮箱已存在 | 409 | 邮箱已被注册 |
### POST /api/v1/auth/login
```json
@@ -160,8 +170,6 @@ Token 通过登录接口获取,过期时间由 `GEN2D_JWT_EXPIRE` 控制(默
| 场景 | code | message |
|------|------|---------|
| 原密码错误 | 400 | 原密码不正确 |
| 用户名已存在 | 409 | 用户名已被注册 |
| 邮箱已存在 | 409 | 邮箱已被注册 |
## 工程管理
@@ -477,6 +485,7 @@ interface PipelineProgress {
{"stage":"prompt_builder","status":"completed","progress":100}
{"stage":"asset_generator","status":"running","progress":0}
{"stage":"asset_generator","status":"completed","progress":100}
{"stage":"quality_supervisor","status":"running","progress":0}
{"stage":"quality_supervisor","status":"completed","progress":100}
{"stage":"format_adapter","status":"running","progress":0}
{"stage":"format_adapter","status":"completed","progress":100,"result":{"assets":[...]}}
@@ -495,9 +504,39 @@ interface PipelineProgress {
## 缓存管理
需认证。
需认证。用于管理应用层去重缓存(详见 [数据存储 — 去重策略](database.md#去重策略)),主要用于调试和运维场景。
| 状态 | 方法 | 路径 | 说明 |
|------|------|------|------|
| [ ] | DELETE | `/api/v1/cache/:key` | 清除特定缓存 |
| [ ] | POST | `/api/v1/cache/clear` | 批量清除缓存 |
| [ ] | DELETE | `/api/v1/cache/:key` | 清除特定去重缓存条目 |
| [ ] | POST | `/api/v1/cache/clear` | 批量清除所有去重缓存 |
### DELETE /api/v1/cache/:key
清除指定去重键的缓存条目。`:key` 为 `hash(prompt + assetType + params)` 生成的去重键,仅在需要手动解除去重锁定时使用。
响应:
```json
{
"code": 0,
"message": "ok",
"data": null
}
```
### POST /api/v1/cache/clear
清除所有去重缓存条目,不影响正在执行的任务。
响应:
```json
{
"code": 0,
"message": "ok",
"data": {
"cleared": 5
}
}
```
+12 -15
View File
@@ -109,6 +109,16 @@ func (s *TaskService) StartWorkers(n int) {
| 队列容量 | 100 | 内存 channel 缓冲大小 |
| Worker 数 | 3 | 并发执行任务数 |
### 超时控制
每个任务的 `processTask` 执行设置超时上下文(默认 10 分钟),超时后:
1. 取消正在执行的管线节点(如 AI 推理调用)
2. 更新 `task.status = failed`,`task.error = "任务执行超时"`
3. Worker 释放,继续处理下一个任务
避免长时间卡住的任务永久占用 Worker。
## 管线阶段与进度
每个阶段对应 Eino Graph 的一个节点,执行过程中更新 `task.stage` 和 `task.progress`:
@@ -173,21 +183,8 @@ ws://host/api/v1/tasks/:taskId/ws?token=<jwt>
## 去重
相同 `prompt + assetType + params` 的并发请求,通过应用层去重避免重复生成:
1. 计算 `hash(prompt + assetType + params)` 作为去重键
2. `sync.Map` 中查找:若存在且任务仍在运行中,直接返回已有 taskId
3. 任务完成或失败后从内存中清除
去重范围为当前实例内存,不跨实例共享。相同输入在不同时间点允许重新生成。
去重策略详见 [数据存储 — 去重策略](database.md#去重策略)。相同输入的并发请求直接返回已有 taskId,任务完成后从内存清除。
## 文件存储
任务完成后,FormatAdapter 将素材上传至 OSS:
- **开发环境**:写入本地 `data/` 目录,通过 Gin 静态文件服务访问
- **生产环境**:上传至 OSS 存储桶,`asset.url` 存储完整 CDN URL
OSS Key 结构:`users/{userId}/projects/{projectId}/tasks/{taskId}/output/`
素材持久化保存,随工程生命周期管理,删除工程时级联删除 OSS 文件。
任务完成后,FormatAdapter 将素材上传至 OSS。素材文件的存储结构与访问方式详见 [数据存储 — 文件存储](database.md#文件存储)。
+15 -6
View File
@@ -11,10 +11,13 @@
```
backend/internal/
├── handler/ # HTTP handlers(薄层,只做参数绑定 + 调用 service)
│ ├── auth.go # 用户注册 / 登录 / 当前用户 / 修改密码
│ ├── project.go # 工程 CRUD + 任务列表
│ ├── generate.go # 生成任务提交 / 查询 / WebSocket
│ ├── project_style.go # 工程风格 CRUD
│ └── health.go # [已有] 健康检查
├── service/ # 业务逻辑层
│ ├── auth.go # 用户认证:注册、登录、JWT 签发与校验
│ ├── pipeline.go # Eino compose.Graph 编排:PromptBuilder → AssetGenerator → QualitySupervisor → FormatAdapter
│ ├── nodes.go # 管线四个节点的实现(每个节点单一职责)
│ ├── types.go # 管线输入/状态/输出的显式结构体定义
@@ -22,10 +25,12 @@ backend/internal/
│ └── project_style.go # 工程风格管理 & 风格合并逻辑
├── model/ # 数据模型 / DTO
│ ├── response.go # [已有] 统一响应
│ ├── user.go # 用户模型
│ ├── task.go # 生成任务 & 素材
│ └── style.go # 工程风格 & 任务风格覆盖
├── middleware/ # 中间件
│ ├── logger.go
│ ├── auth.go # JWT 认证中间件
│ └── ratelimit.go
├── config/ # [已有] 配置
│ └── config.go
@@ -194,12 +199,7 @@ func RunPipeline(ctx context.Context, in PipelineInput) (*PipelineOutput, error)
| Prompt | PromptBuilder 输出的三段式提示词(主题+约束+内容),管线中间产物,不持久化 | 由 Task 生成 |
| Asset | 生成结果素材,关联到任务,包含 URL、元数据(分辨率、帧数、格式) | 属于 Task |
```mermaid
erDiagram
Project ||--|| ProjectStyle : has
Project ||--|{ Task : has
Task ||--|{ Asset : has
```
ER 关系图与外键约束详见 [数据存储 — ER 关系](database.md#er-关系)。
## 风格模型
@@ -234,3 +234,12 @@ finalStyle = merge(projectStyle.KVPairs, taskStyle.KVPairs)
```
任务同名键覆盖工程风格,由 PromptBuilder 节点在生成提示词时执行合并。
## 缓存层
`cache/cache.go` 提供应用内存级缓存,主要用于请求去重(详见 [数据存储 — 去重策略](database.md#去重策略)):
- **数据结构**:`sync.Map`,key 为 `hash(prompt + assetType + params)`,value 为 taskId
- **生命周期**:任务提交时写入,任务完成或失败后清除;可设置 TTL 过期兜底
- **作用域**:单实例内存,不跨实例共享
- **接口**:提供 `Get`/`Set`/`Delete`/`Clear` 方法,同时供 handler 层(缓存管理 API)和 service 层(去重检查)调用
+3
View File
@@ -190,6 +190,7 @@ task 1 ── N asset
| 环境变量 | 默认值 | 说明 |
|----------|--------|------|
| `GEN2D_SERVER_PORT` | `8080` | HTTP 服务监听端口 |
| `GEN2D_DB_DSN` | `root:@tcp(127.0.0.1:3306)/gen2d?charset=utf8mb4&parseTime=True&loc=Local` | MySQL DSN |
| `GEN2D_DB_MAX_OPEN` | `25` | 最大连接数 |
| `GEN2D_DB_MAX_IDLE` | `5` | 最大空闲连接数 |
@@ -224,6 +225,8 @@ backend/internal/migrations/
启动时自动执行 `migrate.Up()`,保证 schema 与代码版本一致。
> 注:`project_style` 表的创建包含在 `000002_init_project.up.sql` 中,与 `project` 表同批迁移。
---
## 索引说明
+23 -10
View File
@@ -136,6 +136,27 @@ sequenceDiagram
API-->>SP: 保存成功
```
## 错误处理
### API 请求错误
- `api/client.ts` 统一拦截 `code !== 0` 的响应,抛出业务异常
- 401:自动清除本地 Token,跳转到登录页(或提示重新登录)
- 403:提示无权访问,不自动跳转
- 429:提示请求过于频繁,稍后重试
- 500:展示通用错误提示
### WebSocket 断连
- 连接断开后自动重连(指数退避,最大间隔 10 秒)
- 重连失败超过 3 次后,降级为轮询模式(`GET /api/v1/tasks/:taskId`,间隔 2-3 秒)
- 连接恢复后自动切回 WebSocket
### 加载状态
- 页面级加载(如 ProjectPage 进入时):展示骨架屏或 Loading 指示器
- 操作级提交(如保存风格、提交生成):按钮置为 loading 态,防止重复提交
## 状态管理
### zustand stores
@@ -248,6 +269,7 @@ interface Task {
stage?: PipelineStage;
progress?: number;
retryCount?: number;
error?: string | null;
createdAt: string;
updatedAt: string;
}
@@ -281,16 +303,7 @@ interface PipelineProgress {
## 预设风格键分类
前端 StyleSelector 以分类标签组织,用户点选:
| 分类 | 键名 | 可选值 |
|------|------|--------|
| 美术风格 | `artStyle` | pixel, cartoon, hand-drawn, vector, flat |
| 色调 | `palette` | warm, cool, neutral, vibrant, muted, monochrome |
| 线条 | `lineWeight` | none, thin, medium, thick |
| 场景 | `scene` | forest, dungeon, city, space, underwater, desert |
| 光照 | `lighting` | bright, dim, dramatic, ambient, neon |
| 情绪 | `mood` | cheerful, dark, mysterious, epic, calm |
前端 StyleSelector 以分类标签组织,完整键值表见 [预设风格键](style-keys.md)。
StyleSelector 两种使用场景:
1. **工程风格**(ProjectPage):全量编辑,保存到后端
+5 -1
View File
@@ -1,6 +1,6 @@
# 多阶段生成管线
gen2d 的核心生成流程采用 Eino `compose.Graph` 编排的四阶段管线,含质检不通过时的重生成分支。
gen2d 的核心生成流程采用 Eino `compose.Graph` 编排的四阶段管线,含质检不通过时的重生成分支。管线编排与节点实现详见 [后端工程 — 管线设计](backend.md#管线设计eino-composegraph)。
```mermaid
flowchart LR
@@ -58,3 +58,7 @@ finalStyle = merge(projectStyle.KVPairs, taskStyle.KVPairs)
- **职责**:格式转换、spritesheet 打包、元数据生成。
- **示例**:输入 4 张 64×64 的角色行走帧 PNG → 输出一张 256×64 的 spritesheet + JSON 元数据(帧尺寸、帧数、锚点偏移),可直接拖入 Unity 2D Animation 使用。
---
管线执行过程中的进度推送与重试机制详见 [异步任务](async-tasks.md)。