角色权限、RequirePermission、/me permissions 与 migration 000015; Reviewer Approve → Closed。Next:ECR-013B Contract Definition。 Co-authored-by: Cursor <cursoragent@cursor.com>
152 lines
5.0 KiB
Markdown
152 lines
5.0 KiB
Markdown
# Feature Spec: 运营后台 RBAC(Ops · ECR-013A)
|
||
|
||
> Status: `Active`(**Closed** · Feature Complete)· Map: `§7 运营后台` · Phase: `Ops-D`
|
||
> Parent: **WAVE0-FROZEN** (`27f27a1`)
|
||
> ESS: `docs/ECR/ECR-013A-admin-rbac.md`(**Closed**)
|
||
> Capability: `AdminGovernance` · BC: `Admin_RBAC`
|
||
> 模板:`docs/WAVE0/contracts/OPS-CONTRACT-TEMPLATE.md`
|
||
|
||
---
|
||
|
||
## ESS 门禁
|
||
|
||
1. Change Level = **L2** → 已 Approved + Coding auth + Implemented + **Closed**
|
||
2. ~~Contract Definition only~~ — 已完成
|
||
3. 实现证据:`docs/TEST_REPORT/ECR-013A.md` · `docs/CODE_REVIEW/ECR-013A.md`
|
||
|
||
---
|
||
|
||
## L0 Capability
|
||
|
||
| 字段 | 内容 |
|
||
|------|------|
|
||
| Capability ID | `AdminGovernance` |
|
||
| Purpose | 以最小权限原则约束管理员可执行的运营动作 |
|
||
| Why now | Ops-A 全员等价权限;进入 M1+ 前必须有权限面,否则越权不可治理 |
|
||
| Non-goals | 用户账户启停(ECR-013B);兑换码;CMS;Ask Prompt;真支付;UGC |
|
||
|
||
---
|
||
|
||
## L1 Bounded Context
|
||
|
||
| 字段 | 内容 |
|
||
|------|------|
|
||
| Primary BC | `Admin_RBAC` |
|
||
| owns | `AdminRole` · `AdminPermission` |
|
||
| does_not_own | `User` · `Profile` · `UserStatus` · `Membership` · `Payment` |
|
||
| allowed | `Admin_Auth_Audit.write_audit` |
|
||
| forbidden | `Payment` · `Membership.write` · `DeviceAuth.user_token_issue` |
|
||
|
||
权威:`.ai/domain/boundary-rules.md`
|
||
|
||
---
|
||
|
||
## 1. 功能定义
|
||
|
||
| 字段 | 内容 |
|
||
|------|------|
|
||
| Name | Admin RBAC |
|
||
| Purpose | 角色与权限点绑定;API 级强制鉴权;变更可审计 |
|
||
| Business Goal | 支撑多运营角色,而不扩大 C 端攻击面 |
|
||
|
||
| In | Out |
|
||
|---|---|
|
||
| Role CRUD(最小:list/get/update permissions) | UserStatus / 封禁(013B) |
|
||
| `GET /admin/me` 返回 permissions | 细粒度数据行级 ACL |
|
||
| 既有 admin 写操作挂 permission 检查 | 新业务模块权限爆炸式新增(另 ECR) |
|
||
|
||
---
|
||
|
||
## L2 Domain
|
||
|
||
| Entity | 不变式 |
|
||
|--------|--------|
|
||
| `AdminRole` | `name` 唯一;系统角色 `super_admin` 不可删除 |
|
||
| `AdminPermission` | 稳定字符串码(见下表);只增不改语义 |
|
||
| `AdminAccount.role_id` | 每个账号恰好一个角色(本切片);无角色视为拒绝写操作 |
|
||
|
||
### Permission catalog(本切片冻结)
|
||
|
||
| Code | 覆盖既有能力 |
|
||
|------|----------------|
|
||
| `admin.users.read` | GET users / users/:id / stats |
|
||
| `admin.users.membership.grant` | POST membership/grant |
|
||
| `admin.users.ask_quota.grant` | POST ask-quota/grant |
|
||
| `admin.orders.read` | GET orders |
|
||
| `admin.audit.read` | GET audit-logs |
|
||
| `admin.analytics.read` | GET analytics/*(Ops-B) |
|
||
| `admin.content.write` | home tools / scales publish(Ops-C) |
|
||
| `admin.roles.read` | GET roles |
|
||
| `admin.roles.write` | 变更角色权限 |
|
||
|
||
`super_admin` 种子拥有上表全部。
|
||
|
||
---
|
||
|
||
## L3 API Contract(意图 · 实现轮同步 OpenAPI)
|
||
|
||
前缀:`/api/v1/admin` · AdminAuth · 信封 `{code,message,data}`
|
||
|
||
| Method | Path | 权限 | 语义 |
|
||
|--------|------|------|------|
|
||
| GET | `/roles` | `admin.roles.read` | 角色列表 |
|
||
| GET | `/roles/:id` | `admin.roles.read` | 角色 + permissions[] |
|
||
| PUT | `/roles/:id/permissions` | `admin.roles.write` | 全量替换权限集;写 AuditLog |
|
||
| GET | `/me` | (已登录) | **扩展**返回 `role` + `permissions[]` |
|
||
|
||
既有写接口:在实现轮挂上表 permission;缺权 → **403** + AuditLog(尝试记录)。
|
||
|
||
`contract_diff`:`docs/CONTRACT_DIFF/ECR-013A.yaml`
|
||
|
||
---
|
||
|
||
## L4 Acceptance Criteria
|
||
|
||
### Functional
|
||
|
||
| ID | Given | When | Then |
|
||
|----|-------|------|------|
|
||
| AC-F-01 | super_admin 已登录 | GET `/roles` | 200,含 `super_admin` |
|
||
| AC-F-02 | 角色存在 | PUT permissions 合法集合 | 200;再次 GET 一致 |
|
||
| AC-F-03 | GET `/me` | — | data 含 `permissions` 数组 |
|
||
|
||
### Security
|
||
|
||
| ID | Given | When | Then |
|
||
|----|-------|------|------|
|
||
| AC-S-01 | Admin 无 `admin.roles.write` | PUT `/roles/:id/permissions` | **403**;AuditLog 有拒绝或尝试记录 |
|
||
| AC-S-02 | Admin 无 `admin.users.membership.grant` | POST membership/grant | **403** |
|
||
| AC-S-03 | 仅 DeviceAuth | 访问 `/admin/roles` | **401** |
|
||
| AC-S-04 | 删除 `super_admin` 角色 | 任意 API | **拒绝**(4xx) |
|
||
|
||
### Performance
|
||
|
||
| ID | Given | When | Then |
|
||
|----|-------|------|------|
|
||
| AC-P-01 | 角色数 N≤100 | GET `/roles` | 本机 integration 环境下 P95 **< 500ms** |
|
||
|
||
### Observability
|
||
|
||
| ID | Given | When | Then |
|
||
|----|-------|------|------|
|
||
| AC-O-01 | PUT permissions 成功 | — | AuditLog action 含 `roles.permissions.update` |
|
||
| AC-O-02 | AC-S-01 触发 | — | AuditLog 可追溯 admin_id + path |
|
||
|
||
---
|
||
|
||
## Forbidden(本切片)
|
||
|
||
- UserStatus / AccountLifecycle(**ECR-013B**)
|
||
- 真支付 · UGC · Prompt/RAG · 兑换码 · CMS Banner 新表
|
||
- 改 DeviceAuth / C 端五 Tab
|
||
|
||
---
|
||
|
||
## Implementation Notes(实现轮才执行)
|
||
|
||
| 项 | 内容 |
|
||
|----|------|
|
||
| Migration | YES(roles / permissions 关联;accounts.role_id;种子 super_admin) |
|
||
| Packages | `service/admin` · repo · middleware permission check · admin-h5 只读展示权限(最小) |
|
||
| Parent | WAVE0-FROZEN |
|