# People Page Contract ## Purpose People manages reusable historical-person records. A Person may appear in many Documents under different relationship roles and may optionally carry one or more photos plus a FamilySearch identifier. ## Routes | Route | Purpose | | --- | --- | | `/people` | Searchable People list. | | `/people/new` | Create a Person. | | `/people/{person_id}` | View one Person and linked Documents. | | `/people/{person_id}/photos` | Manage Person photos. | | `/people/{person_id}/edit` | Edit the Person. | | `/people/{person_id}/delete` | Confirm permanent deletion. | ## List Behavior - The title is **Archival Entities: People**. - **Create new person** opens the create route. - The table defaults to Name order (`Last Name, First & Middle`) and supports search and column sorting. - Columns are Last Name, First & Middle; Tags; FamilySearch ID; Birth Date; Death Date; and # Documents. - Name and Tags are left-aligned; FamilySearch ID, date columns, and # Documents are centered. - # Documents reflects how many linked Documents each Person is connected to. - Birth and death values independently prefer exact date, then approximate date, then `Unknown`. - Selecting a row opens Person Detail. - No records displays `No person records found in repository.` ## Create and Edit Behavior Required: - Last name. - First & middle names. Optional: - Exact and approximate birth/death dates. - Birth/death places. - Biography. - FamilySearch ID. - Tags. Rules: - Missing last name or first/middle names blocks save with a warning. - Exact date inputs are native browser date inputs. - FamilySearch IDs are normalized and validated by `PeopleService`. - Tags use the shared Tag registry and support inline add/select behavior. - Photos are managed from Person Detail via `/people/{person_id}/photos` (not in create/edit form fields). - Metadata JSON remains hidden. - Save success returns to Person Detail. ## Detail Behavior - The header provides **New Document**, **Edit Person**, **Edit Photo(s)**, and **Delete**. - **New Document** opens Document creation with this Person requested for author preselection. - Person Detail shows a single-photo viewer with **Previous/Next** navigation; the page-level **Edit Photo(s)** header action opens photo management. - Photo management (upload, description edit, set-primary, delete) is intentionally moved to `/people/{person_id}/photos`. - Biographical Record shows split names, computed full name, tags, compact birth/death dates, and places. - Birth and death place values are clickable links to Google Maps when present. - FamilySearch ID is shown as a metadata value and is clickable to the FamilySearch person details route when present. - Biography has an explicit empty value. - Linked Documents render as a table with **Document Name**, **Role**, and **Number of Pages**; selecting a row opens Document Detail. - No links shows both an empty state and guidance to link from a Document workflow. - System Logistics shows created and updated timestamps. ## Delete Behavior - The page warns when linked Document relationships exist. - Delete is blocked when related Photos exist. - Confirmed deletion removes the Person and its relationship links; it does not delete Documents. - Success returns to the People list. - Missing or already-deleted records return to a safe list state. ## Photo Gallery Behavior (`/people/{person_id}/photos`) - Upload is triggered from a header-level **Upload Photo(s)** control beside **Back to Person**. - The gallery renders all photos in a responsive grid (3-4 tiles wide on larger screens). - Description text is shown as an overlay at the bottom of each image for quick context. - The editor provides **Save Description**, **Set Primary** (when applicable), and **Delete Photo** actions. ## Acceptance Checklist - List fields, alignment, date fallback, search, sorting, and navigation match this contract. - Last name and first/middle names are enforced on create and edit. - FamilySearch ID validation and link generation use the fixed supported identifier format. - Photo upload and rendering remain constrained to supported media paths. - New Document carries the Person context. - Linked Documents show the correct role and target. - Delete wording distinguishes removal of relationship links from deletion of Documents. ## Implementation Anchors - `src/transcription/ui/pages/people_page.py` - `src/transcription/ui/components/table/people.py` - `src/transcription/services/people.py` - `tests/ui/test_people_page.py` - `tests/services/test_v2_crud.py` ## Deferred Work - Structured name fields, merge/deduplication, advanced metadata editing, and Person-side relationship editing are not current behavior.