Importer consumes conflict-decisions.json to un-quarantine (HUMANQUESTION D)

god maintains tools/import/conflict-decisions.json as Julian/his wife answer
the D-conflicts. extract.py now consumes it (apply_conflict_decisions): for an
animal matching normalize(name)+dob, it clears the conflict, marks
resolvedByDecision, and — when the decision carries a `genotype` (breeder
notation, parsed via genotype.py) and/or `farbschlag` — treats those as
AUTHORITATIVE. Tolerates a missing/empty/garbled file. Genuinely-unresolved
conflicts stay quarantined.

Loader (ImportService): SourceAnimal.ResolvedByDecision flows through; the
report surfaces Animals.ConflictsResolvedByDecision + a German note.

Result on real data: the 2 current decisions (Firefly D-/PP, WildFire PP)
un-quarantine → Konflikte 21 → 19. As god appends entries the count grows;
nothing else needed from me.

Tests: python test_extract (decision clears conflict + genotype authoritative
+ removes from conflicts list + tolerates missing file) and a C# loader test
(a resolved animal loads and is counted). Folded into the EXTRACT-BANDS branch
so the next re-extract applies band-aware Farbschlag + these decisions in one
pass. No schema change (JSON DTO fields). python + dotnet 121/121 green;
has-pending clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-06 11:55:45 +02:00
parent 4aca1d528b
commit df13136955
6 changed files with 101 additions and 7 deletions

View File

@@ -404,6 +404,9 @@ namespace GerbilManagerWebAPI.Import
notes.Add($"Stammbaum-Diagramm: {parentLinksAdded} Tiere über Eltern-Verknüpfung einem (abgeleiteten) Wurf zugeordnet ({derivedLitters} abgeleitete Würfe).");
notes.Add($"FK-Integrität: {litterParentFksDropped} Eltern-Verknüpfung(en) verworfen (Elternteil nicht ladbar), {derivedLittersSkipped} abgeleitete Würfe übersprungen (kein ladbares Elternteil). Bei 0/0 ist /import/execute FK-sicher.");
notes.Add($"Bestand/Herkunft: {residentTotal} im Bestand (Clan Kleine Chaoten), {externalTotal} externe Ahnen ({flippedByParentRule} davon über die Eltern-Regel als Bestand erkannt).");
int conflictsResolvedByDecision = loadable.Count(a => a.ResolvedByDecision);
if (conflictsResolvedByDecision > 0)
notes.Add($"Konfliktauflösungen: {conflictsResolvedByDecision} Tier(e) anhand von conflict-decisions.json un-quarantänet (Genotyp/Farbschlag der Züchterin ist maßgeblich).");
if (!execute) notes.Add("DRY-RUN: nichts gespeichert. /import/execute lädt die konfliktfreien Daten.");
return new ImportReport(
@@ -412,7 +415,7 @@ namespace GerbilManagerWebAPI.Import
Animals: new AnimalSummary(
animals.Count, animalsCreated, linked, fbMatched, fbUnmatched, animalsExisting,
new QuarantineSummary(conflicts, stubs, dateOnly, ambiguous, conflicts + stubs),
parentLinksAdded),
parentLinksAdded, conflictsResolvedByDecision),
Photos: new PhotoSummary(photosAttached, photosMissing),
Samples: samples,
Notes: notes,