---
url: /docs/api-docs/v1/admin.md
---
# Admin MIS 管理后台（v1）

> 统一前缀：`/api/v1/admin/`
> 82 use case / 12 子域（auth / dashboard / user / content / order / withdrawal / review / interpret / release / channel / config / misc）
> 契约权威 = 代码本体：`src/app/admin/interface/api/*.py`（16 路由模块）
> Swagger 调试：`{BASE_URL}/docs`

## 子域文档索引

| 子域 | Phase | action 数 | 路径前缀 | 文档 |
|---|---|---|---|---|
| auth（adminLogin） | P0+P1 | 3 | `/api/v1/admin/auth/*` | [auth](/api-docs/v1/admin/auth) |
| dashboard | P0+P1 | 5 | `/api/v1/admin/dashboard/*` | [dashboard](/api-docs/v1/admin/dashboard) |
| user（C 端用户管理） | P1 | 10 | `/api/v1/admin/user/*` | [users](/api-docs/v1/admin/users) |
| content（内容管理） | P2-A | 8 | `/api/v1/admin/content/*` | [content](/api-docs/v1/admin/content) |
| order（订单管理） | P2-B | 10 | `/api/v1/admin/order/*` | [orders](/api-docs/v1/admin/orders) |
| withdrawal（提现审批） | P2-B | 6 | `/api/v1/admin/withdrawal/*` | [withdrawals](/api-docs/v1/admin/withdrawals) |
| review（评价审核） | P2-A | 5 | `/api/v1/admin/review/*` | [reviews](/api-docs/v1/admin/reviews) |
| interpret（解读报告） | P3 | 5 | `/api/v1/admin/interpret/*` | [interpret](/api-docs/v1/admin/interpret) |
| release（App 版本发布） | P3 | 5 | `/api/v1/admin/release/*` | [release](/api-docs/v1/admin/release) |
| channel（支付/分发渠道） | P3 | 5 | `/api/v1/admin/channel/*` | [channels](/api-docs/v1/admin/channels) |
| config（系统/业务/灰度/告警配置） | P3 | 12 | `/api/v1/admin/config/*` | [config](/api-docs/v1/admin/config) |
| misc（审计/操作/错误日志/字典/通知） | P3 | 5 | `/api/v1/admin/misc/*` | [misc](/api-docs/v1/admin/misc) |
| agreement（协议发布 — 用户协议/隐私政策） | — | 1 | `/api/v1/admin/agreement/*` | [agreement](/api-docs/v1/admin/agreement) |
| storage（存储管理 — STS 直传链路） | R11 | 7 | `/api/v1/admin/storage/*` | [storage](/api-docs/v1/admin/storage) |

## 公共约定（先读这节，后面不重复）

### 统一信封

* **成功**：`{ "code": "0", "msg": "ok", "data": { ... } }`（HTTP 200）
* **业务失败**：HTTP 200 + `{ "code": "40201xxx", "msg": "...", "data": null }`
  （例外见下方「HTTP 状态映射」）
* **RBAC 权限不足**：HTTP **403** + `{ "code": "40201004", "msg": "..." }`

### 鉴权（admin token — 独立体系）

admin 是**独立鉴权**，不复用 OAuth 用户 JWT：

1. `POST /api/v1/admin/auth/login`（username + password）→ 返回 `tokens {access, refresh}`
2. 后续全部请求带 `Authorization: Bearer <access_token>`
3. token 缺失/无效 → HTTP 401 + `{ "code": "40201002" }`

`GET /api/v1/admin/auth/me` 可查当前角色 + 权限清单（前端刷新 role / permissions 用）。

### 响应字段命名约定 ⚠️

* **admin 响应 data 为 snake\_case**（`asdict()` 语义）—— 与 OAuth / user / device 域的 camelCase 不同！
  例：`page_size` / `total_users` / `banned_until` / `new_role`
* **例外**：`GET /dashboard/overview` 的 P0 存量字段为 camelCase
  （`totalAdmins` / `roleDistribution` / `recentLogins24h`），与 snake\_case 新字段**混合返回**
* 请求侧：POST body 与 Query 参数均为 snake\_case（前端需注意转换）

### RBAC 权限矩阵（ADR-0009）

三角色 × 26 权限位，编译期冻结（`src/app/admin/domain/entities/permissions.py`）：

