Commit Graph

165 Commits

Author SHA1 Message Date
396d8f05d8 FEAT: Implement deceased/givenaway enclosure visibility rules, preserve external clan name, and hide receiver fields for deceased gerbils 2026-06-13 01:40:19 +02:00
5732398e60 feat(rennmaeuse): Tiere-Liste neu im Rennmaus-Filter-Design
Some checks failed
CI / Backend Tests (.NET) (push) Successful in 1m2s
CI / Frontend Tests (Node/Vite) (push) Failing after 4m54s
CI / Docker Build & Push (push) Has been skipped
Filter-UX aus dem Design:
- Quick-Chip-Kategorien (Status/Geschlecht/Farbschlag/Herkunft) öffnen ein
  Bottom-Sheet mit Mehrfachauswahl (suchbar bei Farbschlag/Herkunft); aktive
  Filter als entfernbare Chips; Sortierung + "Externe Ahnen" als gleich große
  Chips (Sortierung öffnet dasselbe Drawer).
- Neue zweizeilige Tierkarte (Name + Geschlechts-Kreis + Status-Badge, Meta-Zeile),
  cardIn/Chip/Sheet-Animationen, Titel blendet beim Scrollen aus.

App-weit:
- Design-Palette (Creme/Braun/Terrakotta), Hanken-Grotesk-Schrift und gemeinsamer
  --shadow-Token; obere "Rennmaus-Manager"-Titelleiste entfernt (mobil bleibt die
  untere Aktionsleiste); fixe Shell-Höhe, nur der Hauptbereich scrollt.

Funktion:
- Infinite Scroll via useInfiniteList (seitenweise) + IntersectionObserver-Sentinel.
- Namensgenerator: Option männlich/weiblich/egal.
- Mehrfach-OR-Filter über gridify orGroup; e2e an die neue UI angepasst.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 01:05:44 +02:00
04d189bd2f FEAT: genotype parsing resilience and displayGenotypeSafe format helper 2026-06-08 21:19:11 +02:00
d5c7b77e7e FEAT: redesign GerbilIcon with a cute alert sitting silhouette and dynamic tufted tail 2026-06-08 00:33:40 +02:00
299c038449 feat(JUVENILE-AVATARS): Foto-Avatare pro Jungtier im Wurf-Detail
- JuvenileCard-Komponente in WurfDetailPage mit 36px-Kreis-Avatar links
- Fallback auf GerbilIcon (SVG-Silhouette) wenn kein profilePhotoUrl
- URL-basiertes Fehler-Tracking (failedUrl) statt useEffect+imgError
- wuerfe.css: Flex-Layout fuer Card+Avatar, overflow:hidden/object-fit:cover
- StammbaumPage: gleiche Lint-Verletzung (react-hooks/set-state-in-effect)
  behoben (failedUrl-Pattern, kein useEffect mehr fuer Bild-Reset)
