feat(ECR-012–016): 合规、题库、时辰刷新、头像、MBTI OEJTS 与埋点
落地输入合规、探索题库、报告日/时辰刷新、账号头像、OEJTS 量表,并补齐 H5 埋点与 Admin 漏斗;同步 ESS 工件、切至自建 Git、清理 GitHub Actions。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
| [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 |
|
||||
| [input-compliance.md](input-compliance.md) | 用户文字输入合规 | 横切 · 安全 | 各写接口 · code 40060 | P2 · ECR-012 |
|
||||
|
||||
新功能:复制 `_TEMPLATE.md` → 填满 → 在本表登记 → 再编码。
|
||||
|
||||
|
||||
@@ -84,14 +84,16 @@ Device 绑定到账号 User
|
||||
| R5 | 登出作废 session;设备可再登录其他账号 |
|
||||
| R6 | 正式环境恢复校验前须改回本 Spec |
|
||||
| R7 | 新账号未填昵称时,服务端用「意象词+场景词」词库(100×100)随机生成,如心语岛、微光谷 |
|
||||
| R8 | 账号昵称可在个人档案页修改(PATCH `/auth/me`);首页展示昵称而非「自己」 |
|
||||
| R8 | 账号昵称可在个人档案页修改(PATCH `/auth/me`);首页与各页「自己」展示位统一用昵称(合盘/问答/星座/档案卡) |
|
||||
| R9 | 账号头像可在「我的」页更换:相册或拍照上传;服务端持久化;GET `/auth/me` 返回 `avatar_url`;未设置时 UI 用愈心小人正面默认头像(`public/default-avatar.png`,源图 `public/logo/愈心小人1.png`) |
|
||||
|
||||
---
|
||||
|
||||
## 8. 数据模型影响
|
||||
|
||||
- `users.phone` UNIQUE · `users.password_hash` · `users.nickname`
|
||||
- `users.phone` UNIQUE · `users.password_hash` · `users.nickname` · `users.avatar_url`
|
||||
- `user_sessions(token, user_id, expires_at)`
|
||||
- 本地文件:`data/avatars/{user_id}.{jpg|png|webp}`(进程相对路径)
|
||||
|
||||
---
|
||||
|
||||
@@ -102,8 +104,10 @@ Device 绑定到账号 User
|
||||
| POST | `/api/v1/auth/register` | 注册(可带 nickname) |
|
||||
| POST | `/api/v1/auth/login` | 登录 |
|
||||
| POST | `/api/v1/auth/logout` | 登出 |
|
||||
| GET | `/api/v1/auth/me` | 当前账号 |
|
||||
| GET | `/api/v1/auth/me` | 当前账号(含 avatar_url) |
|
||||
| PATCH | `/api/v1/auth/me` | 更新昵称 `{ nickname }` |
|
||||
| POST | `/api/v1/auth/me/avatar` | multipart `file`;jpeg/png/webp;≤2MB → 更新 avatar_url |
|
||||
| GET | `/api/v1/media/avatars/:file` | 公开读头像文件 |
|
||||
|
||||
---
|
||||
|
||||
@@ -113,12 +117,30 @@ Device 绑定到账号 User
|
||||
|---|---|---|
|
||||
| register/login | ✓ | ✓ |
|
||||
| profiles / reports 写读 | ✗ | ✓ |
|
||||
| 上传头像 | ✗ | ✓ |
|
||||
| 读头像媒体 | ✓ | ✓ |
|
||||
|
||||
---
|
||||
|
||||
## 11. 埋点
|
||||
|
||||
`auth_register` · `auth_login` · `auth_logout`
|
||||
经统一 `track()`(见 [analytics.md](analytics.md) · [ops-analytics.md](ops-analytics.md))。
|
||||
**非** P1 核心漏斗 5 事件;接入后走自有 `POST /analytics/events`(及可选 GA)。
|
||||
禁止参数含手机号、明文密码、头像绝对 URL / `user_id`。
|
||||
|
||||
| Event | 触发 | 可选 params |
|
||||
|---|---|---|
|
||||
| `auth_register` | 账号新建成功(含 OpenLogin 自动建号,`is_new=true`) | `source`: login_page |
|
||||
| `auth_login` | 已有账号登录成功(`is_new=false`) | `source`: login_page |
|
||||
| `auth_logout` | 用户在「我的」点退出且本地 session 已清 | `surface`: mine |
|
||||
| `avatar_sheet_opened` | 「我的」打开更换头像 sheet | `surface`: mine |
|
||||
| `avatar_upload_succeeded` | 头像上传 API 成功且 UI 刷新为新图 | `source`: album \| camera |
|
||||
| `avatar_upload_failed` | 头像上传失败(校验/网络/服务端) | `source`: album \| camera · `reason`: too_large \| bad_type \| network \| server \| unknown |
|
||||
| `nickname_updated` | PATCH 昵称成功 | `surface`: profile |
|
||||
|
||||
`page_view` 对 `/login` · `/mine` 由路由自动采集,本 Spec 不重复定义。
|
||||
|
||||
**实现状态:** 事件名以本表为准;H5 已挂 Login / Mine / Profile(`track` → 自有 ingest + 可选 GA)。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
|
||||
```text
|
||||
/ask
|
||||
├── 愈心 AI / 顾问 Tab
|
||||
├── 顾问列表 → 顾问专属对话(?advisor=key · 顶栏返回回列表)
|
||||
├── Empty(无档案)
|
||||
├── Loading(发送中)
|
||||
├── Normal(历史 + 输入)
|
||||
|
||||
@@ -111,10 +111,15 @@ Tab 陪伴 → /companion
|
||||
|
||||
## 11. 埋点
|
||||
|
||||
| Event | 触发 |
|
||||
|---|---|
|
||||
| `companion_viewed` | 打开 |
|
||||
| `mood_saved` | P2 |
|
||||
| Event | 触发 | 可选 params |
|
||||
|---|---|---|
|
||||
| `companion_viewed` | 打开 `/companion` | — |
|
||||
| `mood_saved` | 心情保存成功 | `score`(整数分,非正文) |
|
||||
| `growth_plan_viewed` | 打开 `/growth-plan` 且列表加载结束 | — |
|
||||
| `growth_plan_created` | 创建计划成功 | — |
|
||||
| `growth_plan_checkin` | 今日打卡成功 | — |
|
||||
|
||||
禁止参数含计划 title/focus/note 明文。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -45,9 +45,9 @@
|
||||
↓
|
||||
进入 /scales/:slug
|
||||
↓
|
||||
加载题目
|
||||
↓
|
||||
逐题作答(须全部完成)
|
||||
已有结果? → 直接展示最近结果 +「重新测试」
|
||||
↓(无结果 / 点重测)
|
||||
加载题目 · 逐题作答(须全部完成)
|
||||
↓
|
||||
无 Self? → 引导建档
|
||||
↓
|
||||
@@ -60,10 +60,13 @@ POST result → 展示丰富结果
|
||||
|
||||
| 子能力 | P1 |
|
||||
|---|---|
|
||||
| 测试入口(探索 Tab) | ✓ |
|
||||
| 测试列表 | ✓ |
|
||||
| 测试入口(探索 Tab · 首页宫格) | ✓ · 产品向 `mbti-lite`;探索主路径为 curated 题库(A 集) |
|
||||
| 测试列表 | ✓ · 探索「题库精选」宫格(每类 1~2)+「题库分类」;分类页 `/explore/bank/:key` |
|
||||
| 题库范围(A) | ✓ 人格 / 情绪能力 / 智能 / 生活与关系;**不含**抑郁焦虑强迫躁狂双相等临床筛查 |
|
||||
| 问题流程 | ✓ |
|
||||
| 答题保存(服务端结果落库) | ✓ |
|
||||
| 最近结果回看 | ✓ GET `/scales/{slug}/result`;有结果进页不重复作答 |
|
||||
| 重新测试 | ✓ 结果页按钮 → 清空草稿再答;新结果落库并覆盖展示 |
|
||||
| 中断恢复 | ✓ localStorage 草稿(`scaleDraft`);提交后清除 |
|
||||
| 结果生成(丰富结构) | ✓ |
|
||||
| 免费层 | ✓ 全量 result |
|
||||
@@ -79,8 +82,10 @@ POST result → 展示丰富结果
|
||||
|
||||
| 路由 | 页面 |
|
||||
|---|---|
|
||||
| `/explore` | ExplorePage |
|
||||
| `/scales/:slug` | ScalePage |
|
||||
| `/explore` | ExplorePage(题库精选宫格 + 题库分类 + 其它工具) |
|
||||
| `/explore/bank/:category` | ExploreBankCategoryPage · curated 题库分类列表 |
|
||||
| `/explore/:category` | ExploreCategoryPage · 产品工具分类(解码/星座等) |
|
||||
| `/scales/:slug` | ScalePage(含 bank slug) |
|
||||
|
||||
```text
|
||||
/scales/:slug
|
||||
@@ -116,6 +121,13 @@ POST result → 展示丰富结果
|
||||
| R5 | result 含 label/summary/overview/dimensions/tips/scripts/growth_plan/faq |
|
||||
| R6 | 结果「不是固定标签」需在文案中提示 |
|
||||
| R7 | 作答过程写入本地草稿(按 slug);提交成功后清除;刷新可恢复未提交答案 |
|
||||
| R8 | 同一用户同一 slug(含 curated 题库 slug)若已有 `scale_results`,再次进入直接展示**最近一次**结果,并提供「重新测试」;未点重测不得自动进入答题 |
|
||||
| R9 | `mbti-lite` 产品展示名统一为「MBTI测试」(首页宫格 / 探索入口 / 量表 title) |
|
||||
| R10 | **标准版 `mbti-lite`**:开源 OEJTS 1.2 · **32 题**(四维各 8)· 双极 1–5 Likert;按维累加,阈值判出 E/I·S/N·T/F·J/P 一侧,合成四字母类型;**免费** |
|
||||
| R11 | **完整版 `mbti-full`**:60 题(四维各 15)· 须**成长会员**;未开通时 GET 返回 `locked=true` 且无题目;提交返回 403 |
|
||||
| R12 | 禁止使用官方 MBTI® 版权题干;结果须提示「不是固定标签」;题库重大更新须 soft-delete 旧 `scale_results` |
|
||||
| R13 | curated 题库(`scalebank`)仅含 A 集非临床探索量表;文案须声明「非诊断」;临床类(抑郁/焦虑/强迫等)不得进入 C 端 |
|
||||
| R14 | curated 题库作答走同一 `/scales/:slug`;完成后再次点击入口须遵守 R8(只看结果或显式重测),不得每次从头作答 |
|
||||
|
||||
---
|
||||
|
||||
@@ -134,6 +146,7 @@ POST result → 展示丰富结果
|
||||
|---|---|---|
|
||||
| GET | `/api/v1/scales` | 列表 |
|
||||
| GET | `/api/v1/scales/{slug}` | 题目 |
|
||||
| GET | `/api/v1/scales/{slug}/result` | 当前用户该量表最近一次结果;无则 404 |
|
||||
| POST | `/api/v1/scales/{slug}/result` | 提交计分 |
|
||||
|
||||
---
|
||||
@@ -144,18 +157,27 @@ POST result → 展示丰富结果
|
||||
|---|---|---|
|
||||
| 看列表/题目 | ✓ | ✓ |
|
||||
| 提交结果 | ✗ | ✓ |
|
||||
| `mbti-full` 作答 | ✗(须成长会员) | ✓(会员 active) |
|
||||
|
||||
---
|
||||
|
||||
## 11. 埋点
|
||||
|
||||
| Event | 触发 |
|
||||
|---|---|
|
||||
| `scale_list_viewed` | 探索列表 |
|
||||
| `scale_started` | 进入作答 |
|
||||
| `scale_completed` | 出结果 |
|
||||
| `scale_share_clicked` | 分享 |
|
||||
| `scale_cta_relation` / `scale_cta_ask` | 导流 |
|
||||
经统一 `track()`;非 P1 核心 5 事件。禁止参数含题干全文、答案明文、档案 ID。
|
||||
|
||||
| Event | 触发 | 可选 params |
|
||||
|---|---|---|
|
||||
| `scale_list_viewed` | 打开 `/explore` 且题库 catalog 加载成功 | — |
|
||||
| `scale_bank_category_viewed` | 打开 `/explore/bank/:category` 且分类加载成功 | `category`(key) |
|
||||
| `scale_started` | 用户点开始进入作答(含「重新测试」后再开始) | `slug` · `access`: free\|member |
|
||||
| `scale_completed` | 提交计分成功并展示结果 | `slug` · `access`: free\|member |
|
||||
| `scale_result_reopened` | 再次进入已有结果直接展示(R8,未重测) | `slug` |
|
||||
| `scale_retake_clicked` | 点「重新测试」 | `slug` |
|
||||
| `scale_locked_viewed` | 会员锁页展示(如 mbti-full) | `slug` |
|
||||
| `scale_share_clicked` | 结果页打开分享 | `slug` |
|
||||
| `scale_cta_relation` / `scale_cta_ask` | 结果导流(若 UI 有) | `slug` |
|
||||
|
||||
`page_view` 对 `/explore` · `/explore/bank/*` · `/scales/*` 由路由自动采集。
|
||||
|
||||
---
|
||||
|
||||
@@ -165,6 +187,14 @@ POST result → 展示丰富结果
|
||||
**When** 答完提交
|
||||
**Then** 返回 label 与 overview/tips 等丰富字段
|
||||
|
||||
**Given** 已提交过结果
|
||||
**When** 再次进入 `/scales/{slug}`
|
||||
**Then** 直接展示最近结果与「重新测试」;不进入答题
|
||||
|
||||
**Given** 结果页点「重新测试」并完成提交
|
||||
**When** 再次进入
|
||||
**Then** 展示新结果
|
||||
|
||||
**Given** 未答完
|
||||
**When** 提交
|
||||
**Then** 前端拦截;不成功落库
|
||||
@@ -186,7 +216,8 @@ POST result → 展示丰富结果
|
||||
| 项 | 内容 |
|
||||
|---|---|
|
||||
| Packages | `internal/scale` · `service/scale` · `ExplorePage` · `ScalePage` |
|
||||
| Seeds | communication-style · emotion-pattern |
|
||||
| Seeds | communication-style · emotion-pattern · **mbti-lite(OEJTS 32)** · **mbti-full(60·会员)** |
|
||||
| Gaps | 结果付费墙若要做须先改 Spec;全量 §11 埋点未挂(核心漏斗见 analytics) |
|
||||
| Tests | score/result L1;`scaleDraft.spec`;Scale 流程组件测 |
|
||||
| Process Review | 草稿恢复已实现 · P1 收口 |
|
||||
| Tests | score/result L1;`ScoreJungian`;`scaleDraft.spec`;Scale 流程组件测 |
|
||||
| Process Review | OEJTS 标准/完整双轨 · 最近结果回看 · P1 收口 |
|
||||
| Credit | OEJTS / Open Psychometrics · openjung MIT |
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
|
||||
```text
|
||||
/
|
||||
├── Hero / 品牌
|
||||
├── 全局顶栏:透明愈心谷 Logo(AppHeader,全站)
|
||||
├── 「自己」卡片标题展示账号昵称(默认意象词+场景词;档案页可改)
|
||||
├── 穿衣指数 · 颜色搭配 · 养生推荐
|
||||
├── 功能入口(4 列固定网格 · 多行换行 · 禁止横向滑动)
|
||||
@@ -91,14 +91,16 @@ Empty:首页本身是入口,不因无档案空白死页。
|
||||
| R2 | 不展示内部运维信息(API 连接状态等) |
|
||||
| R3 | 入口文案符合 lexicon(个人画像/关系理解/成长会员…) |
|
||||
| R4 | Tab 五名冻结:首页·探索·问答·陪伴·我的 |
|
||||
| R5 | 「自己」卡片:穿衣指数 / 颜色搭配 / 养生推荐;有 Self 档案生日时按生日+本地时刻易经卦象种子调大模型生成;无档案或 LLM 不可用则本地回退 |
|
||||
| R5 | 「自己」卡片:穿衣指数 / 颜色搭配 / 养生推荐;有 Self 生日时按生日+**本地日历**+**十二时辰**易经种子生成;**每一时辰准点切换**;无档案或 LLM 不可用则本地回退 |
|
||||
| R6 | 文案禁止占卜/算命恐吓与医疗疗效承诺;卦象仅作节律意象 |
|
||||
| R7 | 贴士按 `user × 时辰起点` 持久缓存;GET 优先读缓存**即时返回**;缓存未命中时先回退/旧值,后台异步生成写入,禁止每次打开同步等 LLM |
|
||||
| R8 | 响应含 `shichen` / `shichen_name` / `valid_until`(下一时辰起点);前端在 `valid_until` 自动静默刷新 |
|
||||
|
||||
---
|
||||
|
||||
## 8. 数据模型影响
|
||||
|
||||
经首页建档时写 `profiles`(见 profile Spec)。每日贴士可缓存(同用户约 45 分钟 / 按时段刷新)。
|
||||
经首页建档时写 `profiles`。`home_daily_tips(user_id, shichen_start, tips jsonb)` 缓存时辰贴士。
|
||||
|
||||
---
|
||||
|
||||
@@ -107,7 +109,7 @@ Empty:首页本身是入口,不因无档案空白死页。
|
||||
| Method | Path | 说明 |
|
||||
|---|---|---|
|
||||
| GET | `/api/v1/home/tools` | 宫格(已有) |
|
||||
| GET | `/api/v1/home/daily-tips` | 自己卡片贴士(DeviceAuth;有 birthday 则 LLM) |
|
||||
| GET | `/api/v1/home/daily-tips` | 自己卡片贴士(读缓存;含 valid_until) |
|
||||
| — | 复用 | `POST /profiles`、`POST /reports/portrait` |
|
||||
|
||||
---
|
||||
@@ -142,9 +144,13 @@ Empty:首页本身是入口,不因无档案空白死页。
|
||||
**When** 提交主 CTA
|
||||
**Then** 进入画像基础结果路径
|
||||
|
||||
**Given** 已登录且有 Self 生日、已配 deepseek
|
||||
**Given** 已登录且有 Self 生日、该时辰已有缓存
|
||||
**When** GET `/home/daily-tips`
|
||||
**Then** `source=llm` 且含 clothing_index / palette / wellness
|
||||
**Then** 立即返回缓存(含 clothing/palette/wellness / valid_until),不阻塞 LLM
|
||||
|
||||
**Given** 时辰切换到点
|
||||
**When** 前端到达 `valid_until`
|
||||
**Then** 静默刷新;穿衣/颜色/养生随新时辰更新
|
||||
|
||||
**Given** 无档案或无 LLM
|
||||
**When** GET `/home/daily-tips`
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
# Feature Spec: 用户文字输入合规校验
|
||||
|
||||
> Status: `Active` · Map: `横切 · 安全/合规` · Phase: `P2`
|
||||
> 关联:[lexicon.md](../lexicon.md) · [.ai/security.md](../../security.md) · account-auth / profile / ask / companion
|
||||
|
||||
---
|
||||
|
||||
## 1. 功能定义
|
||||
|
||||
| 字段 | 内容 |
|
||||
|---|---|
|
||||
| Name | 文字输入合规(Text Compliance) |
|
||||
| Purpose | 所有用户提交的**自由文字**在服务端统一做合法性/合规校验;前端可做即时提示,**以后端拒绝为准** |
|
||||
| Business Goal | 降低 XSS/注入、恐吓与医疗疗效话术、垃圾刷屏进入 DB 与模型上下文的风险 |
|
||||
|
||||
| In | Out |
|
||||
|---|---|
|
||||
| 昵称 · 档案显示名 · 问答 content · 心情/打卡 note · 成长计划 title/focus · 邀请 display_name · 意象场景自填 | 纯数字字段(生日年月日、分数、经纬度) |
|
||||
| 长度 · 格式清洗 · XSS/控制字符 · lexicon 硬禁止 · 简易刷屏特征 | 完整内容审核平台 / 人工审 / 语音 |
|
||||
| 错误码统一 | 改开放登录策略本身 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 用户价值
|
||||
|
||||
1. 避免有害/违规文案入库与进模型。
|
||||
2. 提交失败时得到可读中文原因。
|
||||
3. N/A(安全横切,非付费面)。
|
||||
|
||||
---
|
||||
|
||||
## 3. 用户角色
|
||||
|
||||
Visitor / User / Admin 凡提交自由文字均适用(Admin 运营文案可后续加强;本 Spec **先 C 端用户 API**)。
|
||||
|
||||
---
|
||||
|
||||
## 4. 用户流程
|
||||
|
||||
```text
|
||||
用户输入文字 →(可选)前端即时校验
|
||||
→ API Handler/Service 调用 textsafe.Check(kind, text)
|
||||
→ OK:规范化后入库/进模型
|
||||
→ 拒绝:HTTP 400 · code 40060 · message 可读原因
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5–6. 页面 / 状态
|
||||
|
||||
各既有表单;Error 态展示 `message`。无新页面。
|
||||
|
||||
---
|
||||
|
||||
## 7. Business Rules
|
||||
|
||||
| ID | Rule |
|
||||
|---|---|
|
||||
| R1 | **后端必须校验**所有用户自由文字;前端校验不得替代后端 |
|
||||
| R2 | 种类与上限(rune):`nickname` 1–16;`display_name` 1–24;`ask_content` 1–2000;`note` 0–200;`title` 1–40;`focus` 0–40;`scene` 1–80 |
|
||||
| R3 | 拒绝控制字符(允许消息内 `\n` `\t`);拒绝 HTML/脚本片段(如 `<script`、`javascript:`) |
|
||||
| R4 | 命中 lexicon 硬禁止子串(占卜/算命/改命恐吓/疗效承诺/「测测」品牌自称等)→ 拒绝 |
|
||||
| R5 | 刷屏特征:连续相同字 ≥8,或可见字符全相同且长度 ≥6 → 拒绝 |
|
||||
| R6 | 密码字段不做 lexicon,仅拒空字节;手机号走既有数字规则 |
|
||||
| R7 | 校验通过后写库的是 **Normalize** 后的文本(Trim;压缩首尾空白) |
|
||||
| R8 | 错误码:`40060`;文案过 lexicon(勿用恐吓语气) |
|
||||
|
||||
---
|
||||
|
||||
## 8. 数据模型
|
||||
|
||||
无新表。进程内可选短时计数(本版刷屏以内容特征为主,不做跨请求配额表)。
|
||||
|
||||
---
|
||||
|
||||
## 9. API
|
||||
|
||||
既有写接口;拒绝时统一:
|
||||
|
||||
```json
|
||||
{ "code": 40060, "message": "文案不合规:…", "data": null }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. 权限
|
||||
|
||||
同各业务接口鉴权;校验在鉴权之后、写库之前。
|
||||
|
||||
---
|
||||
|
||||
## 11. 埋点
|
||||
|
||||
可选:`text_rejected{kind}`(本版可不接)。
|
||||
|
||||
---
|
||||
|
||||
## 12. 验收
|
||||
|
||||
| Given | When | Then |
|
||||
|---|---|---|
|
||||
| nickname 含「算命」 | PATCH /auth/me | 40060 |
|
||||
| ask content 含 `<script` | POST messages | 40060 |
|
||||
| display_name 正常「小愈」 | POST profile | 200 |
|
||||
| note=`啊啊啊啊啊啊啊啊` | POST mood | 40060 |
|
||||
|
||||
---
|
||||
|
||||
## 13. AI 检查
|
||||
|
||||
- [x] lexicon
|
||||
- [x] 后端权威
|
||||
- [x] 不扩开放登录
|
||||
|
||||
---
|
||||
|
||||
## 14. Implementation
|
||||
|
||||
| 项 | 内容 |
|
||||
|---|---|
|
||||
| Package | `apps/api/internal/textsafe` |
|
||||
| Mirror | `@yuxingu/utils` `validateUserText`(即时提示) |
|
||||
| Wire | auth · profile · ask · companion · growth · synastry accept |
|
||||
@@ -98,6 +98,10 @@ CTA:节气陪伴 / 问答「生活节奏」/ 分享
|
||||
| R5 | 推荐用语:体质倾向、生活建议、节律、平衡 |
|
||||
| R6 | 可展示五行隐喻,须标注探索/非医疗 |
|
||||
| R7 | 与星象性格、个人画像内容可互相链,不互相覆盖主路径 |
|
||||
| R8 | **体质/五行倾向**随生日确定;**今日/本周生活建议**按**自然日(CST)**刷新(本周焦点随星期变) |
|
||||
| R9 | GET `/reports/latest` 与 GET `/reports/{id}`(type=rhythm):`as_of` ≠ 当日则**原 id 原地更新**时效段并落库;同日即时返回 |
|
||||
| R10 | `summary` 含 `as_of` · `valid_until`(次日 00:00 CST);前端到点静默刷新;**不按十二时辰** |
|
||||
| R11 | `summary.wuxing` 必含五行分布 `bars`(与愈心解码同源算法)及主/辅倾向;缺字段时 GET 原地补全 |
|
||||
|
||||
---
|
||||
|
||||
@@ -108,6 +112,7 @@ CTA:节气陪伴 / 问答「生活节奏」/ 分享
|
||||
| `growth_reports.type` | `rhythm` / `life_rhythm` |
|
||||
| 或 Constitution 专用表 | 若需独立聚合,实现时 ADR |
|
||||
| 禁止 | `luck_score`、病名诊断字段 |
|
||||
| 报告 JSON | `as_of` · `valid_until` · `today_tip` · `week_focus` |
|
||||
|
||||
---
|
||||
|
||||
@@ -155,6 +160,14 @@ CTA:节气陪伴 / 问答「生活节奏」/ 分享
|
||||
**When** 扫 summary+detail
|
||||
**Then** 符合 lexicon
|
||||
|
||||
**Given** 已有 rhythm 报告且 `as_of` 为昨日
|
||||
**When** GET latest
|
||||
**Then** `today_tip` / `week_focus` 按今日更新;报告 `id` 不变
|
||||
|
||||
**Given** 用户停留在 `/rhythm` 跨自然日
|
||||
**When** 到达 `valid_until`
|
||||
**Then** 前端静默刷新建议文案
|
||||
|
||||
---
|
||||
|
||||
## 13. AI 开发前检查
|
||||
|
||||
@@ -118,7 +118,7 @@ analytics_daily_page(可选汇总)
|
||||
- 卡片:DAU、新增、会话数、人均会话时长
|
||||
- 图:日活趋势;页面均停留 TOP
|
||||
- 表:页面明细、退出页 TOP、点击 TOP
|
||||
- 漏斗:画像完成 → 深度 CTA → 支付成功
|
||||
- 漏斗:探索列表 → 开始作答 → 量表完成 → 画像完成 → 深度 CTA → 支付成功
|
||||
|
||||
视觉:愈心谷色系;品牌仅 logo,无「运营后台」字样。
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
| In | Out |
|
||||
|---|---|
|
||||
| Self / Other 档案创建与生日变更触发 | 无档案凭空出合盘 |
|
||||
| 单人:portrait · star · rhythm | 意象卡片抽牌(配额玩法,不预生成) |
|
||||
| 单人:portrait · star · rhythm(star/rhythm 运势与今日建议按自然日在 GET 时原地刷新,见各 Spec) | 意象卡片抽牌(配额玩法,不预生成) |
|
||||
| 有 Self+Other:relation + synastry 成对覆盖 | 附近的人合盘(进页再算) |
|
||||
|
||||
---
|
||||
|
||||
@@ -107,6 +107,9 @@
|
||||
| R9 | 附近的人默认 `geo_visible=false`;仅可见已开启位置的 self 档案 |
|
||||
| R10 | 合盘星历走 Swiss Ephemeris(默认 Moshier);宫位制 Whole Sign |
|
||||
| R11 | 合盘交叉校验:档案 A 为本账号 Self;档案 B 须为本账号 `other` 或附近可见他人 Self;拒绝 self×self / 同 id |
|
||||
| R12 | **本命层**(轮盘/行星/相位/太阳月亮上升)随生日确定,不因打开时间重算;**运势层**(日/周/月/年 outlook · 行运)按**自然日(CST)**刷新 |
|
||||
| R13 | GET `/reports/latest` 与 GET `/reports/{id}`(type=star):若 `summary.as_of` ≠ 当日则**原报告 id 原地更新**时效段并落库;同日再读即时返回;禁止为换日运新建报告 id(以免深度权益丢失) |
|
||||
| R14 | `summary` 含 `as_of`(YYYY-MM-DD)与 `valid_until`(次日 00:00 CST RFC3339);前端到点静默刷新;**不按十二时辰**切换 |
|
||||
|
||||
---
|
||||
|
||||
@@ -119,7 +122,7 @@
|
||||
| `profiles.birth_place` | 可选;常用城市表解析经纬度 |
|
||||
| `profiles.geo_lat/lng/visible` | 附近的人 |
|
||||
| `synastry_invites` | 邀请 token · host/guest · report_id |
|
||||
| 报告 JSON | `charts.*`(五主盘+推运)· `as_of` · 三指数 · fortune/transits |
|
||||
| 报告 JSON | `charts.*`(五主盘+推运)· `as_of` · `valid_until` · 三指数 · fortune/transits |
|
||||
|
||||
详见 erd;实现切片同步 OpenAPI。
|
||||
|
||||
@@ -153,7 +156,7 @@
|
||||
|
||||
| Event | 触发 |
|
||||
|---|---|
|
||||
| `star_completed` / portrait_completed source=star | 基础结果展示 |
|
||||
| `star_completed` | 基础结果展示 |
|
||||
| `star_wheel_viewed` | 点选轮盘行星 |
|
||||
| `synastry_completed` | 合盘结果展示 |
|
||||
| `synastry_invite_created` / `synastry_invite_accepted` | 邀请链路 |
|
||||
@@ -184,6 +187,14 @@
|
||||
**When** 打开 `/star`
|
||||
**Then** 页内生日表单可生成
|
||||
|
||||
**Given** 已有 star 报告且 `as_of` 为昨日
|
||||
**When** GET latest
|
||||
**Then** 日运等 outlook 按今日更新;报告 `id` 不变;响应含当日 `as_of` 与 `valid_until`
|
||||
|
||||
**Given** 用户停留在 `/star` 跨自然日
|
||||
**When** 到达 `valid_until`
|
||||
**Then** 前端静默刷新运势 Tab 内容
|
||||
|
||||
---
|
||||
|
||||
## 13. AI 开发前检查
|
||||
|
||||
+2
-1
@@ -7,7 +7,8 @@
|
||||
- DB: PostgreSQL
|
||||
- Migrations: goose (or golang-migrate) under `apps/api/migrations/`
|
||||
- Log: structured (zap or slog wrapper). No `fmt.Println` in business paths.
|
||||
- Module path: `github.com/yuxingu/digital-psychology/apps/api`
|
||||
- Module path: `github.com/yuxingu/digital-psychology/apps/api`(Go import 身份;**不**表示托管在 GitHub)
|
||||
- Git host: `https://git.jackyu66.com/jack/digital-psychology.git`(唯一远程 `origin`;无 GitHub Actions)
|
||||
|
||||
## User H5
|
||||
|
||||
|
||||
Reference in New Issue
Block a user