- lib/idea-code.ts: pure formatIdeaCode helper (client-safe, no prisma) - lib/idea-code-server.ts: atomic nextIdeaCode via Prisma row-lock, accepts optional TransactionClient for combining with idea.create - lib/idea-plan-parser.ts: parsePlanMd extracts ---yaml---/body, runs yaml.parse + ideaPlanMdFrontmatterSchema, returns line-info on failure; CRLF-tolerant - adds yaml@^2.8.4 dependency - 8 unit tests (parser happy/missing/yaml-error/zod-error/empty-stories/CRLF; formatIdeaCode pad-3 + overflow) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
26 lines
1 KiB
TypeScript
26 lines
1 KiB
TypeScript
// Atomic per-user idea-code generator (DB-side).
|
|
// Schema: User.idea_code_counter Int @default(0) — increment-and-return via
|
|
// Prisma `update` (which acquires a row-lock for the duration of the
|
|
// transaction; concurrent calls serialize). Format: "IDEA-001", "IDEA-002", …
|
|
//
|
|
// Concurrency: vertrouwt op Postgres row-locking binnen Prisma `update`.
|
|
// Geen aparte $transaction nodig voor enkelvoudige update — de update is
|
|
// atomisch op één rij. Voor combineren met een idea.create wordt
|
|
// nextIdeaCode aangeroepen binnen de bredere $transaction van de caller.
|
|
|
|
import { prisma } from '@/lib/prisma'
|
|
import { formatIdeaCode } from '@/lib/idea-code'
|
|
|
|
import type { Prisma } from '@prisma/client'
|
|
|
|
export async function nextIdeaCode(
|
|
userId: string,
|
|
client: Prisma.TransactionClient | typeof prisma = prisma,
|
|
): Promise<string> {
|
|
const u = await client.user.update({
|
|
where: { id: userId },
|
|
data: { idea_code_counter: { increment: 1 } },
|
|
select: { idea_code_counter: true },
|
|
})
|
|
return formatIdeaCode(u.idea_code_counter)
|
|
}
|