- E2E: profilePhotoUrl auf Pippa (pup-abgabe), neuer Avatar-Test

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 08:20:19 +02:00
ecd7ad2658 Merge feature/status-model-fe (STATUS-MODEL-FE): Dropdown Zucht/Liebhaber/Abzugeben; Verstorben/Abgegeben read-only abgeleitet; Labels+Filter
Some checks failed
CI / Backend Tests (.NET) (push) Successful in 1m1s
CI / Docker Build & Push (push) Failing after 9s
CI / Frontend Tests (Node/Vite) (push) Successful in 9m33s
2026-06-07 03:37:48 +02:00
6de56ab112 Merge feature/litter-mortality-fe (LITTER-MORTALITY-FE): deathsWithin8Weeks Feld im Wurf-Formular+Detail mit >totalBorn-Warnung 2026-06-07 03:37:48 +02:00
40f3ce250d STATUS-MODEL-FE: Zucht/Liebhaber/Abzugeben wählbar; Verstorben+Abgegeben abgeleitet (gated auf Pam BE) 2026-06-07 03:36:10 +02:00
ffbbc0dfad Merge feature/stammbaum-avatar (STAMMBAUM-AVATAR): Stammbaum-Knoten konsumieren profilePhotoUrl (Foto-Avatar mit imgError-Fallback auf GerbilIcon)
Some checks failed
CI / Backend Tests (.NET) (push) Successful in 1m1s
CI / Docker Build & Push (push) Has been cancelled
CI / Frontend Tests (Node/Vite) (push) Has been cancelled
2026-06-07 03:33:54 +02:00
29e9c4cd64 LITTER-MORTALITY-FE: deathsWithin8Weeks Feld im Wurf-Formular und -Detail (gated auf Pam BE) 2026-06-07 03:28:11 +02:00
8eddb83c99 STAMMBAUM-AVATAR: Tier-Foto als Avatar in Pedigree-Karte, GerbilIcon-Fallback (profilePhotoUrl-Contract) 2026-06-07 03:27:24 +02:00
2d54cb901f Merge feature/litter-juvenile-details (LITTER-JUVENILE-DETAILS): pro Jungtier Farbschlag/Abgabedatum/Abnehmer/Todestag/Ursache im Wurf-Detail
Some checks failed
CI / Backend Tests (.NET) (push) Successful in 1m16s
CI / Docker Build & Push (push) Has been cancelled
CI / Frontend Tests (Node/Vite) (push) Has been cancelled
2026-06-07 03:25:53 +02:00
03f8e4de90 LITTER-JUVENILE-DETAILS: Farbschlag/Abgabe/Abnehmer/Todesdaten pro Jungtier im Wurf-Detail 2026-06-07 03:23:22 +02:00
ade40eef5e FARBSCHLAG-GENOTYPE-SYNC: Farbschlag↔Gencode bidirektionale Sync im Tier-Formular 2026-06-07 03:16:02 +02:00
7525970ffc STAMMBAUM-FULLDATE: GerbilIcon-SVG + Gencode-Chip + Gerbil-Icon ersetzt 🐭 app-weit 2026-06-07 02:53:31 +02:00
bfc90f8581 STAMMBAUM-FULLDATE: volles Geburtsdatum auf Knoten-Karten (formatDate statt slice 4) + e2e 2026-06-07 02:47:12 +02:00
04971bf3bb Merge feature/stammbaum-litters (STAMMBAUM-LITTERS): Würfe des Wurzeltiers links im Viewer + Link
Some checks failed
CI / Backend Tests (.NET) (push) Successful in 58s
CI / Docker Build & Push (push) Has been cancelled
CI / Frontend Tests (Node/Vite) (push) Has been cancelled
2026-06-07 01:38:10 +02:00
08500757d7 STAMMBAUM-LITTERS: Wuerfe des Wurzeltiers links im Stammbaum-Viewer
Layout: stammbaum-layout (flex-row Desktop / flex-column Mobil) wraps
[Wuerfe-Panel | Canvas]. Panel 148px breit, border-right Trenner;
auf Mobil (<=520px) horizontaler Scroll-Streifen ueber dem Canvas.

Daten: useApi(listLitters fatherId=id|motherId=id) reagiert automatisch
auf Umwurzeln (id-Param). Kein Panel wenn Wurzeltier keine Wuerfe hat.

Pro Wurf: Wurfname (fett) + N Junge + Link zu /wuerfe/{id}.
CSS: flex 0 0 auto Mobil-Override sichert Canvas-Hoehe im column-Mode.
de.ts: littersTitle, littersJunge (Stammbaum-Sektion, disjunkt).

Gate: vitest 122/122 e2e 20/20 Stammbaum (4 neue Tests x 2 Viewports)
build+tsc+eslint clean.
2026-06-07 01:37:08 +02:00
05ef3d9567 Merge feature/namegen-2-fe (NAMEGEN-2-FE): 10 Namens-Kategorien UI (disney/pokemon/EN+HR-Städte/US-Staaten)
Some checks failed
CI / Backend Tests (.NET) (push) Successful in 59s
CI / Docker Build & Push (push) Has been cancelled
CI / Frontend Tests (Node/Vite) (push) Has been cancelled
2026-06-07 01:35:40 +02:00
bda5479b93 UI-FIX: doppelte Überschrift 'Erwartete Farbschläge' auf Wurf-Detailseite entfernt 2026-06-07 01:29:49 +02:00
d5c155953b GEN-4d: rere (Re-Wildtyp) aus Anzeige ausblenden (Julian)
- genotype.ts: toDisplayString filtert Re aus wenn re/re (Wildtyp) —
  analog zur bestehenden Sls-Regel; Rere/ReRe bleiben sichtbar.
  Wildtyp-Anzeige jetzt 7 Loci: AA CC DD EE GG PP spsp (ohne rere).
