Files
meida/docs/开发任务包/T12-极简运营后台.md
T
xsl e511b6a66f 收尾两批并行开发的文档回写与任务包
- Sprint 执行计划 v1.1:§1.1 补第一批交付实据;T9 SPIKE 结论回写 Sprint 1 表
  (T-P0-16 通过 2.8ms;T-P0-12 有条件;T-P0-10 原型 6/6 + 真实照片重验前置);
  Sprint 2 表标注 T-P2-01~06 交付;新增 §9 两批交付记录
- 开发任务拆解 v1.5:交付回写 + 新风险登记(RTMPose 域差异、BiRefNet 异步化)
- 新增 开发任务包/:三批多 agent 并行的协作规程与 14 份任务契约
- 新增 前置开通清单-云资源与资质.md
- 清理已用毕的评审报告(文档评审 2026-08-13、项目整体评审 2026-08-14),
  README 中相应引用改为留痕表述
2026-08-14 21:07:20 +08:00

5.8 KiB
Raw Blame History

T12 · 极简运营后台

对应任务:T-P2-09 🔴 | 需求:FR-ADM-01~05、Sprint 2 出口「顾问可独立完成内容维护、审核、发布与回滚,全程无工程介入」| 分支:task/t12-admin-console | worktree:/home/xsl/meida_backend-t12 先读《README.md(协作规程)》,遵守全部纪律。

1. 目标

apps/admin/ 独立 FastAPI 应用(与 apps/api 平级,部署上分离):知识实体与规则的维护/审核/发布/回滚入口、素材登记与审核、知识缺口看板。这是 M2 出口的成败标志——顾问从此不找工程。

2. 已就绪的契约(协调提交 9c18021 已提供)

配置与鉴权

  • settings.admin_token(env ADMIN_TOKEN):空字符串 = 全部 admin 端点 404(等价未部署)。鉴权方式:请求头 X-Admin-Token 精确匹配(hmac.compare_digest);不匹配 → 40100(UNAUTHENTICATED)。
  • apps 之间互不依赖(import-linter):admin 不许 import apps.api 的任何东西——session 依赖、响应信封在 admin 包内自建(ok/AppError 来自 packages.shared,允许)。

可复用的服务层(先读再用,不改它们)

  • packages/kb/service.py:KbService(实体 CRUD/状态机/图谱/色板)+ KbAssetService(新):register_asset(payload) -> KbAsset、review_asset(asset_id, payload)(tryon_ready 只能随 approved 打开,服务端已强制)、list_assets(...);schemas:AssetCreate/AssetReview/AssetOut 已加。
  • packages/rules/service.py:规则 CRUD + 状态机 + PublishedRules 缓存 invalidate()。
  • packages/retrieval/service.py:模块级 list_gaps(session, ...)(hit_count 降序)+ invalidate_cache()(发布编排后调用——T14 会在背后实现真缓存,你只管调)。
  • 实体状态机:draft→reviewing→published→archived(KbService 内已有 transition 语义,读源码确认方法名;若服务层没有显式 transition 方法,通过 update_entity 的 status 字段走 assert_transition 校验——以代码为准)。

现状

apps/admin/__init__.py(占位注释 FR-ADM-01~05)——你填充;无其它骨架。

3. 实现要点

允许改动:apps/admin/**、测试文件。不改任何 packages/(服务层已齐;发现缺口写进偏差说明)。**

  1. apps/admin/app.py:create_admin_app(settings) -> FastAPI;lifespan 里建 DB engine 复用 packages.shared.db;挂 RequestContextMiddleware、统一异常处理(packages.shared.handlers);路由前缀 /admin/api/v1(与客户端 API 区分);docs 仅 local。
  2. apps/admin/deps.py:admin_auth 依赖(读 X-Admin-Token,空配置 → 全部路由在装配时不注册或请求时 404——选装配时不注册,404 语义更干净);session 依赖(仿 apps/api/deps.session_dep,不 import 它)。
  3. 路由(每域一个 router 文件,全部经 admin_auth):
    • 实体:GET/POST /kb/items、GET/PATCH /kb/items/{id}、POST /kb/items/{id}/transition(body {target: "reviewing"|"published"|"archived"},走服务层状态机;发布成功后调用 rules service invalidate() + retrieval invalidate_cache()——发布编排是后台的职责,这就是 T-P2-10 的"自然失效"入口)、GET /kb/items/{id}/graph;
    • 规则:GET/POST /rules、PATCH /rules/{id}、POST /rules/{id}/transition(发布同样触发双 invalidate);
    • 素材:POST /assets(登记)、GET /assets(entity/tryon_ready 过滤)、POST /assets/{id}/review(审核);
    • 缺口看板:GET /kb/gaps(limit/offset,直接返回 list_gaps 结果)。
  4. 模块 docstring:V1 极简鉴权的边界(共享令牌、无审计日志字段、无角色)与升级路径(运营账号体系属 V2;操作留证当前靠 structlog request_id)。

4. 测试要求

  • 单测 tests/unit/test_admin_app.py:ADMIN_TOKEN="" 时所有路由 404(用 TestClient 打几个代表路径);令牌错误 → 40100;正确令牌 → 200(服务层用假 session 或只测装配层,不连库——若 router 直接依赖 DB session,把鉴权/404 逻辑测在装配层即可)。
  • 集成 tests/integration/test_admin_console.py(新文件,允许跑):
    1. 顾问全流程不碰客户端 API:建实体 → reviewing → published → 建规则 → 发布 → 断言规则可被 PublishedRules 缓存载入、检索新内容可见(简化断言:发布后 invalidate 被调用的副作用可观察——直接再查库即可);
    2. 非法跃迁 published→draft → 40900;
    3. 素材:登记(tryon_ready 恒 False)→ 审核 approved+tryon_ready=true → 列表过滤 tryon_ready=true 命中;
    4. 审核不通过时 tryon_ready=true → 400(服务层约束透传);
    5. 缺口:预插两行 kb_gap → GET /kb/gaps 按 hit_count 降序;
    6. 无令牌/错令牌 → 401。

5. 禁改清单

通用禁改之外:全部 packages/**、apps/api/**、所有已有测试文件。

6. 验收标准(T-P2-09)

  1. 实体/规则/素材/缺口四类操作全部有 HTTP 入口,鉴权生效(空 token 404、错 token 401);
  2. 发布编排(publish → rules invalidate + retrieval invalidate_cache)落地;
  3. 集成测试覆盖顾问全流程(无工程介入语义);
  4. 全部检查绿(mypy 范围:apps packages/shared ... packages/retrieval 全列——照 T6 文档同口径,含你的 apps/admin)。

7. 提交信息

feat(admin): minimal console for KB content operations

apps/admin 独立应用:X-Admin-Token 鉴权(空=404)、实体/规则维护与状态机、
发布编排(双 invalidate)、素材登记与审核、缺口看板(T-P2-09,FR-ADM-01~05)。

偏差说明:<如有写在这里,无则写"无">