feat: track generation jobs

This commit is contained in:
2026-04-18 16:29:22 +08:00
parent 16fafe0fe0
commit 96dfc677e2
18 changed files with 709 additions and 71 deletions

View File

@@ -14,6 +14,8 @@
- Pydantic v2 兼容性 warning 清理
- Dockerfile build warning 清理
- 管理后台弱默认密码防护
- Generation job/event 轻量落库
- `retryable_assets` 标准响应字段
- 后端统一生成接口
- 故事封面资产补全
- 故事音频资产补全
@@ -42,12 +44,15 @@ SMOKE_AUDIO=1 ./scripts/demo_smoke.sh
- Docker 管理前端镜像 `dreamweaver-admin-frontend:dev` 构建通过。
- Docker 后端镜像 `dreamweaver-backend:dev` 构建通过。
- `ruff check app tests` 通过。
- `pytest -q` 通过71 个测试通过Pydantic v2 deprecation warning 已清零。
- `pytest -q` 通过73 个测试通过Pydantic v2 deprecation warning 已清零。
- `SMOKE_AUDIO=1 ./scripts/demo_smoke.sh` 通过。
- smoke 会断言 `retryable_assets` 在故事、音频、绘本补全前后按预期变化。
- 本地用户端可通过 `http://localhost:52080` 访问。
- 本地管理端可通过 `http://localhost:52888` 访问。
- 技术债扫描未发现 `class Config``TODO``FIXME`、旧 Issue 注释或 Dockerfile `FROM ... as`
- 后端不再内置 `admin123` 管理密码;非 debug 环境开启管理后台时会拒绝空/弱密码。
- 统一生成和资产重试会写入 `generation_jobs``generation_job_events`
- API 响应返回 `retryable_assets`,前端按标准字段展示补全/重试入口。
已确认的演示能力:

View File

@@ -88,6 +88,7 @@ Week 2 的目标不是做“完整商业产品”,而是做出一个面试时
| W2-13 | Tech Debt | 清理 Pydantic v2 warning、Dockerfile warning 和旧 TODO | 测试无 warningDocker build 无 casing warning | P1 | 0.5d | Done |
| W2-14 | Frontend | 同步管理端生成状态与资产补全体验 | 用户端/管理端状态体验不再分叉 | P1 | 0.5d | Done |
| W2-15 | Security | 移除管理后台弱默认密码 | 非 debug 管理后台拒绝空/弱密码 | P1 | 0.5d | Done |
| W2-16 | Workflow | 轻量落库 generation job/event 与 retryable assets | 生成/资产补全过程可追踪,前端按标准字段展示 CTA | P1 | 1.0d | Done |
---

View File

@@ -29,8 +29,12 @@ DreamWeaver 当前同时支持普通故事生成、完整故事生成和绘本
- `audio_status`
- `last_error`
- `audio_path`
- 已新增轻量可查询的生成过程记录:
- `generation_jobs`
- `generation_job_events`
- Storybook 阅读器已支持按 ID 恢复,不再只依赖 Pinia 内存态
- 故事列表页、故事详情页、绘本阅读页已接入统一状态展示
- API 响应已统一返回 `retryable_assets`,前端不再各自推断可补全资产
- 故事音频已支持首次生成后缓存复用
- `degraded_completed` 已在服务层和前端语义中落地
- 已新增首版统一资产重试入口:`POST /api/stories/{story_id}/assets/retry`
@@ -50,8 +54,9 @@ DreamWeaver 当前同时支持普通故事生成、完整故事生成和绘本
### Still Missing
- 普通故事、完整生成、绘本生成已有统一外部入口,内部 workflow 已开始抽取公共步骤,但旧 service 函数仍作为兼容层保留
- 统一资产重试入口仍是首版:已覆盖普通故事封面、绘本缺失插图、故事音频,并已抽出 asset completion helper 与 `AssetCompletionResult`,但尚未落库为完整 generation job 模型
- `partial_ready``retryable_assets` 等更细粒度状态仍停留在目标态
- 统一资产重试入口仍是首版:已覆盖普通故事封面、绘本缺失插图、故事音频,并已抽出 asset completion helper 与 `AssetCompletionResult`
- `generation_jobs` 已记录请求、完成、失败和资产重试事件,但尚未扩展到逐 provider 调用、逐页面资产步骤和完整运营分析
- `partial_ready``text_status` 等更细粒度状态仍停留在目标态
### What This Means

View File

@@ -4,9 +4,15 @@
## 当前结论
短期不新增 `generation_jobs` 表,继续把求职版状态落在 `stories` 主记录上
已新增轻量 `generation_jobs` `generation_job_events` 表,但不引入复杂工作流引擎
原因是当前 MVP 的生成方式仍然以同步请求为主:后端在一次请求中完成主内容保存,再补全封面、绘本插图或语音。用户最关心的是“这个故事现在能不能读、哪些资产可补全”,而不是一个独立 job 的生命周期
原因是当前 MVP 的生成方式仍然以同步请求为主:后端在一次请求中完成主内容保存,再补全封面、绘本插图或语音。用户最关心的是“这个故事现在能不能读、哪些资产可补全”;系统侧则需要有足够的轨迹说明“这次生成做到了哪一步、哪里失败、哪些资产还能重试”
因此当前采用轻量落库策略:
- `stories` 继续承载用户可见结果和当前状态。
- `generation_jobs` 记录一次生成或资产补全尝试。
- `generation_job_events` 记录关键步骤事件,例如 `request_accepted``generation_completed``asset_retry_started``asset_retry_completed`
## 现有状态模型
@@ -21,7 +27,7 @@
## 什么时候需要落库 job
如果后续进入真实生产化,需要重新评估 `generation_jobs`
如果后续进入真实生产化,需要扩展当前 job/event 模型
- 生成流程改成真正异步,前端需要轮询 job 进度。
- 单个故事会产生多次生成尝试,需要审计每次 provider 调用。
@@ -29,15 +35,14 @@
- 需要按 provider、成本、延迟和失败原因做运营分析。
- 需要断点续跑,避免 Worker 重启后丢失中间状态。
## 推荐未来结构
## 推荐未来扩展
未来可以新增两层记录
当前已有两层记录,未来可以继续扩展字段和事件颗粒度
- `generation_jobs`: 一次用户发起的生成任务,记录输入、状态、耗时、错误和关联 story
- `generation_job_events`: 任务事件流记录每一步开始、成功、失败、provider、耗时和错误摘要
这会把“用户可见结果”和“系统执行过程”分开,但目前还不是求职版的最高优先级。
- `generation_job_events` 中补 provider、耗时、成本和错误摘要
- 对绘本逐页插图、TTS、后处理任务记录更细事件
- 为前端提供 job 查询接口,用于真正异步生成时轮询进度。
## 面试表达
现在没有急着加 job 表,是因为 MVP 首要目标是让故事结果稳定可读,并让资产失败可恢复。等生成链路变成真正异步、需要审计和运营指标时,再把执行过程拆到 job/event 表,会比现在提前设计复杂表结构更稳
没有一上来引入复杂工作流引擎,而是先用轻量 job/event 表把关键执行轨迹落下来。这样既能回答“生成过程是否可追踪”,又不会为了求职版 MVP 牺牲主链路稳定性