feat(ECR-006): 落地运营后台 Phase A(admin API + admin-h5)
新增独立鉴权的 /api/v1/admin 与 Vue 控制台;会员授予与审计同事务,并补集成/单测。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+5
-3
@@ -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 A(ECR-006) |
|
||||
| `packages/sdk` | Multi-platform HTTP client |
|
||||
| `packages/types` | Shared TS types |
|
||||
| `packages/utils` | Pure helpers |
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -81,6 +81,16 @@ npm run test:e2e # Playwright(先 build:h5;用系统 Chrome)
|
||||
|
||||
---
|
||||
|
||||
## Admin H5(Ops 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)。
|
||||
|
||||
@@ -172,6 +172,36 @@
|
||||
| payload | jsonb | |
|
||||
| created_at | timestamptz | |
|
||||
|
||||
### admin_accounts(Ops-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
|
||||
```
|
||||
|
||||
@@ -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)
|
||||
|
||||
| 路径 | 页面 | 说明 |
|
||||
|
||||
@@ -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` → 填满 → 在本表登记 → 再编码。
|
||||
|
||||
|
||||
@@ -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 用户侧交付后的日常运维;避免直接改库 |
|
||||
|
||||
| In(Phase A) | Out(后置) |
|
||||
|---|---|
|
||||
| 管理员账号登录 / 会话 | UGC 审核 · 达人 · 推送任务 |
|
||||
| 用户列表 / 详情(档案摘要) | 首页运营位 / 工具配置 CMS |
|
||||
| 订单列表 | 优惠券 · 退款工单流 |
|
||||
| 成长会员只读 + **授予/延长**(mock 履约) | 真支付渠道配置 |
|
||||
| 操作审计日志 | 细粒度 RBAC(多角色矩阵) |
|
||||
| `apps/admin-h5` 桌面友好壳 | 小程序后台 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 用户价值
|
||||
|
||||
1. **为何需要:** P1 已有用户/会员/订单,无控制台则只能改库,风险高。
|
||||
2. **完成后获得:** 可检索用户、看会员与订单、安全授予会员并留痕。
|
||||
3. **为何付费:** N/A(内部工具)。
|
||||
|
||||
---
|
||||
|
||||
## 3. 用户角色
|
||||
|
||||
| Actor | 说明 | 本功能能力 |
|
||||
|---|---|---|
|
||||
| Guest / Visitor | 终端用户身份 | **无**后台入口 |
|
||||
| User / VIP | 终端用户 | **无** |
|
||||
| Admin(Phase 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 Report(Phase 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 未并入 admin;RBAC/CMS 后置
|
||||
|
||||
---
|
||||
|
||||
## 分期
|
||||
|
||||
| Phase | 内容 |
|
||||
|---|---|
|
||||
| **A(本 ECR)** | 登录 · 用户 · 订单 · 授予会员 · 审计 · admin-h5 壳 |
|
||||
| B | 内容配置 / 测评上下架 / 封禁注销 |
|
||||
| C | RBAC · 推送 · 优惠券 · 退款工单 |
|
||||
Reference in New Issue
Block a user