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]>
This commit is contained in:
Nick SzaunigandClaude Opus 5.5 committed 2026-10-16 14:07:30 +02:00
1 parent dcb578f062
commit f227aeb8f9
269 files changed
+28054 -141

No files matched your search

+73
View File
@@ -0,0 +1,73 @@
/**
* Minimale Typen fuer fontkit 2.0.4 — das Paket bringt keine eigenen mit.
* Abgedeckt ist nur, was die Urkunden-Engine (lib/certificate/fonts.ts)
* tatsaechlich nutzt: Font aus Buffer erzeugen, Text setzen (inkl. Kerning
* und Ligaturen), Glyphenpfade und Metriken lesen, Glyphenabdeckung pruefen.
* Weitere Felder bei Bedarf hier ergaenzen, nicht per `any` umgehen.
*/
declare module "fontkit" {
/** Ein Zeichenbefehl eines Glyphenpfads in Font-Einheiten (y nach oben). */
export interface PathCommand {
command: "moveTo" | "lineTo" | "quadraticCurveTo" | "bezierCurveTo" | "closePath";
args: number[];
}
export interface BoundingBox {
minX: number;
minY: number;
maxX: number;
maxY: number;
width: number;
height: number;
}
export interface Path {
commands: PathCommand[];
bbox: BoundingBox;
}
export interface Glyph {
id: number;
codePoints: number[];
advanceWidth: number;
path: Path;
bbox: BoundingBox;
name?: string;
}
/** Position eines Glyphen im Lauf, in Font-Einheiten. */
export interface GlyphPosition {
xAdvance: number;
yAdvance: number;
xOffset: number;
yOffset: number;
}
export interface GlyphRun {
glyphs: Glyph[];
positions: GlyphPosition[];
advanceWidth: number;
}
export interface Font {
type: string;
postscriptName: string;
familyName: string;
unitsPerEm: number;
ascent: number;
descent: number;
lineGap: number;
capHeight: number;
xHeight: number;
layout(text: string, features?: string[] | Record<string, boolean>): GlyphRun;
hasGlyphForCodePoint(codePoint: number): boolean;
glyphForCodePoint(codePoint: number): Glyph;
}
export interface FontCollection {
type: "TTC" | "DFont";
fonts: Font[];
}
export function create(buffer: Uint8Array, postscriptName?: string): Font | FontCollection;
}