| 子域 | 权限位 | super | operator | it |
|---|---|---|---|---|
| auth | `admin:login` / `admin:logout` / `admin:me` | ✅ | ✅ | ✅ |
| dashboard | `dashboard:read` | ✅ | ✅ | ✅ |
| user | `user:read` / `user:ban` / `user:write` | ✅ | ✅ | ❌ |
| content | `content:read` / `content:write` / `content:review` | ✅ | ✅ | ❌ |
| order | `order:read` / `order:write` / `order:refund` | ✅ | ✅ | ❌ |
| withdrawal | `withdrawal:read` / `withdrawal:approve` | ✅ | ✅ | ❌ |
| review | `review:read` / `review:approve` | ✅ | ✅ | ❌ |
| interpret | `interpret:read` / `interpret:write` | ✅ | ✅ | ✅ |
| release | `release:read` / `release:write` | ✅ | ❌ | ✅ |
| channel | `channel:read` / `channel:write` | ✅ | ❌ | ✅ |
| config | `config:read` / `config:write` | ✅ | ❌ | ✅ |
| misc | `misc:read` | ✅ | ❌ | ✅ |

**权限不足响应**：HTTP 403 + `{ "code": "40201004", "msg": "权限不足: <permission>" }`
（`40201004` 与 NOT\_FOUND 同码 Enum 别名 — 靠 HTTP 状态区分：403=权限不足 / 404=资源不存在）

### HTTP 状态映射

默认**业务失败 HTTP 200**（与 OAuth 同源），仅以下例外：

| code | HTTP | 场景 |
|---|---|---|
| `40201001` PARAM\_INVALID | 400 | 参数非法（缺字段 / 格式错 / confirm\_text 错） |
| `40201002` UNAUTHORIZED | 401 | 未登录 / token 无效 |
| `40201003` FORBIDDEN / `40201006` USER\_BANNED | 403 | 无权限 / 账号封禁 |
| `40201004` | 403（RBAC 守卫）/ 404（NOT\_FOUND 路径） | 双语义 |
| `40201007` INTERNAL\_ERROR | 500 | 内部错误 |

### 错误码区段（40201xxx）

| 区段 | 子域 | 范围 |
|---|---|---|
| 通用 | — | 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（40201501 与 LOGIN\_FAILED 同码别名） |
| 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 |

### 高敏感操作（confirm\_text 双二次确认）

以下 6 个操作要求请求体携带**逐字常量** `confirm_text`，不匹配 → `40201001`（400）：

| 操作 | confirm\_text 值 | 文档 |
|---|---|---|
| `order/refund` | `"REFUND"` | [orders](/api-docs/v1/admin/orders) |
| `order/adjust-price` | `"ADJUST"` | [orders](/api-docs/v1/admin/orders) |
| `withdrawal/payout` | `"PAYOUT"` | [withdrawals](/api-docs/v1/admin/withdrawals) |
| `user/delete` | `"DELETE"` | [users](/api-docs/v1/admin/users) |
| `release/rollback` | `"ROLLBACK"` | [release](/api-docs/v1/admin/release) |
| `channel/close` | `"CLOSE"` | [channels](/api-docs/v1/admin/channels) |

### 审计留痕（ADR-0010）

全部写操作必写 audit log（`operator_id` + `before` / `after` + `ip` + `ua`）。
`ip` 取 `X-Forwarded-For` 首段（nginx 代理后），`ua` 取 `User-Agent` —— **由服务端自动采集，不在请求体里传**。
回查入口：`GET /api/v1/admin/misc/audit-logs`。

### 路由注册顺序（P0 兼容）

`main.py` 中 `dashboard_v1`（P1 superset）**先于** P0 `dashboard` 注册（FastAPI 首匹配胜出）——
`/dashboard/overview` 实际命中 v1 版本，P0 字段合并在其中返回。存量前端无感。

### P0 legacy 端点（保留兼容）

| 端点 | 说明 | 文档 |
|---|---|---|
| `GET /api/v1/admin/dashboard/overview` | P0 版被 v1 superset 覆盖（同路径） | [dashboard](/api-docs/v1/admin/dashboard) |
| `GET /api/v1/admin/users` | admin 账号列表（require\_role super/operator） | [users](/api-docs/v1/admin/users) |
| `GET /api/v1/admin/tenants/me` | 当前租户（`X-Tenant-Schema` / `X-Tenant-ID` header 解析） | 本页 |
| `GET /api/v1/admin/sms-mock` | mock 短信列表（`?limit=N`，dev only；非 mock 模式返回 409） | 本页 |
| `GET /api/v1/admin/sms-mock/{phone}` | 指定手机号的最近 mock 短信（⚠️ 仅 dev；无记录 404） | 本页 |

### 实现参考

* 完整设计：`docs/internal-wiki/architecture/admin-mis-design.md`（§2 RBAC / §3 行动表 / §6 错误码 / §7 验收）
* 模块结构 + 端口契约：`src/app/admin/CLAUDE.md`
