fix: bulletproof registry number allocation using actual DB entries as source of truth

The old allocateSequenceNumber blindly incremented a counter in
RegistrySequence, which drifted out of sync when entries were deleted
or moved between companies — producing wrong numbers (e.g., #6 for
the first entry of a company).

New approach:
- Uses pg_advisory_xact_lock inside a Prisma interactive transaction
  to serialize concurrent allocations
- Always queries the actual MAX sequence from KeyValueStore entries
  (the source of truth) before allocating the next number
- Takes MAX(actual entries, counter) + 1 so the counter can never
  produce a stale/duplicate number
- Upserts the counter to the new value for consistency
- Also adds recalculateSequence to DELETE handler so the counter
  stays in sync after entry deletions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
AI Assistant
2026-03-11 21:11:52 +02:00
parent 8e56aa7b89
commit dbed7105b7
2 changed files with 57 additions and 11 deletions
+6
View File
@@ -431,6 +431,12 @@ export async function DELETE(req: NextRequest) {
await deleteEntryFromDB(id);
// Recalculate counter so next allocation reads the correct max
await recalculateSequence(
existing.company as CompanyId,
existing.direction as RegistryDirection,
);
await logAuditEvent({
entryId: id,
entryNumber: existing.number,