refactor: extract numbering logic into numbering.service.ts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
BOHA
2026-03-23 09:00:07 +01:00
parent d2b22e9399
commit 2146696bc6
6 changed files with 86 additions and 127 deletions

View File

@@ -1,46 +0,0 @@
import prisma from '../config/database';
/**
* Atomically get and increment the next sequence number for a document type and year.
* Uses the `number_sequences` table with upsert to avoid race conditions.
*/
export async function nextSequenceNumber(type: string, year: number): Promise<number> {
// Use a transaction with a raw query to atomically increment
const result = await prisma.$queryRaw<Array<{ last_number: number }>>`
INSERT INTO number_sequences (type, year, last_number)
VALUES (${type}, ${year}, 1)
ON DUPLICATE KEY UPDATE last_number = last_number + 1;
SELECT last_number FROM number_sequences WHERE type = ${type} AND year = ${year};
`;
// $queryRaw with multiple statements may not work on all drivers, use a transaction fallback
return result[0]?.last_number ?? 1;
}
/**
* Atomically get and increment the next sequence number using Prisma transaction.
* Compatible with all Prisma drivers.
*/
export async function getNextNumber(type: string, year: number): Promise<number> {
return prisma.$transaction(async (tx) => {
// Try to find existing sequence
const existing = await tx.number_sequences.findFirst({
where: { type, year },
});
if (existing) {
const nextNum = (existing.last_number ?? 0) + 1;
await tx.number_sequences.update({
where: { id: existing.id },
data: { last_number: nextNum },
});
return nextNum;
}
// Create new sequence
await tx.number_sequences.create({
data: { type, year, last_number: 1 },
});
return 1;
});
}