feat: CSV-Import/-Export für Gerichte/Allergene/Zusatzstoffe, RSS-Fix für mehrere Essenszeiten
CSV-Import/-Export (Gerichte, Allergene, Zusatzstoffe): neue Export-/ Import-Routen unter app/api/*/export und */import, hand-geschriebener CSV-Parser/-Serializer (lib/csv.ts, keine neue Abhängigkeit), Upsert über Kürzel (Allergene/Zusatzstoffe) bzw. exakten Namen (Gerichte, mit Ambiguitäts-Check bei Namensdopplung). UI-Buttons in DishManager und CodeListManager. RSS-Feed: <content:encoded> zusätzlich zu <description> ausgeben, da mehrere Feed-Reader description als kürzbare Vorschau behandeln und dadurch bei mehreren Essenszeiten pro Tag nur die erste zeigten. Version 1.7.0. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
import { query } from "@/lib/db";
|
||||
import { authErrorResponse, requireRole } from "@/lib/auth/session";
|
||||
import { toCsv } from "@/lib/csv";
|
||||
import type { Dish } from "@/lib/types";
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
await requireRole(["staff", "admin"]);
|
||||
const dishes = await query<Dish>("select * from dishes order by name");
|
||||
const rows = [
|
||||
["name", "name_en", "name_pl", "price", "allergens", "additives"],
|
||||
...dishes.map((d) => [
|
||||
d.name,
|
||||
d.name_en ?? "",
|
||||
d.name_pl ?? "",
|
||||
String(d.price),
|
||||
(d.allergens ?? []).join(";"),
|
||||
(d.additives ?? []).join(";"),
|
||||
]),
|
||||
];
|
||||
return new Response(toCsv(rows), {
|
||||
headers: {
|
||||
"Content-Type": "text/csv; charset=utf-8",
|
||||
"Content-Disposition": 'attachment; filename="gerichte.csv"',
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
const res = authErrorResponse(err);
|
||||
if (res) return res;
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user