import { eq } from "drizzle-orm"; import type { AppDatabase } from "../database-context.js"; import { circuitListEquipmentIdentifiers } from "../schema/circuit-list-equipment-identifiers.js"; export function normalizeEquipmentIdentifier(value: string): string { return value.trim().toLowerCase(); } /** * The DB-level normalized unique index uses SQLite's built-in lower(), * which only folds ASCII a-z and leaves German characters (Ä/Ö/Ü/ß/…) * untouched, so it alone would let e.g. "Ä1" and "ä1" coexist. This check * normalizes with JS's Unicode-aware toLowerCase() against every * identifier already registered for the circuit list (circuits and * distribution-board components share one BMK namespace via * circuit_list_equipment_identifiers), catching what the DB index cannot. */ export function assertEquipmentIdentifierAvailable( database: AppDatabase, circuitListId: string, equipmentIdentifier: string, excludeOwnerId?: string ): void { const candidate = normalizeEquipmentIdentifier(equipmentIdentifier); const existing = database .select({ ownerId: circuitListEquipmentIdentifiers.ownerId, equipmentIdentifier: circuitListEquipmentIdentifiers.equipmentIdentifier, }) .from(circuitListEquipmentIdentifiers) .where(eq(circuitListEquipmentIdentifiers.circuitListId, circuitListId)) .all(); const duplicate = existing.some( (row) => row.ownerId !== excludeOwnerId && normalizeEquipmentIdentifier(row.equipmentIdentifier) === candidate ); if (duplicate) { throw new Error("Duplicate equipmentIdentifier in circuit list."); } }