import "server-only"; import { query, queryOne, withTransaction } from "@/lib/db"; import type { CodeItem } from "@/lib/types"; // "allergens"/"additives" sind identisch aufgebaute Tabellen (Kürzel + // Bezeichnung in DE/EN/PL). Tabellenname kommt nie aus Nutzereingaben, // sondern immer aus dem literal getypten Parameter unten – sicher für // String-Interpolation in der Query. export type CodeTable = "allergens" | "additives"; export async function listCodes(table: CodeTable): Promise { return query(`select * from ${table} order by sort`); } export async function createCode( table: CodeTable, input: { code: string; name: string; name_en: string | null; name_pl: string | null } ): Promise { const maxRow = await queryOne<{ sort: number }>( `select sort from ${table} order by sort desc limit 1` ); return (await queryOne( `insert into ${table} (code, name, name_en, name_pl, sort) values ($1, $2, $3, $4, $5) returning *`, [input.code, input.name, input.name_en, input.name_pl, (maxRow?.sort ?? 0) + 1] ))!; } export async function updateCode( table: CodeTable, originalCode: string, input: { code: string; name: string; name_en: string | null; name_pl: string | null } ): Promise { return queryOne( `update ${table} set code = $1, name = $2, name_en = $3, name_pl = $4 where code = $5 returning *`, [input.code, input.name, input.name_en, input.name_pl, originalCode] ); } export async function deleteCode(table: CodeTable, code: string): Promise { await query(`delete from ${table} where code = $1`, [code]); } export interface CodeImportRow { code: string; name: string; name_en: string | null; name_pl: string | null; } /** CSV-Import: legt neue Kürzel an, bestehende (gleicher Code) werden * aktualisiert – ein doppelter Code innerhalb derselben Datei * aktualisiert also einfach zweimal statt einen Fehler zu werfen. */ export async function importCodes( table: CodeTable, rows: CodeImportRow[] ): Promise<{ created: number; updated: number }> { return withTransaction(async (client) => { const existing = await client.query<{ code: string }>(`select code from ${table}`); const known = new Set(existing.rows.map((r) => r.code)); const maxRow = await client.query<{ sort: number }>( `select coalesce(max(sort), 0) as sort from ${table}` ); let nextSort = (maxRow.rows[0]?.sort ?? 0) + 1; let created = 0; let updated = 0; for (const row of rows) { if (known.has(row.code)) { await client.query( `update ${table} set name = $1, name_en = $2, name_pl = $3 where code = $4`, [row.name, row.name_en, row.name_pl, row.code] ); updated++; } else { await client.query( `insert into ${table} (code, name, name_en, name_pl, sort) values ($1, $2, $3, $4, $5)`, [row.code, row.name, row.name_en, row.name_pl, nextSort++] ); known.add(row.code); created++; } } return { created, updated }; }); }