docs(tasks): synastry staging fix brief (create fails on missing gte)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Ad9rqAB8pXXvyzh7f4X8v
This commit is contained in:
Jesse_Chen
2026-10-21 14:02:22 +08:00
co-authored by Claude Opus 5.5
parent 63984d4fca
commit cb3bc330eb
2 changed files with 67 additions and 0 deletions
+1
View File
@@ -509,4 +509,5 @@
| `TASK-niryaana-shoola-pvr-20261018.md` | `PROGRESS-niryaana-shoola-pvr-20261018.md` | #84 Niryaana Shoola 改 PVR 口径(我们的表与 Shoola 逐行相同;推翻 BUG-1283 所选 profile;占星师 7a773d13) | 待验收 | `codex/niryaana-shoola-pvr-20261018` |
| `TASK-synastry-full-report-20261018.md` | #82 | 婚恋合盘:选人页 + 完整合盘报告(关系画像九节:结论+折叠的分析逻辑+关系时间线+技术依据摘要;英文按需;计费键 synastry.full) | 排队(等 #78、#79、#81) | `codex/synastry-full-report-20261018`;动表 |
| `TASK-synastry-report-chat-20261018.md` | `PROGRESS-synastry-report-chat-20261018.md` | 从合盘报告某一节进入对话问依据(绑定报告与节、对话里可用术语、只依据已存计算结果并逐条核对、计费照普通对话) | 已验收 | `549e37b99`;动表 |
| `TASK-synastry-staging-fix-20261021.md` | — | 婚恋合盘 staging 点「开始合盘」即失败(兼容层缺 `.gte`)+ 时间线无起止、英文缺分析逻辑、删模型后旧对话改用默认模型(BUG-1399 起) | 待提 issue | `codex/synastry-staging-fix-20261021`;动表 |
| `TASK-synastry-report-chat-fix-20261020.md` | `PROGRESS-synastry-report-chat-20261018.md` | 大运核对要认报告里的「小运」和英文 mahadasha / antardasha;预填文案只留一句 | 已验收 | `549e37b99` |
@@ -0,0 +1,66 @@
# 修复单:婚恋合盘在 staging 点「开始合盘」就失败,及验收遗留(2026-10-21)
## 基线
- `origin/staging` = `63984d4fc`(已部署,`/api/health` 的 `gitCommit` 一致)。开工前 `git fetch origin --prune`。
- 分支:`codex/synastry-staging-fix-20261021`;工作树:`.worktrees/synastry-staging-fix-20261021`。
- 关联:#82(完整合盘报告)、#83(进对话问依据)、BUG-990(自托管兼容层缺查询写法)、BUG-1397、BUG-1398。
## 事故实证
| # | 现象(产品负责人 10-21 真机) | 根因(按符号定位) |
| --- | --- | --- |
| 1 | **P0**:选好两个人点「开始合盘」,按钮下出现「报告生成暂时不可用」,一份报告都生成不了 | `frontend/src/lib/synastry-full-create.ts` 的 `createSynastryFullReport` 用 `.gte("created_at", …)` 数今天已生成的报告;自托管数据库客户端 `frontend/src/lib/db/local-postgres-client-core.ts` 的查询构造器**没有 `gte` 方法**(只有 `eq / neq / gt / lte / like / in / is / not / or`;内部类型里有 `gte` 但没实现,编译分支里也没有 `>=`)。调用时报 TypeError,被 `app/api/reports/route.ts` 的 `POST` 外层 `catch` 吞成通用 500「报告生成暂时不可用」。出错在预留点数之前,不扣点。单测用的是手写桩(`Query` 类型里自带 `gte`),所以测试全绿、门禁也绿。与 BUG-990 同一类:兼容层不支持的写法只在真库上暴露 |
| 2 | 关系时间线每段只显示阶段名和描述,看不出是哪段时间 | `components/synastry/synastry-report-view.tsx` 时间线只渲染 `segment.phase` / `segment.text`;`TimelineSegment` 里有 `start` / `end`(`lib/synastry-full-timeline.ts`)但从未显示。#82 任务书 E6 要求写起止年月 |
| 3 | 英文报告里「分析逻辑」和时间线依据不见了 | `67c1e6881` 重排时给两处加了 `language === "zh" ? … : null`,改之前中英文都显示;DESIGN.md 没写这条 |
| 4 | 后台删除已发布模型后,绑定这个模型的用户旧对话不能再提问 | `0a5d93ab7` 的 `admin_delete_model_version`;对话按 `chat_sessions.model_id / model_config_version` 解析模型(`app/api/consult/route.ts` 的 `resolveModel` → `resolveSessionLanguageModel`),解析不到就无法继续。`PROGRESS-model-admin-draft-delete-20261020.md` 也写明了这一后果 |
| 5 | 开关读取失败时显示「星盘档案暂时读不出来」(读的是开关不是档案);开关关闭时先闪一下选人页再变「合盘服务暂未开放」 | `components/synastry/synastry-picker.tsx` 的 `load` |
| 6 | `docs/BUG_HISTORY.md` 里 BUG-1397 整段写了两遍 | `006b067e8` |
## 决策记录(产品负责人 2026-10-21)
| # | 决定 |
| --- | --- |
| K1 | 第 4 条选 **B**:被删模型绑定的旧对话,下一轮**自动改用当前默认模型**继续,不报错;对话里不另行提示(模型名在设置里本来就能看到) |
| K2 | 第 2、3 条按 #82 原定:时间线每段显示起止年月;英文报告同样有「分析逻辑」和时间线依据(英文内容来自英文那一次生成,不翻译中文) |
| K3 | 定价 `synastry.full` 19 点维持(已在 staging 生效) |
## 硬红线
1. 修 P0 用**补齐兼容层**(`gte`,顺手补对称的 `lt`),不改业务查询去绕开;这是 AGENTS §7.6 要求的「新用到的查询写法必须 test:db 真查」。
2. 新增一条防复发测试:扫描 `frontend/src` 里对数据库查询构造器调用的方法名(`.eq(` `.gte(` 等,限定在 `from(...)` 链上),断言每个都在 `local-postgres-client-core.ts` 的构造器上有实现。实现方式不限,但要能拦住「桩里有、真客户端没有」。
3. 合盘创建链路必须有一条 `npm run test:db` 真库测试:用真的自托管客户端走 `createSynastryFullReport` 到「预留成功、任务入队」为止(模型与 Python 计算可打桩),**不得用手写 `Query` 桩**。
4. 动表的轮次真跑 `npm run test:db`;改既有断言写三栏;不改 `.gitea/`。
5. 修完推 staging 后,在 PROGRESS 里写明需要产品负责人真机复测的步骤(见 T6);执行方不得写「已通过」。
## 任务分解
| # | 内容 | 验收标准 |
| --- | --- | --- |
| T1 | **P0**:`local-postgres-client-core.ts` 补 `gte`、`lt`(构造器方法 + 编译成 `>=`、`<`);BUG_HISTORY 新编号,关联 BUG-990 | `test:db`:新增兼容层测试真查 `gte` / `lt`;合盘创建真库测试(红线 3)通过 |
| T2 | 防复发扫描测试(红线 2) | 把 `gte` 方法临时删掉时该测试会红(PROGRESS 里写这一步的结果) |
| T3 | 时间线显示起止年月:每段标题行「2027 年 9 月 – 2029 年 3 月 阶段名」,英文「Sep 2027 – Mar 2029」;第一段起点是今天时写「现在」/「Now」 | 渲染测试用名人 golden |
| T4 | 英文报告恢复「分析逻辑」(Analysis)与时间线依据,折叠方式与中文一致;DESIGN.md 补一句 | 渲染测试:英文模式下每个正文节都有折叠块 |
| T5 | K1:对话解析不到绑定的模型时,改用当前默认模型继续,并把会话的 `model_id / model_config_version` 更新成新模型;没有任何可用模型时才报现有的「模型不可用」 | 单测:被删版本的会话下一轮用默认模型;无默认模型时仍报错 |
| T6 | 选人页:开关读取失败显示「合盘服务暂时连不上,请稍后再试」;开关结果回来之前不渲染选人区(只渲染标题和副标题);删掉 BUG_HISTORY 里重复的 BUG-1397 一段;CHANGELOG、PROGRESS(含真机复测步骤:选两人生成一份、等待页、报告揭幕、切英文、从末尾进对话问一节) | 渲染测试;文档齐 |
## 让步顺序
T1、T2 最先做,单独一个提交先推 staging(门禁绿、部署后告知产品负责人可以复测生成);T3~T6 随后。
## 开工前置命令
```bash
git fetch origin --prune
git worktree add -b codex/synastry-staging-fix-20261021 .worktrees/synastry-staging-fix-20261021 origin/staging
cd .worktrees/synastry-staging-fix-20261021
grep -n "gte\| lt(" frontend/src/lib/db/local-postgres-client-core.ts
grep -rn "\.gte(\|\.lt(" frontend/src --include=*.ts --include=*.tsx | grep -v "z\.\|number()"
grep -n "BUG-1[0-9][0-9][0-9]" docs/BUG_HISTORY.md | tail -3
```
验证:`tsc --noEmit`、`npm run lint`、`npm test`(失败名单与基线逐条一致)、`npm run test:db`、`npm run build`(`/` 仍 Static,首屏 gzip ±2%)。
## BUG 编号
从 **BUG-1399** 起(10-21 staging 最大 BUG-1398),开工时核对。