diff --git a/TASK-report-list-500-20260907.md b/TASK-report-list-500-20260907.md new file mode 100644 index 00000000..e71215e4 --- /dev/null +++ b/TASK-report-list-500-20260907.md @@ -0,0 +1,55 @@ +# 任务书 · 报告列表 500 修复:PostgREST JSON 路径列在 staging 不可用(2026-09-07) + +基线:`origin/staging` @ `5c644f92`(开工 `git fetch` 后以 HEAD 为准)。 + +## 事故实证(委托方已用真实会话对照实测) + +- `GET /api/reports` 稳定 500:`{"error":"报告列表暂时无法读取","code":"report_generation_failed"}`(部署 `0a1076d6`,含 MD 页 `cfcd369d`)。 +- 同一会话 `GET /api/reports/<旧报告id>` **200**——鉴权、DB 连接、`personal_reports` 表读取都正常。 +- 该列表路由(含 failed 报告的 `personal_report_sections` 聚合查询)在 09-04/05 的旧部署上**成功返回过完整列表**。`cfcd369d` 对列表查询的唯一改动是新增 select 列: + +```ts +"card_summary:report_document->executiveSummary->>summary" +``` + +- 结论:这个 PostgREST JSON 路径别名 select 在 staging 自托管 Postgres/PostgREST 上被拒,supabase 返回 error → `if (error) throw error` → catch-all 500。列表路由错误日志只记 `error.name`(PostgrestError 非 Error 实例 → `UnknownError`),线上日志无法直接看到 PostgREST 错误码——本轮顺带修观测。 +- 消费点唯一:`frontend/src/app/api/reports/route.ts`(:48 select、:80-81 映射)。 + +## 根因教训(防复发,写进红线) + +执行方单测用 stub supabase client,select 字符串**从未经过真实 PostgREST 解析**——与 gaps2"虚构盘骗过覆盖表"同款模式。凡新增 PostgREST 查询语法特性(JSON 路径、嵌套 embed、别名),必须有 `test:db` 层真实查询覆盖,或列入部署后 smoke 清单。 + +## 硬红线 + +1. 修复不得再依赖未经真实验证的 PostgREST 语法变体(比如换成带引号的 path 再赌一次);本轮修复必须以 `test:db` 真实查询或本地 Postgres+PostgREST 验证过的形态为准。 +2. 列表接口对**没有摘要**的行为必须优雅(无 `cardSummary` 字段即可,前端已是可选消费)。 +3. 其余既有红线延续(迁移规范、不改 `.gitea/workflows/**`、不提升 main、`./node_modules/.bin/tsc`)。 + +## 任务 + +### 任务 1(P0)· 止血:列表恢复可用 + +`REPORT_LIST_COLUMNS` 移除 JSON 路径列,恢复 09-06 前的列集合;`cardSummary` 暂缺省。目标:`GET /api/reports` 立即恢复 200。可单独先推一次。 + +### 任务 2(P1)· 卡片摘要走专用列 + +迁移给 `personal_reports` 加 `card_summary text`(可空,≤500 字符 check),MD 生成成功时由 worker 从 MD「摘要」段写入(与现有写 `executiveSummary.summary` 的截取逻辑同源);列表 select 该普通列。旧报告不回填(产品已放弃兼容)。迁移照既有红线,`test:db` 覆盖:列可空、authenticated 只读、worker(service_role) 可写、超长被拒。 + +### 任务 3(P1)· 观测修正 + +列表 catch 里对 PostgrestError 记 `code`/`hint` 级别信息(非 Error 实例时取其 `code` 字段;不记行数据),避免再出现 `UnknownError` 无从下手。 + +### 任务 4(P0 收尾)· 部署后 smoke + +部署对齐后用真实会话验证:列表 200;创建一份新报告端到端(这同时是 MD 页任务 5 一直欠着的收官验收:~30s ready、详情页 TOC/宽表、导出 .md、计费 0 用量结算、新报告卡片摘要显示)。把「列表 GET + 详情 GET + 创建 POST」固化进部署后 smoke 清单文档。 + +## 收尾 + +`docs/tasks/PROGRESS-report-list-500-20260907.md`;`docs/BUG_HISTORY.md` 条目(编号对远端;关联 cfcd369d);不提升 main。 + +## 交付物清单 + +1. 止血 diff + 列表恢复 200 证据 +2. `card_summary` 迁移 + worker 写入 + `test:db` 四断言 +3. 观测修正 + 测试 +4. 部署后 smoke 记录(含 MD 页端到端收官全项)