- StammbaumPage.tsx: Druck-Ahnentafel nutzt toDisplayString(fromDisplayString(g.genotype))
  statt rohem g.genotype-String (Audit: einzige Display-Stelle ausserhalb toDisplayString).
  (GerbilDetailPage/BreedingResultView gehen bereits via toDisplayString.)
- genetics.test.ts: Alle Display-String-Assertions auf 7-Loci-Format aktualisiert;
  Rere-Nachweis zum Sls/Re-Test ergaenzt; Katalog-Regex auf {6,8}.
- colorVarietySeed.generated.json regeneriert (kein rere in canonicalGenotype).
- backend.json unveraendert (Pam: DB-Speicherung bleibt volles 8-Loki-Format).
2026-06-07 01:28:06 +02:00
b72e0a9d9a GEN-4c: PEW=REW konsolidiert (Julian) + REW-2-Verifikation
- catalog.ts: 'Pink Eyed White (PEW)' -> 'REW' (frozen rename; chch+pp
  engine-computes 'REW' per Julian; entry now round-trips correctly)
- genetics.test.ts: REW_SHADOWED-Ausnahme entfernt (kein Bedarf mehr);
  CATALOG[0]-Assertion auf 'REW'; aa cchmcchm+pp-Test als REW-2-Nachweis
  (Julian: A-Locus egal fuer REW-Bedingung)
- chipColors.ts: 'REW'-Chip ergaenzt (gleiche Farbe wie PEW; additive;
  PEW-Eintrag bleibt fuer Rueckwaertskompatibilitaet waehrend DB-Migration)
- Seed-Artefakte regeneriert (70 Reihen, REW statt PEW an Position 0)
- FLAGGED to god: 'Altweiss (REW)' hat volles C (C:'C') -> faellt NICHT
  unter REW-Bedingung; warte auf Julian-Entscheid vor Aenderung
2026-06-07 01:08:23 +02:00
a42966ad8e STAMMBAUM-EXPAND: +-Button prominenter + Mini-Legende (Stammbaum-UX)
Punkt 1 - Expand-Button sichtbar/zuverlaessig:
- 40px solid-fill (war 32px outline), box-shadow, flex-centered;
  deutlich sichtbar auf 190px Karte, touch-tauglich (>=40px Tap-Target).
  Hover/focus-visible: opacity + outline.
- Edge-case (Litter mit null-Eltern): +-Button bleibt sichtbar --
  unbekannt-Karten sind korrektes Feedback fuer quarantaenierte Eltern.

Punkt 2 - Bottom-Hint Mini-Legende:
- stammbaum-hint -> stammbaum-hints ul (flex-wrap, 3 Items):
  Umwurzeln / Name=Akte / +=Nachladen. Gut lesbar auf 390px.
  de.ts: hintName + hintExpand (neue Keys; tapHint bleibt fuer card title).

e2e: +2 Specs x 2 Viewports = 4 neue Tests (Legende + Expand-Klick).
Emil (Gen 4, litterId w-emil) liefert Testanker im Mock-Stammbaum.

Gate: vitest 122/122 e2e 166+68skipped build+tsc+eslint clean.
2026-06-07 00:38:46 +02:00
54ffb809c4 CHARAKTERBOGEN-2 (E1): Trait-Katalog in 4 Kategorien + 10 neue Traits + Warnsignale
- de.ts: traits-Array -> traitCategories (4 Kategorien: Sozialverhalten / Eignung &
  Umgang / Hobbys & Eigenarten / Wesen & Temperament); alle 15 bestehenden Keys
  erhalten (stored auf Live-Tieren); 10 neue Keys additiv; warn:true auf
  schwer-vergesellschaftbar + territorial.
- format/traits.ts: TraitEntry/TraitCategory-Interface, TRAIT_CATEGORIES-Export,
  ALL_TRAITS via flatMap, neuer isWarnTrait()-Helper.
