diff --git a/.ai/domain/domain-map.md b/.ai/domain/domain-map.md index a3345d7..6ff71f2 100644 --- a/.ai/domain/domain-map.md +++ b/.ai/domain/domain-map.md @@ -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-013B(Identity_Profile owns UserStatus) | | Content_Safety | ContentSafety · CrisisCare | Draft | | Ask_Ops | AskOperations · AICoreConfig | Draft | | Ops_CMS_NoUGC | OpsCMS | Draft | diff --git a/.ai/domain/entity-catalog.md b/.ai/domain/entity-catalog.md index 5f7ab1f..3b1f66b 100644 --- a/.ai/domain/entity-catalog.md +++ b/.ai/domain/entity-catalog.md @@ -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 改动。 diff --git a/.ai/product/feature-map.md b/.ai/product/feature-map.md index df450c0..7e77fc4 100644 --- a/.ai/product/feature-map.md +++ b/.ai/product/feature-map.md @@ -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** AccountLifecycle(Contract Definition)。详见 `docs/WAVE0/`。 | | 排除 | **UGC / 社区广场**(M10.2)仍 `[No]`;真支付最后 | 不计入 P1 Complete;不进入五 Tab。 diff --git a/.ai/product/feature-spec/README.md b/.ai/product/feature-spec/README.md index 281739d..79b633e 100644 --- a/.ai/product/feature-spec/README.md +++ b/.ai/product/feature-spec/README.md @@ -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` → 填满 → 在本表登记 → 再编码。 diff --git a/.ai/product/feature-spec/ops-account-lifecycle.md b/.ai/product/feature-spec/ops-account-lifecycle.md new file mode 100644 index 0000000..944aff0 --- /dev/null +++ b/.ai/product/feature-spec/ops-account-lifecycle.md @@ -0,0 +1,156 @@ +# Feature Spec: 账户生命周期 / UserStatus(Ops · 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.status(013A 外) | +| 权限码 `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 | 200;GET 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 **< 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 | YES(transitions 表;permission 种子;必要时 CHECK/注释枚举) | +| Packages | service account/lifecycle · DeviceAuth/session 拒绝 · admin handler · admin-h5 用户详情最小 CTA | +| Depends | ECR-013A Closed(permission middleware) | diff --git a/.ai/product/feature-spec/ops-admin.md b/.ai/product/feature-spec/ops-admin.md index 0f62021..d17a1ae 100644 --- a/.ai/product/feature-spec/ops-admin.md +++ b/.ai/product/feature-spec/ops-admin.md @@ -209,5 +209,6 @@ Phase A 可先 `console`/本地;不挡验收。 | **B(ECR-007 Closed)** | 自有埋点 · 管理端「数据」看板 — Spec `ops-analytics.md` | | **C(ECR-008 Closed)** | 首页宫格 CRUD · 测评上下架 — Spec `ops-content.md` | | **E(ECR-013A Closed)** | Admin RBAC — Spec `ops-rbac.md` · Parent WAVE0-FROZEN | +| **F(ECR-013B Draft)** | AccountLifecycle — Spec `ops-account-lifecycle.md` · **契约中,禁 coding** | | D | 订单筛选 · 展示价 · 退款只读(另开 ECR) | -| 后置 | AccountLifecycle = **ECR-013B**;封禁加深 · 推送占位 | +| 后置 | 封禁加深(Account_Risk)· 推送占位 | diff --git a/docs/BACKEND_DESIGN/BD-2026-013B-account-lifecycle.md b/docs/BACKEND_DESIGN/BD-2026-013B-account-lifecycle.md new file mode 100644 index 0000000..668194c --- /dev/null +++ b/docs/BACKEND_DESIGN/BD-2026-013B-account-lifecycle.md @@ -0,0 +1,106 @@ +# Backend Design: ECR-013B AccountLifecycle + +> Architect 产出;**Contract Definition** — Status Draft;Approve 前禁止实现。 +> 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-delete;UGC;真支付;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 + +- Integration:AC-F/S/O;AC-P-01 本机抽样 +- 禁止跳过 Security AC(含 C 端拒绝) + +## Rollback Plan + +- down migration;DeviceAuth 去掉 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 diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 3343ad1..968482a 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -2,6 +2,8 @@ ## 2026-08-07 +- **ECR-013B Contract Definition**(Start Authorization):AccountLifecycle / UserStatus L0–L4 · 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 Approve(Admin RBAC) - **ECR-013A Implemented**:Admin RBAC(roles/permissions · RequirePermission · `/me` permissions · admin-h5 最小展示) TEST_REPORT PASS · STATE Closed diff --git a/docs/CONTRACT_DIFF/ECR-013B.yaml b/docs/CONTRACT_DIFF/ECR-013B.yaml new file mode 100644 index 0000000..af5e97f --- /dev/null +++ b/docs/CONTRACT_DIFF/ECR-013B.yaml @@ -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" diff --git a/docs/ECR/ECR-013B-account-lifecycle.md b/docs/ECR/ECR-013B-account-lifecycle.md new file mode 100644 index 0000000..029e3d6 --- /dev/null +++ b/docs/ECR/ECR-013B-account-lifecycle.md @@ -0,0 +1,68 @@ +# ECR-013B + +**Title:** AccountLifecycle(UserStatus 状态机 · 运营启停/封禁 · C 端拒绝) +**Status:** Draft +**Date:** 2026-08-07 +**Start Authorization:** 2026-08-07(Human · 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 L0–L4 · Domain 对齐 · BD Draft · AC · feature-map §7 · TRACEABILITY · STATE · TASK + +### Forbidden(Non-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_admin;integration 覆盖 | + +## Acceptance Criteria + +见 Spec `ops-account-lifecycle.md` L4:AC-F-01..04 · AC-S-01..04 · AC-P-01 · AC-O-01..02 + +契约轮完成标准: + +- [x] L0–L4 填满 +- [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 diff --git a/docs/ENGINEERING_SPEC/ECR-013B-account-lifecycle.md b/docs/ENGINEERING_SPEC/ECR-013B-account-lifecycle.md new file mode 100644 index 0000000..186ff3b --- /dev/null +++ b/docs/ENGINEERING_SPEC/ECR-013B-account-lifecycle.md @@ -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 handlers:POST status · GET transitions;挂 `RequireAdminPermission` +5. OpenAPI +6. admin-h5:用户详情最小状态 CTA(依赖 `can('admin.users.status.write')`) +7. Integration:AC-F/S/O;Perf 抽样 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 无回归 diff --git a/docs/HANDOFF/ECR-013B-architect-to-engineer.md b/docs/HANDOFF/ECR-013B-architect-to-engineer.md new file mode 100644 index 0000000..ab3737d --- /dev/null +++ b/docs/HANDOFF/ECR-013B-architect-to-engineer.md @@ -0,0 +1,36 @@ +# HANDOFF — ECR-013B Architect → Engineer + +## Gate + +**Parent:** WAVE0-FROZEN (`27f27a1`) +**Predecessor:** ECR-013A **Closed** + +**Start Authorization: 2026-08-07(Human)→ 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` diff --git a/docs/PRODUCT_SPEC/ECR-013B-account-lifecycle.md b/docs/PRODUCT_SPEC/ECR-013B-account-lifecycle.md new file mode 100644 index 0000000..6155763 --- /dev/null +++ b/docs/PRODUCT_SPEC/ECR-013B-account-lifecycle.md @@ -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-delete;Payment;Community;ECR-013C+。 diff --git a/docs/PROJECT_PROFILE.md b/docs/PROJECT_PROFILE.md index 8fe5a7b..78aa057 100644 --- a/docs/PROJECT_PROFILE.md +++ b/docs/PROJECT_PROFILE.md @@ -46,9 +46,9 @@ ## Active anchors -- ECR: **ECR-013A Closed**;**WAVE0-FROZEN** @ 27f27a1;ECR-012 Implemented(review);Next=ECR-013B +- ECR: **ECR-013B** AccountLifecycle(Contract 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` diff --git a/docs/STATE/ECR-013B.md b/docs/STATE/ECR-013B.md new file mode 100644 index 0000000..0aeef4b --- /dev/null +++ b/docs/STATE/ECR-013B.md @@ -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-07(Contract Definition · **No Coding**)。 +待 Human Approve ECR+BD + coding Start Authorization 后方可实现。 diff --git a/docs/TASKS/TASK-013B-ECR013B.yaml b/docs/TASKS/TASK-013B-ECR013B.yaml new file mode 100644 index 0000000..a0b55ca --- /dev/null +++ b/docs/TASKS/TASK-013B-ECR013B.yaml @@ -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 diff --git a/docs/TRACEABILITY.md b/docs/TRACEABILITY.md index 232550e..2250a17 100644 --- a/docs/TRACEABILITY.md +++ b/docs/TRACEABILITY.md @@ -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** |