Files
Wabenhain/src/app/konto/patenschaft/[id]/medaille.svg/route.ts
T
Nick SzaunigandClaude Opus 5.5 f227aeb8f9 feat: Bienenpatenschaft mit Urkunde, Abo, Medaillen und 3D-Konto
Setzt Teilprojekte 1-5 der Spec 2026-10-16 um:
- Urkunden-Engine (lib/certificate): ein Layout fuer PDF, Vorschau und
  3D-Textur, Vorlage classic@1, eingebettete OFL-Schriften, Testmatrix
- Einmal-Patenschaft ueber Traegerprodukte (Kategorie PATENSCHAFT),
  Paket wird im Checkout in Patenschaft (Regelsatz) und Honig aufgeteilt,
  Kontopflicht, rein digitale Bestellungen (FulfillmentMethod DIGITAL)
- Ausstellung nach Zahlung idempotent, Wiederholung im App-Prozess
  (instrumentation + background-jobs), Ablage in CERTIFICATE_DIR
- Verkaufsseite /patenschaft mit Konfigurator und Live-Vorschau,
  Warenkorb mit Schluessel je Position
- Kundenkonto: 3D-Ansicht von Urkunde und Medaille, Downloads, ZIP,
  Uebertragung per befristetem Einmal-Link, Treuestufen bis VIP
- Admin: Angebote, Patenschaften, Druck, Korrektur mit Revisionen,
  Abos, Erntefenster, Deckung, SEPA-Frist, Treuestufen
- Abo ueber Stripe Billing: Lieferung erst nach bezahlten Monaten,
  SEPA-Neukunden-Frist und Rueckbuchungsschutz, Honigreservierung,
  Kuendigungsbutton, Monatsrechnungen, Stripe-Einrichtungsskript

Startangebote werden inaktiv angelegt; Livebetrieb erst nach Freigabe.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-16 14:07:30 +02:00

17 lines
828 B
TypeScript

import { renderMedalSvg } from "@/lib/medals";
import { loadOwnedSponsorship } from "../../_lib/owner";
import { notFoundResponse, privateFileResponse } from "../../_lib/http";
import { downloadNames } from "../../_lib/bundle";
import { sponsorshipMedalInput } from "../../_lib/medal";
/** Patenschafts-Medaille als Vektor (SVG, Text als Pfade) — immer als Download, nie inline. */
export async function GET(_request: Request, { params }: { params: Promise<{ id: string }> }) {
const owned = await loadOwnedSponsorship((await params).id);
if (!owned?.sponsorship.revision) return notFoundResponse();
const svg = renderMedalSvg(sponsorshipMedalInput(owned.sponsorship));
return privateFileResponse(svg, {
contentType: "image/svg+xml; charset=utf-8",
downloadName: downloadNames(owned.sponsorship).svg,
});
}