Produktionsnachweis: kontogebundene Report-Quota
- Datum: 26. August 2026
- Issue: #312
- Implementierungs-PR: #517
- Produktionscommit:
44a6df465d7c27487d08b69ab2acd20e826737e5 - PR-CI (grün): GitHub Actions Run 32905112959
- Main-CI (grün, 12:29 min): GitHub Actions Run 32906135919
- Vercel-Produktion:
dpl_7oaJ63NAyGrCdawxL5ABKt3dmuCn - Produktionsdomain:
https://www.landnutzen.at
Aussage dieses Nachweises
Die in ADR-0057 entschiedene Trennung der
Report-Quota ist auf dem exakten Merge-Commit produktiv ausgeliefert. Anonyme
Aufrufe, bestehende gleich-originäre Kontositzungen und API-Keys verwenden
getrennte Bucket-Verträge. Ungültige oder widerrufene Keys enden vor Cookie,
Session und Quota mit 401; ein nicht sicher auflösbarer beziehungsweise
gelöschter Session-User fällt auf den anonymen IP-Bucket zurück.
Der Nachweis verbindet vier getrennte Ebenen:
- den realen PostgreSQL-Schema-Readback vor und nach dem Rollout,
- den commitgenauen geschützten Vercel-Preview,
- den öffentlichen Produktionsdeploy auf
www.landnutzen.atund - die automatisierten Gegenproben für Bucket-Trennung, Löschung und Parallelität.
Er erzeugt bewusst kein künstliches Produktionskonto, keine Kundenadresse und keinen positiven personenbezogenen Produktionsreport. Die positive Trennung zweier Konten ist lokal, in Unit-Tests und im echten PostgreSQL-Lifecycle bewiesen; der Produktionsnachweis belegt Schema, Transport, Auth-Reihenfolge und ausgelieferte Dokumentation ohne neue personenbezogene Schreibdaten.
Produktionsmigration und Schema-Readback
Vor Migration 0051_account_rate_limit_buckets.sql ergab die rein lesende
Produktionsprüfung:
| Prüfung | Ergebnis |
|---|---|
| Waisenreports mit nicht vorhandenem User | 0 |
| vorhandene Account-Bucket-Tabelle | nein |
vorhandene rate_limits.account_bucket-Spalte | nein |
bestehende account:v1:-Zeilen | 0 |
Die additive und idempotente Migration wurde anschließend mit 8/8 Statements erfolgreich angewandt. Der unmittelbare Readback bestätigte:
account_rate_limit_buckets.bucketund.user_idals nicht nullable;rate_limits.account_bucketals nullable Übergang für nicht kontogebundene Buckets;- die validierten Cascades
account_rate_limit_buckets_user_id_fkey,rate_limits_account_bucket_fkundreports_user_id_fk; - die gültigen Indizes
account_rate_limit_buckets_user_idxundrate_limits_account_bucket_idx; - weiterhin
0Account-Mappings,0Account-Rate-Limits und0Waisenreports.
Nach dem öffentlichen Live-Readback blieb derselbe Nullbestand erhalten; die
sicheren 400-/401-Prüfungen schrieben keinen Quota- oder Reportdatensatz.
Commitgenauer Preview
Der geschützte Vercel-Preview lief auf Head-Commit
9366201378e481e754f9c916f3dfbe2a5d4dab00. Der projektgebundene
Protection-Bypass der Vercel CLI bestätigte:
- HTTP
200für/docs/account-report-quota-v1mit den drei getrennten Buckets und demaccount:v1-Vertrag; - OpenAPI mit
X-Auth-Mode: anon|session|key,private, no-storefür Fehlerantworten undAccountDeletionSummary; - eine adresslose Report-Anfrage mit
400 address_missing; - einen absichtlich ungültigen Bearer-Key mit
401 unauthorized; - für beide Negativpfade den exakten Preview-Commit im Header
X-Deploy-Commitund keine Rate-Limit-Header.
Öffentlicher Produktions-Readback
Vercel meldete Deployment dpl_7oaJ63NAyGrCdawxL5ABKt3dmuCn als READY
und band es an www.landnutzen.at, landnutzen.at und den Main-Alias. Auf der
öffentlichen Domain antworteten folgende Oberflächen mit HTTP 200 und dem
neuen Quota-Vertrag:
/docs/account-report-quota-v1/docs/api-guide/docs/report-contract/docs/compliance/docs/status/docs/feature-konto-team/datenschutz
GET /api/v1/openapi.json lieferte die drei Auth-Modi anon, session und
key, den Fehler-Cachevertrag private, no-store, das Schema
AccountDeletionSummary sowie die dokumentierten DELETE /me-Antworten
200, 400, 401, 403, 404, 409 und 500.
Die zwei sicheren Runtime-Gegenproben liefen auf dem exakten Produktionscommit:
| Anfrage | HTTP | X-Deploy-Commit | Cache | Quota-Header |
|---|---|---|---|---|
POST /api/v1/report mit {} | 400 address_missing | 44a6df465d7c27487d08b69ab2acd20e826737e5 | private, no-store | keine |
POST /api/v1/report mit absichtlich ungültigem Bearer-Key | 401 unauthorized | 44a6df465d7c27487d08b69ab2acd20e826737e5 | private, no-store | keine |
Der 401-Pfad wies im Server-Timing die Reihenfolge
body_parse → guard → auth → total aus. Beide Anfragen endeten vor der
Quota-Erhöhung; deshalb sind das erwartete fehlende X-Auth-Mode und die
fehlenden Rate-Limit-Header selbst Teil des Guard-Nachweises.
Automatisierte Verifikation
- Vollständige Unit-Suite: 245 Dateien bestanden, 4 übersprungen; 3.084 Tests bestanden, 18 übersprungen.
- TypeScript, ESLint, Content-Audit, SEO-Audit und Österreich-Adapter-Audit bestanden.
- Der echte PostgreSQL-Lifecycle migriert das Schema zweimal, erzeugt zwei
HMAC-Generationen, löscht den User und belegt alle Cascades. Derselbe
Runtime-CTE liefert nach der Löschung
INSERT 0 0; anonyme Buckets bleiben unberührt und ein Waisenreport wird vom FK abgewiesen. - Der dedizierte Playwright-Lauf bestand 4/4 Doku-, OpenAPI- und Guard-Tests.
- Der Implementierungsbuild erzeugte 110 Seiten; der Nachweisbuild mit dieser zusätzlichen öffentlichen Evidenzseite erzeugte 111 Seiten erfolgreich.
- PR-CI und Main-CI führen den PostgreSQL-Lifecycle zusätzlich im Postgres-16/PostGIS-Service vor den bestehenden Source-Release-Gates aus.
Verbleibende Grenze
Dieser Nachweis ist technische Produktions- und Vertragsverifikation, keine fachliche Abnahme durch reale Büro- oder Gemeindeanwender. Eine echte Nutzungssitzung kann künftig anhand regulärer, autorisierter Nutzung beobachtet werden; sie ist keine Voraussetzung dafür, die ausgelieferte Trennung als produktiv verifiziert zu bezeichnen. Es wurden für diesen Nachweis weder Produktionskonten noch personenbezogene Testdaten angelegt oder gelöscht.