From c62de4c0d0ce5f0e03595e6c30101ca7b7a26f8f Mon Sep 17 00:00:00 2001 From: Madhura68 Date: Sun, 26 Apr 2026 21:23:16 +0200 Subject: [PATCH] fix(ST-511): add createWithCodeRetry helper to handle P2002 race on auto codes Co-Authored-By: Claude Opus 4.7 (1M context) --- lib/code-server.ts | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/lib/code-server.ts b/lib/code-server.ts index f78f4fa..5c09fcb 100644 --- a/lib/code-server.ts +++ b/lib/code-server.ts @@ -1,5 +1,43 @@ +import { Prisma } from '@prisma/client' import { prisma } from '@/lib/prisma' +const MAX_AUTO_CODE_ATTEMPTS = 3 + +function isCodeUniqueConflict(error: unknown): boolean { + if (!(error instanceof Prisma.PrismaClientKnownRequestError)) return false + if (error.code !== 'P2002') return false + const target = (error.meta as { target?: string[] | string } | undefined)?.target + if (!target) return false + if (Array.isArray(target)) return target.includes('code') + return target.includes('code') +} + +/** + * Generate an auto code, then run the create. If the insert collides with an + * existing code (P2002 on the code column), regenerate and retry up to a small + * number of attempts. Protects against the SELECT-MAX → INSERT race when two + * concurrent requests pick the same next number. + */ +export async function createWithCodeRetry( + generate: () => Promise, + create: (code: string) => Promise, +): Promise { + let lastError: unknown + for (let attempt = 0; attempt < MAX_AUTO_CODE_ATTEMPTS; attempt++) { + const code = await generate() + try { + return await create(code) + } catch (e) { + if (isCodeUniqueConflict(e)) { + lastError = e + continue + } + throw e + } + } + throw lastError ?? new Error('Kon geen unieke code genereren') +} + const STORY_AUTO_RE = /^ST-(\d+)$/ const PBI_AUTO_RE = /^PBI-(\d+)$/