diff --git a/frontend/src/lib/db/local-postgres-client-core.ts b/frontend/src/lib/db/local-postgres-client-core.ts index c2479ebe..f2d220c2 100644 --- a/frontend/src/lib/db/local-postgres-client-core.ts +++ b/frontend/src/lib/db/local-postgres-client-core.ts @@ -128,6 +128,16 @@ function databaseValue(type: string | undefined, value: unknown): unknown { return value; } +function queryValue(type: string | undefined, value: unknown): unknown { + if (type !== "date" || !(value instanceof Date)) return value; + // pg parses DATE at local midnight; UTC formatting can shift the calendar day. + return [ + String(value.getFullYear()).padStart(4, "0"), + String(value.getMonth() + 1).padStart(2, "0"), + String(value.getDate()).padStart(2, "0"), + ].join("-"); +} + class LocalPostgresQueryBuilder implements PromiseLike { private selectedColumns: string[] | null = null; private mutation: Mutation | null = null; @@ -411,7 +421,14 @@ class LocalPostgresQueryBuilder implements PromiseLike { } const result = await client.query(sql, parameters); - const rows = result.rows; + const rows = result.rows.map((row) => + Object.fromEntries( + Object.entries(row).map(([column, value]) => [ + column, + queryValue(types.get(column), value), + ]), + ), + ); let data: unknown = this.selectedColumns ? rows : null; if (this.cardinality !== "many") { if ( diff --git a/frontend/tests/database-local-business.test.ts b/frontend/tests/database-local-business.test.ts index 8e2482b8..107f322b 100644 --- a/frontend/tests/database-local-business.test.ts +++ b/frontend/tests/database-local-business.test.ts @@ -183,20 +183,24 @@ test("local PostgreSQL applies the reviewed business schema and serves authentic ), `SET\n${userId}\nlocal-user@example.com`, ); + fixture.psql(`update public.profiles set birth_date = '1997-08-08' where id = '${userId}'`); const local = createLocalPostgresDataClient( fixture.connectionUrl("app_runtime", "app-runtime-test-password"), { id: userId, email: "local-user@example.com" }, ); const profile = await local.from("profiles") - .select("id,email,credits") + .select("id,email,credits,birth_date,created_at") .eq("id", userId) .single(); assert.equal(profile.error, null); - assert.deepEqual(profile.data, { + const { created_at: createdAt, ...profileData } = profile.data as Record; + assert.ok(createdAt instanceof Date); + assert.deepEqual(profileData, { id: userId, email: "local-user@example.com", credits: 0, + birth_date: "1997-08-08", }); const nonAbandonedProfiles = await local.from("profiles") .select("id")