Files
Jyotisha/docs/tasks/TASK-api-not-configured-mislabel-20260904.md
T

73 lines
4.8 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.
# TASK · 部署/数据库瞬断被报成「服务尚未配置」(2026-09-04)
- 基线:`origin/staging` @ `a75929c1`
- 分支:`codex/api-not-configured-mislabel-20260904`
- 执行方:coding agent;验收:Claude
- BUG 编号起点:**BUG-542**(若 `TASK-rectification-quality-probe-dedupe-20260904.md` 尚未开工则从 BUG-540 起;开工时 `grep -o "BUG-5[0-9][0-9]" docs/BUG_HISTORY.md | sort -u | tail -1` 复核)
## 1. 事故实证
2026-09-04 约 22:00UTC+8)用户在 staging 校正面点选答案,`POST /api/rectification/agent``GET /api/rectification/cases/<id>?sessionId=…` 均返回 `503 {"error":"服务尚未配置"}`。同一时刻 `GET /api/health`
| 字段 | 当时 | 数分钟后 |
| --- | --- | --- |
| `deployment.gitCommit` | `a75929c1`(刚落地) | `a75929c1` |
| `status` | `blocked` | `ok` |
| `database.latestMigration` | `null` | `20260904010000_read_report_candidate_range.sql` |
| `database.requiredMigrationsPresent` | `false` | `true` |
| `checks.rectificationMigrations` | `degraded` / `"Error"` | `ok` |
| `checks.modelCatalog` | `blocked` / `database_model_catalog_unavailable` | `ok` |
即:数据库在部署切换窗口内短暂不可用,随后自愈;环境变量从未缺失。
## 2. 根因
16 处路由用同一段兜底(示例 `frontend/src/app/api/rectification/cases/[caseId]/route.ts` L3845、`frontend/src/app/api/rectification/agent/route.ts` L143153):
```
try { supabase = await createServerSupabaseClient(); accounting = createAdminSupabaseClient(); }
catch { return 503 {"error":"服务尚未配置"} }
```
`createServerSupabaseClient()` 在自托管分支里会先读身份会话(`readIdentitySession` → 数据库查询),任何数据库连接错误都从这里抛出,被 `catch` 一律翻译成"尚未配置"。文案本来只对应 `SupabaseConfigurationError``frontend/src/lib/supabase/config.ts``code = "DATABASE_NOT_CONFIGURED"`,缺环境变量时抛出)。
全部 16 处:`api/rectification/{agent, cases/open, cases/entry-summary, cases/[caseId], cases/[caseId]/{close, adopt-skill, upgrade-skill, candidates/accept, turns/[turnId]/regenerate}}``api/consult/{route, status, cancel}``api/models``api/birth-time-journey``api/birth-time-guide``lib/onboarding-post.ts`
## 3. 决策记录
1. 只有 `isSupabaseConfigurationError(error)` 为真时才允许返回"服务尚未配置";其它异常一律 `503 {"error":"服务暂时不可用,请稍后重试","code":"service_unavailable"}`,并 `console.error` 带路由名与 `error.name`(不打印堆栈里的连接串)。
2. 不新增重试、不改部署顺序、不动 health 判定;部署窗口内的短暂 503 是可接受的,这里只修**说法**,让用户与验收方不再误以为环境变量丢了。
3. 16 处收敛为一个共享 helper(放 `frontend/src/lib/api/` 或既有的 route 工具目录,位置由执行方按现有惯例选),不得复制 16 份新文案。
## 4. 硬红线
- 不得改 `createServerSupabaseClient` / `createAdminSupabaseClient` 的抛错语义与调用顺序。
- 未登录仍是 `401`,与本任务无关的路径不得顺带改动。
- 不得在错误响应里回显任何环境变量名之外的信息;配置错误响应保留现有 `"服务尚未配置"` 文案(既有测试引用)。
## 5. 任务分解
### 5.1 共享 helper + 16 处替换
- 验收:`grep -rn "服务尚未配置" frontend/src` 只命中 helper 一处;`tsc --noEmit``npm run lint` 0 error。
### 5.2 回归测试
- 新增 `frontend/tests/api-service-unavailable-20260904.test.ts`:模拟 `createServerSupabaseClient` 抛 (a) `SupabaseConfigurationError` → 503 `服务尚未配置`(b) 普通 `Error("connection refused")` → 503 `code=service_unavailable`,文案不含"尚未配置"。至少覆盖 `rectification/agent``cases/[caseId]` 两条路由(Node 22 module mock 契约见 `docs/BUG_HISTORY.md``test(reports): document Node 22 mock contract` 相关条目)。
- 既有引用"服务尚未配置"的测试若断言的是非配置类异常,改断言并写"原值 / 新值 / 原因"。
### 5.3 记录
- `docs/BUG_HISTORY.md` 新增一条(现象、触发条件=部署切换窗口、根因=兜底翻译、修复、验证);`CHANGELOG.md` 一条;`docs/tasks/PROGRESS-api-not-configured-mislabel-20260904.md`
## 6. 让步顺序
5.1 > 5.2 > 5.3。若某条路由的测试 harness 不支持 mock,只覆盖两条主路由并把其余写进进度记录。
## 7. 开工前置命令
```bash
git fetch origin --prune
git worktree add -b codex/api-not-configured-mislabel-20260904 .worktrees/api-not-configured-mislabel-20260904 origin/staging
cd .worktrees/api-not-configured-mislabel-20260904
ln -s /workspace/Jyotisha/frontend/node_modules frontend/node_modules
grep -rn "服务尚未配置" frontend/src frontend/tests | wc -l
```