- Charakterbogen.tsx: grouped-Rendering nach Kategorie (section + h4); warn-Chips
  mit trait-chip--warn-Klasse + trait-warn-badge.
- charakterbogen.css: .trait-category__heading + .trait-chip--warn (amber) +
  .trait-warn-badge.
- format/__tests__/traits.test.ts: 14 neue Vitest-Tests (Kategorien, Keys, warn,
  traitLabel/traitLabels).
- Gate: vitest 122/122, tsc clean, build clean, eslint clean.
2026-06-06 22:32:16 +02:00
643f1a6831 Merge feature/catalog-generator (AR-5): committed Katalog-Generator (gen:catalog) + frozen colorVarietySeed.backend.json + Drift-Guard
Some checks failed
CI / Backend Tests (.NET) (push) Successful in 1m0s
CI / Frontend Tests (Node/Vite) (push) Successful in 9m31s
CI / Docker Build & Push (push) Failing after 8s
Frontend-only (Generator .mts + Seed-Artefakte + catalog-drift test). Gate: vitest 109/109.
Backend-Artefakt (70 Eintraege, GEN-4/4b-final) = Quelle fuer die Backend-ColorVariety-Re-Seed-Migration (Pam) vor dem WIPE+REIMPORT.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 22:20:00 +02:00
c8ab6bf072 STAMMBAUM-OPEN: Name in Ahnen-Karte ist Link zur Tier-Detailseite
- PedigreeCard: <span className=nametext> → <Link to=/rennmaeuse/{id}> mit e.stopPropagation() (Re-Root bleibt auf Karten-Bereich außerhalb des Namens)
- stammbaum.css: .pedigree-card__nametext color:inherit + text-decoration:none; hover→underline
- Kein Link im Drucklayout (PrintPedigree unverändert)
- e2e: href=/rennmaeuse/fridolin verifiziert + Keyboard-Navigation (fokus+Enter) öffnet Detailseite

Gate: vitest 108/108, e2e 162/162, tsc clean
2026-06-06 21:54:33 +02:00
30ee7b6198 AR-5: Seed-Artefakte auf finalem Katalog regeneriert (70 Eintraege, GEN-4/4b)
npm run gen:catalog lief auf rebased HEAD (post-GEN-4b, main 7fe538d).
Beide Artefakte aktualisiert:
- colorVarietySeed.generated.json: 70 Zeilen, Klammer-Notation (Display)
  Neue Namen: Dilute Gold/Platin/Agouti/Silberagouti/Kohlfuchs/Anthrazit/
  Topas/Blaufuchs + Dilute Fuchs-Varianten (Algierfuchs/Goldfuchs/Rotfuchs/Polarfuchs)
- colorVarietySeed.backend.json: 70 Zeilen, frozen symbols (ef/cchm/ch)
  Quelle fuer Pams Backend-Re-Seed-Migration (Guardrail: nie Klammern)
Drift-Guard (catalog-drift.test.ts) laeuft gruen.
Gate: build ✓  eslint ✓  vitest 109/109 ✓
2026-06-06 21:52:44 +02:00
29207e41da AR-5: Committed Katalog-Generator + Drift-Guard + Backend-Artefakt
- gen-seed.mts: deterministischer Generator aus catalog.ts (Single Source);
  emittiert BEIDE Artefakte: generated.json (Klammer-Notation, Display) +
  backend.json (frozen ef/cchm/ch, für Pam EF-Migrationen). Kein magisches
  Artefakt mehr.
- package.json: npm run gen:catalog (npx tsx gen-seed.mts)
- catalog-drift.test.ts: Drift-Guard — liest generated.json von Disk via
  import.meta.url + readFileSync, vergleicht mit live CATALOG; Fail-Meldung
  zeigt 'npm run gen:catalog'. 5 Test-Files, 93 Tests grün.
- colorVarietySeed.backend.json: 66 Zeilen frozen symbols (ef/cchm/ch),
  kein sofortiger Backend-Eingriff (AR-5 Guardrail; Pam konsumiert bei
  nächster Reseed-Migration).
