Files
GerbilManager/gerbil-manager-web
Gulum b12b5d720d GEN-4: Dilute-Präfix, REW-Erkennung, CP-Fuchs-Fix, BreedingResultView Gencode+Layout
Katalog (catalog.ts):
- 8 'X dd'/'dd X' Einträge → 'Dilute X' (Agouti/Silberagouti/Kohlfuchs/Anthrazit/
  Topas/Blaufuchs dd + dd Gold/Platin → Dilute Gold/Platin etc.)
- 4 neue Dilute-Fuchs-Basiseinträge (Dilute Algierfuchs/Goldfuchs/Rotfuchs/Polarfuchs)
  → verhindert naked 'Fuchs' Fallback für agouti+dilute+fox Genotypen. 66→70 Einträge.
- colourpointName: 'Dilute X' Base → 'Dilute CP-X' statt 'CP-Dilute X' (Präfix-Reihenfolge)
  → AA cchmcchm dd ee GG PP = 'Dilute CP-Algierfuchs' statt 'CP-Fuchs'.

Engine (farbschlagFor):
- REW-Check: c0==cchm && c1==cchm && p0==p && p1==p → 'REW' (Rotaugenweiß).
  Unabhängig von A/D/E/G. Flagged to god zur Bestätigung.

BreedingResultView:
- Gencode (bracket notation) pro Farbschlag-Karte (erster/wahrscheinlichster Genotyp).
- Layout-Fix: flexbox body (name+gencode gestapelt), min-width:0 gegen Overflow,
  word-break, grid min 15rem, prob flex-shrink:0 rechtsbündig.

Tests: GEN-4 describe (Dilute/REW/no-bare-Fuchs Fixtures); CATALOG_SIZE 66→70;
  CP-Fuchs/CP-Fuchs-Hell → Dilute CP-Algierfuchs(-Hell) in bestehenden Tests.
Gate: build ✓  eslint ✓  vitest 95/95 ✓  e2e 148/148 ✓
2026-06-06 21:27:32 +02:00
..

gerbil-manager-web

Frontend des Rennmaus-Managers — React + TypeScript + Vite, mobile-first (Smartphone und Laptop).

Entwicklung

npm install
npm run dev

Erwartet die laufende GerbilManagerWebAPI unter http://localhost:5179 (Profil http in GerbilManagerWebAPI/Properties/launchSettings.json).

Konfiguration

Variable Standard Beschreibung
VITE_API_BASE_URL http://localhost:5179 Basis-URL der GerbilManagerWebAPI

Konventionen

  • Alle für Benutzer sichtbaren Texte sind Deutsch und liegen zentral in src/strings/de.ts — keine Texte direkt in Komponenten hartkodieren.
  • API-Zugriffe laufen über src/api/client.ts.
  • Routen werden in src/App.tsx registriert, Seiten liegen in src/pages/.
  • Mutationen (useMutation aus src/hooks/useApi.ts): run() wirft NIE, sondern liefert ein MutationOutcome<T>{ ok: true, value } oder { ok: false, error, cause }. Aufrufer MÜSSEN verzweigen: const r = await m.run(x); if (r.ok) navigate(r.value.id). m.error treibt die Inline-Anzeige; für Spezialfälle (z. B. HTTP 409) r.cause prüfen (r.cause instanceof ApiError && r.cause.status === 409). So sind unbehandelte Promise-Rejections an Aufrufstellen ausgeschlossen (siehe auch src/dev/unhandledRejectionGuard.ts).

Build

npm run build
npm run preview

E2E-Tests (QA-1, Playwright)

npm run e2e                # Mock-Modus: startet Vite auf :5199, API wird gemockt
npx playwright test --project=phone   # nur Smartphone-Viewport (390px)
  • Mock-Modus (Standard): kein Backend nötig. e2e/mock-api.ts fängt alle API-Aufrufe ab (DATA-2-Vertrag: Gridify-Paging, camelCase, 409-Konflikte) mit frischem Datenbestand pro Test (e2e/mock-data.ts).
  • Live-Modus: dieselbe Suite gegen den echten Stack — $env:E2E_BASE_URL = 'http://localhost:5173'; npm run e2e (vorher AppHost starten). Tests, die Mock-Seed-Daten voraussetzen, überspringen sich selbst; die übrigen legen eigene Datensätze an.
  • Beide Viewports (Smartphone 390px, Laptop 1280px) laufen für jede Spec; alle Assertions prüfen die deutschen Oberflächentexte direkt aus src/strings/de.ts.