apps/admin 独立应用:X-Admin-Token 鉴权(空=全部路由不注册=404)、实体/规则
维护与状态机流转、发布编排(publish/archive → 规则缓存 invalidate +
retrieval invalidate_cache 双失效)、素材登记与审核(tryon_ready 门禁透传)、
缺口看板(T-P2-09,FR-ADM-01~05)。V1 共享令牌鉴权,无角色无审计字段,
操作留证靠 structlog request_id。
测试:单测 tests/unit/test_admin_app.py(10 例:空令牌 404、错/缺/非 ASCII
令牌 40100、正确令牌 200 假服务、发布编排接线、幂等重放无副作用);
集成 tests/integration/test_admin_console.py(5 例:顾问全流程不碰客户端
API、双失效副作用可观察、非法跃迁 40900、素材审核门禁、缺口看板排序、
令牌 401)。483 单测 + 43 集成全绿;ruff/mypy/lint-imports 全绿。
偏差说明:
1. packages/retrieval.repo.list_gaps 有缺陷:对 select(KbGap) 的结果调
.mappings(),行键是实体名而非列名,GapSummary(row) 取 row.gap_id 必然
AttributeError(该路径无既有测试覆盖,接真库即暴露)。packages/** 本
任务禁改,故缺口查询在 apps/admin/routers/gaps.py 以等价 SQL 自实现
(hit_count 降序、同频次按 last_seen_at 降序、limit/offset 语义一致);
建议合并阶段修复上游后切回 retrieval.list_gaps。
2. 实体 transition 的 target 收全量四态(任务文档示例仅列 reviewing/
published/archived):按任务测试要求 published→draft 必须返回 40900
(状态机语义冲突)而非 schema 422;draft 作为目标由服务层跃迁矩阵恒拒。
3. 规则路由以 rule_key 为路径参数(任务文档写 /rules/{id},但 RuleService
全程以 rule_key 寻址,无按数字 id 的接口,以代码为准)。
4. 发布编排触发面含 archived(撤稿):依据 retrieval.invalidate_cache 的
自身契约「发布/归档知识后调用」,比文档字面的「发布成功后」多了撤稿
方向;reviewing 等其余状态不触发。
5. updated_by/author 记 "admin-console":V1 共享令牌无操作者身份,字段
留渠道来源;运营账号体系属 V2(见包 docstring 的升级路径)。
20 lines
1.3 KiB
Python
20 lines
1.3 KiB
Python
"""极简运营后台(T-P2-09,FR-ADM-01~05):知识内容的维护 / 审核 / 发布 / 回滚入口。
|
||
|
||
与 ``apps/api`` 平级的独立 FastAPI 应用(部署上分离):顾问从这里完成实体、
|
||
规则、素材与缺口看板的全部操作,不再需要工程介入——这是 M2 出口的成败标志。
|
||
|
||
V1 极简鉴权的边界与升级路径:
|
||
|
||
- **共享令牌,无角色**:全后台只有一把 ``X-Admin-Token``(``ADMIN_TOKEN``),
|
||
建库与审核是同一个人。没有「编辑 / 审核分离」的角色体系。
|
||
- **无审计日志字段**:谁在什么时间改了什么,V1 只能靠 structlog 的
|
||
request_id 关联访问日志(service 层的每个写操作都有结构化事件兜底),
|
||
没有独立的审计表。令牌泄露 = 全权限泄露,轮换令牌是唯一的处置手段。
|
||
- **升级路径**:运营账号体系(登录、角色、操作审计)属 V2;届时把
|
||
``apps.admin.deps.admin_auth`` 换成账号会话依赖即可,路由与服务层不动。
|
||
- **空令牌 = 未部署**:``ADMIN_TOKEN`` 为空时应用装配期不注册任何业务路由
|
||
(docs/openapi 一并关闭),所有 admin 端点 404——避免带病上线。
|
||
|
||
应用工厂见 :func:`apps.admin.app.create_admin_app`。
|
||
"""
|