docs(ECR-013B): 启动 AccountLifecycle 契约定义

Human Start Authorization:UserStatus 状态机 Spec/BD/contract_diff;
禁止 coding,待 Approve + coding Start Authorization。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jackyu66git
2026-08-07 17:23:04 +08:00
co-authored by Cursor
parent b5a05941d9
commit f75b42397f
17 changed files with 549 additions and 9 deletions
+1 -1
View File
@@ -35,7 +35,7 @@
| Admin_RBAC | AdminGovernance | Draft → ECR-013A |
| Analytics_OpsB | GrowthInsights / UserIntelligence(read) | Shipped Ops-B |
| Ops_Content | ExploreConfig (partial) | Shipped Ops-C |
| Account_Risk | AccountLifecycle | Draft |
| Account_Risk | AccountLifecycle | Spec via ECR-013BIdentity_Profile owns UserStatus |
| Content_Safety | ContentSafety · CrisisCare | Draft |
| Ask_Ops | AskOperations · AICoreConfig | Draft |
| Ops_CMS_NoUGC | OpsCMS | Draft |
+4 -4
View File
@@ -36,8 +36,8 @@ Status: `Draft`
| Banner / FeedSlot | Ops_CMS_NoUGC | OpsCMS | 后置 |
| UGC* | Community | — | **Forbidden** |
## 状态机预告ECR-013B · 仅文档
## 状态机(ECR-013B · 契约已开
`UserStatus`: `active``disabled` | `banned` | `suspended`
`banned` / `disabled` → C 端 DeviceAuth **拒绝**(细则写入 013B AC)。
`deleted` soft-delete **不在 013B**(另开)
`UserStatus`: `.ai/product/feature-spec/ops-account-lifecycle.md`
`deleted` soft-delete **不在 013B**(另开)。
实现轮前:**禁止** migration / DeviceAuth 改动
+1 -1
View File
@@ -235,7 +235,7 @@ UI **不出现「塔罗」**。禁止神谕吉凶、恐吓话术。
| Phase A `[Ops]` | 登录 · 用户/订单查询 · 会员授予 · 审计 · `apps/admin-h5`ECR-006 Closed |
| Phase B `[Ops]` | 行为分析:自有埋点 + 管理端「数据」看板(**ECR-007 Closed** · Spec `ops-analytics.md` |
| Phase C `[Ops]` | 内容:首页宫格 CRUD · 测评上下架(**ECR-008 Closed** · Spec `ops-content.md` |
| Phase D+ | **Contract-First**Capability→BC→Domain→API(+contract_diff)→四类 AC,再 ECR 切片。首波 **ECR-013A** Admin RBAC**ECR-013B** AccountLifecycle。详见 `docs/WAVE0/`。 |
| Phase D+ | **Contract-First**Capability→BC→Domain→API(+contract_diff)→四类 AC,再 ECR 切片。**ECR-013A Closed****ECR-013B** AccountLifecycleContract Definition。详见 `docs/WAVE0/`。 |
| 排除 | **UGC / 社区广场**M10.2)仍 `[No]`;真支付最后 |
不计入 P1 Complete;不进入五 Tab。
+1
View File
@@ -24,6 +24,7 @@
| [ops-analytics.md](ops-analytics.md) | 运营行为分析(埋点+数据看板) | §7 | `admin-h5` `/analytics` · H5 track | Ops-B · ECR-007 Closed |
| [ops-content.md](ops-content.md) | 运营内容(宫格+测评上下架) | §7 | `admin-h5` `/content` · `GET /home/tools` | Ops-C · ECR-008 Closed |
| [ops-rbac.md](ops-rbac.md) | 运营 RBAC | §7 | `admin-h5` `/me` permissions · `/admin/roles*` | Ops-D · **ECR-013A Closed** |
| [ops-account-lifecycle.md](ops-account-lifecycle.md) | 账户生命周期 / UserStatus | §7 | `admin-h5` 用户详情 status CTA · C 端拒绝 | Ops-D · **ECR-013B Draft(契约)** |
新功能:复制 `_TEMPLATE.md` → 填满 → 在本表登记 → 再编码。
@@ -0,0 +1,156 @@
# Feature Spec: 账户生命周期 / UserStatusOps · ECR-013B
> Status: `Active`(契约定义)· Map: `§7 运营后台` · Phase: `Ops-D`
> Parent: **WAVE0-FROZEN** (`27f27a1`) · Predecessor: **ECR-013A Closed**
> ESS: `docs/ECR/ECR-013B-account-lifecycle.md`Draft · Contract Definition · **禁止编码**
> Capability: `AccountLifecycle` · BC: `Identity_Profile`
> 模板:`docs/WAVE0/contracts/OPS-CONTRACT-TEMPLATE.md`
---
## ESS 门禁
1. Change Level = **L2** → 须 ECR + BD **Approved** 后方可改 `apps/`
2. **当前阶段:Contract Definition only**Start Authorization 2026-08-07)— 禁止 migration / handler / DeviceAuth 改动
3. 实现轮:TEST_REPORT 映射全部 AC-ID · contract_diff · boundary-rules 复核
---
## L0 Capability
| 字段 | 内容 |
|------|------|
| Capability ID | `AccountLifecycle` |
| Purpose | 以可审计状态机管理 C 端用户账户启停与封禁,阻断违规会话 |
| Why now | `users.status` 字段已存在但无运营迁移与强制拒绝;013A 权限面就绪后可挂状态写权限 |
| Non-goals | soft-delete / `deleted`;UGC 社区封禁;真支付;Admin 账号启停(已有 admin.status);推送通知 |
---
## L1 Bounded Context
| 字段 | 内容 |
|------|------|
| Primary BC | `Identity_Profile` |
| owns | `User` · `UserStatus` · `AccountStateTransition` |
| does_not_own | `AdminRole` · `Membership` · `Payment` · `BanRecord`Account_Risk 后置加深) |
| allowed | `Admin_Auth_Audit.write_audit`(经 admin 调用) |
| forbidden | `Payment` · `Membership.write` · soft-delete User |
权威:`.ai/domain/boundary-rules.md` · `Account_Risk` 仅允许经明确服务触发 `UserStatus.transition`
---
## 1. 功能定义
| 字段 | 内容 |
|------|------|
| Name | Account Lifecycle / UserStatus |
| Purpose | 运营可迁移用户状态;非 active 会话在 C 端被拒绝 |
| Business Goal | 风险处置最小闭环,不引入社区/UGC |
| In | Out |
|---|---|
| 状态机 `active/disabled/banned/suspended` | soft-delete / GDPR 擦除 |
| Admin 迁移 API + AuditLog + Transition 记录 | 站内推送 / 短信 |
| DeviceAuth / Bearer 对非 active 拒绝 | AdminAccount.status013A 外) |
| 权限码 `admin.users.status.write` | 行级数据 ACL |
---
## L2 Domain
| Entity | 不变式 / 状态机 |
|--------|----------------|
| `UserStatus` | 取值冻结:`active` · `disabled` · `banned` · `suspended`;非法值拒写 |
| `User.status` | 与 `UserStatus` 同值;默认 `active`(已有列) |
| `AccountStateTransition` | 只追加;记录 from→to · admin_id · reason · created_at |
### 合法迁移
```text
active → disabled | banned | suspended
disabled → active | banned
suspended → active | banned | disabled
banned → active | disabled
```
其它边 → **400**。同状态写 → **400**(幂等拒绝,避免空审计噪音)。
### C 端效应
| Status | DeviceAuth / 已登录 Bearer |
|--------|------------------------------|
| `active` | 放行 |
| `disabled` / `banned` / `suspended` | **401**(或 403 统一码,实现轮定一)+ 不可发新 session |
---
## L3 API Contract(意图 · 实现轮同步 OpenAPI)
前缀:`/api/v1/admin` · AdminAuth · 信封 `{code,message,data}`
| Method | Path | 权限 | 语义 |
|--------|------|------|------|
| POST | `/users/:id/status` | `admin.users.status.write` | 迁移 UserStatus;写 Transition + AuditLog |
| GET | `/users/:id/status-transitions` | `admin.users.read` | 最近迁移列表(limit |
既有 `GET /users` · `GET /users/:id` 已暴露 `status` — 保持;实现轮确认枚举文档化。
`contract_diff``docs/CONTRACT_DIFF/ECR-013B.yaml`
RBAC catalog **additive**`admin.users.status.write` → 种子写入 `super_admin`migration)。
---
## L4 Acceptance Criteria
### Functional
| ID | Given | When | Then |
|----|-------|------|------|
| AC-F-01 | 用户 `active` | POST status=`banned` + reason | 200GET user.status=`banned` |
| AC-F-02 | 用户 `banned` | POST status=`active` | 200;可再次 DeviceAuth |
| AC-F-03 | 非法边(如 `active``active` | POST | **400** |
| AC-F-04 | GET status-transitions | — | 含最近 from/to/admin/reason |
### Security
| ID | Given | When | Then |
|----|-------|------|------|
| AC-S-01 | Admin 无 `admin.users.status.write` | POST status | **403** + deny audit |
| AC-S-02 | 用户 `banned` | C 端带原 Bearer 访问受保护 API | **401/403** |
| AC-S-03 | 仅 DeviceAuth 无 Admin | POST `/admin/users/:id/status` | **401** |
| AC-S-04 | 无 Admin session | GET transitions | **401** |
### Performance
| ID | Given | When | Then |
|----|-------|------|------|
| AC-P-01 | transitions ≤1000 行/用户 | GET transitions limit=50 | 本机 P95 **&lt; 500ms** |
### Observability
| ID | Given | When | Then |
|----|-------|------|------|
| AC-O-01 | 迁移成功 | — | AuditLog action=`users.status.transition` |
| AC-O-02 | 迁移成功 | — | `account_state_transitions` 有对应行 |
---
## Forbidden(本切片)
- soft-delete / `deleted` 状态
- 真支付 · UGC · Prompt · 兑换码 · Crisis 深化
- 改 Admin RBAC 模型(仅 **additive** 一枚 permission
- 自动开下一 ECR
---
## Implementation Notes(实现轮才执行)
| 项 | 内容 |
|----|------|
| Migration | YEStransitions 表;permission 种子;必要时 CHECK/注释枚举) |
| Packages | service account/lifecycle · DeviceAuth/session 拒绝 · admin handler · admin-h5 用户详情最小 CTA |
| Depends | ECR-013A Closedpermission middleware |
+2 -1
View File
@@ -209,5 +209,6 @@ Phase A 可先 `console`/本地;不挡验收。
| **BECR-007 Closed** | 自有埋点 · 管理端「数据」看板 — Spec `ops-analytics.md` |
| **CECR-008 Closed** | 首页宫格 CRUD · 测评上下架 — Spec `ops-content.md` |
| **EECR-013A Closed** | Admin RBAC — Spec `ops-rbac.md` · Parent WAVE0-FROZEN |
| **FECR-013B Draft** | AccountLifecycle — Spec `ops-account-lifecycle.md` · **契约中,禁 coding** |
| D | 订单筛选 · 展示价 · 退款只读(另开 ECR) |
| 后置 | AccountLifecycle = **ECR-013B**;封禁加深 · 推送占位 |
| 后置 | 封禁加深(Account_Risk· 推送占位 |