Appearance
模块手册 · 管理域(admin)
收录 1 个模块的权威开发手册(源自各模块
CLAUDE.md,随仓库同步)。
本文目录
- admin
1. admin 模块
源:
src/app/admin/CLAUDE.md(随仓库同步)
src/app/admin/
admin MIS 后台管理域 — DDD 4 层架构,82 use case 全栈落地。
模块职责
admin 是面向 B 端运营/运维人员的内部管理后台 API,覆盖以下 12 个子域:
| 子域 | Phase | use case 数 | 角色分配 | 文档 |
|---|---|---|---|---|
auth(adminLogin) | P0 + P1 | 3 | 三角色共享 | §3.1 |
dashboard | P0 + P1 | 6 | 三角色共享 | §3.2 |
user(C 端用户管理) | P1 | 10 | super + operator | §3.3 |
content(内容审核) | P2-A | 8 | super + operator | §3.4 |
order(订单管理) | P2-B | 10 | super + operator | §3.5 |
withdrawal(提现审批) | P2-B | 6 | super + operator | §3.6 |
review(评价审核) | P2-A | 5 | super + operator | §3.7 |
interpret(解读报告) | P3 | 5 | 三角色共享 | §3.8 |
release(App 版本发布) | P3 | 5 | super + IT | §3.9 |
channel(支付/分发渠道) | P3 | 5 | super + IT | §3.10 |
config(系统/业务/灰度/告警配置) | P3 | 12 | super + IT | §3.11 |
misc(审计/操作/错误日志/字典/通知) | P3 | 5 | super + IT | §3.12 |
合计 82 use case(含 P0 legacy 3 个保留位:admin_login / dashboard / list_admins)。
DDD 4 层结构
src/app/admin/
├── domain/ # 零 web 框架依赖(已被 scripts/check_layers.py 卡控)
│ ├── entities/ # 11 个 dataclass + Enum 状态机
│ │ ├── admin_user.py # AdminUser + AdminRole (SUPER/OPERATOR/IT)
│ │ ├── end_user.py # C 端用户(与 oauth.User 物理隔离)
│ │ ├── permissions.py # Permission 枚举 + ROLE_PERMISSIONS 编译期矩阵
│ │ ├── content.py # Content + Comment
│ │ ├── review.py # Review + ReviewStatus
│ │ ├── order.py # Order + OrderStatus
│ │ ├── withdrawal.py # Withdrawal + WithdrawalStatus
│ │ ├── interpret.py # InterpretReport + InterpretReportStatus + Measurement
│ │ ├── release.py # AppVersion + VersionStatus + RolloutStrategy
│ │ ├── channel.py # Channel + ChannelStatus + ChannelType
│ │ └── dictionary.py # DictionaryEntry(config/misc 双读)
│ ├── value_objects/ # (暂无 — P3 待扩展)
│ ├── events/ # (暂无 — 事件总线在 application 层)
│ ├── repositories.py # —(端口在 application 层)
│ └── exceptions.py # AdminErrorCode (40201xxx) + AdminError
│
├── application/ # use case 编排 + 端口契约(与 OAuth 同源 P5 范式)
│ ├── ports/
│ │ ├── repositories.py # 17 个 Port(EndUser / Content / Order / Interpret / Channel 等)
│ │ └── services.py # AdminTokenServicePort / PasswordHasherPort / ImpersonationTokenPort
│ ├── usecase/ # 82 use case(按子域分文件)
│ │ ├── admin_login.py / admin_session.py # auth 3 use case
│ │ ├── dashboard.py / dashboard_stats.py # dashboard 6 use case
│ │ ├── user_query.py / user_ban.py / user_role.py / user_account.py / user_impersonate_invite.py
│ │ ├── content_mgmt.py / review_mgmt.py # content 8 + review 5
│ │ ├── order_mgmt.py / withdrawal_mgmt.py # order 10 + withdrawal 6
│ │ ├── interpret_mgmt.py # interpret 5(三角色共享)
│ │ ├── release_mgmt.py # release 5(rollback 高敏感)
│ │ ├── channel_mgmt.py # channel 5(close 高敏感)
│ │ ├── config_mgmt.py # config 12(四组 GET/PATCH + 字典 CRUD)
│ │ └── misc_mgmt.py # misc 5(全只读)
│ └── factories/
│ └── create_admin_usecases.py # 聚合工厂:注入全部 port → use_cases dict
│
├── infrastructure/ # 端口实现(默认 InMemory,生产可换 SQLModel)
│ ├── adapters/
│ │ ├── scrypt_password_hasher.py # scrypt 密码哈希
│ │ └── admin_token_service.py # SimpleAdminTokenService + SimpleImpersonationTokenService
│ └── persistence/
│ └── inmemory_admin_repositories.py # 17 个 InMemory 实现 + seed_dev_fixtures + reset_for_test
│
└── interface/ # FastAPI 路由 + RBAC 守卫 + 异常处理
├── api/ # 16 个路由模块(每个子域一个)
│ ├── auth.py / dashboard.py / dashboard_v1.py
│ ├── users.py / tenants.py / user_mgmt.py
│ ├── content_mgmt.py / review_mgmt.py
│ ├── order_mgmt.py / withdrawal_mgmt.py
│ ├── interpret_mgmt.py / release_mgmt.py
│ ├── channel_mgmt.py / config_mgmt.py / misc_mgmt.py
│ └── sms_mock.py
├── dependencies.py # cz_require_permission() RBAC 守卫(Permission 注入)
├── normalizer.py # (顶层宽容归一化 — 与 oauth 同源)
└── handlers.py # register_admin_exception_handlers(顺序敏感 — OATH-M-006 同款)入口与启动
FastAPI 路由注册(src/main.py 第 326-353 行 — 顺序敏感):
python
## ⚠️ dashboard_v1 先于 P0 dashboard 注册(FastAPI 首匹配胜出)
app.include_router(cz_build_dashboard_v1_router(...)) # P1 superset
app.include_router(build_admin_dashboard_router(...)) # P0 legacy
app.include_router(build_admin_users_router(...)) # P0 legacy
app.include_router(cz_build_user_mgmt_router(...)) # P1 user
app.include_router(cz_build_content_mgmt_router(...)) # P2-A content
app.include_router(cz_build_review_mgmt_router(...)) # P2-A review
app.include_router(cz_build_order_mgmt_router(...)) # P2-B order
app.include_router(cz_build_withdrawal_mgmt_router(...)) # P2-B withdrawal
app.include_router(cz_build_interpret_mgmt_router(...)) # P3 interpret
app.include_router(cz_build_release_mgmt_router(...)) # P3 release
app.include_router(cz_build_channel_mgmt_router(...)) # P3 channel
app.include_router(cz_build_config_mgmt_router(...)) # P3 config
app.include_router(cz_build_misc_mgmt_router(...)) # P3 misc
app.include_router(build_admin_auth_router(...)) # auth
app.include_router(cz_build_tenants_router(...)) # 多租户端口前缀:所有 admin 端点统一 /api/v1/admin/,子路径映射子域(例 user/list、release/rollback)。
对外接口(按 Phase 分组)
P1:dashboard / user / auth(已稳定)
GET /api/v1/admin/dashboard/{overview,user-growth,order-stats,revenue,anomalies}— 5 dashboard action/api/v1/admin/user/{list,detail,ban,unban,promote,demote,reset-password,delete,impersonate,invite}— 10 user action/api/v1/admin/auth/{login,logout,me}— 3 auth action
P2-A:content / review(已稳定)
/api/v1/admin/content/{list,detail,publish,unpublish,feature,tag,categorize,moderate-comment}— 8 content action/api/v1/admin/review/{list,detail,approve,reject,handle-appeal}— 5 review action
P2-B:order / withdrawal(已稳定 + 财务链路 E2E)
/api/v1/admin/order/{list,detail,refund,close,close-reasons,update-logistics,return-goods,adjust-price,update-address,update-recipient}— 10 order action/api/v1/admin/withdrawal/{list,detail,approve,reject,payout,recall}— 6 withdrawal action
P3:interpret / release / channel / config / misc(新完成)
/api/v1/admin/interpret/{health-data,body-composition,report-list,report-detail,write}— 5 action/api/v1/admin/release/{version-list,version-detail,set-rollout,force-upgrade,rollback}— 5 action(rollback 高敏感 confirm_text='ROLLBACK')/api/v1/admin/channel/{list,detail,set-config,switch,close}— 5 action(close 高敏感 confirm_text='CLOSE')/api/v1/admin/config/{system,business,rollout,alert,dictionary}— 5 action(dictionary 含 list/create/update/delete)/api/v1/admin/misc/{audit-logs,operation-logs,error-logs,data-dictionary,notifications}— 5 action
关键依赖与配置
应用层端口契约(17 个 Port)
定义于 src/app/admin/application/ports/repositories.py:
| Port | InMemory 实现 | 备注 |
|---|---|---|
AdminUserRepositoryPort | InMemoryAdminUserRepository | admin_user 表(与 OAuth user 物理隔离) |
EndUserRepositoryPort | InMemoryEndUserRepository | 3 方法极简(§5.1 端口最小化) |
UserAggregatePort | InMemoryUserAggregateRepository | detail 页 + delete 前置校验 |
DashboardStatsPort | InMemoryDashboardStatsRepository | 3 方法 |
ContentRepositoryPort / CommentRepositoryPort | InMemoryContent/CommentRepository | content 8 use case 共享 |
ReviewRepositoryPort | InMemoryReviewRepository | |
OrderRepositoryPort | InMemoryOrderRepository | 财务链路核心 |
WithdrawalRepositoryPort | InMemoryWithdrawalRepository | 提现审批 |
NotificationPort | InMemoryNotificationRepository | withdrawal/order 通知 |
InterpretRepositoryPort | InMemoryInterpretRepository | P3 interpret 5 use case |
ReleaseRepositoryPort | InMemoryReleaseRepository | P3 release 5 use case |
ChannelRepositoryPort | InMemoryChannelRepository | P3 channel 5 use case |
ConfigRepositoryPort | InMemoryConfigRepository | P3 config 12 use case + dictionary |
AuditLogRepositoryPort | InMemoryAuditLogRepository | 全部写操作 audit 留痕 |
LogQueryPort | InMemoryLogQueryRepository | P3 misc(operation-logs/error-logs) |
InviteRepositoryPort | InMemoryInviteRepository | P1 user invite action |
PermissionServicePort | (由 cz_role_has_permission() 兜底) | RBAC 域层判定 |
服务层端口(3 个 Port)
定义于 src/app/admin/application/ports/services.py:
| Port | 默认实现 |
|---|---|
PasswordHasherPort | ScryptPasswordHasher(scrypt 哈希,dev/test 共用) |
AdminTokenServicePort | SimpleAdminTokenService(JWT 签发/校验) |
ImpersonationTokenPort | SimpleImpersonationTokenService(admin 模拟 C 端 user) |
Dev 种子(main.py on_startup)
- 3 个 admin 账号:
admin/admin123(SUPER) /admin_ops/ops12345(OPERATOR) /admin_it/it123456(IT) - 全部 InMemory 仓储调用
seed_dev_fixtures()(interpret/release/channel/config/log_query 均为空种子兜底)
数据模型(domain/entities/)
实体清单(11 个核心实体)
| 实体 | 关键字段 | 状态机 |
|---|---|---|
AdminUser | id, username, password_hash, role, status | ACTIVE/SUSPENDED/BANNED |
EndUser | id, phone, nickname, role, status | ACTIVE/BANNED/DELETED |
Content / Comment | id, title, body, status | DRAFT/PUBLISHED/UNPUBLISHED/FEATURED |
Review | id, content_id, user_id, rating, status | PENDING/APPROVED/REJECTED/APPEALED |
Order | id, user_id, amount, status, items | PENDING/PAID/REFUNDED/CLOSED |
Withdrawal | id, user_id, amount, status | PENDING/APPROVED/REJECTED/PAID/RECALLED |
InterpretReport | id, user_id, status, ai_interpretation, interpretation_content | PENDING/AI_GENERATED/INTERPRETED |
Measurement | type, value, unit, measured_at | (无状态机 — 派生数据) |
AppVersion | id, version_code, status, rollout_, rolled_back_ | DRAFT/TESTING/GRAY/RELEASED/ROLLED_BACK/SUSPENDED |
Channel | id, type, status, config, migration_strategy | ACTIVE/INACTIVE/CLOSED |
DictionaryEntry | type, code, label, value, sort | (无状态机 — CRUD + 幂等键 (type,code)) |
业务码体系(AdminErrorCode)
错误码区间 40201xxx(与 OAuth 40101xxx 完全隔离)。详见 src/app/admin/domain/exceptions.py:
| 区段 | 子域 | 范围 |
|---|---|---|
| 通用 | — | 40201001-099 |
| user | §6.3 | 40201101-105 |
| content | §6.4 | 40201201-208 |
| order | §6.5 | 40201301-310 |
| withdrawal | §6.6 | 40201401-406 |
| auth / review | §6.7 | 40201501-504 |
| interpret | §6.8 | 40201601-604 |
| release | §6.9 | 40201701-706 |
| channel | §6.9 | 40201721-723 |
| config / dictionary | §6.9 | 40201741-744 |
| misc | §6.9 | 40201761-762 |
⚠️ HTTP 状态映射默认 200(与 OAuth 同源),仅 UNAUTHORIZED (401) / FORBIDDEN / USER_BANNED (403) / NOT_FOUND (404) / PARAM_INVALID (400) 例外。
⚠️ PERMISSION_DENIED = NOT_FOUND (Enum 别名) — 走 cz_require_permission(http_status=403) 区分,存量 NOT_FOUND → 404 行为不变。
测试与质量
测试覆盖
| 文件 | 范围 | 用例数(估算) |
|---|---|---|
tests/integration/test_admin_mis_p3.py | P3 interpret + release + channel + config + misc E2E | 25+ |
tests/unit/application/test_p3_usecases.py | P3 use case 单元(含错误分支) | 30+ |
tests/unit/domain/test_permissions.py | RBAC 矩阵单测(含修正后 IT 三角色共享 interpret) | 15+ |
| 旧 P1/P2 集成测试 | dashboard / user / content / review / order / withdrawal E2E | (先前 commit 累计) |
质量门禁
- 覆盖率 ≥ 80%(
pyproject.toml --cov-fail-under=80) - Ruff + mypy strict(pre-commit hooks)
- DDD 4 层守卫:
scripts/check_layers.py— domain 层零 web 框架依赖 - ExceptionHandler 注册顺序:
scripts/check_exception_handlers.py - RBAC 矩阵冻结:Phase 1 冻结矩阵 IT 仅 interpret:read;Phase 3 修正为 interpret:write 三角色共享(与 §2.2 §3.8.5 对齐)
关键 E2E 链路(§7.5 验收)
| 子域 | 链路 | 错误分支覆盖 |
|---|---|---|
| release 回滚 | rollback(confirm_text='ROLLBACK') → 版本 rolled_back → force-upgrade 下发规则 → audit 闭环 | 40201701/703/706 |
| channel 切换 | switch 旧渠道(active→inactive)→ 新渠道(→active)→ list 流量指向断言 + audit | 40201721/722/723 |
| order 退款 | refund → 渠道余额扣减 → audit → notification | 40201302-310 |
| withdrawal 打款 | approve → payout → notification | 40201401-406 |
| interpret 写解读 | pending/ai_generated → write → interpreted + audit | 40201601-604 |
常见问题 (FAQ)
Q1: 为什么 admin 模块实体放在 src/app/admin/domain/entities/ 而不是 models/? A: DDD 4 层规范。entities/ 是域对象(dataclass + 业务行为),models/ 是 ORM 映射(生产可挂在 infrastructure/persistence/sqlmodel_models/)。当前默认 InMemory 实现无需 ORM 层。
Q2: 如何新增一个子域(如 marketing)? A: 参见 src/app/admin/application/usecase/interpret_mgmt.py(5 use case 范例)— 流程:
domain/entities/新建实体 + 状态机domain/exceptions.py追加错误码区段(§6.x 章节)application/ports/repositories.py定义 Portapplication/usecase/<sub>_mgmt.py实现 use case(每 use case 一个类 + Request/Response dataclass)infrastructure/persistence/inmemory_admin_repositories.py实现 Port + seed_dev_fixturesinterface/api/<sub>_mgmt.py注册路由 + RBAC 守卫application/factories/create_admin_usecases.py聚合注入main.py装配并app.include_routerdomain/entities/permissions.py追加 Permission + ROLE_PERMISSIONS 矩阵tests/unit/application/test_<sub>_usecases.py+tests/integration/test_admin_mis_<phase>.py
Q3: 为什么 interpret 是三角色共享而 release/channel/config/misc 只给 IT? A: 设计文档 §2.2 RBAC 矩阵:
- interpret 业务协作(operator 写解读报告 + IT 系统标注)
- release/channel/config/misc 是 IT 专属的系统级操作(不影响业务数据流)
- super 拥有全部权限(应急接管)
Q4: 高敏感操作的 confirm_text 双二次确认如何工作? A: release/rollback 要求 confirm_text="ROLLBACK",channel/close 要求 confirm_text="CLOSE" — use case 入口第一行校验,错误 → 40201001 PARAM_INVALID。审计通过 AuditLogRepositoryPort.write() 留痕(operator_id + before + after + ip + ua)。
相关文件清单
src/app/admin/
├── CLAUDE.md ← 本文件
├── domain/entities/{admin_user,end_user,permissions,content,review,order,withdrawal,
│ interpret,release,channel,dictionary}.py
├── domain/exceptions.py ← AdminErrorCode (40201xxx)
├── application/ports/repositories.py ← 17 个 Port
├── application/ports/services.py ← 3 个服务 Port
├── application/usecase/ ← 19 个文件 = 82 use case
├── application/factories/create_admin_usecases.py
├── infrastructure/adapters/{scrypt_password_hasher,admin_token_service}.py
├── infrastructure/persistence/inmemory_admin_repositories.py
├── interface/api/ ← 16 个路由模块
├── interface/dependencies.py ← cz_require_permission() 守卫
└── interface/handlers.py ← 异常映射注册
tests/
├── integration/test_admin_mis_p3.py ← P3 E2E(interpret/release/channel/config/misc)
├── unit/application/test_p3_usecases.py ← P3 use case 单元
└── unit/domain/test_permissions.py ← RBAC 矩阵(含 IT 三角色共享 interpret 修正)变更记录 (Changelog)
| 日期 (Asia/Shanghai) | 版本 | 变更 |
|---|---|---|
| 2026-09-16 11:24:07 | 0.4.0 | admin 模块完整 CLAUDE.md — 82 use case + 12 子域 + RBAC + 业务码 + DDD 4 层结构 |
| 2026-09-15 22:00:00 | 0.3.0 | admin MIS Phase 1 + 2-A + 2-B + RBAC 矩阵(commit 0b9a2a7/bbe16dd/d2cf0c1/b2dced3) |
| 2026-09-15 20:05:33 | 0.1.0 | 空仓库首次规划 |