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

@@ -503,13 +503,24 @@ export default function GerbilDetailPage() {
'—'
)}
</Kv>
{g.spottingType && (
<Kv label={t.fields.spottingType}>
{de.pages.gerbils.spottingTypes[
g.spottingType as keyof typeof de.pages.gerbils.spottingTypes
] || g.spottingType}
</Kv>
)}
{/* Ticket 9f92c834 (CoCo): Scheckungsart bei jeder Schecke zeigen — auch wenn noch
nicht erfasst (dann Platzhalter), damit sichtbar ist, dass es eine Schecke ist und
welche Art. Schecke erkannt am Sp-Allel im Genotyp oder am Farbschlag-Namen. */}
{(() => {
const isSchecke =
/Sp/.test(g.genotype ?? '') ||
(storedColorName?.toLowerCase().includes('schecke') ?? false);
if (!g.spottingType && !isSchecke) return null;
return (
<Kv label={t.fields.spottingType}>
{g.spottingType
? de.pages.gerbils.spottingTypes[
g.spottingType as keyof typeof de.pages.gerbils.spottingTypes
] || g.spottingType
: de.pages.gerbils.spottingTypes.notRecorded}
</Kv>
);
})()}
{showEnclosure && (
<Kv label={t.fields.enclosure}>{lookup(enclosureName, g.enclosureId)}</Kv>
)}

View File

@@ -204,6 +204,7 @@ export const de = {
},
spottingTypes: {
none: '— keine Scheckungsart —',
notRecorded: 'noch nicht erfasst',
Punktschecke: 'Punktschecke',
Kragenschecke: 'Kragenschecke',
Ansatzschecke: 'Ansatzschecke',