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
@@ -0,0 +1,106 @@
# Backend Design: ECR-013B AccountLifecycle
> Architect 产出;**Contract Definition** — Status DraftApprove 前禁止实现。
> Parent: WAVE0-FROZEN · Predecessor: ECR-013A Closed
| Field | Value |
|-------|-------|
| ID | BD-2026-013B |
| ECR | ECR-013B |
| Change Level | L2 |
| Status | Draft |
| Author | Architect |
| Date | 2026-08-07 |
| Risk | Medium |
---
## Context
- 目标:UserStatus 状态机 + 运营迁移 + C 端拒绝非 active
- 非目标:soft-deleteUGC;真支付;AdminAccount 启停深化
- Spec`ops-account-lifecycle.md` · boundary-rules `Identity_Profile`
## Architecture Change
- 分层边界:**No**
- 受影响层:API(admin) · Application(account/lifecycle 或 admin 协作服务) · Middleware(DeviceAuth) · Infrastructure(repo+migration) · UI(admin-h5 最小)
## Module Changes
| Module | Layer | Change | Must NOT |
|--------|-------|--------|----------|
| account / user status service | App | 迁移 + 边校验 + 事务 | soft-delete |
| DeviceAuth / session | API | 拒绝非 active | 改 Visitor 创建语义 |
| admin handlers | API | POST status · GET transitions | Handler SQL |
| admin_rbac seed | Infra | additive permission | 重做 RBAC |
| admin-h5 | UI | 用户详情 CTA | 直连 DB |
## Data Flow
```text
Admin POST /users/:id/status
→ RequirePermission(admin.users.status.write)
→ validate edge
→ tx: UPDATE users.status + INSERT transition + AuditLog
→ 200
C-end request
→ DeviceAuth / Bearer resolve user
→ if status != active → 401/403
```
## API Changes
- 契约意图见 Spec;实现轮写 `proto/openapi.yaml`
- 兼容:additive;既有 status 字段语义收紧(非 active 开始拒绝)
## Database Changes
- Migration **Required: YES**(实现轮)
- 表:`account_state_transitions`
- Permission 种子:`admin.users.status.write`
- Wave 0 / Contract 轮:**不写 migration 文件**
## Failure Handling
- 非法边 / 同状态:400
- 无权限:403
- 无会话:401
- 用户不存在:404
## Test Plan
- IntegrationAC-F/S/OAC-P-01 本机抽样
- 禁止跳过 Security AC(含 C 端拒绝)
## Rollback Plan
- down migrationDeviceAuth 去掉 status 检查;permission 行可留(无害)
---
## Backend Change Boundary
```text
Change Level: L2
Change: UserStatus transitions + C-end reject non-active
Affected:
Domain: UserStatus, AccountStateTransition
Application: account lifecycle service
Infrastructure: migration + repo
API: /admin/users/:id/status*
Middleware: DeviceAuth / session gate
Migration: Required at implement — NOT in contract phase
Tests: integration admin status + device reject
Risk: Medium
```
## Architecture Regression Check
- [ ] 无 Handler 直连 DB
- [ ] Admin / Device 鉴权隔离
- [ ] UserStatus 归属 Identity_Profile
- [ ] 不拥有 Payment / UGC
- [ ] 符合 boundary-rules
+2
View File
@@ -2,6 +2,8 @@
## 2026-08-07
- **ECR-013B Contract Definition**Start Authorization):AccountLifecycle / UserStatus L0L4 · Spec `ops-account-lifecycle` · BD-2026-013B Draft · `CONTRACT_DIFF/ECR-013B.yaml`
Parent WAVE0-FROZEN · Predecessor ECR-013A Closed · **禁止 coding** · 待 Human Approve
- **ECR-013A Closed**Reviewer ApproveAdmin RBAC
- **ECR-013A Implemented**Admin RBACroles/permissions · RequirePermission · `/me` permissions · admin-h5 最小展示)
TEST_REPORT PASS · STATE Closed
+50
View File
@@ -0,0 +1,50 @@
ecr: ECR-013B
capability: AccountLifecycle
bounded_context: Identity_Profile
parent: WAVE0-FROZEN
predecessor: ECR-013A
change:
type: additive
breaking_change: false
migration_required: true
compatibility_notes: >
users.status already exists (default active).
Non-active users begin to be rejected by DeviceAuth/Bearer (behavior tightening).
New table account_state_transitions (append-only).
RBAC catalog additive: admin.users.status.write seeded to super_admin.
entities:
- name: UserStatus
before:
fields: [status string on users]
notes: no enforced transitions
after:
values: [active, disabled, banned, suspended]
machine: enforced edges
- name: AccountStateTransition
before: null
after:
fields: [id, user_id, from_status, to_status, admin_id, reason, created_at]
- name: AdminPermission
before:
catalog_ref: ECR-013A
after:
catalog_additive:
- admin.users.status.write
apis:
- method: POST
path: /api/v1/admin/users/{id}/status
change: added
- method: GET
path: /api/v1/admin/users/{id}/status-transitions
change: added
security_impact:
- "C-end reject when User.status != active"
- "RequirePermission admin.users.status.write on POST status"
- "403 + AuditLog on deny"
observability_impact:
- "AuditLog users.status.transition"
- "account_state_transitions append-only"
+68
View File
@@ -0,0 +1,68 @@
# ECR-013B
**Title:** AccountLifecycleUserStatus 状态机 · 运营启停/封禁 · C 端拒绝)
**Status:** Draft
**Date:** 2026-08-07
**Start Authorization:** 2026-08-07Human · Contract Definition
**Parent:** WAVE0-FROZEN (`27f27a1`)
**Predecessor:** ECR-013A **Closed**
**Change Level: L2**(行为:账户状态强制;栈与分层不变)
## Change
1. Active Feature Spec`.ai/product/feature-spec/ops-account-lifecycle.md`
2. Domain:落实 `UserStatus` · `AccountStateTransition`
3. API 意图:`POST /admin/users/:id/status` · `GET .../status-transitions`
4. C 端:非 `active` → DeviceAuth/Bearer **拒绝**
5. RBAC additive`admin.users.status.write`
6. **contract_diff**`docs/CONTRACT_DIFF/ECR-013B.yaml`P0
7. **不含** soft-delete / UGC / 真支付
## Motivation
`users.status` 已存在但无运营迁移与会话阻断;013A 权限门禁就绪后可落地最小风控闭环。
## Scope
### Allowed
- Spec L0L4 · Domain 对齐 · BD Draft · AC · feature-map §7 · TRACEABILITY · STATE · TASK
### ForbiddenNon-goals
- coding · migration 文件 · DeviceAuth 实现改动(待 Approve + coding Start Authorization
- soft-delete · GDPR 擦除
- 真支付 · UGC · Prompt · Crisis 深化
## Risk
| Risk | Mitigation |
|------|------------|
| 误封超级用户/自测号 | reason 必填;Audit + transitions;可回迁 active |
| 与 session 缓存不一致 | 每次请求读 User.status(本切片不引入长缓存) |
| 权限码遗漏种子 | migration 写入 super_adminintegration 覆盖 |
## Acceptance Criteria
见 Spec `ops-account-lifecycle.md` L4AC-F-01..04 · AC-S-01..04 · AC-P-01 · AC-O-01..02
契约轮完成标准:
- [x] L0L4 填满
- [x] contract_diff 已交
- [x] BD Draft + HANDOFF(禁 coding
- [ ] Human **Approve** ECR+BD → 方可 Start Authorization coding
## Rollback
- 契约轮:废弃 Draft
- 实现轮:down migration + 回退 DeviceAuth 检查
## Linked
- Feature Spec: `.ai/product/feature-spec/ops-account-lifecycle.md`
- PRODUCT_SPEC: `docs/PRODUCT_SPEC/ECR-013B-account-lifecycle.md`
- ENGINEERING_SPEC: `docs/ENGINEERING_SPEC/ECR-013B-account-lifecycle.md`
- BACKEND_DESIGN: `docs/BACKEND_DESIGN/BD-2026-013B-account-lifecycle.md`
- CONTRACT_DIFF: `docs/CONTRACT_DIFF/ECR-013B.yaml`
- Parent: WAVE0-FROZEN · Predecessor: ECR-013A
@@ -0,0 +1,28 @@
# ENGINEERING_SPEC — ECR-013B AccountLifecycle
权威设计:`docs/BACKEND_DESIGN/BD-2026-013B-account-lifecycle.md`
产品:`.ai/product/feature-spec/ops-account-lifecycle.md`
**当前:Contract Definition — 禁止执行下列 Implement order。**
## Implement order(仅 Approved + coding Start Authorization 后)
1. Migration`account_state_transitions``admin.users.status.write` 种子;必要时 status CHECK
2. Service:合法边校验 · 写 status + transition + audit(同事务)
3. DeviceAuth / session 解析:User.status ≠ active → 拒绝
4. Admin handlersPOST status · GET transitions;挂 `RequireAdminPermission`
5. OpenAPI
6. admin-h5:用户详情最小状态 CTA(依赖 `can('admin.users.status.write')`
7. IntegrationAC-F/S/OPerf 抽样 AC-P-01
8. TEST_REPORT · CODE_REVIEW · TRACEABILITY
## Constraints
- 函数 ≤50 · 文件 ≤400
- Handler → Service → Repository
- 禁止 soft-delete
- 禁止改 RBAC 模型(仅 additive permission
- 不提交密钥
## Done when
ECR Acceptance + 四类 AC 映射绿 + `ess-validate --phase review` + boundary-rules 无回归
@@ -0,0 +1,36 @@
# HANDOFF — ECR-013B Architect → Engineer
## Gate
**Parent:** WAVE0-FROZEN (`27f27a1`)
**Predecessor:** ECR-013A **Closed**
**Start Authorization: 2026-08-07Human)→ Contract Definition only**
**ECR-013B + BD-2026-013B = Draft****禁止改 `apps/`** 直至:
1. Human **Approve** ECR-013B + BD-2026-013B
2. 另发 **coding Start Authorization**
## Consume
1. `.ai/product/feature-spec/ops-account-lifecycle.md`
2. ECR / PRODUCT / ENGINEERING / BD / `docs/CONTRACT_DIFF/ECR-013B.yaml`
3. `.ai/domain/boundary-rules.md` · `glossary.yaml` · `entity-catalog.md`
## Do(仅 Approve + coding auth 后)
按 ENGINEERING_SPEC Implement order。
## Do not
- soft-delete / `deleted`
- 真支付 · UGC · Prompt
- 跳过 Security AC(含 C 端拒绝)
- 重做 RBAC(仅 additive permission
## Return
1. HANDOFF engineer→reviewer
2. TEST_REPORT 映射全部 AC-ID
3. CODE_REVIEW
4. `ess-validate --phase review --ecr ECR-013B`
@@ -0,0 +1,50 @@
# PRODUCT_SPEC — ECR-013B AccountLifecycle
对齐 Feature Spec`.ai/product/feature-spec/ops-account-lifecycle.md`
Parent: **WAVE0-FROZEN** (`27f27a1`) · Predecessor: **ECR-013A Closed**
Phase: **Contract Definition**No Coding
## Meta
| 字段 | 值 |
|------|-----|
| ECR | ECR-013B |
| Status | Draft |
| Capability (L0) | `AccountLifecycle` |
| Bounded Context (L1) | `Identity_Profile` |
| Change Level | L2 |
## L0 Capability
| 字段 | 内容 |
|------|------|
| Capability ID | `AccountLifecycle` |
| Purpose | 可审计的用户账户启停/封禁,并阻断 C 端会话 |
| Why now | status 字段无运营闭环;013A 已提供权限挂载点 |
| Non-goals | soft-delete · UGC · 真支付 · Admin 账号启停深化 |
## L1 Bounded Context
`.ai/domain/boundary-rules.md``Identity_Profile`owns UserStatus)。
## L2 Domain
`UserStatus` · `AccountStateTransition` — glossary 已登记;状态机见 Spec。
## L3 API
见 Spec §L3`docs/CONTRACT_DIFF/ECR-013B.yaml`
## L4 AC
Spec AC-F / AC-S / AC-P / AC-O — 实现轮 TEST_REPORT 必须引用 ID。
## Outcome(实现后)
1. 运营可迁移 UserStatus
2. 非 active C 端拒绝
3. 迁移可审计(AuditLog + Transition
## Out of scope
soft-deletePaymentCommunityECR-013C+。
+2 -2
View File
@@ -46,9 +46,9 @@
## Active anchors
- ECR: **ECR-013A Closed****WAVE0-FROZEN** @ 27f27a1ECR-012 Implementedreview);Next=ECR-013B
- ECR: **ECR-013B** AccountLifecycleContract Definition · Start Authorization · **No Coding**);**ECR-013A Closed****WAVE0-FROZEN** @ 27f27a1
- EXP: (无)
- STATE: `docs/STATE/ECR-013A.md`
- STATE: `docs/STATE/ECR-013B.md`
- Ops foundation: `docs/WAVE0/` · `.ai/domain/boundary-rules.md` · `glossary.yaml`
- TRACEABILITY: `docs/TRACEABILITY.md`
- ADR: `.ai/adr/0007-ess-ai-dual-track.md`
+20
View File
@@ -0,0 +1,20 @@
# STATE — ECR-013B
| Field | Value |
|-------|-------|
| ECR | ECR-013B |
| Title | AccountLifecycle / UserStatus |
| Status | Draft · Contract Definition |
| Phase | architect |
| Owner | architect |
| Parent | WAVE0-FROZEN (`27f27a1`) |
| Predecessor | ECR-013A Closed |
| Spec | `.ai/product/feature-spec/ops-account-lifecycle.md` |
| Backend Design | BD-2026-013B **Draft** |
| Contract Diff | `docs/CONTRACT_DIFF/ECR-013B.yaml` |
| Test | — |
| Review | — |
| Updated | 2026-08-07 |
Human Start Authorization 2026-08-07Contract Definition · **No Coding**)。
待 Human Approve ECR+BD + coding Start Authorization 后方可实现。
+21
View File
@@ -0,0 +1,21 @@
id: TASK-013B-ECR013B
ecr: ECR-013B
title: AccountLifecycle Contract Definition
role: architect
status: contract
change_level: L2
parent: WAVE0-FROZEN
predecessor: ECR-013A
inputs:
- docs/WAVE0/
- .ai/domain/entity-catalog.md
- .ai/product/feature-spec/ops-account-lifecycle.md
outputs:
- docs/ECR/ECR-013B-account-lifecycle.md
- docs/BACKEND_DESIGN/BD-2026-013B-account-lifecycle.md
- docs/CONTRACT_DIFF/ECR-013B.yaml
- docs/HANDOFF/ECR-013B-architect-to-engineer.md
acceptance:
- L0-L4 filled
- No coding / no migration files
- soft-delete out of scope
+1
View File
@@ -17,3 +17,4 @@
| ECR-012 | 星座对齐收口(星盘 · outlook · 合盘) | **Implemented** | Spec star-profile · BD-2026-012 · TEST_REPORT · HANDOFF review |
| WAVE-0 | Ops Contract-First Foundation | **FROZEN** (`WAVE0-FROZEN` @ 27f27a1) | `docs/WAVE0/` · HUMAN_REVIEW FREEZE · boundary-rules · glossary · contract template |
| ECR-013A | Admin RBAC | **Closed** | Spec ops-rbac · BD-2026-013A · migration 000015 · TEST_REPORT · CODE_REVIEW Approve · Parent WAVE0-FROZEN |
| ECR-013B | AccountLifecycle / UserStatus | **Draft / Contract Definition** | Spec ops-account-lifecycle · BD-2026-013B · CONTRACT_DIFF · Parent WAVE0-FROZEN · Predecessor 013A · **No Coding** |