feat(ECR-010): Ops-E 系统运营;修复登出解绑;P2 Complete
ci / h5 (push) Canceled after 0s
ci / api (push) Canceled after 0s
ci / ess-docs (push) Canceled after 0s

落地管理员 RBAC/封禁/推送任务 stub,logout 解绑 device 并统一各页 ensureAccount,同时收口 P2 生日生成与状态文档。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jackyu66git
2026-08-11 18:54:59 +08:00
co-authored by Cursor
parent 0ee4d4f5ae
commit 5ceb3ce749
85 changed files with 2098 additions and 103 deletions
+6 -5
View File
@@ -1,6 +1,6 @@
# P2 Backlog — 探索三模块 + 合规全量目录
**状态:** 合规全量探索进行中(Wave 0–4)
**状态:`P2 Complete`(见 [../p2-status.md](../p2-status.md)**
**命名决策:** 星座 / 身心节律 / 意象卡片;UI 无「塔罗」主入口、无「算命/占卜」恐吓
**契约:** [../lexicon.md](../lexicon.md) · [../feature-map.md](../feature-map.md) · [../STRATEGY.md](../STRATEGY.md)
@@ -13,11 +13,11 @@
| 顺序 | 模块 | Spec | 路由 | 状态 |
|---|---|---|---|---|
| 0 | 探索目录 | — | `/explore` · `/explore/:category` | Done |
| 1 | 星座 | [star-profile.md](star-profile.md) | `/star` | Done(星盘/运势/合盘对齐中) |
| 2 | 身心节律 | [life-rhythm.md](life-rhythm.md) | `/rhythm` | Done(今日/本周) |
| 1 | 星座 | [star-profile.md](star-profile.md) | `/star` · `/synastry` | Done |
| 2 | 身心节律 | [life-rhythm.md](life-rhythm.md) | `/rhythm` | Done |
| 3 | 意象卡片 | [image-card.md](image-card.md) | `/cards` | Done(≥78 牌 · ≥8 场景) |
| 4 | 量表矩阵 | [explore-test.md](explore-test.md) | `/scales/*` | Done(≥8 |
| 5 | 成长计划 | companion | `/growth-plan` | Done |
| 5 | 成长计划 | companion / growth | `/growth-plan` | Done |
| 6 | 心情轨迹 | companion | `/companion` | Done |
---
@@ -28,4 +28,5 @@
|---|---|
| 设计三 Spec | Done |
| 探索 catalog API | Done |
| 真支付 | 部署阶段 |
| L0L3 验证 | Done(见 p2-status |
| 真支付 | 部署阶段(不挡 P2 Complete |
+7 -5
View File
@@ -15,19 +15,21 @@
| [membership.md](membership.md) | 深度版 / 成长会员 | §6 · §5.3 | `/membership` | P1 |
| [reports.md](reports.md) | 成长报告列表/详情 | §2.1.2 · §5.2 | `/reports` · `/reports/:id` | P1 |
| [share.md](share.md) | 分享卡 | journey 双引擎 | `/share` | P1 |
| [companion.md](companion.md) | 陪伴(节气 | §4 | `/companion` | P1 壳 / P2 |
| [companion.md](companion.md) | 陪伴(节气+心情 | §4 | `/companion` | P2 Complete |
| [analytics.md](analytics.md) | 增长埋点最小集 | 横切 | H5 `track` | P1 |
| [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 设计 |
| [star-profile.md](star-profile.md) | 星象性格 | §2.6 | `/star` | P2 Complete |
| [life-rhythm.md](life-rhythm.md) | 身心节律 | §2.7 | `/rhythm` | P2 Complete |
| [image-card.md](image-card.md) | 意象卡片 | §2.8 | `/cards` | P2 Complete |
| [ops-admin.md](ops-admin.md) | 运营后台 | §7 | `admin-h5` `/` `/users/:id` … | Ops-A |
| [ops-analytics.md](ops-analytics.md) | 运营行为分析(埋点+数据看板) | §7 | `admin-h5` `/analytics` · H5 track | Ops-B · ECR-007 Implemented |
| [ops-content.md](ops-content.md) | 运营内容(宫格+测评上下架) | §7 | `admin-h5` `/content` · `GET /home/tools` | Ops-C · ECR-008 Implemented |
| [ops-commerce.md](ops-commerce.md) | 运营商业加深(订单筛选+展示价+退款只读) | §7 | `admin-h5` `/orders` `/pricing` | Ops-D · ECR-009 |
| [ops-system.md](ops-system.md) | 运营系统(RBAC+封禁+推送占位) | §7 | `admin-h5` `/push` `/admins` | Ops-E · ECR-010 |
新功能:复制 `_TEMPLATE.md` → 填满 → 在本表登记 → 再编码。
**P1 全量流程走查:** [P1-PROCESS-REVIEW.md](P1-PROCESS-REVIEW.md)
**P2 三模块队列(设计立项 / 编码另批):** [P2-BACKLOG.md](P2-BACKLOG.md)
**P2 收口状态:** [../p2-status.md](../p2-status.md) · [P2-BACKLOG.md](P2-BACKLOG.md)
**竞品逆向(测测前端全量):** [cece-frontend-re/](cece-frontend-re/README.md) · **完整设计包:** [cece-frontend-re/complete-design/](cece-frontend-re/complete-design/README.md) · 方法见 [../../design/reverse-engineering-spec.md](../../design/reverse-engineering-spec.md)
+1
View File
@@ -126,6 +126,7 @@ Device 绑定到账号 User
| 新设备 | 未登录 POST portrait | 401 |
| 注册成功 | 建档 | 200 且生成报告包 |
| 登录另一设备 | list profiles | 见同一账号数据 |
| 已登录设备 | POST logout 后无 Bearer 再 GET /auth/me | 401(设备已解绑,刷新不再显示登录态) |
---
+3 -3
View File
@@ -1,6 +1,6 @@
# Feature Spec: 陪伴(节气壳)
> Status: `Active`(壳) · Map: `§4 陪伴 [P2 主做;P1 可占位]` · Phase: `P1 Shell / P2`
> Status: `Active` · Map: `§4 陪伴 [P2]` · Phase: `P2 Complete`
> 规范:[../feature-design.md](../feature-design.md)
---
@@ -142,6 +142,6 @@ Tab 陪伴 → /companion
|---|---|
| Packages | `CompanionPage` · `internal/companion` · moods 表 |
| 实现 | GET `/solar-terms/today` · POST `/moods` · GET `/moods/today` · H5 心情 UI |
| Gaps | 成长计划、推送、心情趋势 |
| Label | 陪伴 P2 心情已接;真支付仍后置 |
| Gaps | 推送(后置 / Ops-E |
| Label | Feature CompleteP2:节气 + 心情 + 近七日轨迹;成长计划见 `/growth-plan` |
| Process Review | 2026-08-02 [P1-PROCESS-REVIEW](P1-PROCESS-REVIEW.md) · 心情已按产品「其他先做」落地 |
+5 -4
View File
@@ -1,6 +1,6 @@
# Feature Spec: 意象卡片
> Status: `Active`(设计)· Map: `2.8 意象卡片 [P2]` · Phase: `P2`
> Status: `Active` · Map: `2.8 意象卡片 [P2]` · Phase: `P2 Complete`
> 规范:[../feature-design.md](../feature-design.md) · 队列:[P2-BACKLOG.md](P2-BACKLOG.md)
> 竞品对照:塔罗体系(能力同构;**UI 禁止「塔罗」入口名**)
@@ -170,7 +170,7 @@
- [x] Spec 齐全 · 禁用塔罗入口已写清
- [x] lexicon ImageCard
- [ ] 内容库 seed 与 OpenAPI(编码时)
- [x] 内容库 seed 与 OpenAPI(编码时)
---
@@ -181,5 +181,6 @@
| 复用 | ShareSheet · membership/orders · Explore 入口 |
| 工作量 | 卡面文案/视觉资产最大;宜先 22~78 张小库 MVP |
| Packages | `internal/imagecard` · `ImageCardPage` `/cards` |
| 实现 | scenes/quota/draw API · 报告 type=`image_card` · 日配额 · seed 12 卡 |
| 编码顺序 | P2-BACKLOG 切片 3 Done |
| 实现 | scenes/quota/draw API · 报告 type=`image_card` · 日配额 · ≥78 牌(手写底稿+确定性扩容)· ≥8 场景 |
| Gaps | 全手写美术资产;推送 |
| Label | Feature CompleteP2 |
+2 -2
View File
@@ -1,6 +1,6 @@
# Feature Spec: 身心节律
> Status: `Active`(设计)· Map: `2.7 身心节律 [P2]`= `2.5 身心探索` 产品化主入口)· Phase: `P2`
> Status: `Active` · Map: `2.7 身心节律 [P2]`= `2.5 身心探索` 产品化主入口)· Phase: `P2 Complete`
> 规范:[../feature-design.md](../feature-design.md) · 队列:[P2-BACKLOG.md](P2-BACKLOG.md)
> 竞品对照:命理体系之生活向(能力同构,禁止算命/流年吉凶叙事)
@@ -161,7 +161,7 @@ CTA:节气陪伴 / 问答「生活节奏」/ 分享
- [x] Spec 齐全 · 与 2.5 关系已写清
- [x] lexicon LifeRhythm
- [ ] OpenAPI/erd(编码时)
- [x] OpenAPI/erd(编码时)
---
+3 -1
View File
@@ -20,9 +20,11 @@
| 用户列表 / 详情(档案摘要) | 首页运营位 / 工具配置 CMS |
| 订单列表 | 优惠券 · 退款工单流 |
| 成长会员只读 + **授予/延长**(mock 履约) | 真支付渠道配置 |
| 操作审计日志 | 细粒度 RBAC(多角色矩阵) |
| 操作审计日志 | 真支付渠道配置 |
| `apps/admin-h5` 桌面友好壳 | 小程序后台 |
> Phase EECR-010):RBAC / 封禁 / 推送占位见 [ops-system.md](ops-system.md)。
---
## 2. 用户价值
+170
View File
@@ -0,0 +1,170 @@
# Feature Spec: 运营系统(Ops-E
> Status: `Active` · Map: `§7 Phase E` · Phase: `Ops-E` · ECR: `ECR-010`
> 规范:[../feature-design.md](../feature-design.md)
> 上游:Ops-ADECR-006009
---
## 1. 功能定义
| 字段 | 内容 |
|---|---|
| Name | 运营系统 Ops-E |
| Purpose | 两角色 RBAC、C 端用户封禁、推送任务占位,支撑安全运维 |
| Business Goal | 限制写权限;可处置违规账号;预留推送运营入口(不下发) |
| In | Out |
|---|---|
| `admin_accounts.role``super` \| `ops` | 细粒度权限矩阵 / 动态权限表 |
| 用户封禁 / 解封(`users.status` active↔banned | 设备级 / IP 封禁 |
| `push_jobs` 草稿 CRUDdraft / cancelled | 真推送通道 · Worker · 站内信 |
| Admin API 动作级 403 + admin-h5 导航裁剪 | UGC · 真支付 |
---
## 2. 用户价值
1. **为何需要:** 全员等同 Admin 风险高;无封禁只能改库。
2. **完成后获得:** ops 可查可封可建推送草稿;写会员/定价/内容仅 super。
3. **为何付费:** N/A(内部工具)。
---
## 3. 用户角色
| Actor | 能力 |
|---|---|
| Admin `super` | 全部读写;Admin 账号列表与改角色 |
| Admin `ops` | 读全模块;封禁/解封;推送草稿;**不可**授予会员、改价、内容写、管 Admin |
| C 端 User `banned` | DeviceAuth / 会话拒绝(40310 |
| Guest | 无后台入口 |
---
## 4. 用户流程
```text
Admin 登录 → Me 含 role
ops:导航隐藏「定价写 / 内容写入口仍可见只读?按表:内容写否」
→ 用户详情 → 封禁 → C 端下次请求 40310
→ 推送页 → 新建 draft → 可 cancelled
super:另开「管理员」改 role
失败:无权限 403;未登录 401
```
---
## 5. 页面设计
| 路由 | 页面 | 说明 |
|---|---|---|
| `/users/:id` | UserDetailPage | 封禁 / 解封按钮 |
| `/push` | PushJobsPage | 列表 + 新建草稿 |
| `/admins` | AdminsPage | 仅 super:列表改角色 |
```text
AdminShell Nav += 推送 | 管理员(super)
```
---
## 6. 状态
| 态 | 要求 |
|---|---|
| Loading | 列表/详情请求中 |
| Empty | 无推送任务 / 无管理员(不应发生) |
| Error | 403 提示无权限;封禁失败可感知 |
| Normal | 状态与角色展示正确 |
---
## 7. 业务规则
1. Bootstrap / 存量 admin 默认 `super`
2. `ops` 调用 grant / PUT plan-prices / 内容写 → HTTP 403。
3. 封禁写 `users.status='banned'` + audit `user.ban`;解封 `active` + `user.unban`
4. 被封用户:Bearer 会话与 DeviceAuth 解析后均拒绝(40310);可撤销 sessions。
5. 推送仅 `draft`/`cancelled`;创建不下发。
6.`super``PATCH` admin role**禁止**降级最后一个 `super`HTTP 409 / code 40901)。
7. 推送标题非空且 ≤128 字符(rune),否则 400。
---
## 8. 数据
- `admin_accounts.role` varchar CHECK (`super`,`ops`) DEFAULT `super`
- `users.status` CHECK (`active`,`banned`)(存量补齐)
- `push_jobs(id, title, body, audience, status, created_by, created_at, updated_at)`
---
## 9. API
| Method | Path | 说明 |
|---|---|---|
| GET | `/api/v1/admin/me` | 响应含 `role` |
| POST | `/api/v1/admin/users/{id}/ban` | super+ops |
| POST | `/api/v1/admin/users/{id}/unban` | super+ops |
| GET | `/api/v1/admin/admins` | super |
| PATCH | `/api/v1/admin/admins/{id}` | super · body `{role}` |
| GET | `/api/v1/admin/push-jobs` | super+ops |
| POST | `/api/v1/admin/push-jobs` | super+ops · draft |
| PATCH | `/api/v1/admin/push-jobs/{id}` | 改文案或 cancelled |
既有写接口对 `ops` 返回 403。
---
## 10. 埋点
N/A(内部);审计日志覆盖封禁与角色变更。
---
## 11. 事件
| Audit action | 何时 |
|---|---|
| `user.ban` / `user.unban` | 封禁变更 |
| `admin.role_update` | 改角色 |
| `push_job.create` / `push_job.update` | 推送占位 |
---
## 12. 验收
**Given** ops 账号
**When** PUT plan-prices 或 grant membership
**Then** 403
**Given** 用户被 ban
**When** C 端带该 user 的 DeviceAuth 请求
**Then** 40310
**Given** 唯一 super
**When** PATCH role=ops
**Then** 40901,角色不变
**Given** push title 超 128 字
**When** POST push-jobs
**Then** 40055
---
## 13. AI 开发前检查
- [x] Spec §4/7/9/12
- [x] ECR-010 · BD-2026-010
---
## 14. Implementation Notes
| 项 | 内容 |
|---|---|
| Packages | `middleware` · `service/admin` · `AdminRepo` · admin-h5 |
| Migration | `000016_ops_system` |
| Label | Feature CompleteOps-E MVP |
+1 -1
View File
@@ -1,6 +1,6 @@
# Feature Spec: 星座
> Status: `Active` · Map: `2.6 星座 [P2]` · Phase: `P2`
> Status: `Active` · Map: `2.6 星座 [P2]` · Phase: `P2 Complete`
> 规范:[../feature-design.md](../feature-design.md) · 队列:[P2-BACKLOG.md](P2-BACKLOG.md)
> 竞品对照:测测星座体系(本命排盘 · 运势大全 · 连线合盘)