# PROGRESS · 新用户启程(一)数据层(2026-10-22) Issue #95。只做 T1 首问免费和 T2 引导状态、人物关系。T3–T7 不做。 ## 基线 - 开工时 `origin/staging` = `dfa9acaf05089dbb94ee8afe34c1d5626ffb1b23`(任务书写的 `c1aa72fcb` 已过期)。 - BUG-1420 已被「Bug 历史去重」占用。本轮首问免费记 **BUG-1421**。 ## 做了什么 - 迁移 `20261022190000_onboarding_first_consult_and_relation.sql`:账户上记下首问是否用过、当前占用的请求、引导状态;别人的档案增加关系。只加列和约束,不删废列。 - 预扣在同一笔事务里占用免费额度。回答完成才记为已用。取消或寒暄把占用还回去,不记成已用。 - 账户接口增加 `firstConsultFree`。前端发送前和输入框占位,在它为真时不再当「没有点数」。 - 已登录接口读写引导状态。只接受清单关闭时间、看过的提示、进过星盘页。提示 id 只收任务书 T6 那八个。未登录 401。写入用当前登录的人,不读请求体里的用户 id。 - 档案的添加和编辑(档案页和星盘页编辑别人)加「TA 是你的」。本人不出现这项。空关系显示「其他」。 ## 红线 3 怎么选 选了 **只扣差价**。免费覆盖的是已经公布的 `chat.standard` / `standard` 价格。传入的价格更高时,只扣多出来的部分。这样标准档仍是 0 点,更贵的模型也不会整问白送。 没有公布中的标准档价格时,**不免费**,仍按传入的点数扣。现有计费测试没有这条价格,因此不会被误改成免费。 会员已经包住这一问时,不占用免费额度,留给还没有会员的那一次。合盘报告会话不占用这份额度。 0 点流水不能写进点数流水(现有约束不允许金额为 0)。记在用量台账上,后台「资金来源」显示「首问免费」;差价大于 0 时显示「首问免费(差价 N 点)」。筛选里原来对不上的 complimentary 换成「首问免费」。 ## 老账户 只把「已经有过一条完成的、且不是寒暄的咨询」标成用过。只有寒暄的账户仍然有这一次。迁移结束时跑一遍,测试可以再跑同一函数。 ## 本人与关系 本人档案行已经被现有约束拒绝写入(`chart_subject_self_mirror_retired`)。关系只存在别人的行上。本人界面仍只标「本人」。 ## 自测 | 检查 | 命令 | 结果 | | --- | --- | --- | | 类型 | `frontend\node_modules\.bin\tsc --noEmit -p frontend` | 通过,0 错 | | lint | `frontend` 下 `npm run lint` | 0 error(原有 warning 未动) | | 定向测试 | `node node_modules/tsx/dist/cli.mjs --test` 跑了本轮改到的测试文件 | 通过 | | 数据库 | `frontend` 下 `npm run test:db` | 91 项,通过 77,失败 14,取消 0。其中 13 条失败与 `tools/agent-loop/windows-known-failures.txt` 同名。多出的一条是校正遥测,见下方 | 未跑前端全量 `npm test` 和 Python 快速门(本轮不改 Python)。 全套里多出的失败是「rectification telemetry: server-only write, dedupe, retention, aggregate-only admin read, account cascade」。迁移进程退出码 1,报错只有 database migration failed,用时约 10 秒,容器日志没有 SQL 错误。同一轮里本单自己的数据库测试通过。这条遥测单独再跑:通过 1,失败 0。没有把它写进已知失败清单。 ## 偏离 - 任务书 BUG 起点 1420 已占用,顺延为 1421。 - 没有单独造一套会员夹具去测「会员不占免费额度」;规则写在预扣函数里:来源是会员时不写入占用。