5824e70895
Duplicate detection (the "merge / skip / overwrite" the user asked for):
- New POST /gedcom/preview dry-runs the file and flags incoming people that
resemble existing ones (name similarity via difflib + birth-year guard;
high/medium score). No writes.
- /gedcom/import takes default_action (new|skip|merge|overwrite) + per-xref
resolutions {xref: {action, target_id}}:
new create as a new person (current behavior)
skip link families to the existing person, copy nothing
merge attach the incoming names (as alternates), events, citations,
and notes onto the existing person
overwrite soft-delete the existing person, import the incoming one fresh
Relationship creation is deduped so a merge can't double an edge.
Richer record mapping (covers the user's repo's GEDCOM):
- Multiple NAME records honor their TYPE; _MARNM (and NICK) import as typed
alternate names — maiden stays primary, married becomes a "married" Name.
- RELI -> a "religion" event with the value in detail; OCCU/EDUC values too.
- NOTE -> person notes (and event notes); NOTE/RELI are no longer "unmapped".
- Export round-trips name TYPE.
Verified against the user's 2185-person export: 0 unmapped tags. 48 tests pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
26 lines
597 B
Python
26 lines
597 B
Python
import uuid
|
|
|
|
from pydantic import BaseModel
|
|
|
|
|
|
class ImportReport(BaseModel):
|
|
counts: dict[str, int]
|
|
unmapped_tags: list[str]
|
|
|
|
|
|
class DuplicateMatch(BaseModel):
|
|
# An incoming GEDCOM person that resembles an existing one in the tree.
|
|
xref: str
|
|
incoming_name: str
|
|
incoming_birth_year: str | None = None
|
|
existing_person_id: uuid.UUID
|
|
existing_name: str
|
|
existing_birth_year: str | None = None
|
|
score: str # "high" | "medium"
|
|
|
|
|
|
class ImportPreview(BaseModel):
|
|
counts: dict[str, int]
|
|
potential_duplicates: list[DuplicateMatch]
|
|
unmapped_tags: list[str]
|