ADR-0061: Produktnaher Vier-Tier-Report-Vertrag im PDF/UA-Preview-Shadow
- Status: angenommen; Preview und Produktionstrennung verifiziert, Produktrollout offen
- Datum: 28. August 2026
- Issue: #333 bleibt offen
- Vorgänger: ADR-0060
Kontext
Slice B belegt einen reinen Node.js-PDF/UA-1-Shadow mit vier direkt für den
Renderer definierten synthetischen View-Fixtures. Der Pfad ist in Preview
laufzeitverifiziert und bleibt in Produktion verborgen. Er beweist jedoch
nicht, dass sich der deployte Report-Vertrag kontrolliert auf dieselbe
semantische Ausgabe abbilden lässt.
Ein unmittelbarer Zugriff auf gespeicherte Reports wäre für diesen Schritt zu früh: Er würde Datenbank-, Retention-, Adress- und Kontogrenzen in einen noch nicht freigegebenen Renderer ziehen. Slice C benötigt stattdessen einen produktnahen, reproduzierbaren Eingang, der die tatsächlichen Feldnamen und Tiergates verwendet, ohne reale Daten oder einen neuen öffentlichen Pfad zu eröffnen.
Entscheidung
-
Slice C definiert für
free,standard,premiumundplanerje ein vollständig repository-fixiertes Objekt des deployten TypeScript-TypsReport. Alle Werte sind erfunden. Die Meta-Adresse bezeichnet sich ausdrücklich als nicht reale Adresse, die Koordinate istnull, der Report ist nicht gespeichert und besitzt weder Konto- noch Permalink-ID. -
Ein expliziter Mapper reduziert den
Report-Eingang auf die bereits validierte PDF/UA-View. Nur folgende Bindungen sind erlaubt:Report-FeldPDF/UA-View meta.report_tier,generated_at,as_ofTier und Zeitstand parcel.area_m2synthetischer Standort-Steckbrief erste drei steckbrief-EinträgeRisiko-Tabelle scenarios[]Szenario-, Status-, Kosten- und Narrativdarstellung foerderungen[].programmFörderhinweis-Liste solar.googleausschließlich drei fest erwartete numerische Solarwerte Adresse, Koordinate, Katasterbezeichnungen, Disclaimer-Rohobjekte,
imagery_quality,imagery_date, Quellenobjekte und andere nicht aufgeführte Felder gelangen nicht in die Renderer-View. -
Der Mapper schließt fail-closed, wenn Fläche, Zeitstand, Zahl der Szenarien oder Förderhinweise, Risikostatus oder die drei Solarwerte vom festen Vertrag abweichen. So kann eine spätere Fixture-Mutation nicht still den validierten Layout- und Strukturvertrag verändern.
-
Die vorhandenen Tiergates bleiben maßgeblich: Nur
standardundpremiumenthaltenscenarios[].narrativ; nurpremiumundplanerenthalten den synthetischensolar.google-Block. Der Mapper leitet diese Unterschiede aus den tatsächlichen Reportfeldern ab und berechnet sie nicht ein zweites Mal. -
Der HTTP-Zugang bleibt unverändert eng:
POST /api/internal/pdf-ua-shadow/[tier], ausschließlichVERCEL_ENV=preview, ohne Query oder Body und hinter Vercel Deployment Protection. Produktion, Development, Nicht-POST-Methoden und ungültige Tiers bleiben geschlossen. Die Antwort kennzeichnet Slice C mitX-LandNutzen-PDF-UA-Shadow: slice-c-1. -
Renderer, Finalizer, fünfseitiger Strukturvertrag, zwei informative Figuren, zwei Links, PDF/UA-1-/veraPDF-Gate, Poppler-Gates, 4-MB-Limit, kooperativer 50-Sekunden-Timer und instanzlokale Ein-Render-Sperre bleiben bestehen. Weder Runtime noch Prüfpfad führen Netzwerkzugriffe aus oder veröffentlichen PDFs als CI-Artefakte.
-
Der öffentliche Endpunkt
GET /api/v1/report/{id}/pdfbleibt unverändert bei React-PDF und weiterhin nicht als PDF/UA getaggt. Slice C liest keine Datenbank und keine gespeicherten Reports, bewirbt keine neue Produktfunktion und ist keine Freigabe des PDF/UA-Produktpfads. -
Issue #333 bleibt offen. Noch nicht belegt sind die vollständige Abbildung aller real vorkommenden Reportsektionen, echte Karten-Alternativtexte und Umbrüche, vorhandene Mehrseiten-Viewergates für den neuen Renderer, ein kontrollierter Produktrollout, der PDF/UA-Live-Readback eines neu erzeugten Produktreports und die manuelle Screenreader-Abnahme.
Konsequenzen
- Der Shadow prüft nun den echten
Report-Vertrag und dessen Tierfelder, bleibt aber deterministisch, nicht personenbezogen und netzwerkfrei. - Der mapperseitige Datenminimierungsvertrag ist separat testbar: Dass die repository-fixierte Report-Fixture eine künstliche Adresse und providerförmige Felder besitzt, bedeutet nicht, dass diese in der PDF-View oder HTTP-Antwort erscheinen.
- Ein grüner Slice-C-Lauf ist ein Integrationsbeleg für produktnahe Reportobjekte, nicht für gespeicherte oder reale Reports.
- Die historische Slice-B-Evidenz bleibt unverändert an ihren damaligen
Commit und
PDF-UA-SLICE-B-1gebunden. Der aktuelle Preview-Shadow trägtPDF-UA-SLICE-C-1.