- README.md: Katalog-Generator-Doku (wann laufen, was erzeugt wird).
Gate: build ✓  eslint ✓  vitest 93/93 ✓
2026-06-06 21:51:55 +02:00
7fe538dd5d Merge feature/gen-4 (GEN-4b): 7 Farbarten als Engine-Guard (keine Farbschläge) + Schimmel-Naming-Fix
Some checks failed
CI / Backend Tests (.NET) (push) Successful in 59s
CI / Docker Build & Push (push) Has been cancelled
CI / Frontend Tests (Node/Vite) (push) Has been cancelled
ff42341: CATEGORY_NAMES-Guard (Standard/Colourpoint/Dilute/Fuchs/Fuchsschimmel/Schimmel/CP-Dilute nie als Ergebnis, FK=0);
locusToken E ef/e→'ef' (het-Schimmel matchen konkrete Katalog-Eintraege statt Family-Fallback 'Fuchsschimmel');
baseColourFor Family-Fallback→null; Orangeschimmel A-Restriktion (aa→Kohlfuchsschimmel). Frontend-only. vitest 96, e2e 148.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 21:49:20 +02:00
c452b69dd6 NAMEGEN-2-FE: 5 neue Namenskategorien (Disney, Pokémon, Englische/Kroatische Städte, US-Bundesstaaten)
- NAMEGEN_USAGES: +disney, +pokemon, +encities, +hrcities, +usstates (jetzt 10 Einträge)
- names.test.ts: Count-Test 5→10, neue toContain-Checks für alle 5 Codes

Gate: vitest 107/107, e2e 160/160, tsc clean
2026-06-06 21:48:08 +02:00
ff42341c47 GEN-4 Addendum: 7 Farbarten-Kategorien blockiert + locusToken ef/e-Fix
catalog.ts:
- locusToken E: ef/e -> 'ef' (phenotypisch ausgedrücktes Allel; enables
  catalog-Match fuer het Schimmel-Tiere wie Kohlfuchsschimmel/Orangeschimmel).
  Vorher: 'eef' matchte keinen Katalogeintrag -> Family-Fallback 'Fuchsschimmel'.
- baseColourFor: Family-Fallback entfernt (null statt family-Name) — Familie
  ist nur noch Katalog-Suchfilter, nie direkter Ausgabewert.
- CATEGORY_NAMES Guard in farbschlagFor: Fuchs/Fuchsschimmel/Schimmel/Standard/
  Colourpoint/Dilute/Colourpoint Dilute -> Unbekannter Farbschlag wenn Engine
  diese Namen zurueckgeben wuerde.
- Orangeschimmel: A:'A' hinzugefuegt (Agouti-Einschraenkung), damit aa-ef-Tiere
  durch zu Kohlfuchsschimmel fallen.
- FK-Check: Keine der 7 Kategorie-Namen sind in BASE_COLORS -> 0 FK-Risiko.

genetics.test.ts:
- 'eef with unknown other loci': erwartet jetzt 'Kohlfuchsschimmel' (korrekt!)
- GEN-4 Farbarten-Fixture: Kategorie-Guard-Test + FK-Check-Assert.
Gate: build ✓  eslint ✓  vitest 96/96 ✓  e2e 148/148 ✓
2026-06-06 21:42:15 +02:00
90f998d189 Merge feature/animal-litters (ANIMAL-LITTERS): 'Wuerfe als Elternteil' auf Tier-Detailseite
Some checks failed
CI / Backend Tests (.NET) (push) Successful in 59s
CI / Docker Build & Push (push) Has been cancelled
CI / Frontend Tests (Node/Vite) (push) Has been cancelled
GerbilDetailPage: Sektion listet Wuerfe wo fatherId|motherId==Tier (Gridify OR-Filter),
je Link /wuerfe/{id} + Vater/Mutter-Badge + Datum + totalBorn; Leer-Zustand. Rueckweg Tier→Wuerfe.
Frontend-only. vitest 104, e2e 160.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 21:42:04 +02:00
d5f4be76be ANIMAL-LITTERS: Tier-Detailseite zeigt Würfe dieses Tiers als Elternteil
- GerbilDetailPage: listLittersPaged({filter: fatherId={id}|motherId={id}}) + neue Sektion 'Würfe als Elternteil' vor den Tabs; je Wurf: Link /wuerfe/{id}, Vater/Mutter-Badge, Datum, Wurfstärke; Leer-Zustand wenn keine Würfe
- de.ts: parentLittersTitle, parentLittersEmpty, parentLittersRoleVater/Mutter (append-only in detail-Sektion)
- e2e: +2 Tests (Fridolin hat Wurf K als Vater; Krümel hat Leer-Zustand)

