Files
flimmer/src/app/api/v1/export/route.ts
T
Florian Wilde bb63827bf7 feat: REST-API unter /api/v1 mit OpenAPI-Beschreibung
Dieselben Endpunkte bedienen Skripte und das eigene Frontend: erst wird ein
Bearer-Token geprüft, sonst das Sitzungscookie.

Sichtungsaktionen geben immer watchIds zurück — damit lässt sich genau diese
Aktion über DELETE zurücknehmen, ohne raten zu müssen, was dazugehörte.

Die OpenAPI-Beschreibung ist handgeschrieben statt aus Zod erzeugt: die
Schnittstelle ist überschaubar, und ein Generator brächte eine weitere
Abhängigkeit für einen Nutzen, den ein Dutzend Zeilen JSON auch hergeben.
2026-09-01 20:24:48 +02:00

34 lines
1.1 KiB
TypeScript

import { NextResponse } from "next/server";
import { withApi } from "@/lib/api";
import { exportCsv, exportJson } from "@/lib/transfer";
/**
* GET /api/v1/export?format=json|csv
*
* Vollständiger Export der eigenen Daten. JSON enthält zusätzlich Sichtungen
* und Universen, CSV ist die schlanke Tabellenform für Tabellenkalkulationen.
*/
export const GET = withApi(async (request, user) => {
const url = new URL(request.url);
const format = url.searchParams.get("format") === "csv" ? "csv" : "json";
const stamp = new Date().toISOString().slice(0, 10);
if (format === "csv") {
const csv = await exportCsv(user.id);
return new NextResponse(csv, {
headers: {
"content-type": "text/csv; charset=utf-8",
"content-disposition": `attachment; filename="flimmer-${stamp}.csv"`,
},
});
}
const data = await exportJson(user.id);
return new NextResponse(JSON.stringify(data, null, 2), {
headers: {
"content-type": "application/json; charset=utf-8",
"content-disposition": `attachment; filename="flimmer-${stamp}.json"`,
},
});
});