import { QueryFailedError } from "typeorm"; /** Postgres unique-violation SQLSTATE. */ const PG_UNIQUE_VIOLATION = "23505"; /** * True when `error` is a Postgres unique-constraint violation. Used to detect a * reference-number collision from a concurrent insert so the caller can retry * with a freshly-computed number instead of surfacing a 500. */ export function isUniqueViolation(error: unknown): boolean { if (!(error instanceof QueryFailedError)) return false; const driver = ( error as QueryFailedError & { driverError?: { code?: string } } ).driverError; return driver?.code === PG_UNIQUE_VIOLATION; } /** * Run `insert(reference)` under a "generate → try → retry on collision" loop. * * `MAX(sequence) + 1` alone is not concurrency-safe: two requests can read the * same max and derive the same reference, and one insert then hits the unique * index. On that collision we recompute the reference and try again, so the * sequence advances under load instead of throwing. Non-collision errors (and * exhausting the attempt budget) propagate unchanged. * * @param generate Async producer of the next reference (e.g. `CTR-2026-00033`). * Re-invoked on each attempt so it re-reads the current max. * @param insert Performs the insert with the given reference; its result is * returned on success. * @param attempts Maximum tries before giving up (default 5). */ export async function insertWithGeneratedReference( generate: () => Promise, insert: (reference: string) => Promise, attempts = 5, ): Promise { let lastError: unknown; for (let attempt = 0; attempt < attempts; attempt++) { const reference = await generate(); try { return await insert(reference); } catch (error) { if (!isUniqueViolation(error)) throw error; lastError = error; } } throw lastError; }