Gate: vitest 104/104, e2e 160/160, tsc clean
2026-06-06 21:39:14 +02:00
433f9ee592 Merge feature/gen-4 (GEN-4): Farbschlag-Benennung (Dilute-Praefix, REW, Fuchs spezifisch) + BreedingView
Some checks failed
CI / Docker Build & Push (push) Has been cancelled
CI / Frontend Tests (Node/Vite) (push) Has been cancelled
CI / Backend Tests (.NET) (push) Successful in 58s
- dd → 'Dilute '-Praefix (Agouti dd→Dilute Agouti etc.); 4 Dilute-Fuchs-Eintraege gegen nackten 'Fuchs'
- REW = beide C-Allele reduziert (kein volles C) + pp (alle 3 Kombis, A-unabhaengig)
- CP-Fuchs in berechneter Verteilung unterdrueckt
- BreedingResultView: Gencode (Klammer) pro Karte + Karten-Layout-Fix (overflow/responsive)
Frontend-only (engine+catalog.ts+BreedingResultView+index.css). vitest 95, e2e 148.
OFFEN als Follow-up: 7 Kategorie-Eintraege entfernen, PEW=REW-Konsolidierung, Backend-Re-Seed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 21:34:17 +02:00
5c327cd8d8 GEN-4 REW erweitert: alle 3 C-Kombi + pp = REW (Julian bestätigt)
- cReduced(c) = cchm || ch; REW wenn cReduced(c0) && cReduced(c1) && pp
  (cchm/cchm, cchm/ch, ch/ch alle REW; mind. ein volles C = NICHT REW)
- Counterproof-Test: C/cchm + pp und C/ch + pp = nicht REW
- Frozen-Round-Trip-Test: PEW (ch/ch+pp) explizit ausgenommen (intentional
  shadow durch REW-Check per Julian-Regel; PEW bleibt Dropdown-Name)
Gate: build ✓  eslint ✓  vitest 95/95 ✓  e2e 148/148 ✓
2026-06-06 21:32:20 +02:00
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
097a04cbd8 FEAT-NAMEGEN UC-1: 'Name vorschlagen'-Panel auf GerbilFormPage
- api/names.ts: suggestNames() + buildSuggestPath() + NAMEGEN_USAGES (norn/japa/mythg/ger/arb)
- de.ts: namegen-Sektion (button, panelTitle, letter/usages/load/states)
- NameSuggestPanel.tsx: inline-Panel mit Buchstabe/Herkunftskultur-Multiselect, Vorschlagsliste; 503 NamesKeyMissing → freundlicher Hinweis
- GerbilFormPage: 'Name vorschlagen'-Button neben Namensfeld (htmlFor-Pattern), Panel schließt+befüllt bei Auswahl
- vitest: 11 Tests (buildSuggestPath URL-Logik + NAMEGEN_USAGES-Struktur)
- e2e: mock /names/suggest + namesConfigured-Flag; 4 Specs (Panel öffnen, Klick befüllt, Buchstabe-Filter, 503-Fallback)

