Commit Graph

2 Commits

Author SHA1 Message Date
Matthias Hochmeister
6975679c4e fix(detail): validate route-param UUID and align e2e storageState
Detailseiten & Kontakt (WS8) – zwei BLOCKING-Befunde behoben:

- UUID-Validierung an der Grenze (Querschnittsstandard 4): Die drei
  Detailseiten (fahrzeuge/geraete/wehren [id]) gaben den Route-Param `id`
  ungeprüft an die DB (Postgres `uuid`). Ein malformter Pfad wie
  /fahrzeuge/abc erzeugte `invalid input syntax for type uuid` -> 500.
  Jetzt: uuidSchema.safeParse(id) -> notFound() (deutsche 404) vor dem
  Query-Aufruf.

- e2e-Harness: detail-auth.spec.ts nutzte storageState
  "tests/e2e/.auth/wehr-read.json" (existiert nicht, ENOENT -> ganzer
  'Eingeloggt'-Block errort). Auf Projektkonvention umgestellt:
  storageState: process.env.E2E_WEHR_READ_STATE ?? { cookies, origins }
  + test.skip ohne Fixture (analog verwaltung-scoping.spec.ts).
  Zusätzlich nicht-UUID-Fall (/fahrzeuge/abc -> deutsche 404) abgesichert.

Verifiziert (offline): tsc --noEmit OK, vitest detail-Unit-Tests OK,
next build "Compiled successfully" + Typecheck OK. Build-Page-Data-Phase
und e2e deferred (kein Postgres/Server in der Sandbox).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 11:50:01 +02:00
Matthias Hochmeister
44050c7278 Workstream 8: Detailseiten & Kontakt (Phase 5)
Drei serverseitige Lese-Detailseiten (Fahrzeug, Gerät, Wehr), default-deny:
- src/lib/detail/merkmale.ts: formatMerkmal (de-AT Tausenderpunkt + NBSP,
  Ja/Nein, enum-Label, „–"), toEckdaten. ICU-unabhängige Zahl-Formatierung
  (formatToParts -> Punkt/Komma), da de-AT je nach ICU-Build U+202F gruppiert.
- src/lib/detail/queries.ts: read-only, wehrübergreifend; loadMerkmalRows
  (Join merkmal_values↔merkmale↔merkmal_optionen via wert=value_text),
  getFahrzeugDetail (+Beladung, +WehrCard), getGeraetDetail (Fahrzeug-Link
  oder „im Gerätehaus"), getWehrDetail (Fuhrpark + Geräte im Haus),
  getBrigadeCard. UUID-IDs.
- Komponenten: detail/{DetailHeader,EckdatenGrid,BeladungListe,StatusBadge},
  kontakt/{KontaktButton (tel:/mailto:, Telefon ohne Leerzeichen, subject;
  Empty-State),WehrCard}.
- Seiten (app)/{fahrzeuge,geraete,wehren}/[id]/page.tsx mit requireSession()
  als erster Zeile (Default-deny in der Tiefe) + fahrzeuge/[id]/not-found.tsx.
- i18n-Keys (detail/kontakt/wehr) ergänzt; keine hartkodierten Strings.

Tests: merkmale.test.ts (11), queries.test.ts (3, gemockte DB für
„im Gerätehaus" + not-found). Playwright detail-auth.spec.ts geschrieben
(deferred: kein Server/DB in Sandbox); Detailrouten ins Gating-Manifest
aufgenommen.

Offline verifiziert: vitest src/lib/detail grün; tsc --noEmit ok; eslint
ok; next build erfolgreich (alle drei [id]-Routen vorhanden).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 11:35:34 +02:00