V5.1 Modify Person table: split full name into first & last, added tags support
Quality Gate / gate (push) Failing after 11s

This commit is contained in:
Jim Lancaster
2026-08-23 12:23:57 -05:00
parent 141ee1fa85
commit ae3483ec2e
28 changed files with 555 additions and 145 deletions
+33 -9
View File
@@ -13,6 +13,7 @@ from transcription.db.models import DocumentPerson
from transcription.db.models import DocumentTag
from transcription.db.models import Job
from transcription.db.models import Person
from transcription.db.models import PersonTag
from transcription.db.models import Source
from transcription.db.models import Tag
from transcription.db.models import Photo
@@ -132,7 +133,7 @@ async def test_delete_document_removes_person_links(default_session_factory, tmp
name="person-linked-delete",
)
)
person = await people_service.create_person(Person(full_name="Linked Person"))
person = await people_service.create_person(Person(given_names="Linked", last_name="Person"))
author_role = await people_service.create_person_role(label="Author")
await people_service.create_document_person(
DocumentPerson(
@@ -197,7 +198,7 @@ async def test_read_person_detail_loads_document_links(default_session_factory):
name="linked-doc",
)
)
person = await people_service.create_person(Person(full_name="Linked Person"))
person = await people_service.create_person(Person(given_names="Linked", last_name="Person"))
author_role = await people_service.create_person_role(label="Author")
await people_service.create_document_person(
DocumentPerson(
@@ -221,16 +222,17 @@ async def test_update_person_refreshes_updated_timestamp(default_session_factory
created = await service.create_person(
Person(
full_name="timestamp-person",
given_names="timestamp",
last_name="person",
updated_at=datetime(2000, 1, 1, tzinfo=UTC),
)
)
original_updated_at = created.updated_at
created.display_name = "updated"
created.given_names = "updated"
updated = await service.update_person(created)
assert updated.display_name == "updated"
assert updated.given_names == "updated"
assert updated.updated_at >= original_updated_at
@@ -245,7 +247,7 @@ async def test_delete_person_removes_links_when_linked_documents_exist(default_s
name="block-person-delete-doc",
)
)
person = await service.create_person(Person(full_name="Blocked Person"))
person = await service.create_person(Person(given_names="Blocked", last_name="Person"))
author_role = await service.create_person_role(label="Author")
await service.create_document_person(
DocumentPerson(
@@ -268,7 +270,7 @@ async def test_delete_person_removes_links_when_linked_documents_exist(default_s
async def test_delete_person_succeeds_when_unlinked(default_session_factory):
service = PeopleService(session_factory=default_session_factory)
person = await service.create_person(Person(full_name="Free Person"))
person = await service.create_person(Person(given_names="Free", last_name="Person"))
await service.delete_person(person)
@@ -280,7 +282,7 @@ async def test_delete_person_succeeds_when_unlinked(default_session_factory):
async def test_delete_person_blocks_when_photos_exist(default_session_factory):
service = PeopleService(session_factory=default_session_factory)
person = await service.create_person(Person(full_name="Photo Protected Person"))
person = await service.create_person(Person(given_names="Photo Protected", last_name="Person"))
async with service._session_scope() as session:
session.add(
Photo(
@@ -313,7 +315,7 @@ async def test_update_document_person_changes_role_id(default_session_factory):
service = PeopleService(session_factory=default_session_factory)
document = await documents_service.create_document(Document(id=uuid4(), name="role-sync-doc"))
person = await service.create_person(Person(full_name="Role Sync Person"))
person = await service.create_person(Person(given_names="Role Sync", last_name="Person"))
author_role = await service.create_person_role(label="Author")
recipient_role = await service.create_person_role(label="Recipient")
link = await service.create_document_person(
@@ -357,3 +359,25 @@ async def test_sync_document_tags_by_labels_creates_and_replaces_tags(default_se
assert len(listed) == 1
listed_labels = {link.tag_ref.label for link in listed[0].document_tags if link.tag_ref is not None}
assert listed_labels == {"Census", "Research"}
@pytest.mark.asyncio
async def test_sync_person_tags_by_labels_creates_and_replaces_tags(default_session_factory):
people = PeopleService(session_factory=default_session_factory)
person = await people.create_person(Person(given_names="Tagged", last_name="Person"))
await people.sync_person_tags_by_labels(person_id=person.id, labels=["Family", "Census"])
await people.sync_person_tags_by_labels(person_id=person.id, labels=["Census", "Research"])
async with people._session_scope() as session:
links = (await session.exec(select(PersonTag).where(PersonTag.person_id == person.id))).all()
tags = (await session.exec(select(Tag))).all()
assert len(links) == 2
linked_ids = {link.tag_id for link in links}
linked_labels = {tag.label for tag in tags if tag.id in linked_ids}
assert linked_labels == {"Census", "Research"}
detail = await people.read_person_detail(person.id)
listed_labels = {link.tag_ref.label for link in detail.person_tags if link.tag_ref is not None}
assert listed_labels == {"Census", "Research"}