Gate: vitest 104/104, e2e 156/156, tsc clean
2026-06-06 21:17:42 +02:00
d1baba686f QA-SMOKE-2: Live-Smoke GEN-3h/FORM-FIELDS/CR-2/UI-POLISH/GEHEGE (18/18 gruen) 2026-06-06 19:51:45 +02:00
52303b90b2 CR-1a: ee[-] Parser-Fix (Silvain) — lookbehind trennt e[-] vom führenden Allel
normalizeToken: lookbehind-Regex /(?<=[A-Za-z])e\[-\]/→'?' greift wenn e[-]
von einem Buchstaben (erstes Allel) gefolgt wird (ee[-] → e?); standalone e[-]
fällt durch auf die generische \[-\]→? Regel (→ e?). Beide Pfade liefern
splitToken 2 Allele [e,?]. Vorher: ee[-]→ee?→ 3 Allele → Fehler.
Fixture: Silvain 'aa c[chm]c[chm] Dd ee[-] Gg Pp Spsp' → E=[e,?] ✓.
Gate: build ✓  eslint ✓  vitest 92/92 ✓  e2e 126/126 ✓
2026-06-06 18:24:06 +02:00
4b6a07544d GEN-3h: Breeder bracket-notation display + E-locus e-vor-e[f] Sortierung
- genotype.ts: toDisplayString zeigt ef→e[f], cchm→c[chm], ch→c[h] (Display-only;
  Storage-Contract unverändert). E-Locus Display-Rank E>e>ef: {ef,e} Paar
  rendert als ee[f] statt e[f]e (Züchterin-Konvention, Julian-Feedback).
- genotype.ts: normalizeToken akzeptiert Klammer-Eingabe (e[f], c[chm], c[h],
  [-]) → interne Symbole; vollständiger Round-Trip Display→Parse.
- genetics.test.ts: Katalog-Regex auf [A-Za-z[\]?-]+ erweitert; GEN-3h
  Notation-Fixtures (C/Zuleika/Milka-Orakel, Klammer-Round-Trip, E-Sortierung).
- colorVarietySeed.generated.json: neu generiert (66 Zeilen mit Klammer-Notation).
Gate: build ✓  eslint ✓  vitest 91/91 ✓  e2e 120/120 ✓
2026-06-06 18:24:06 +02:00
69ffe58d6b UI-POLISH-2: '(ohne Namen)' Platzhalter in Stammbaum, Vertrag-Wizard, Wurf-Formular
- StammbaumPage: PedigreeCard-Name + PrintCell-Name + beide titleFor()-Aufrufe → g.name || nameless
- VertragWizardPage: wizard-pick__name + join(', ')-Tierliste → g.name || nameless
- WurfFormPage: fatherName/motherName in Prefill (nameById.get || nameless) + Picker-Auswahl (g.name || nameless)

e2e: neuer Test stammbaum.spec — namenloser Ahne zeigt Platzhalter in Karte + Titel

Gate: vitest 82/82, e2e 148/148, tsc clean
2026-06-06 17:53:24 +02:00
db49150206 FORM-FIELDS-1: originBreeder + isDeaf in GerbilFormPage
- types.ts: isDeaf?: boolean|null in Gerbil + CreateGerbil (UpdateGerbil erbt via Partial)
- de.ts: fields.originBreeder, fields.isDeaf; form.isDeafUnknown/Yes/No
- GerbilFormPage: originBreeder Freitext-Input (neben originContactId-Dropdown); isDeaf Tristate-Select (Unbekannt/Ja/Nein); round-trip load→display→save

e2e: 2 neue Tests (originBreeder Freitext + isDeaf Tristate round-trip)

Gate: vitest 82/82, e2e 146/146, tsc clean
Rebase auf Pams CR-2 folgt nach deren Merge.
2026-06-06 17:47:25 +02:00
319aca7608 Merge feature/ui-polish: namenlose Tiere Platzhalter '(ohne Namen)' + Leerwert-'—'-Konsistenz
Some checks failed
CI / Backend Tests (.NET) (push) Successful in 56s
CI / Docker Build & Push (push) Has been cancelled
CI / Frontend Tests (Node/Vite) (push) Has been cancelled
- de.ts nameless + GerbilsPage/GerbilDetailPage/AnimalPicker zeigen '(ohne Namen)' statt leer
- causeOfDeath/notes via || null → Rows zeigen '—' konsistent (Herkunft war schon korrekt)
- +4 e2e (Platzhalter Liste+Detail x2 Viewports). vitest 82, e2e 130, build clean. Kein EF.
[god-QA: disjunkt zu qa-regression+import-backfill-Merges]

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 17:39:15 +02:00
55c298ad1f UI-POLISH-1: namenlose Tiere + Leerwert-Konsistenz
- de.ts: nameless = '(ohne Namen)' (neuer Platzhalter-String)
- GerbilsPage: g.name || t.nameless in Karten-Name + Checkbox-Aria
- GerbilDetailPage: g.name || nameless im h2-Header; g.causeOfDeath/notes via || null (leer-string-sicher wie Herkunft)
- AnimalPicker: g.name || nameless im Picker-Button

