Files
transcription/docs/ui/entities/person/schema-mapping.md
T

264 lines
12 KiB
Markdown

# Person Schema-to-UI Mapping
Purpose: Map the Person schema to the UI, while clearly separating intended target behavior from current implementation.
Companion document: user-journey.md
Acceptance criteria: acceptance-criteria.md
## 1. Entity Snapshot
- Table: Person
- Primary key: id (UUID)
- Related entities: DocumentPerson, Document
- Canonical schema references:
- src/transcription/db/models.py
- docs/schema_v2.md
## 2. Mapping Rules
This document uses three lenses:
1. Intended behavior: what the UX should support.
2. Current behavior: what the code supports today.
3. Gap to target: what must change to align implementation with the intended UX.
## 3. Field Inventory
| Field | DB Type | Nullable | Default/Auto Value | Intended UI Treatment | Notes |
|---|---|---|---|---|---|
| id | UUID | No | uuid4() | Hidden, system-managed | Primary key |
| full_name | str | No | None | Shown, editable on create and update | Required canonical name |
| display_name | str | Yes | None | Shown, editable | Optional |
| maiden_name | str | Yes | None | Shown, editable | Optional |
| birth_date | date | Yes | None | Shown, editable | Canonical exact date when present |
| birth_date_raw | str | Yes | None | Shown, editable | Approximate or unknown date text |
| birth_place | str | Yes | None | Shown, editable | Optional |
| death_date | date | Yes | None | Shown, editable | Canonical exact date when present |
| death_date_raw | str | Yes | None | Shown, editable | Approximate or unknown date text |
| death_place | str | Yes | None | Shown, editable | Optional |
| biography | str | Yes | None | Shown, editable | Optional narrative |
| portrait_path | str | Yes | None | Shown, editable | Optional path |
| metadata_ | JSONB/JSON | Yes | None | Hidden in first release | Advanced metadata |
| created_at | datetime | No | datetime.now(UTC) | Hidden or read-only | System-managed |
| updated_at | datetime | No | datetime.now(UTC) | Hidden or read-only | System-managed |
## 4. CREATE Mapping
### 4.1 Intended Create Flow
Entry point: Person page
User action: Create new person
Success destination: new Person detail page
| Field | Intended User Input | Required | Visible | Notes |
|---|---|---|---|---|
| full_name | Text input | Yes | Yes | Canonical identity field |
| display_name | Text input | No | Yes | Optional |
| maiden_name | Text input | No | Yes | Optional |
| birth_date | Date input | No | Yes | Structured exact date |
| birth_date_raw | Text input | No | Yes | Approximate/uncertain date |
| birth_place | Text input | No | Yes | Optional |
| death_date | Date input | No | Yes | Structured exact date |
| death_date_raw | Text input | No | Yes | Approximate/uncertain date |
| death_place | Text input | No | Yes | Optional |
| biography | Text area | No | Yes | Optional |
| portrait_path | Text input | No | Yes | Optional |
| metadata_ | None | No | No | Hidden in first release |
| created_at | None | No | No | System-generated |
| updated_at | None | No | No | Not user-entered |
Related records during intended create:
- No DocumentPerson link is required during Person creation.
- Document linking can be done later from Document or Person workflows.
### 4.2 Current Implementation
Current entry point: no dedicated Person UI page yet
Current user action: none in UI
Current backend path: service calls via DocumentService.create_person()
| Field | Current Value at Create | Source | Visible to User | Evidence |
|---|---|---|---|---|
| id | Generated UUID | System | No | Person model default factory in src/transcription/db/models.py |
| full_name | Caller-provided | Service/API caller | No | create_person() in src/transcription/services/documents.py |
| display_name | Caller-provided or None | Service/API caller | No | create_person() in src/transcription/services/documents.py |
| maiden_name | Caller-provided or None | Service/API caller | No | create_person() in src/transcription/services/documents.py |
| birth_date | Caller-provided or None | Service/API caller | No | create_person() in src/transcription/services/documents.py |
| birth_date_raw | Caller-provided or None | Service/API caller | No | create_person() in src/transcription/services/documents.py |
| birth_place | Caller-provided or None | Service/API caller | No | create_person() in src/transcription/services/documents.py |
| death_date | Caller-provided or None | Service/API caller | No | create_person() in src/transcription/services/documents.py |
| death_date_raw | Caller-provided or None | Service/API caller | No | create_person() in src/transcription/services/documents.py |
| death_place | Caller-provided or None | Service/API caller | No | create_person() in src/transcription/services/documents.py |
| biography | Caller-provided or None | Service/API caller | No | create_person() in src/transcription/services/documents.py |
| portrait_path | Caller-provided or None | Service/API caller | No | create_person() in src/transcription/services/documents.py |
| metadata_ | Caller-provided or None | Service/API caller | No | Person model in src/transcription/db/models.py |
| created_at | Current UTC timestamp | System | No | Person model default in src/transcription/db/models.py |
| updated_at | Current UTC timestamp | System | No | Person model default in src/transcription/db/models.py |
### 4.3 Gap to Target
To satisfy the intended Create flow, implementation must add:
1. a Person page and dedicated create form
2. user-entered controls for Person fields
3. create validation and success/failure UX states
4. post-submit routing to a Person detail page
## 5. READ Mapping
### 5.1 Intended Read Behavior
On the Person detail page, the user should be able to see:
1. Person identity and biographical metadata
2. linked Documents (through DocumentPerson)
3. empty-state behavior when no linked documents exist
### 5.2 Current Implementation
Current Person visibility in the UI is not implemented as a dedicated page.
| Field | Current Rendering | Visible to User | Notes | Evidence |
|---|---|---|---|---|
| full_name | Rendered in header and summary | Yes | Dedicated Person page exists | `src/transcription/ui/pages/people_page.py` |
| display_name | Not rendered | No | No current Person page | no Person page in src/transcription/ui |
| maiden_name | Not rendered | No | No current Person page | no Person page in src/transcription/ui |
| birth_date | Not rendered | No | No current Person page | no Person page in src/transcription/ui |
| birth_date_raw | Not rendered | No | No current Person page | no Person page in src/transcription/ui |
| birth_place | Not rendered | No | No current Person page | no Person page in src/transcription/ui |
| death_date | Not rendered | No | No current Person page | no Person page in src/transcription/ui |
| death_date_raw | Not rendered | No | No current Person page | no Person page in src/transcription/ui |
| death_place | Not rendered | No | No current Person page | no Person page in src/transcription/ui |
| biography | Not rendered | No | No current Person page | no Person page in src/transcription/ui |
| portrait_path | Rendered as text and image when available | Yes | Dedicated Person page exists | `src/transcription/ui/pages/people_page.py` |
| metadata_ | Not rendered | No | Hidden advanced field | no current UI field |
| created_at | Not rendered | No | No current Person page | no Person page in src/transcription/ui |
| updated_at | Not rendered | No | No current Person page | no Person page in src/transcription/ui |
### 5.3 Gap to Target
To satisfy the intended Read flow, implementation now includes:
1. metadata rendering for Person fields
2. linked Documents section with empty states
3. document-link navigation paths
## 6. UPDATE Mapping
### 6.1 Intended Update Behavior
The user should be able to edit Person metadata from the Person detail page or a dedicated edit flow.
Intended editable fields:
- full_name
- display_name
- maiden_name
- birth_date
- birth_date_raw
- birth_place
- death_date
- death_date_raw
- death_place
- biography
- portrait_path
Intended system-managed fields:
- id
- created_at
- updated_at
Hidden in first release:
- metadata_
### 6.2 Current Implementation
| Field | Updatable via UI | Updatable via Service | Notes |
|---|---|---|---|
| id | No | Practically no | Primary key should be treated as immutable |
| full_name | No | Yes | DocumentService.update_person() |
| display_name | No | Yes | DocumentService.update_person() |
| maiden_name | No | Yes | DocumentService.update_person() |
| birth_date | No | Yes | DocumentService.update_person() |
| birth_date_raw | No | Yes | DocumentService.update_person() |
| birth_place | No | Yes | DocumentService.update_person() |
| death_date | No | Yes | DocumentService.update_person() |
| death_date_raw | No | Yes | DocumentService.update_person() |
| death_place | No | Yes | DocumentService.update_person() |
| biography | No | Yes | DocumentService.update_person() |
| portrait_path | No | Yes | DocumentService.update_person() |
| metadata_ | No | Yes | Technically updatable, hidden in first release |
| created_at | No | Technically yes | Should remain system-managed |
| updated_at | No | Technically yes | Should remain system-managed |
### 6.3 Gap to Target
Implementation now includes:
1. Person edit controls in the UI
2. validation and save behavior for Person metadata
3. a consistent updated_at update policy for Person edits
## 7. DELETE Mapping
### 7.1 Intended Delete Behavior
The UI should provide a delete action for Person with guardrails.
Rules:
1. Deletion can proceed when relationship policy allows no retained document links.
2. If linked DocumentPerson records exist and policy requires cleanup first, deletion is blocked.
3. Delete confirmation must make clear that deletion is permanent.
### 7.2 Current Implementation
| Action | UI Exposed | Backend Capability | Notes |
|---|---|---|---|
| Delete Person | No | Yes | DocumentService.delete_person() exists, but no dedicated UI guard flow exists |
### 7.3 Gap to Target
Implementation must add:
1. a Person delete control in the UI
2. relationship-aware pre-delete checks
3. user-facing blocked-delete messaging
4. confirmation UX for successful delete attempts
## 8. Hidden and System-Managed Fields
| Field | Category | Why Hidden or Protected |
|---|---|---|
| id | System-managed | Internal identifier |
| created_at | System-managed | Audit timestamp |
| updated_at | System-managed | Audit timestamp |
| metadata_ | Hidden in first release | Advanced JSON metadata not needed in initial UI |
## 9. Structured Name Deferred Note
Structured name fields are deferred to a future schema revision.
Current policy:
1. full_name remains canonical and required.
Future revision intent:
1. introduce first_name, middle_name, last_name, and optional suffix fields.
2. maintain compatibility with existing full_name records during migration.
3. define normalization and reconciliation rules when structured and canonical forms differ.
## 10. Traceability Anchors
Schema and models:
- docs/schema_v2.md
- src/transcription/db/models.py
Current implementation:
- src/transcription/services/documents.py
- src/transcription/ui (no dedicated Person pages yet)
Companion UX spec:
- docs/ui/entities/person/user-journey.md
Acceptance checklist:
- docs/ui/entities/person/acceptance-criteria.md
## 11. Acceptance Checklist Summary
- Every Person schema field appears in the field inventory.
- Intended Create behavior matches the companion user journey.
- Current Create behavior reflects service-level implementation.
- Gaps between intended and current behavior are explicit.
- Read, Update, and Delete sections distinguish target behavior from current code.