fix: replace \d with [0-9] in all PostgreSQL regex patterns

PostgreSQL POSIX regex on the server does not support \d shorthand,
causing SUBSTRING to return NULL and every entry to get sequence 1.

Replaced all \d with [0-9] in:
- allocateSequenceNumber (new + old format queries)
- recalculateSequence (new + old format queries)
- debug-sequences endpoint (GET + POST queries)

Also added samples field to debug GET for raw number diagnostics,
and POST now handles old-format entries (BTG→B mapping) with
ON CONFLICT GREATEST for proper counter merging.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
AI Assistant
2026-03-11 21:59:04 +02:00
parent 0f555c55ee
commit 39d64b033e
2 changed files with 64 additions and 19 deletions
@@ -257,8 +257,9 @@ export async function allocateSequenceNumber(
const oldPrefix = OLD_COMPANY_PREFIX[companyPrefix] ?? "";
// New format: B-2026-00001
// NOTE: Use [0-9] instead of \d — PostgreSQL POSIX regex may not support \d
const newLike = `%"number":"${companyPrefix}-${yr}-%"%`;
const newRegex = `${companyPrefix}-${yr}-(\\d{5})`;
const newRegex = `${companyPrefix}-${yr}-([0-9]{5})`;
const newMaxRows = await tx.$queryRaw<Array<{ maxSeq: number | null }>>`
SELECT MAX(
CAST(SUBSTRING(value::text FROM ${newRegex}) AS INTEGER)
@@ -274,7 +275,7 @@ export async function allocateSequenceNumber(
let oldMax = 0;
if (oldPrefix) {
const oldLike = `%"number":"${oldPrefix}-${yr}-%"%`;
const oldRegex = `${oldPrefix}-${yr}-(?:IN|OUT|INT)-(\\d{5})`;
const oldRegex = `${oldPrefix}-${yr}-(?:IN|OUT|INT)-([0-9]{5})`;
const oldMaxRows = await tx.$queryRaw<Array<{ maxSeq: number | null }>>`
SELECT MAX(
CAST(SUBSTRING(value::text FROM ${oldRegex}) AS INTEGER)
@@ -333,8 +334,9 @@ export async function recalculateSequence(
const seqType = "SEQ";
// Find max from new format (B-2026-00001)
// NOTE: Use [0-9] instead of \d — PostgreSQL POSIX regex may not support \d
const newLike = `%"number":"${companyPrefix}-${yr}-%"%`;
const newRegex = `${companyPrefix}-${yr}-(\\d{5})`;
const newRegex = `${companyPrefix}-${yr}-([0-9]{5})`;
const newRows = await prisma.$queryRaw<Array<{ maxSeq: number | null }>>`
SELECT MAX(
CAST(SUBSTRING(value::text FROM ${newRegex}) AS INTEGER)
@@ -349,7 +351,7 @@ export async function recalculateSequence(
// Also check old format (BTG-2026-OUT-00001)
if (oldPrefix) {
const oldLike = `%"number":"${oldPrefix}-${yr}-%"%`;
const oldRegex = `${oldPrefix}-${yr}-(?:IN|OUT|INT)-(\\d{5})`;
const oldRegex = `${oldPrefix}-${yr}-(?:IN|OUT|INT)-([0-9]{5})`;
const oldRows = await prisma.$queryRaw<Array<{ maxSeq: number | null }>>`
SELECT MAX(
CAST(SUBSTRING(value::text FROM ${oldRegex}) AS INTEGER)