# Document Schema-to-UI Mapping

Purpose: Map the Document 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: Document
- Primary key: `id` (UUID)
- Related entities: `Source`, `Job`, `DocumentPerson`, `Person`
- 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 |
| name | str | No | None | Shown, editable on create and edit | Required |
| document_type | str | Yes | None | Shown, editable on create and edit | Required by intended UX |
| document_date | date | Yes | None | Shown, editable | Canonical exact date when present |
| document_date_raw | str | Yes | None | Shown, editable | Approximate or unknown date text |
| location_created | str | Yes | None | Shown, editable | Optional metadata |
| notes | str | Yes | None | Shown, editable | Optional metadata |
| archive_identifier | str | Yes | None | Shown, editable | Free text in first release |
| 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: Document page  
User action: Create new document  
Success destination: new Document detail page

| Field | Intended User Input | Required | Visible | Notes |
|---|---|---|---|---|
| name | Text input | Yes | Yes | Primary identifier used by the user |
| document_type | Text input | Yes | Yes | Free text in first release |
| document_date | Date input | No | Yes | Structured exact date |
| document_date_raw | Text input | No | Yes | Approximate or uncertain date |
| location_created | Text input | No | Yes | Optional |
| notes | Text area | No | Yes | Optional |
| archive_identifier | Text input | No | Yes | Free text |
| created_at | None | No | No | System-generated |
| updated_at | None | No | No | Not used during initial create |

Related records during intended create:
- A related person may optionally be selected or created.
- If present, the system creates a `DocumentPerson` link.
- Jobs are not created during Document create.
- Sources are not created during Document create.

### 4.2 Current Implementation

Current entry point: `/documents` page  
Current user action: open create form, fill metadata, optionally select an existing Person  
Current backend path: document page submit callback -> `DocumentService.create_document()` -> optional `DocumentService.create_document_person()`

| Field | Current Value at Create | Source | Visible to User | Evidence |
|---|---|---|---|---|
| id | Generated UUID | System | No | `Document` default factory in `src/transcription/db/models.py` |
| name | User-provided | User input | Yes | `src/transcription/ui/pages/documents_page.py` |
| document_type | User-provided or None | User input | Yes | `src/transcription/ui/pages/documents_page.py` |
| document_date | Parsed from date input or None | User input | Yes | `src/transcription/ui/pages/documents_page.py` |
| document_date_raw | User-provided or None | User input | Yes | `src/transcription/ui/pages/documents_page.py` |
| location_created | User-provided or None | User input | Yes | `src/transcription/ui/pages/documents_page.py` |
| notes | User-provided or None | User input | Yes | `src/transcription/ui/pages/documents_page.py` |
| archive_identifier | User-provided or None | User input | Yes | `src/transcription/ui/pages/documents_page.py` |
| created_at | Current UTC timestamp | System | No | Default factory in `src/transcription/db/models.py` |
| updated_at | Current UTC timestamp | System | No | Default factory in `src/transcription/db/models.py` |

Current related-record behavior:
- User may optionally select an existing `Person`.
- If selected, `DocumentPerson` is created with role `author`.
- `Job` is not created during Document create.
- `Source` is not created during Document create.

### 4.3 Gap to Target

To satisfy the intended Create flow, implementation now includes:
1. a Document page and dedicated create form
2. user-entered metadata fields for `document_type`, `document_date`, `document_date_raw`, `location_created`, `notes`, and `archive_identifier`
3. optional Person lookup through a dropdown of existing people
4. optional `DocumentPerson` link creation when a person is chosen
5. post-submit routing to a Document detail page

## 5. READ Mapping

### 5.1 Intended Read Behavior

On the Document detail page, the user should be able to see:
1. Document metadata
2. linked people
3. a Sources section with empty-state behavior when no sources exist
4. a Jobs section with empty-state behavior when no jobs exist
5. filtered Jobs and Sources views for the current document

### 5.2 Current Implementation

Current Document visibility in the UI is direct.

