fix(api): parse Postgres bigint (int8) as Number, not string

duration_ms/file_size are int8; node-postgres returned them as strings,
a footgun for any consumer doing arithmetic/sorting/comparison (already
hand-patched once in playout totals). Register a global int8 type parser
so the API emits real numbers. All such values are < 2^53 (no precision loss).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Zac Gaetano 2026-05-31 21:46:54 -04:00
parent ef329399f1
commit 64bbb221f7

View file

@ -1,4 +1,16 @@
import { Pool } from 'pg';
import { Pool, types } from 'pg';
// node-postgres returns BIGINT (int8, OID 20) as a *string* by default, because
// a 64-bit integer can exceed JS Number.MAX_SAFE_INTEGER. Our int8 columns
// (duration_ms, file_size, …) are always well within 2^53, so a string here is
// pure footgun: it breaks any consumer that does arithmetic or comparison on the
// value (e.g. `duration_ms + x` silently string-concatenates, sorts go
// lexicographic, `!ms`/`Math.round` edge cases). Parse int8 to a real Number so
// the API always emits numeric duration_ms/file_size in its JSON.
//
// 20 = int8/bigint OID. Values above Number.MAX_SAFE_INTEGER would lose
// precision, but no column in this schema ever reaches that range.
types.setTypeParser(20, (val) => (val === null ? null : parseInt(val, 10)));
// Prefer DATABASE_URL (set in docker-compose) over individual DB_* vars
const pool = process.env.DATABASE_URL