feat(ECR-006): 落地运营后台 Phase A(admin API + admin-h5)
ci / h5 (push) Canceled after 0s
ci / api (push) Canceled after 0s
ci / ess-docs (push) Canceled after 0s

新增独立鉴权的 /api/v1/admin 与 Vue 控制台;会员授予与审计同事务,并补集成/单测。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jackyu66git
2026-08-06 18:35:53 +08:00
co-authored by Cursor
parent 4a583c9480
commit 879bf70cb7
59 changed files with 2462 additions and 20 deletions
+5 -3
View File
@@ -6,14 +6,16 @@ Domain / ERD[domain/domain-map.md](domain/domain-map.md) · [domain/erd.md](d
## Allowed call graph
```
UI (user-h5 / mini-program)
→ packages/sdk
UI (user-h5 / mini-program / admin-h5)
→ packages/sdk(或 admin 薄 api 客户端)
→ API Handler
→ Service
→ Repository
→ Database
```
Admin 路由挂 `/api/v1/admin/*`,鉴权与终端 `DeviceAuth` **隔离**(见 `feature-spec/ops-admin.md`)。
## Forbidden
- Handler → Database (skip Service/Repository)
@@ -30,7 +32,7 @@ UI (user-h5 / mini-program)
| `apps/api` | Only backend |
| `apps/user-h5` | Primary client (Vue3+TS) |
| `apps/mini-program` | Scaffold only until tasked |
| `apps/admin-h5` | Deferred |
| `apps/admin-h5` | Ops Phase AECR-006 |
| `packages/sdk` | Multi-platform HTTP client |
| `packages/types` | Shared TS types |
| `packages/utils` | Pure helpers |
+1
View File
@@ -20,6 +20,7 @@
| `membership` | 成长会员状态与额度 | Yes | `service/membership`ECR-001 Phase C 已从 report 抽出) |
| `order` | Order + pay-mock + DeepAccess 发放 | Yes | 用例在 `service/membership`(同 Phase C;未单独拆包) |
| `imagecard` | 意象卡片 | P2 | `service/imagecard` |
| `admin` | 运营后台鉴权与运维用例 | Ops-A | `service/admin`ECR-006 |
### Engine vs Service
+10
View File
@@ -81,6 +81,16 @@ npm run test:e2e # Playwright(先 build:h5;用系统 Chrome
---
## Admin H5Ops Phase A · ECR-006
```bash
# config.local.yaml 需 admin.bootstrap_*(见 config.example.yaml);仅空库种子
npm run dev:admin # http://127.0.0.1:5174/
npm run build:admin
```
---
## CI / production
见 [deployment.md](deployment.md) · [docker.md](docker.md)。
+32
View File
@@ -172,6 +172,36 @@
| payload | jsonb | |
| created_at | timestamptz | |
### admin_accountsOps-A · ECR-006
| column | type | notes |
|---|---|---|
| id | uuid PK | |
| username | text unique | |
| password_hash | text | bcrypt |
| status | text | active/disabled |
| created_at | timestamptz | |
| updated_at | timestamptz | |
### admin_sessions
| column | type | notes |
|---|---|---|
| id | uuid PK | |
| admin_id | uuid FK→admin_accounts | |
| token | text unique | opaque |
| expires_at | timestamptz | |
| created_at | timestamptz | |
### admin_audit_logs
| column | type | notes |
|---|---|---|
| id | uuid PK | |
| admin_id | uuid FK | |
| action | text | e.g. membership.grant |
| target_type | text | user/order/… |
| target_id | text | |
| meta | jsonb | |
| created_at | timestamptz | 只追加 |
---
## Relationship sketch
@@ -185,4 +215,6 @@ users 1──* orders 1──* payments
growth_reports 1──* deep_accesses
profiles ── relation_insights ── profiles
users 1──* ask_threads 1──* ask_messages
admin_accounts 1──* admin_sessions
admin_accounts 1──* admin_audit_logs
```
+13
View File
@@ -225,6 +225,19 @@ UI **不出现「塔罗」**。禁止神谕吉凶、恐吓话术。
---
## 7. 运营后台(内部 · 非 C 端 Tab)
详见 Spec[feature-spec/ops-admin.md](feature-spec/ops-admin.md) · ECR-006
| 分期 | 内容 |
|---|---|
| Phase A `[Ops]` | 登录 · 用户/订单查询 · 会员授予 · 审计 · `apps/admin-h5` |
| Phase B+ | 内容配置 · 测评上下架 · 封禁 · RBAC · 推送(后置) |
不计入 P1 Complete;不进入五 Tab。
---
## L2 路由(冻结 · user-h5
| 路径 | 页面 | 说明 |
+1
View File
@@ -18,6 +18,7 @@
| [star-profile.md](star-profile.md) | 星象性格 | §2.6 | `/star` | P2 设计 |
| [life-rhythm.md](life-rhythm.md) | 身心节律 | §2.7 | `/rhythm` | P2 设计 |
| [image-card.md](image-card.md) | 意象卡片 | §2.8 | `/cards` | P2 设计 |
| [ops-admin.md](ops-admin.md) | 运营后台 | §7 | `admin-h5` `/` `/users/:id` … | Ops-A |
新功能:复制 `_TEMPLATE.md` → 填满 → 在本表登记 → 再编码。
+208
View File
@@ -0,0 +1,208 @@
# Feature Spec: 运营后台(Ops Admin
> Status: `Active` · Map: `§7 运营后台 [Ops · Phase A]` · Phase: `Ops-A`
> 规范:[../feature-design.md](../feature-design.md)
> 对标推导参考:`cece-frontend-re/complete-design/40-ops-commerce.md`IA 全量;本 Spec 只交付 Phase A
---
## 1. 功能定义
| 字段 | 内容 |
|---|---|
| Name | 运营后台 |
| Purpose | 让内部运营/客服在受控权限下查询用户与商业数据,并做可审计的会员权益干预 |
| Business Goal | 支撑 P1 用户侧交付后的日常运维;避免直接改库 |
| InPhase A | Out(后置) |
|---|---|
| 管理员账号登录 / 会话 | UGC 审核 · 达人 · 推送任务 |
| 用户列表 / 详情(档案摘要) | 首页运营位 / 工具配置 CMS |
| 订单列表 | 优惠券 · 退款工单流 |
| 成长会员只读 + **授予/延长**(mock 履约) | 真支付渠道配置 |
| 操作审计日志 | 细粒度 RBAC(多角色矩阵) |
| `apps/admin-h5` 桌面友好壳 | 小程序后台 |
---
## 2. 用户价值
1. **为何需要:** P1 已有用户/会员/订单,无控制台则只能改库,风险高。
2. **完成后获得:** 可检索用户、看会员与订单、安全授予会员并留痕。
3. **为何付费:** N/A(内部工具)。
---
## 3. 用户角色
| Actor | 说明 | 本功能能力 |
|---|---|---|
| Guest / Visitor | 终端用户身份 | **无**后台入口 |
| User / VIP | 终端用户 | **无** |
| AdminPhase A | `admin_accounts` 账号 | 登录;读写本 Spec In 范围 API |
| 运营/审核/客服分角色 | 后置 | Phase A 全部等同 Admin |
---
## 4. 用户流程
```text
打开 admin-h5
未登录 → /login(用户名+密码)
↓ POST /api/v1/admin/auth/login
↓ 存 token → 壳布局
用户列表 / 订单 / 审计
↓ 点用户 → 详情(档案数 · 会员 · 近单)
↓ [可选] 授予会员 → 写 memberships + audit_logs
失败:401 回登录;403/5xx 页内错误态
```
---
## 5. 页面设计
| 路由 | 页面 | 说明 |
|---|---|---|
| `/login` | LoginPage | 无壳 |
| `/` | UsersPage | 用户列表 |
| `/users/:id` | UserDetailPage | 用户详情 + 授予会员 |
| `/orders` | OrdersPage | 订单列表 |
| `/audit` | AuditPage | 审计日志 |
```text
AdminShell
├── Nav: 用户 | 订单 | 审计 | 退出
└── Outlet
```
对照:不进入 user-h5 `page-tree`;独立 `apps/admin-h5`
---
## 6. 页面状态
| 页 | Loading | Empty | Error | Normal | Locked |
|---|---|---|---|---|---|
| Login | 提交中 | — | 账号错误 | 表单 | — |
| Users | 表格骨架 | 无用户 | 拉取失败 | 分页列表 | 未登录→登录 |
| UserDetail | 骨架 | 用户不存在 | 失败 | 摘要+操作 | — |
| Orders / Audit | 同 Users | 无记录 | 失败 | 列表 | — |
---
## 7. Business Rules
| ID | Rule |
|---|---|
| R1 | 管理员鉴权与终端 `DeviceAuth` **隔离**;禁止用 `X-Device-Key` 访问 `/admin/*` |
| R2 | 除 `POST /admin/auth/login` 外,admin API 必须带有效 Admin Token |
| R3 | 用户列表默认按 `created_at DESC`;支持 `q` 精确匹配 `users.id`UUID |
| R4 | 授予会员:`plan ∈ {month,quarter,year}`;写入/更新 `memberships``active``expires_at` 按套餐延长;**必须**写 `admin_audit_logs` |
| R5 | Phase A **不**提供封禁/注销(避免误伤;后置) |
| R6 | Bootstrap:仅当 `admin_accounts` 为空且配置了 bootstrap 密码时,启动可种子一个超级管理员 |
| R7 | 审计日志只追加,不可通过 API 删除/篡改 |
| R8 | 文案用愈心谷 lexicon;UI 不出现竞品品牌词 |
---
## 8. 数据模型影响
新增表(见 `.ai/domain/erd.md`):
- `admin_accounts` — 管理员账号(password_hash
- `admin_sessions` — 会话 token
- `admin_audit_logs` — 操作审计
复用只读:`users` · `profiles` · `memberships` · `orders`
---
## 9. API 需求
前缀:`/api/v1/admin`
| Method | Path | 意图 |
|---|---|---|
| POST | `/auth/login` | 登录,返回 token + account |
| POST | `/auth/logout` | 注销当前会话 |
| GET | `/me` | 当前管理员 |
| GET | `/users` | 列表 `?q=&limit=&offset=` |
| GET | `/users/:id` | 详情(含 membership · profiles 摘要 · 近订单) |
| POST | `/users/:id/membership/grant` | 授予/延长会员 |
| GET | `/orders` | 订单列表 |
| GET | `/audit-logs` | 审计列表 |
信封仍为 `{code,message,data}`。细节同步 OpenAPI。
---
## 10. 权限设计
| 能力 | Admin Phase A |
|---|---|
| 登录 / me / logout | ✓ |
| 用户读 | ✓ |
| 订单读 | ✓ |
| 授予会员 | ✓ |
| 审计读 | ✓ |
| 改用户 status / 删数据 | ✗ |
---
## 11. 埋点
| event | 属性 |
|---|---|
| `admin_login` | ok / fail_reason |
| `admin_user_view` | user_id |
| `admin_membership_grant` | user_id, plan |
| `admin_page_view` | route |
Phase A 可先 `console`/本地;不挡验收。
---
## 12. 测试验收标准
| # | Given / When / Then |
|---|---|
| T1 | 无 token 调 GET `/admin/users` → 401 |
| T2 | 正确账号登录 → 200 + token;错密 → 非 0 code |
| T3 | 登录后列表可见已有 users |
| T4 | grant membership → memberships active + audit 一条 |
| T5 | admin-h5:登录 → 用户列表 → 详情 → 授予 → 审计页可见 |
---
## 13. AI 开发前检查
- [x] 有 Active Spec(本文件)
- [x] feature-map §7 已挂
- [x] ERD / API 意图已写
- [x] In/Out 边界清晰(无 UGC/达人)
- [x] ECR-006 Approved + BACKEND_DESIGN
- [x] 实现后过 DoD + Review Report
---
## Review ReportPhase A
- Feature: 运营后台 Phase A
- Scope label: **Feature Complete**Ops-A;非 P1 Complete 扩展)
- Architecture: PASS — admin 与 DeviceAuth 隔离;H→S→R
- API: PASS — `/api/v1/admin/*` + OpenAPI
- Security: PASS — bcrypt · session token · 审计
- Test: PASS — `TestAdminOpsPhaseA` · `TestPlanDays` · `build:admin`
- Known Issues: SDK 未并入 adminRBAC/CMS 后置
---
## 分期
| Phase | 内容 |
|---|---|
| **A(本 ECR** | 登录 · 用户 · 订单 · 授予会员 · 审计 · admin-h5 壳 |
| B | 内容配置 / 测评上下架 / 封禁注销 |
| C | RBAC · 推送 · 优惠券 · 退款工单 |