10 KiB
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 - Canonical schema references:
src/transcription/db/models.pydocs/schema_v2.md
2. Mapping Rules
This document uses three lenses:
- Intended behavior: what the UX should support.
- Current behavior: what the code supports today.
- 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 future edit | Required |
| document_type | str | Yes | None | Shown, editable on create and future 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
DocumentPersonlink. - Jobs are not created during Document create.
- Sources are not created during Document create.
4.2 Current Implementation
Current entry point: upload page
Current user action: upload file via upload widget
Current backend path: upload page submit callback -> create_upload_job() -> _create_upload_records()
| 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 | Basename of uploaded filename | User file name transformed by service | Indirectly | Set in src/transcription/services/store.py |
| document_type | None |
Service default | No | Not set in src/transcription/services/store.py |
| document_date | None |
Service default | No | Not set in src/transcription/services/store.py |
| document_date_raw | None |
Service default | No | Not set in src/transcription/services/store.py |
| location_created | None |
Service default | No | Not set in src/transcription/services/store.py |
| notes | None |
Service default | No | Not set in src/transcription/services/store.py |
| archive_identifier | None |
Service default | No | Not set in src/transcription/services/store.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:
Jobis created automatically.Sourceis created automatically.JobSourceis created automatically.- No
PersonorDocumentPersonrecords are created.
4.3 Gap to Target
To satisfy the intended Create flow, implementation must add:
- a Document page and dedicated create form
- user-entered metadata fields for
document_type,document_date,document_date_raw,location_created,notes, andarchive_identifier - optional Person lookup and inline Person creation
- optional
DocumentPersonlink creation when a person is chosen - post-submit routing to a Document detail page
- removal of the assumption that Document creation always starts with file upload
5. READ Mapping
5.1 Intended Read Behavior
On the Document detail page, the user should be able to see:
- Document metadata
- linked people
- a Sources section with empty-state behavior when no sources exist
- a Jobs section with empty-state behavior when no jobs exist
- future links to filtered Jobs and Sources views for the current document
5.2 Current Implementation
Current Document visibility in the UI is indirect.
| Field | Current Rendering | Visible to User | Notes | Evidence |
|---|---|---|---|---|
| name | Indirect filename context in jobs list and job detail | Yes, indirect | The UI shows source/job filename, not a dedicated Document page | src/transcription/ui/pages/jobs_page.py, src/transcription/ui/components/table/jobs.py |
| id | Not shown as Document id | No | Job id is shown instead | src/transcription/ui/pages/jobs_page.py |
| document_type | Not rendered | No | Hidden metadata | no current UI field |
| document_date | Not rendered | No | Hidden metadata | no current UI field |
| document_date_raw | Not rendered | No | Hidden metadata | no current UI field |
| location_created | Not rendered | No | Hidden metadata | no current UI field |
| notes | Not rendered | No | Hidden metadata | no current UI field |
| archive_identifier | Not rendered | No | Hidden metadata | no current UI field |
| created_at | Not rendered as Document timestamp | No | Job timestamps are shown instead | src/transcription/ui/components/table/jobs.py |
| updated_at | Not rendered as Document timestamp | No | Job metadata is shown instead | src/transcription/ui/components/transcript.py |
5.3 Gap to Target
To satisfy the intended Read flow, implementation must add:
- a Document detail page
- metadata rendering for Document fields
- linked people rendering
- Sources and Jobs sections with empty states
- filtered navigation from the detail page into document-specific Jobs and Sources 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:
namedocument_typedocument_datedocument_date_rawlocation_creatednotesarchive_identifier
Intended system-managed fields:
idcreated_atupdated_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 | No | Yes | DocumentService.update_document() |
| document_type | No | Yes | DocumentService.update_document() |
| document_date | No | Yes | DocumentService.update_document() |
| document_date_raw | No | Yes | DocumentService.update_document() |
| location_created | No | Yes | DocumentService.update_document() |
| notes | No | Yes | DocumentService.update_document() |
| archive_identifier | No | Yes | 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 must add:
- Document edit controls in the UI
- validation and save behavior for Document metadata
- a consistent
updated_atupdate policy if metadata edits are introduced
7. DELETE Mapping
7.1 Intended Delete Behavior
The UI should eventually provide a delete action for Document with guardrails.
Rules:
- A Document can be deleted when it has no attached Jobs and no attached Sources.
- If dependent Jobs or Sources exist, the UI should block deletion and explain that those related records must be removed first.
- Delete confirmation should make it clear that the action is permanent.
7.2 Current Implementation
| Action | UI Exposed | Backend Capability | Notes |
|---|---|---|---|
| Delete Document | No | Yes | DocumentService.delete_document() exists, but no dedicated UI guard flow exists |
7.3 Gap to Target
Implementation must add:
- a Document delete control in the UI
- pre-delete dependency checks for Jobs and Sources
- user-facing messaging when deletion is blocked
- 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.mdsrc/transcription/db/models.py
Current implementation:
src/transcription/services/documents.pysrc/transcription/services/store.pysrc/transcription/ui/pages/upload_page.pysrc/transcription/ui/pages/jobs_page.pysrc/transcription/ui/components/table/jobs.pysrc/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.