feat(triage): Ticket-Fixes (Daten + Code) + prod-fähige Triage
Some checks failed
CI / Backend Tests (.NET) (push) Successful in 1m36s
CI / Frontend Tests (Node/Vite) (push) Successful in 9m35s
CI / Docker Build & Push (push) Successful in 1m28s
CI / Deploy auf TrueNAS (Custom App) (push) Failing after 3s

Daten-Fixes (conflict-decisions.json, re-ingest-stabil) für ~30 Tickets:
Merges (Jamie/Hiro/Mino/Jana/Blacky/Sakura/Malou/Socke→Marty), Eltern-Korrekturen
(Jacky/Idefix/Ichika/Roni/Ethan), Kruke→Kuke (+ Todesdatum), Targa-Wurf R14 + Druna,
Stacy/Merle/Domi/Eliza; Joghurt-Phantomwurf entfernt.

Code-Fixes:
- Gaida & alle Verstorbenen: Status wird aus Todesdatum/Abgabe abgeleitet
  (Program.cs Startup-Sweep heilt Altfälle; IngestResolved re-derived nach Freeze).
- CoCo: Scheckungsart wird bei jeder Schecke angezeigt (Platzhalter wenn leer).
- M-Wurf/Gale: über-gemergte Fremdtiere via neuem litterChildren-Override entfernt.
- renameTo eltern-verknüpfungssicher (Quell-Name im Index); dateOfDeath als Override.

Prod-fähige Triage (API):
- GET /feedback/{id} + GET /feedback?status= (kein 2-MB-Dump).
- POST /import/ingest-resolved/upload (multipart) → Ingest gegen Prod ohne SSH.

Tests: 280 Backend, 149 Frontend, alle Python, betroffene Playwright grün.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-21 00:41:43 +02:00
parent 0a4bcabd98
commit 2e7911074f
17 changed files with 749 additions and 468 deletions

View File

@@ -35,6 +35,39 @@ wartet auf die Züchterin, `Resolved` ist fertig — beide überspringen.
- Feedback überlebt den Import-Ingest (FK-freie Spalten) — Tickets bleiben
erhalten, auch wenn die DB neu befüllt wird.
## Ziel-System: lokal ODER Prod (WICHTIG — zuerst klären)
Die Tickets liegen dort, wo die Züchterin sie meldet — im Regelfall **Prod**
(TrueNAS Custom-App). Kläre zu Beginn, gegen welches System der Lauf geht, und
setze die **API-Base-URL** entsprechend für ALLE `feedback`/`gerbils`/`litters`-Aufrufe:
| System | API-Base | Bookmark der Züchterin |
|---|---|---|
| **Prod** (Regelfall) | `http://truenas:8090/api` | http://truenas:8090/ |
| **Lokal** (Aspire) | `http://localhost:5179` | — (App via `dotnet run --project GerbilManager.AppHost`) |
- **Ticket-CRUD läuft immer gegen das Ziel-System** (Prod: `…/api/feedback`).
Einzelticket: `GET /feedback/{id}`; nur die offenen: `GET /feedback?status=Open,Answered`
(spart den 2-MB-Volldump). Encoding: über Datei holen + Python-UTF-8 lesen.
- **Untersuchung bleibt lokal**: die Quellen (Stammbaum-xlsx, `_rpro3.db`, Wurfchronik,
`output/*.json`) liegen lokal. Datenfixes gehören re-ingest-stabil in
`conflict-decisions.json` / `rpro3-decisions.json` — NICHT die Live-DB patchen.
- **Prod-Re-Ingest ohne SSH** (bevorzugt): lokal `resolved_import.json` generieren
(extract → extract_contracts → merge_and_resolve), dann **per HTTP hochladen + ingesten**:
```bash
curl -X POST http://truenas:8090/api/import/ingest-resolved/upload \
-F "resolved=@tools/import/output/resolved_import.json" \
[-F "photos=@neue_fotos.zip"] # photos optional, nur bei neuen Fotos
```
Der Endpoint staget die Datei serverseitig und ruft denselben UPSERT-Ingest auf
(manuell/verified/feedback überleben). **DB-Copy vom lokalen Stand ist VERBOTEN**,
sobald Prod eigenständig kuratiert wurde — es überschreibt die Prod-Kuratierung;
nur der Upsert-Ingest bewahrt sie. (Fallback ohne Endpoint: `resolved_import.json`
per `scp` + `docker cp` nach `ix-gerbilmanager-api-1:/tools/import/output/` und
`POST …/api/import/ingest-resolved`.)
- Vor jeder **Prod-Mutation** (Ingest, Ticket-Schließen im großen Stil) kurz beim
Nutzer rückversichern.
## Ablauf
### 1. Tickets holen & einteilen