The self-hosted client was typed as a full Supabase client, so an old scoring poll called .single() on a plain promise and failed. The new DataClient only lists methods the adapter implements. Co-Authored-By: Grok (agent loop)
6.2 KiB
PROGRESS · 数据访问层 DataClient 类型(第一阶段)
- 分支:
codex/data-layer-types-20261013 - 基线:
origin/staging9274491681f6fcacbc87e3797441d2c5221de874 - 前置:
origin/codex/node-runtime-resources-20261013已是origin/staging的祖先(merge-base --is-ancestor退出码 0)。local-postgres-client-core.ts只加了import type和两处implements。 frontend/src/lib/rectification-agentic/session.ts已不在,本单没有改它。- 编号:任务书预留 BUG-1343。开工时
docs/BUG_HISTORY.md最大号是 BUG-1350,1343 没有条目。按台账规则从最大号往后,记为 BUG-1351。
T1 · 编译器暴露的 2 条
DataClient 换上之后、缺陷尚未修时,tsc --noEmit 退出码 2,恰好 2 条:
src/app/api/chart-profiles/route.ts(59,40): error TS7006: Parameter 'row' implicitly has an 'any' type.
src/lib/birth-time-scoring-job-store.ts(103,10): error TS2339: Property 'single' does not exist on type 'Promise<Readonly<{ data: any; error: Readonly<{ message: string; code?: string | undefined; }> | null; count?: number | null | undefined; }>>'.
grep:as unknown as SupabaseClient 在 frontend/src 无结果。@supabase/supabase-js 只剩 admin-client-core.ts 的 createClient 回滚分支。
T2 · 缺陷修复红转绿
修复前,claimScoringJob 对返回数组的假 rpc 调用 .single():
claimScoringJob reads the first row when rpc returns an array:失败,TypeError: supabase.rpc(...).single is not a functionclaimScoringJob also accepts the single-object rpc shape:同样失败
去掉 .single() 并兼容数组与单对象之后,这两条通过。真实迁移用例 claim_birth_time_scoring_job returns an array and claimScoringJob accepts it 通过:data 是数组,第一行 claim_state 为 claimed,store 返回 { kind: "claimed", algorithmVersion }。第一次启动测试库时迁移进程只留下笼统的 database migration failed(脚本会把非预期异常收成这一句),容器未到 Healthy。同一条用例在容器 Healthy 后重跑通过。
chart-profiles/route.ts 的 row 标为 unknown。
修完后 tsc --noEmit 退出码 0。npm run lint 退出码 0,0 error,123 warning(与改动前的存量警告数量一致,本单没有新增 warning)。
T3 · 转译差分
类型层改动用 esbuild 0.28.1、--format=esm、--tsconfig=frontend/tsconfig.json,旧文件与新文件都按这份 tsconfig 转译。除 T2 的两个文件和新建的 data-client.ts 外,全部 SAME:
src/lib/birth-time-journey-case-loader.tssrc/lib/birth-time-journey-store.tssrc/lib/birth-time-journey-turn-persistence.tssrc/lib/db/local-postgres-client-core.tssrc/lib/rectification-agentic/v9/case-service.tssrc/lib/rectification-agentic/v9/product-domain.tssrc/lib/rectification-agentic/v9/tool-service.ts(只改了一句注释;转译后注释被去掉,产物相同)src/lib/rectification-in-chat-server.tssrc/lib/supabase/admin-client-core.tssrc/lib/supabase/server.tssrc/mastra/rectification-v9-tools.ts
任务书把旧文件写到系统临时目录再转译。esbuild 0.28.1 会沿文件所在目录寻找 tsconfig.json。临时目录找不到本仓库的 tsconfig.json(target 为 ES2017),类字段的转译结果会和仓库内文件不一致,即使源码只有类型或注释差别也会报 DIFF。两边都带上同一份 --tsconfig 后为 SAME。这不是运行时变化。
T4 · 把 data 收成 unknown 的错误清单
临时把 UntypedData 改成 unknown 后 tsc --noEmit 退出码 2,共 93 条、12 个文件。随后已改回 any。
| 条数 | 文件 |
|---|---|
| 24 | src/app/api/account/route.ts |
| 17 | src/app/api/consult/route.ts(其中 1 条是 DataClient 不能赋给 GuardedTitleClient,consult/route.ts 约 1055 行) |
| 16 | src/app/api/consult/status/route.ts |
| 12 | src/app/api/payment/epay/status/route.ts |
| 7 | src/lib/epay/availability.ts |
| 5 | src/lib/rectification-agentic/v9/product-domain.ts |
| 4 | src/app/api/sessions/route.ts |
| 3 | src/lib/rectification-agentic/v9/agent-route-request.ts |
| 2 | src/app/api/chart-profiles/[id]/route.ts |
| 1 | src/app/api/account/avatar/route.ts |
| 1 | src/app/api/chart-profiles/route.ts |
| 1 | src/app/api/sessions/[id]/route.ts |
和任务书写作时的 122 条相比,consult/route.ts 少了 10 条,chart-profiles/route.ts 少了 1 条(本单已把 row 标成 unknown)。没有单独再出现一条 session-title-guard.ts 的错误,GuardedTitleClient 那条记在 consult/route.ts 里。这些留给第二阶段,本单没有改那些业务文件。
test:db
npm run test:db(tsx --test --test-concurrency=1 tests/database-*.test.ts)约 19 分钟,退出码 1。汇总:85 条,通过 72,失败 13,取消 0,跳过 0。
失败的 13 条与 tools/agent-loop/windows-known-failures.txt 逐条一致,没有多出来的失败:
- staging backups are encrypted, atomic, private, and retain the newest three
- rejects destructive backup directory aliases and symlink components before mutation
- rejects unsafe writable backup parents before creating the target
- rejects a direct canonical sticky shared backup directory before chmod
- creates every absent backup path component privately despite a permissive caller umask
- same-second backups publish once without overwriting the completed archive
- find enumeration failures preserve existing backups and do not report completion
- refuses full disks and removes a failed-pipeline partial file
- database env validator accepts punctuated literal required secrets
- database env validator enforces an explicit staging owner uid without printing values
- database env validator accepts a private valid file without printing values
- personal report job migration is atomic, lease-bound, recoverable, and owner read-only
- personal report sections enforce owner-read RLS and service-owned durable transitions
本单新增的 3 条(两条假客户端、一条真实迁移认领)都在通过的 72 条里。