You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 851b9c6
Browse filesBrowse the repository at this point in the historyBrowse files
fix(runtime-ts): a field.timestamp reached the wire as Postgres text, not ISO 8601
The TS generated routes answered `"createdAt":"2026-09-20 12:00:00+00"`.
Codegen maps a Postgres field.timestamp to `timestamp(…, { mode: "string" })`,
and in string mode Drizzle returns what node-postgres received: Postgres' output
format, rendered in the SESSION time zone. The contract (api-contract.md, via
normalization.md) is `YYYY-MM-DDTHH:MM:SS[.fff]Z`, always UTC, and the other four
ports already answer that way. An adopter estate's strict ISO 8601 client found
it; no in-repo gate could, because the api-contract runners normalize createdAt
before comparing and every other adapter test ran on libsql.
runtime-ts now canonicalizes timestamp columns where the Fastify and Hono mounts
send rows (list, get, create, update, projections, M:N traversal, TPH). Columns
are found from the Drizzle column objects (columnType + withTimezone), never from
a value's shape. The offset is converted to UTC; the fraction is truncated to ms,
trailing zeros stripped, omitted when zero; @localtime keeps its wall clock with
no Z (and an @localtime value carrying an offset passes through untouched).
Date-mode columns lose `.000`. No regen: the generated routes delegate to these
mounts. `timestampWire` / `canonicalTimestamp` are exported for hand-written
routes. The false "round-trips ISO-8601" comment in column-mapper.ts is corrected.
Gated on a real Postgres whose session runs in America/New_York (so relabelling
+00 as Z cannot pass), both adapters, src and dist entry points:
runtime-ts/test/timestamp-wire-pg.test.ts. ci-local's ts-slow lane now runs it
and read-only-raw-sql-pg.test.ts, which needed a database and skipped everywhere.
Also fixed, found by the new test: the Hono update handler passed an empty PATCH
body to `.set({})`, which throws `No values to set` and was redacted into a 500.
It now answers as a read (200 with the row, or 404), as the Fastify mount does.
Verified: runtime-ts 513 tests, 0 fail; real-PG files 71/71; TS api-contract
lanes 82/82 (Testcontainers); estate TS port 43/43 on the local build (41/43 on
rc.7); ci-local --quick green. Reviewed with /code-review high (one finding,
fixed) and simplify-qwen (dedupe applied; a non-compiling edit reverted).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EaGv4zNk4oT7FooD4eK5MD
0 commit comments