feat(import): isResident-Override + Vorfahren Bentley/Alexandria/Bugatti
- Neuer isResident-Override im Import (merge_and_resolve, NACH dem Dedup, damit die Zusammenführung ihn nicht überschreibt). Matcht über externalRef (präzise, auch für namenlose Tiere) oder normalize(call-name)+dob. Ein Nicht-Bestandstier verliert den eigenen Zucht-Breeder. - conflict-decisions.json: Bentley, Alexandria, Bugatti = nur Vorfahren (isResident=false), bestätigt von der Züchterin (Tickets 09bcac78 / 45cc501b). - Regressionstests ergänzt/aktualisiert (Bentley/Alexandria/Bugatti isResident; Danielle Vater Makoto; Catelyn Eddard×Milena; Gaida Zhuāngzǐ×Zaibunissa). Alle python test_*.py grün. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -3016,6 +3016,51 @@ def main():
|
||||
|
||||
print(f"Deduplicated to {len(resolved_gerbils)} unique gerbil records.")
|
||||
|
||||
# ── isResident-Overrides (Mensch-Entscheidung) ────────────────────────────
|
||||
# NACH dem Dedup anwenden, sonst würde die Dedup-Zusammenführung (IsResident=True
|
||||
# falls eine Variante resident ist) sie wieder überschreiben. Matcht primär über
|
||||
# `externalRef` (präzise, auch für namenlose Tiere) oder sonst über
|
||||
# normalize(call-name)+ISO-dob (leere dob = name-only, für Vorfahren ohne Datum).
|
||||
_isres_by_extref = {}
|
||||
_isres_by_namedob = {}
|
||||
for d in _decisions:
|
||||
if "isResident" not in d:
|
||||
continue
|
||||
val = bool(d["isResident"])
|
||||
er = (d.get("externalRef") or "").strip()
|
||||
if er:
|
||||
_isres_by_extref[er] = val
|
||||
nm = d.get("name")
|
||||
if nm is not None:
|
||||
ck = normalize_name(get_call_name(nm or ""))
|
||||
iso = parse_date(d.get("dob")) if d.get("dob") else ""
|
||||
_isres_by_namedob[(ck, iso or "")] = val
|
||||
_isres_applied = 0
|
||||
if _isres_by_extref or _isres_by_namedob:
|
||||
for g in resolved_gerbils:
|
||||
er = g.get("ExternalRef") or ""
|
||||
ck = normalize_name(get_call_name(g.get("Name") or ""))
|
||||
iso = g.get("DateOfBirth") or ""
|
||||
if er and er in _isres_by_extref:
|
||||
val = _isres_by_extref[er]
|
||||
elif er and any(er.endswith(k) for k in _isres_by_extref):
|
||||
val = next(v for k, v in _isres_by_extref.items() if er.endswith(k))
|
||||
elif (ck, iso) in _isres_by_namedob:
|
||||
val = _isres_by_namedob[(ck, iso)]
|
||||
elif (ck, "") in _isres_by_namedob:
|
||||
val = _isres_by_namedob[(ck, "")]
|
||||
else:
|
||||
continue
|
||||
if g.get("IsResident") != val:
|
||||
g["IsResident"] = val
|
||||
# Ein Nicht-Bestandstier ist kein eigenes Zuchttier → den eigenen
|
||||
# Zucht-Breeder entfernen (nur, wenn er auf die eigene Zucht zeigt).
|
||||
if not val and g.get("OriginBreeder") == "Zucht der kleinen Chaoten":
|
||||
g["OriginBreeder"] = None
|
||||
_isres_applied += 1
|
||||
if _isres_applied:
|
||||
print(f"isResident-Overrides angewandt: {_isres_applied}")
|
||||
|
||||
# Apply age-based death threshold (6.0 years) to all resolved gerbils
|
||||
dt_now = datetime.now()
|
||||
for g in resolved_gerbils:
|
||||
|
||||
Reference in New Issue
Block a user