import { Client } from 'pg'; import { dbSessionConfig } from '../src/prisma/db-session'; import { PrismaService } from '../src/prisma/prisma.service'; /** * Prisma fills @default(now()) on the client as UTC wall clock, SQL now() * stores the session's wall clock - both in `timestamp without time zone` * columns. They only agree if every session runs in UTC, whatever the * server or database default is (the local test DB runs Europe/Berlin). */ describe('Database session time zone (e2e)', () => { let prisma: PrismaService; const aggregateId = `tz-${Date.now()}-${Math.round(Math.random() * 1e6)}`; beforeAll(() => { prisma = new PrismaService(); }); afterAll(async () => { await prisma.domainEvent.deleteMany({ where: { aggregateId } }); await prisma.$disconnect(); }); it('runs a fresh Prisma connection in UTC', async () => { const [{ TimeZone }] = await prisma.$queryRaw< { TimeZone: string }[] >`SHOW TIME ZONE`; expect(TimeZone).toBe('UTC'); }); it('writes a Prisma default timestamp and SQL now() on the same clock', async () => { const seconds = await prisma.$transaction(async (tx) => { const event = await tx.domainEvent.create({ data: { type: 'TaskDue', aggregateType: 'Task', aggregateId, payload: { dueOn: '2026-10-13' }, correlationId: aggregateId, }, }); const [{ s }] = await tx.$queryRaw< { s: number }[] >`SELECT EXTRACT(EPOCH FROM now() - "occurredAt")::float AS s FROM "DomainEvent" WHERE "id" = ${event.id}`; return s; }); expect(Math.abs(seconds)).toBeLessThan(1); }); it('runs a raw pg connection with the shared session options in UTC (LISTEN client)', async () => { const client = new Client(dbSessionConfig(process.env.DATABASE_URL)); await client.connect(); try { const { rows } = await client.query<{ TimeZone: string }>( 'SHOW TIME ZONE', ); expect(rows[0].TimeZone).toBe('UTC'); } finally { await client.end(); } }); });