spb/cancerindex
Public
TypeScript 97.2%
SQL 1.5%
CSS 0.6%
JavaScript 0.5%
1import { sql } from 'drizzle-orm';2import { formatId, type IdNamespace } from '@cancerindex/shared';3import type { Database } from './client.js';45/**6 * Mint stable public identifiers from per-namespace counters (CLAUDE.md §6).7 * Atomic upsert-increment; `count` ids are reserved in one round trip.8 */9export async function mintIds(db: Database, ns: IdNamespace, count = 1): Promise<string[]> {10 if (count < 1) return [];11 const rows = await db.execute<{ next: string | number }>(sql`12 INSERT INTO id_sequences (namespace, next) VALUES (${ns}, ${count + 1})13 ON CONFLICT (namespace) DO UPDATE SET next = id_sequences.next + ${count}14 RETURNING next15 `);16 const next = Number(rows[0]?.next ?? 0);17 const first = next - count;18 return Array.from({ length: count }, (_, i) => formatId(ns, first + i));19}2021export async function mintId(db: Database, ns: IdNamespace): Promise<string> {22 const [id] = await mintIds(db, ns, 1);23 if (!id) throw new Error('mint failed');24 return id;25}26