Strengthen financial reconciliation checks
This commit is contained in:
Executable
+29
@@ -0,0 +1,29 @@
|
||||
import { randomUUID, createHash } from 'node:crypto';
|
||||
import type { Pool } from 'pg';
|
||||
import { z } from 'zod';
|
||||
import { CUSTODY_WRITE_LOCK } from './postgres-schema.ts';
|
||||
import { auditPostgres } from './postgres-custody.ts';
|
||||
|
||||
/** Operator-only acknowledgement AFTER externally reviewed repair/restore; never repairs or resets a journal. */
|
||||
export async function resolveCustodyIncident(pool: Pool, evidenceId: string): Promise<{ resolutionId: string }> {
|
||||
z.string().uuid().parse(evidenceId);
|
||||
const c = await pool.connect();
|
||||
try {
|
||||
await c.query('BEGIN');
|
||||
await c.query("SET LOCAL statement_timeout='10s'; SET LOCAL lock_timeout='3s'; SET LOCAL idle_in_transaction_session_timeout='10s'; SET LOCAL synchronous_commit=on");
|
||||
await c.query('SELECT pg_advisory_xact_lock($1::bigint)', [CUSTODY_WRITE_LOCK]);
|
||||
const allowed = await c.query("SELECT pg_has_role(current_user,nspowner,'MEMBER') AS owns FROM pg_namespace WHERE nspname='wk_custody'");
|
||||
if (allowed.rows[0]?.owns !== true) throw new Error('Schema-owner approval required for integrity resolution');
|
||||
const incident = await c.query("SELECT value FROM wk_custody.custody_meta WHERE key='integrity_incident_v1' FOR UPDATE");
|
||||
if (!incident.rowCount) throw new Error('No unresolved custody integrity incident');
|
||||
// Delete is UNCOMMITTED and exclusively locked. Any audit failure rolls it back, leaving the hold intact.
|
||||
await c.query("DELETE FROM wk_custody.custody_meta WHERE key='integrity_incident_v1'");
|
||||
await auditPostgres(c);
|
||||
const resolutionId = randomUUID();
|
||||
await c.query('INSERT INTO wk_custody.custody_meta VALUES($1,$2)', [`integrity_resolution:${resolutionId}`,
|
||||
JSON.stringify({ version: 1, evidenceId, resolvedAt: Date.now(),
|
||||
incidentDigest: createHash('sha256').update(incident.rows[0].value).digest('hex') })]);
|
||||
await c.query('COMMIT'); return { resolutionId };
|
||||
} catch (error) { await c.query('ROLLBACK').catch(() => {}); throw error; }
|
||||
finally { c.release(); }
|
||||
}
|
||||
Reference in New Issue
Block a user