e2e: +1 nameless-stub in mock-data; 2 neue Tests (Liste + Detail-Header)

Gate: vitest 82/82, e2e 130/130, tsc clean
2026-06-06 17:32:26 +02:00
e1e088f041 QA-REGRESSION-1: GEHEGE-RENAME Regressions-Netz (Redirect /becken→/gehege, Nav-Negativ, Landing /rennmaeuse) 2026-06-06 17:30:31 +02:00
0b9b03eb2d Merge feature/wurf-link: Wurf auf Tier-Detailseite als Hyperlink
Some checks failed
CI / Backend Tests (.NET) (push) Successful in 52s
CI / Frontend Tests (Node/Vite) (push) Successful in 9m31s
CI / Docker Build & Push (push) Failing after 9s
GerbilDetailPage: Wurf-Feld → <Link to=/wuerfe/{litterId}> wenn litterId+Name aufloesbar,
sonst plain '—' (kein toter Link). +e2e tiere.spec (Link klickbar, navigiert zur Wurf-Detail).
Frontend-only, kein EF. [god-QA: disjunkt zu gehege-rename]

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 17:01:26 +02:00
d4c9be23c8 Merge feature/gehege-rename: Becken→Gehege + Terrarium-Icon + Start-Nav raus, /rennmaeuse = Landing
- UI-Begriff 'Becken' → 'Gehege' (de.ts, Becken-Pages, Abgabe/Hilfe), Route /becken→/gehege+Redirect
- Nav-Icon Badewanne → Terrarium; 'Start'-Nav-Eintrag entfernt
- Index-Route '/' → Navigate /rennmaeuse (Landing Page), HomePage.tsx geloescht
- e2e navigation/becken-kontakte angepasst
Frontend-only, kein EF. [god-QA: disjunkt zu main-Commits, Home-Assertions nur in navigation.spec (selbst gefixt), live-data.spec referenziert kein '/']

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 17:01:09 +02:00
f6bfc0ebab WURF-LINK-Addendum: Herkunft-Zeile zeigt originBreeder + Kontaktlink
- originContactId gesetzt → Link /kontakte/{id} mit Kontaktname (Priorität)
- Sonst originBreeder (Freitext) gesetzt → plain text
- Sonst '—' (bisheriges Fallback)
Behebt: 74 Tiere mit originBreeder sahen '—' obwohl Daten vorhanden

e2e: 2 neue Tests (originBreeder-Text + Kontaktlink)

Gate: vitest 82/82, e2e 126/126, build+tsc clean
2026-06-06 17:00:32 +02:00
3160b66697 WURF-LINK: Wurf-Feld auf Tier-Detailseite als Link zur Wurf-Detailseite (/wuerfe/{id})
- GerbilDetailPage: Wurf-Feld zeigt Link wenn litterId + Name auflösbar; sonst bisheriger '—'-Fallback (kein toter Link)
- e2e: neuer Test verifiziert Link sichtbar + Navigation zu Wurf-Detail

Gate: vitest 82/82, e2e 122/122, build+tsc clean
2026-06-06 16:56:54 +02:00
162a0fafb1 GEHEGE-RENAME Addendum: /rennmaeuse = Landing Page, 'Start'-Nav entfernt
- AppShell.tsx: Start-Eintrag (/) aus PRIMARY entfernt; /rennmaeuse ist
  nun erste Kachel und Landing Page
- App.tsx: index-Route → <Navigate to="/rennmaeuse" replace>;
  HomePage-Import entfernt
- HomePage.tsx: gelöscht (nicht mehr referenziert, via git wiederherstellbar)
- de.ts: nav.home + pages.home entfernt (nur von AppShell/HomePage genutzt)
- e2e/navigation.spec.ts: HomePage-Assertions → de.pages.gerbils.title
Gate: build ✓  eslint ✓  vitest 82/82 ✓  e2e 120/120 ✓
2026-06-06 16:49:21 +02:00