import type { Pool } from 'pg'; import { describe, expect, it } from 'vitest'; import type { FindingReview } from '../../src/domain/canonical-model'; import { PostgresAssessorRepository } from '../../server/postgres/postgres-assessor-repository'; import { riskCommand } from '../domain/risk-acceptance-fixture'; describe('PostgreSQL risk decision transaction', () => { it('locks the scoped occurrence, appends JSON history and rolls back conflicts', async () => { const statements: string[] = []; let review: FindingReview | undefined; let revision = 0; const query = async (sql: string, values: unknown[] = []) => { statements.push(sql); if (sql.startsWith('SELECT revision FROM assessor_repository_state')) return { rows: [{ revision }], rowCount: 1 }; if (sql.startsWith('UPDATE assessor_repository_state')) return { rows: [{ revision: ++revision }], rowCount: 1 }; if (sql.startsWith('SELECT o.id')) return { rows: [{ id: 'occurrence' }], rowCount: 1 }; if (sql.startsWith('SELECT data FROM assessor_reviews')) return { rows: review ? [{ data: structuredClone(review) }] : [], rowCount: review ? 1 : 0 }; if (sql.startsWith('INSERT INTO assessor_reviews')) { review = JSON.parse(values[4] as string) as FindingReview; return { rows: [], rowCount: 1 }; } return { rows: [], rowCount: 0 }; }; const pool = { query, connect: async () => ({ query, release() {} }) } as unknown as Pool; const repository = await PostgresAssessorRepository.create(pool); const accepted = await repository.recordRiskAcceptance('project', 'occurrence', riskCommand(), 0); expect(accepted).toEqual(review); expect(statements.some(sql => sql.includes('a.project_id=$2 FOR UPDATE OF o'))).toBe(true); expect(statements.at(-1)).toBe('COMMIT'); const previous = structuredClone(review); await expect(repository.recordRiskAcceptance('project', 'occurrence', riskCommand('revoke'), 0)).rejects.toThrow(); expect(statements.at(-1)).toBe('ROLLBACK'); expect(review).toEqual(previous); const revoked = await repository.recordRiskAcceptance('project', 'occurrence', riskCommand('revoke'), 1); expect(revoked.riskAcceptance?.revisions).toHaveLength(2); expect(revoked.riskAcceptance?.revisions[0]).toEqual(accepted.riskAcceptance?.revisions[0]); }); });