Files
digital-psychology/.ai/product/feature-spec/input-compliance.md
T
jackyu66gitandCursor 89756f65b4 feat(ECR-012–016): 合规、题库、时辰刷新、头像、MBTI OEJTS 与埋点
落地输入合规、探索题库、报告日/时辰刷新、账号头像、OEJTS 量表,并补齐 H5 埋点与 Admin 漏斗;同步 ESS 工件、切至自建 Git、清理 GitHub Actions。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-13 01:27:58 +08:00

124 lines
3.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 可读原因
```
---
## 56. 页面 / 状态
各既有表单;Error 态展示 `message`。无新页面。
---
## 7. Business Rules
| ID | Rule |
|---|---|
| R1 | **后端必须校验**所有用户自由文字;前端校验不得替代后端 |
| R2 | 种类与上限(rune):`nickname` 116`display_name` 124`ask_content` 12000`note` 0200`title` 140`focus` 040`scene` 180 |
| 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 |