| Field | Current Rendering | Visible to User | Notes | Evidence |
|---|---|---|---|---|
| name | Rendered as title and detail heading | Yes | Dedicated Document detail page | `src/transcription/ui/pages/documents_page.py` |
| id | Not shown as raw id | No | Internal identifier remains hidden | `src/transcription/ui/pages/documents_page.py` |
| document_type | Rendered | Yes | Shown on detail and editable on create/edit | `src/transcription/ui/pages/documents_page.py` |
| document_date | Rendered | Yes | Exact date shown when present | `src/transcription/ui/pages/documents_page.py` |
| document_date_raw | Rendered | Yes | Approximate date shown when present | `src/transcription/ui/pages/documents_page.py` |
| location_created | Rendered | Yes | Optional metadata shown | `src/transcription/ui/pages/documents_page.py` |
| notes | Rendered | Yes | Optional metadata shown | `src/transcription/ui/pages/documents_page.py` |
| archive_identifier | Rendered | Yes | Optional metadata shown | `src/transcription/ui/pages/documents_page.py` |
| created_at | Rendered read-only | Yes | System timestamp shown on detail | `src/transcription/ui/pages/documents_page.py` |
| updated_at | Rendered read-only | Yes | System timestamp shown on detail | `src/transcription/ui/pages/documents_page.py` |

### 5.3 Gap to Target

To satisfy the intended Read flow, implementation now includes:
1. metadata rendering for Document fields
2. linked people rendering
3. document-scoped Sources and Jobs navigation views

## 6. UPDATE Mapping

### 6.1 Intended Update Behavior

The user should eventually be able to edit Document metadata from the Document detail page or a dedicated edit flow.

Intended editable fields:
- `name`
- `document_type`
- `document_date`
- `document_date_raw`
- `location_created`
- `notes`
- `archive_identifier`

Intended system-managed fields:
- `id`
- `created_at`
- `updated_at`

### 6.2 Current Implementation

| Field | Updatable via UI | Updatable via Service | Notes |
|---|---|---|---|
| id | No | Practically no | Primary key should be treated as immutable |
| name | Yes | Yes | Editable from dedicated document edit page via `DocumentService.update_document()` |
| document_type | Yes | Yes | Editable from dedicated document edit page via `DocumentService.update_document()` |
| document_date | Yes | Yes | Editable from dedicated document edit page via `DocumentService.update_document()` |
| document_date_raw | Yes | Yes | Editable from dedicated document edit page via `DocumentService.update_document()` |
| location_created | Yes | Yes | Editable from dedicated document edit page via `DocumentService.update_document()` |
| notes | Yes | Yes | Editable from dedicated document edit page via `DocumentService.update_document()` |
| archive_identifier | Yes | Yes | Editable from dedicated document edit page via `DocumentService.update_document()` |
| 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. Document edit controls in the UI
2. validation and save behavior for Document metadata
3. author relationship controls through the edit flow

## 7. DELETE Mapping

### 7.1 Intended Delete Behavior

The UI should eventually provide a delete action for Document with guardrails.

Rules:
1. A Document can be deleted when it has no attached Jobs and no attached Sources.
2. If dependent Jobs or Sources exist, the UI should block deletion and explain that those related records must be removed first.
3. Delete confirmation should make it clear that the action is permanent.

### 7.2 Current Implementation

| Action | UI Exposed | Backend Capability | Notes |
|---|---|---|---|
| Delete Document | Yes | Yes | `DocumentService.delete_document()` exists and the UI blocks dependent deletes |

### 7.3 Gap to Target

Implementation includes:
1. a Document delete control in the UI
2. pre-delete dependency checks for Jobs and Sources
3. user-facing messaging when deletion is blocked
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 |

## 9. Traceability Anchors

Schema and models:
- `docs/schema_v2.md`
- `src/transcription/db/models.py`

Current implementation:
- `src/transcription/ui/pages/documents_page.py`
- `src/transcription/services/documents.py`
- `src/transcription/services/store.py`
- `src/transcription/ui/pages/jobs_page.py`
- `src/transcription/ui/components/transcript.py`

Companion UX spec:
- `docs/ui/entities/document/user-journey.md`

## 10. Acceptance Checklist Summary

- Every Document schema field appears in the field inventory.
- Intended Create behavior matches the companion user journey.
- Current Create behavior reflects the existing upload-driven implementation.
- Gaps between intended and current behavior are explicit.
- Read, Update, and Delete sections distinguish target behavior from current code.
