落地埋点 ingest/数据看板、首页宫格 CMS 与测评上下架;含账号引导、问答流式与免责声明去重,以及 review P1 审计同事务修复。 Co-authored-by: Cursor <cursoragent@cursor.com>
130 lines
3.4 KiB
Markdown
130 lines
3.4 KiB
Markdown
# Feature Spec: 生日包生成(档案引导)
|
||
|
||
> Status: `Active` · Map: `1.1 个人档案` · Phase: `P1`
|
||
> 关联:[account-auth.md](account-auth.md) · [profile.md](profile.md) · [portrait.md](portrait.md) · [star-profile.md](star-profile.md)
|
||
|
||
---
|
||
|
||
## 1. 功能定义
|
||
|
||
| 字段 | 内容 |
|
||
|---|---|
|
||
| Name | 生日衍生数据一次生成与覆盖 |
|
||
| Purpose | 输入/修改生日后服务端一次性生成并落库;结果页优先读缓存 |
|
||
| Business Goal | 降低重复输入;保证本人与 TA 数据归属同一账号 |
|
||
|
||
| In | Out |
|
||
|---|---|
|
||
| Self / Other 档案创建与生日变更触发 | 无档案凭空出合盘 |
|
||
| 单人:portrait · star · rhythm | 意象卡片抽牌(配额玩法,不预生成) |
|
||
| 有 Self+Other:relation + synastry 成对覆盖 | 附近的人合盘(进页再算) |
|
||
|
||
---
|
||
|
||
## 2. 用户价值
|
||
|
||
1. 填一次生日,解码/星座/节律可直接看。
|
||
2. 添加的 TA 挂在账号下;与本人关系/合盘一并备好。
|
||
3. 改生日自动覆盖旧结果。
|
||
|
||
---
|
||
|
||
## 3. 用户角色
|
||
|
||
仅 **已登录 User**。Visitor 被鉴权拦截。
|
||
|
||
---
|
||
|
||
## 4. 用户流程
|
||
|
||
```text
|
||
登录 → 创建/编辑档案(含生日)
|
||
↓
|
||
Server GenerateBundle(profile)
|
||
├─ 单人报告:portrait / star / rhythm(同 type 软删旧 → 新建)
|
||
└─ 若存在配对:self×each other → relation + synastry 覆盖
|
||
↓
|
||
结果页:GET latest by profile+type(无则引导档案,不强制再填生日)
|
||
```
|
||
|
||
---
|
||
|
||
## 5. 页面设计
|
||
|
||
| 路由 | 行为变更 |
|
||
|---|---|
|
||
| `/portrait` `/star` `/rhythm` | 有 Self → 读 latest;无 → 引导 `/profile` 或登录 |
|
||
| `/relation` `/synastry` | 选已有 Self+TA → 读 latest pair;缺则引导加档案 |
|
||
| `/profile` | 创建/改生日后展示「已生成」提示 |
|
||
|
||
---
|
||
|
||
## 6. 页面状态规范
|
||
|
||
| 状态 | UI |
|
||
|---|---|
|
||
| Loading | 生成中/拉取中 |
|
||
| Empty | 无档案 → 去建档;未登录 → 去登录 |
|
||
| Normal | 展示缓存报告 |
|
||
| Error | 重试 |
|
||
|
||
---
|
||
|
||
## 7. Business Rules
|
||
|
||
| ID | Rule |
|
||
|---|---|
|
||
| R1 | 仅登录用户可写档案 |
|
||
| R2 | Create/Update 若 birth_date(或 time/place)相对旧值变化 → GenerateBundle |
|
||
| R3 | 覆盖=同 user + profile + type(+ peer)软删旧报告再插入 |
|
||
| R4 | Other 档案 `user_id` 必须=当前账号;删除 Other 时软删其单人报告及含其 peer 的配对报告 |
|
||
| R5 | 结果页不得再要求重复输入已知生日,除非用户主动改档案 |
|
||
|
||
---
|
||
|
||
## 8. 数据模型影响
|
||
|
||
- `growth_reports.peer_profile_id` nullable(配对报告)
|
||
- 索引便于 latest 查询
|
||
|
||
---
|
||
|
||
## 9. API 需求
|
||
|
||
| Method | Path | 说明 |
|
||
|---|---|---|
|
||
| POST/PATCH | `/profiles` | 成功后服务端同步 GenerateBundle |
|
||
| GET | `/reports/latest` | `profile_id` · `type` · 可选 `peer_profile_id` |
|
||
|
||
现有 POST `/reports/*` 保留(幂等覆盖),供重算;主路径以 latest 为准。
|
||
|
||
---
|
||
|
||
## 10. 权限设计
|
||
|
||
同 account-auth:必须 User。
|
||
|
||
---
|
||
|
||
## 11. 埋点
|
||
|
||
`profile_bootstrap_done` · `report_cache_hit`
|
||
|
||
---
|
||
|
||
## 12. 测试验收标准
|
||
|
||
| Given | When | Then |
|
||
|---|---|---|
|
||
| 登录用户建 Self | POST profile | DB 有 portrait/star/rhythm |
|
||
| 再加 Other | POST other | 有 relation+synastry 相对 Self |
|
||
| 改 Self 生日 | PATCH | 旧报告 soft-deleted,新报告可读 |
|
||
| 登录用户开 /portrait | GET latest | 无需再填生日 |
|
||
|
||
---
|
||
|
||
## 13. AI 开发前检查
|
||
|
||
- [x] 合盘不造假 TA
|
||
- [x] lexicon:愈心解码 / 星座 / 合盘 / 个人档案
|