UI update planning continued

This commit is contained in:
Jim Lancaster
2026-08-02 10:00:03 -05:00
parent 2b3d33e50e
commit 646a360aca
9 changed files with 1576 additions and 21 deletions
@@ -0,0 +1,131 @@
# Document Acceptance Criteria
Purpose: Define implementation-ready acceptance criteria for Document Read, Update, and Delete workflows.
Companion documents:
- docs/ui/entities/document/user-journey.md
- docs/ui/entities/document/schema-mapping.md
## Scope
This checklist covers:
1. Read flow
2. Update flow
3. Delete flow
This checklist does not cover:
1. Source upload workflow details
2. Job execution internals
3. Revision editor behavior
## Read Acceptance Criteria
### RD-1 Document detail retrieval
1. Given a valid Document id
2. When the user opens the Document detail page
3. Then the system displays Document metadata for that record only
### RD-2 Metadata visibility
1. The page shows name, document_type, document_date, document_date_raw, location_created, notes, archive_identifier
2. created_at and updated_at are displayed as system-managed, read-only values
### RD-3 Related people section
1. Given zero linked people
2. Then the page shows a no linked people yet empty state
3. Given one linked person
4. Then the page shows that linked person
### RD-4 Sources section empty state
1. Given no related Source records
2. Then the page shows no sources added yet and an action to add sources
### RD-5 Jobs section empty state
1. Given no related Job records
2. Then the page shows no jobs created yet and an action to start or create jobs
### RD-6 Filtered navigation readiness
1. The detail page provides links or actions that can route to document-scoped Sources and Jobs views
2. Target views are filtered to the current Document id
### RD-7 Failure state
1. Given a nonexistent Document id
2. Then the UI shows a clear not found state without crashing
## Update Acceptance Criteria
### UP-1 Edit entry
1. Given a loaded Document detail page
2. When the user chooses Edit document
3. Then editable controls are shown for allowed fields only
### UP-2 Editable fields
1. Editable: name, document_type, document_date, document_date_raw, location_created, notes, archive_identifier
2. Not editable: id, created_at, updated_at
### UP-3 Required validation
1. name is required
2. document_type is required
3. Save is blocked with inline feedback when either required field is missing
### UP-4 Date handling rule
1. document_date only is allowed
2. document_date_raw only is allowed
3. both fields together are allowed
4. if both are present, document_date is treated as canonical exact date and document_date_raw is retained as descriptive context
### UP-5 Successful save
1. Given valid input
2. When the user saves
3. Then changes persist
4. Then success feedback is shown
5. Then the user remains on Document detail with refreshed values
6. Then updated_at reflects update policy
### UP-6 Save failure
1. Given backend failure during save
2. Then clear error feedback is shown
3. Then the user-entered values remain available for retry where possible
4. Then no false success feedback is shown
## Delete Acceptance Criteria
### DL-1 Delete entry and confirmation
1. Given a Document detail page
2. When the user chooses Delete document
3. Then a confirmation dialog appears with permanent-action wording
### DL-2 Dependency guardrails
1. Delete is allowed only when the Document has no related Source records and no related Job records
2. Delete is blocked when at least one related Source or Job exists
### DL-3 Blocked delete behavior
1. When blocked
2. Then the UI explains why deletion is blocked
3. Then the UI identifies dependency categories present: Sources, Jobs, or both
4. Then the UI provides navigation to dependency cleanup paths
### DL-4 Successful delete
1. Given no blocking dependencies
2. When the user confirms delete
3. Then the Document is removed
4. Then success feedback is shown
5. Then the user is returned to the Document list page
### DL-5 Delete failure
1. Given backend failure during delete
2. Then a clear error message is shown
3. Then the user remains on Document detail with retry path
## Cross-Criteria Quality Gates
### QG-1 Separation of intent and implementation
1. Journey intent remains in docs/ui/entities/document/user-journey.md
2. Current versus target implementation mapping remains in docs/ui/entities/document/schema-mapping.md
### QG-2 Traceability
1. Each accepted behavior maps to at least one future UI action or service call path
2. No acceptance criterion contradicts the current deferred-item policy
### QG-3 First-release constraints
1. Linked person during create remains optional
2. Recipient and multi-person expansion remain deferred
+3 -2
View File
@@ -2,7 +2,8 @@
Purpose: Map the Document schema to the UI, while clearly separating intended target behavior from current implementation.
Companion document: `user-journey.md`
Companion document: user-journey.md
Acceptance criteria: acceptance-criteria.md
## 1. Entity Snapshot
@@ -225,7 +226,7 @@ Current implementation:
Companion UX spec:
- `docs/ui/entities/document/user-journey.md`
## 10. Acceptance Checklist
## 10. Acceptance Checklist Summary
- Every Document schema field appears in the field inventory.
- Intended Create behavior matches the companion user journey.
+162 -19
View File
@@ -4,6 +4,8 @@ Purpose: Define how a user should interact with the UI to create and manage a Do
Scope: This document describes intended user interaction for the Document UI. It is the UX contract for the Document entity.
Companion acceptance criteria: acceptance-criteria.md
## 1. Overview
A Document represents a real historical artifact the user wants to describe, organize, and eventually transcribe. The user should be able to create a Document before uploading or linking any source files.
@@ -248,27 +250,168 @@ Examples:
4. failed DocumentPerson link creation
5. database or server error
## 11. Non-Goals for This Flow
## 11. Read Document Journey
The Create Document flow does not:
1. upload document images or PDFs
2. create transcription jobs
3. start AI processing
4. create Source rows directly
5. edit page-level transcription content
### 11.1 User Intent
Those actions belong to later workflows.
The user wants to open a specific Document and quickly understand:
1. what the document is
2. which people are linked to it
3. whether sources exist
4. whether jobs exist
5. what the next action should be
## 12. Relationship to Other Workflows
### 11.2 Entry Points
This Document creation workflow should precede:
1. adding Sources to a Document
2. creating transcription Jobs
3. reviewing raw transcription output
4. editing revised transcription text
5. linking additional people or recipients later
A user can reach a Document detail page by:
1. selecting a document from the Document page list
2. being redirected after successfully creating a new document
3. following a direct link to a known Document record
## 13. Relationship to Schema Mapping
### 11.3 Document Detail Layout
The Document detail page should include:
1. a header area with document name, document type, and key date values
2. a metadata section with location_created, notes, and archive_identifier
3. system metadata where created_at and updated_at are shown as read-only values
4. a related people section
5. a Sources section
6. a Jobs section
The Document detail page should support:
1. empty-state messaging when no related records exist
2. clear next actions from each empty state
3. future links to filtered Sources and Jobs views scoped to the current document
### 11.4 Read Empty States
If no related records exist:
1. People section says no linked people yet
2. Sources section says no sources added yet
3. Jobs section says no jobs created yet
4. each section presents one clear next action
### 11.5 Read Success Criteria
A successful Read experience means:
1. user can identify the Document immediately
2. user can see whether work has started
3. user can navigate directly to document-scoped Jobs and Sources workflows
## 12. Update Document Journey
### 12.1 User Intent
The user wants to correct or enrich metadata after creation without touching jobs or source transcriptions directly.
### 12.2 Update Entry Point
From the Document detail page:
1. user selects Edit document
2. UI opens edit mode or a dedicated edit view
### 12.3 Editable Fields
First release editable fields:
1. name
2. document_type
3. document_date
4. document_date_raw
5. location_created
6. notes
7. archive_identifier
Read-only or system-managed fields:
1. id
2. created_at
3. updated_at
### 12.4 Update Validation Rules
1. name remains required
2. document_type remains required
3. document_date and document_date_raw may both be present
4. if both date fields are present, document_date remains canonical
5. validation errors should be shown inline and block save
### 12.5 Update Save Behavior
On save:
1. system validates form data
2. system persists Document updates
3. updated_at is refreshed by system policy
4. UI shows a confirmation message
5. user remains on Document detail page with refreshed values
### 12.6 Update Failure Behavior
If save fails:
1. show a clear error message
2. keep user edits in form where possible
3. do not show stale success messaging
4. allow retry without losing context
## 13. Delete Document Journey
### 13.1 User Intent
The user wants to remove a Document only when it is safe and unambiguous.
### 13.2 Delete Entry Point
From the Document detail page:
1. user selects Delete document
2. UI opens a confirmation dialog explaining permanence
### 13.3 Delete Guardrails
Delete is allowed only when:
1. the Document has no related Source records
2. the Document has no related Job records
Delete is blocked when:
1. any Source exists for the Document
2. any Job exists for the Document
### 13.4 Blocked Delete UX
When blocked:
1. show an explicit reason that related Jobs or Sources exist
2. show which dependency types are present
3. provide links to filtered Sources and Jobs for cleanup
4. keep the Document unchanged
### 13.5 Allowed Delete UX
When allowed:
1. show final confirmation with document name
2. perform delete
3. show success confirmation
4. return user to Document page list
### 13.6 Delete Failure Behavior
If delete fails due to system error:
1. show a clear error message
2. keep user on Document detail page
3. preserve ability to retry
## 14. Non-Goals for This Flow
The Document journey does not define:
1. Source upload field-level UX
2. Job execution internals
3. revision editor behavior for transcriptions
4. multi-person recipient workflows in first release
## 15. Relationship to Other Workflows
This Document workflow integrates with:
1. Sources workflow for adding pages or files to the document
2. Jobs workflow for transcription execution
3. Person workflow for future expansion beyond one optional linked person
## 16. Relationship to Schema Mapping
This document is the intended UX contract.
@@ -278,10 +421,10 @@ The companion schema-mapping document should answer:
3. whether the field is hidden, editable, or system-managed
4. what the implementation gap is between intended UX and current code
## 14. Deferred Items
## 17. Deferred Items
These topics are intentionally deferred to future revisions:
1. multiple linked people during create
2. recipient support during create
1. multiple linked people during create and update
2. recipient support during create and update
3. a broader role model for non-author document relationships
4. filtered Jobs and Sources list navigation details
@@ -0,0 +1,144 @@
# Person Acceptance Criteria
Purpose: Define implementation-ready acceptance criteria for Person Create, Read, Update, and Delete workflows.
Companion documents:
- docs/ui/entities/person/user-journey.md
- docs/ui/entities/person/schema-mapping.md
## Scope
This checklist covers:
1. Create flow
2. Read flow
3. Update flow
4. Delete flow
This checklist does not cover:
1. advanced metadata_ editing UX
2. structured-name schema migration implementation
3. bulk merge or dedup workflow design
## Create Acceptance Criteria
### CR-1 Person creation entry
1. Given a Person page
2. When the user selects Create new person
3. Then the user can open a Person create form
### CR-2 Required field validation
1. full_name is required
2. Save is blocked when full_name is empty
3. Inline feedback is shown for required-field errors
### CR-3 Optional field handling
1. Optional fields may be blank without blocking create
2. Date raw and exact fields can coexist
3. Exact date remains canonical when both exact and raw are provided
### CR-4 Successful create outcome
1. Given valid input
2. When the user saves
3. Then the Person record is created
4. Then success feedback is shown
5. Then the user is routed to Person detail page
### CR-5 Create failure outcome
1. Given backend failure during create
2. Then clear error feedback is shown
3. Then entered values are retained where possible
4. Then no false success feedback is shown
## Read Acceptance Criteria
### RD-1 Person detail retrieval
1. Given a valid Person id
2. When the user opens the Person detail page
3. Then the system displays Person metadata for that record only
### RD-2 Metadata visibility
1. The page shows full_name and available optional person fields
2. created_at and updated_at are shown as system-managed, read-only values
### RD-3 Linked documents section
1. Given no linked DocumentPerson rows
2. Then the page shows a no linked documents yet empty state
3. Given linked documents exist
4. Then the page shows linked document entries
### RD-4 Read failure state
1. Given a nonexistent Person id
2. Then the UI shows a clear not found state without crashing
## Update Acceptance Criteria
### UP-1 Edit entry
1. Given a loaded Person detail page
2. When the user selects Edit person
3. Then editable controls are shown for allowed fields only
### UP-2 Editable fields
1. Editable: full_name, display_name, maiden_name, birth/death fields, places, biography, portrait_path
2. Not editable: id, created_at, updated_at
3. metadata_ remains hidden in first release
### UP-3 Required validation
1. full_name remains required
2. Save is blocked with inline feedback when full_name is empty
### UP-4 Successful save
1. Given valid input
2. When the user saves
3. Then changes persist
4. Then success feedback is shown
5. Then the user remains on Person detail with refreshed values
### UP-5 Save failure
1. Given backend failure during save
2. Then clear error feedback is shown
3. Then the user-entered values remain available for retry where possible
4. Then no false success feedback is shown
## Delete Acceptance Criteria
### DL-1 Delete entry and confirmation
1. Given a Person detail page
2. When the user selects Delete person
3. Then a confirmation dialog appears with permanent-action wording
### DL-2 Relationship guardrails
1. Delete is allowed only when relationship policy allows it
2. If linked DocumentPerson rows must be removed first, delete is blocked
### DL-3 Blocked delete behavior
1. When blocked
2. Then the UI explains why deletion is blocked
3. Then the UI identifies linked-document dependency presence
4. Then the UI provides navigation to cleanup paths
### DL-4 Successful delete
1. Given no blocking dependencies
2. When the user confirms delete
3. Then the Person record is removed
4. Then success feedback is shown
5. Then the user returns to the Person list page
### DL-5 Delete failure
1. Given backend failure during delete
2. Then clear error feedback is shown
3. Then the user remains on Person detail with retry path
## Cross-Criteria Quality Gates
### QG-1 Separation of intent and implementation
1. UX intent remains in user-journey.md
2. current versus target implementation mapping remains in schema-mapping.md
### QG-2 Traceability
1. Each accepted behavior maps to at least one future UI action or service call path
2. No acceptance criterion contradicts the deferred-item policy
### QG-3 First-release constraints
1. metadata_ remains hidden in first release
2. structured name field split remains deferred
3. recipient and multi-person role management stays in later revisions
+265
View File
@@ -0,0 +1,265 @@
# 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 | Not rendered in dedicated Person UI | No | No current Person page | no Person page in src/transcription/ui |
| 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 | Not rendered | No | No current Person page | no Person page in src/transcription/ui |
| 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 must add:
1. a Person detail page
2. metadata rendering for Person fields
3. linked Documents section with empty states
4. 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 must add:
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.
+289
View File
@@ -0,0 +1,289 @@
# Person User Journey
Purpose: Define how a user should interact with the UI to create and manage a Person record, including expected inputs, validation, outcomes, and links to Document relationships.
Scope: This document describes intended user interaction for the Person UI. It is the UX contract for the Person entity.
Companion schema mapping: schema-mapping.md
Companion acceptance criteria: acceptance-criteria.md
## 1. Overview
A Person represents a historical individual who may be associated with one or more Documents.
Managing a Person is a profile-first workflow:
1. The user opens the Person page.
2. The user selects Create new person.
3. The user enters known biographical fields.
4. The system creates the Person record.
5. The user can later associate the Person with one or more Documents through DocumentPerson links.
## 2. User Goal
The user wants to:
1. create and maintain historical person records
2. reuse the same Person across multiple Documents
3. record both precise and approximate date values where certainty is limited
4. link people to documents as author or recipient in future flows
## 3. Page Model
### 3.1 Person Page
The Person page is the general UI surface where users manage people.
It should support:
1. listing or locating existing people
2. starting the Create new person flow
3. navigating into a specific Person after it exists
### 3.2 Person Detail Page
The Person detail page is the page for one specific Person after creation.
It should show:
1. core identity fields
2. biographical metadata
3. related Documents section
4. empty state when no linked documents exist yet
## 4. Entry Point
Entry point: Person page
Primary action: Create new person
Expected UI affordance:
1. a visible action labeled Create new person
2. activation opens a dedicated form view, modal, or detail panel
Preferred first implementation:
1. dedicated Person create page or panel
2. simple labeled form controls
3. text inputs are acceptable for first release
## 5. Create Person Form
### 5.1 Required Fields
| UI Label | Schema Field | Input Type | Required | Notes |
|---|---|---|---|---|
| Full name | full_name | Text input | Yes | Canonical identity field |
### 5.2 Optional Name Fields
| UI Label | Schema Field | Input Type | Required | Notes |
|---|---|---|---|---|
| Display name | display_name | Text input | No | Friendly or abbreviated display |
| Maiden name | maiden_name | Text input | No | Historical alternate surname |
### 5.3 Birth and Death Date Fields
| UI Label | Schema Field | Input Type | Required | Notes |
|---|---|---|---|---|
| Birth date | birth_date | Date input | No | Exact known date |
| Birth date (approximate/raw) | birth_date_raw | Text input | No | Approximate or uncertain value |
| Death date | death_date | Date input | No | Exact known date |
| Death date (approximate/raw) | death_date_raw | Text input | No | Approximate or uncertain value |
Date handling rule:
1. exact and raw values may both be entered
2. exact date is canonical when present
3. raw date is retained as historical context
### 5.4 Optional Biographical Fields
| UI Label | Schema Field | Input Type | Required | Notes |
|---|---|---|---|---|
| Birth place | birth_place | Text input | No | Free text |
| Death place | death_place | Text input | No | Free text |
| Biography | biography | Text area | No | Narrative context |
| Portrait path | portrait_path | Text input | No | File or resource path |
| Metadata | metadata_ | Hidden or advanced JSON editor | No | Prefer hidden in first release |
### 5.5 System Fields
| Schema Field | User Editable | Notes |
|---|---|---|
| id | No | System-generated |
| created_at | No | System-generated |
| updated_at | No | System-managed |
## 6. Validation Rules
### 6.1 Required Validation
1. full_name is required
2. save is blocked when full_name is empty
### 6.2 Date Validation
1. birth_date and birth_date_raw may coexist
2. death_date and death_date_raw may coexist
3. exact date fields are canonical when present
4. raw fields remain descriptive context
### 6.3 Integrity Validation
1. form accepts unknown values for optional fields
2. missing birth or death data does not block creation
## 7. Submission Behavior
On submit:
1. system validates required fields
2. system creates Person record
3. system returns user to Person detail page
4. system shows success message
Recommended transactional behavior:
1. Person writes are atomic
2. no partial save state should be persisted
## 8. Expected Result After Success
After successful creation:
1. user sees Person detail page for the new record
2. full_name is visible in the header or summary
3. empty Related Documents section is shown if no links exist
4. user can proceed to link this person from Document workflows
## 9. Expected Result After Failure
If creation fails:
1. show clear error message
2. show field-level feedback for validation failures
3. preserve entered data where possible
4. do not show false success messaging
## 10. Read Person Journey
### 10.1 User Intent
The user wants to open a Person and quickly understand:
1. identity and key biography fields
2. whether this person is linked to any documents
3. what next action to take
### 10.2 Read Surfaces
The Person detail page should show:
1. full_name and display fields
2. birth and death fields
3. biography summary
4. related documents list or empty state
### 10.3 Read Empty State
If no linked documents exist:
1. show No linked documents yet
2. provide guidance to link from Document workflow
## 11. Update Person Journey
### 11.1 User Intent
The user wants to correct or enrich person metadata over time.
### 11.2 Editable Fields
Editable:
1. full_name
2. display_name
3. maiden_name
4. birth_date
5. birth_date_raw
6. birth_place
7. death_date
8. death_date_raw
9. death_place
10. biography
11. portrait_path
System-managed:
1. id
2. created_at
3. updated_at
4. metadata_ can remain hidden in first release
### 11.3 Update Save Behavior
On save:
1. validate required fields
2. persist updates
3. refresh updated_at by system policy
4. show confirmation
5. keep user on Person detail page
### 11.4 Update Failure Behavior
1. show clear error feedback
2. preserve form state where possible
3. allow retry
## 12. Delete Person Journey
### 12.1 User Intent
The user wants to remove incorrect or duplicate person records safely.
### 12.2 Delete Guardrails
Delete is allowed when:
1. Person has no required retained relationships
Delete is blocked when:
1. Person is linked to one or more Documents via DocumentPerson and unlink policy requires cleanup first
### 12.3 Blocked Delete UX
1. explain that linked Document relationships exist
2. show link count or list
3. provide cleanup path
### 12.4 Allowed Delete UX
1. show confirmation dialog
2. confirm permanent action
3. delete Person
4. return to Person list with success message
## 13. Relationship to Other Workflows
This Person workflow integrates with:
1. Document create and update workflows through person lookup and linking
2. DocumentPerson mapping for role assignments
3. future recipient and multi-person enhancements
## 14. Relationship to Schema Mapping
The companion schema-mapping document should specify:
1. field visibility per CRUD action
2. current implementation status
3. intended behavior
4. gap-to-target items
## 15. Deferred Items
Deferred to future revisions:
1. advanced metadata_ editing UI
2. multi-person role editing in the Person UI itself
3. richer relationship timeline views
4. bulk merge or dedup workflows
5. structured name fields migration (first_name, middle_name, last_name, optional suffix)
### 15.1 Structured Name Fields Migration Note
For now, `full_name` remains the canonical required name field.
Future revision intent:
1. introduce structured fields such as first_name, middle_name, last_name, and optional suffix
2. keep full_name during transition for backward compatibility and historical formatting
3. define normalization and formatting rules for display and sorting
4. update search and dedup workflows to use both structured and canonical forms during migration
Migration considerations:
1. schema migration and backfill strategy for existing Person records
2. validation updates for create and update forms
3. compatibility for existing APIs and UI components that currently rely on full_name
4. clear precedence and reconciliation rules when structured fields and full_name differ
@@ -0,0 +1,141 @@
# Source Acceptance Criteria
Purpose: Define implementation-ready acceptance criteria for Source Create, Read, Update, and Delete workflows.
Companion documents:
- docs/ui/entities/source/user-journey.md
- docs/ui/entities/source/schema-mapping.md
## Scope
This checklist covers:
1. Create flow
2. Read flow
3. Update flow
4. Delete flow
This checklist does not cover:
1. advanced multi-version revision history design
2. job orchestration state-machine behavior
3. provider-level transcription internals
## Create Acceptance Criteria
### CR-1 Source creation entry
1. Given the user is in job creation or job configuration flow
2. When the user selects Add sources
3. Then the user can upload one or more source files or a folder
4. Then source creation is not offered as a standalone first-release document-only flow
### CR-2 Required create values
1. document_id is derived from selected Document context
2. JobSource.job_id is derived from the active Job context
3. Each created Source is linked to the active Job through JobSource at create time
4. page_number is assigned to preserve ordering
5. upload_name, filename, and file_path are persisted for each created source
### CR-3 Ordering and filename strategy
1. Given a multi-file or folder upload
2. When source records are created
3. Then page ordering follows alphabetical order of original filenames
4. Then upload_name stores the original filename
5. Then filename is stored using UUID plus original extension in the form UUID.extension
### CR-4 Successful create outcome
1. Given valid uploads
2. When source creation completes
3. Then Source records are created and linked to the Document
4. Then Source records are linked to the active Job through JobSource
5. Then source list reflects new pages in sequence
6. Then the user can open preview or revision workflow
### CR-5 Create failure outcome
1. Given upload or persistence failure
2. Then clear error feedback is shown
3. Then no false success feedback is shown
4. Then retry path remains available
5. Then creation fails when required Document or Job linkage cannot be established
## Read Acceptance Criteria
### RD-1 Source detail retrieval
1. Given a valid Source id in source context, typically via job detail in first release
2. When the user opens source detail or equivalent panel
3. Then source metadata and preview are displayed for that source only
### RD-2 Transcription and revision visibility
1. Original transcription context is visible read-only
2. Revision state is visible
3. If revised_text is absent, no revision yet messaging is shown
### RD-3 Missing source state
1. Given a missing source
2. Then UI shows clear no source available or not found messaging without crashing
## Update Acceptance Criteria
### UP-1 Revision editing entry
1. Given a source context
2. When the user enters revision edit flow
3. Then revised_text input is available
### UP-2 Revision validation
1. revised_text cannot be saved as empty after trimming
2. Warning feedback is shown for invalid empty input
### UP-3 Successful revision save
1. Given valid revision text
2. When the user saves
3. Then revised_text persists
4. Then date_revised is updated
5. Then success feedback is shown
6. Then refreshed revision content is visible
### UP-4 Revision save failure
1. Given backend failure during save
2. Then clear error feedback is shown
3. Then the user-entered text remains available for retry where possible
## Delete Acceptance Criteria
### DL-1 Delete entry and confirmation
1. Given a source in source context, typically via job detail in first release
2. When the user selects delete source
3. Then a permanent-action confirmation dialog appears
### DL-2 Dependency guardrails
1. If policy requires cleanup of related JobSource records first, delete is blocked
2. If policy allows dependent cleanup path, delete can proceed
### DL-3 Blocked delete behavior
1. When blocked
2. Then UI explains dependency constraints
3. Then UI provides guidance for dependency cleanup
### DL-4 Successful delete
1. Given no blocking dependencies
2. When the user confirms deletion
3. Then source is removed
4. Then success feedback is shown
5. Then the user returns to source list context
### DL-5 Delete failure
1. Given backend failure during delete
2. Then clear error feedback is shown
3. Then the user remains in source context with retry path
## Cross-Criteria Quality Gates
### QG-1 Separation of intent and implementation
1. UX intent remains in user-journey.md
2. current versus target mapping remains in schema-mapping.md
### QG-2 Traceability
1. Each accepted behavior maps to at least one future UI action or service path
2. No acceptance criterion contradicts first-release deferred items
### QG-3 First-release constraints
1. Source interaction may remain job-detail-centric initially
2. revised_text is the primary editable source field in first release
3. source creation requires both Document linkage and Job linkage at create time
4. richer source management surfaces are phased in later
+213
View File
@@ -0,0 +1,213 @@
# Source Schema-to-UI Mapping
Purpose: Map the Source 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: Source
- Primary key: id (UUID)
- Related entities: Document, JobSource, Job
- 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 |
| document_id | UUID FK | No | None | Hidden/context-managed | Selected Document context |
| page_number | int | No | 1 | Shown read-only or ordered list | Sequential ordering |
| upload_name | str | No | None | Shown read-only after upload | Original user-provided name |
| filename | str | No | None | Shown read-only | Stored filename |
| file_path | str | No | None | Usually hidden; preview uses path internally | Filesystem path |
| raw_transcription | str | Yes | None | Shown read-only | Immutable machine output context |
| revised_text | str | Yes | None | Shown editable | Human-authored correction |
| date_uploaded | datetime | No | datetime.now(UTC) | Shown read-only | System-managed timestamp |
| date_revised | datetime | Yes | None | Shown read-only | Set when revision is saved |
## 4. CREATE Mapping
### 4.1 Intended Create Flow
Entry point: Job creation or job configuration Add sources action
User action: upload one or more source files, or a whole folder
Success destination: source preview or revision flow in job detail context
| Field | Intended User Input | Required | Visible | Notes |
|---|---|---|---|---|
| document_id | Hidden/context | Yes | No | Comes from selected Document |
| JobSource.job_id | Hidden/context | Yes | No | Comes from active Job; required for first release |
| page_number | Auto or user-assisted ordering | Yes | Indirectly | Should preserve sequence |
| upload_name | File picker name | Yes | Yes | Original display name |
| filename | None | Yes | No or read-only | System-stored as UUID.extension |
| file_path | None | Yes | No | Storage path |
| raw_transcription | None | No | No | Filled by processing |
| revised_text | None | No | No | Initially empty |
| date_uploaded | None | No | No | System-generated |
| date_revised | None | No | No | Null until revision |
### 4.2 Current Implementation
Current entry point: upload page through create_upload_job()
Current user action: upload one file through upload flow
Current backend path: upload submit -> create_upload_job -> _create_upload_records
| Field | Current Value at Create | Source | Visible to User | Evidence |
|---|---|---|---|---|
| id | Generated UUID | System | No | Source model default in src/transcription/db/models.py |
| document_id | Created Document id | Service | Indirectly | src/transcription/services/store.py |
| page_number | 1 | Service default in upload flow | No | src/transcription/services/store.py |
| upload_name | original filename basename | User file name transformed by service | Indirectly | src/transcription/services/store.py |
| filename | stored generated filename | Service | Indirectly | src/transcription/services/store.py |
| file_path | stored path | Service | Indirectly | src/transcription/services/store.py |
| raw_transcription | None initially | System | No at create | Source model defaults |
| revised_text | None initially | System | No at create | Source model defaults |
| date_uploaded | current UTC timestamp | System | No | Source model default |
| date_revised | None | System | No | Source model default |
### 4.3 Gap to Target
To satisfy intended Create flow, implementation must add:
1. multi-source and folder upload support in job create/configure flows
2. deterministic page_number assignment from alphabetical original filename ordering
3. enforced create-time Source-to-Document and Source-to-Job linkage invariants
4. complete filename storage policy migration to UUID.extension only
## 5. READ Mapping
### 5.1 Intended Read Behavior
On Source detail/list surfaces, users should be able to see:
1. source page preview
2. source metadata and ordering
3. revision state
4. original transcription context
### 5.2 Current Implementation
Current Source reading is primarily embedded in job detail.
| Field | Current Rendering | Visible to User | Notes | Evidence |
|---|---|---|---|---|
| upload_name | Shown in source-related UI | Yes | Displayed in job detail source context | src/transcription/ui/components/job_detail.py |
| filename | Indirectly shown in jobs list/detail | Yes | Via Job.filename and source metadata | src/transcription/ui/components/table/jobs.py, src/transcription/ui/pages/jobs_page.py |
| file_path | Used for preview rendering | Indirectly | Source preview in job detail page | src/transcription/ui/pages/jobs_page.py |
| page_number | Not explicitly rendered in current jobs page flow | Limited | Ordering implicit via selected source | jobs page flow |
| raw_transcription | Rendered from JobSource context | Yes | Original transcription card | src/transcription/ui/components/transcript.py |
| revised_text | Rendered/editable in revision editor | Yes | Revision editor in job detail page | src/transcription/ui/pages/jobs_page.py |
| date_uploaded | Limited visibility | Partial | Shown in some source metadata components | src/transcription/ui/components/job_detail.py |
| date_revised | Indirect via revision row timestamp | Partial | Used in revision caption | src/transcription/ui/components/transcript.py |
### 5.3 Gap to Target
To satisfy intended Read flow, implementation must add:
1. dedicated Source list and detail surfaces under Document context
2. explicit page_number presentation and navigation
3. clearer source metadata display independent of Job-centric pages
## 6. UPDATE Mapping
### 6.1 Intended Update Behavior
Primary user update for Source is revised_text maintenance.
Intended editable fields (first release):
- revised_text
Intended read-only fields (first release):
- document_id
- page_number
- upload_name
- filename
- file_path
- raw_transcription
- date_uploaded
- date_revised
### 6.2 Current Implementation
| Field | Updatable via UI | Updatable via Service | Notes |
|---|---|---|---|
| revised_text | Yes | Yes | Saved via TranscriptionService.upsert_revision_for_source() |
| date_revised | No | Yes | Set automatically on revision save |
| other fields | No | Technically yes in service layer | No first-class UI editing flow |
### 6.3 Gap to Target
Implementation should add:
1. explicit Source edit boundaries in dedicated Source UI
2. validation and save UX for revisions in document-scoped source views
3. optional future controls for page ordering and metadata corrections
## 7. DELETE Mapping
### 7.1 Intended Delete Behavior
Source deletion should include dependency-aware guardrails.
Rules:
1. Deletion can proceed when policy allows cleanup of related JobSource records.
2. If related execution history must be preserved first, deletion is blocked with guidance.
### 7.2 Current Implementation
| Action | UI Exposed | Backend Capability | Notes |
|---|---|---|---|
| Delete Source | No | Yes | TranscriptionService.delete_source() exists, no dedicated UI delete flow |
### 7.3 Gap to Target
Implementation must add:
1. source delete controls in source/document context UI
2. dependency checks for JobSource links
3. blocked-delete messaging and cleanup path guidance
4. confirmation UX for successful delete attempts
## 8. Hidden and System-Managed Fields
| Field | Category | Why Hidden or Protected |
|---|---|---|
| id | System-managed | Internal identifier |
| document_id | Context-managed | Derived from selected document context |
| file_path | Operational/internal | Used for file storage and preview plumbing |
| date_uploaded | System-managed | Audit timestamp |
| date_revised | System-managed | Revision timestamp set by system |
## 9. Traceability Anchors
Schema and models:
- docs/schema_v2.md
- src/transcription/db/models.py
Current implementation:
- src/transcription/services/store.py
- src/transcription/services/transcription.py
- src/transcription/ui/pages/jobs_page.py
- src/transcription/ui/components/transcript.py
- src/transcription/ui/components/job_detail.py
Companion UX spec:
- docs/ui/entities/source/user-journey.md
Acceptance checklist:
- docs/ui/entities/source/acceptance-criteria.md
## 10. Acceptance Checklist Summary
- Every Source schema field appears in the field inventory.
- Intended Create behavior matches the companion user journey.
- Source create invariant requires both Document linkage and Job linkage at create time.
- Current behavior reflects upload-centric and job-detail-centric implementation.
- Gaps between intended and current behavior are explicit.
- Read, Update, and Delete sections distinguish target behavior from current code.
+228
View File
@@ -0,0 +1,228 @@
# Source User Journey
Purpose: Define how a user should interact with the UI to create and manage Source records, including page-level transcription context and revision behavior.
Scope: This document describes intended user interaction for the Source UI. It is the UX contract for the Source entity.
Companion schema mapping: schema-mapping.md
Companion acceptance criteria: acceptance-criteria.md
## 1. Overview
A Source represents one page or file unit associated with a Document.
Managing Source records is page-first:
1. The user starts from a transcription job flow.
2. The user adds one or more source files.
3. The system creates Source records linked to the Document and linked to the Job through JobSource.
4. The user reviews original transcription output and can maintain revised text.
## 2. User Goal
The user wants to:
1. add page files to a Document
2. ensure every source is attached to the transcription job context
3. keep page order reliable
4. review original machine output
5. save human revisions per page
6. navigate source pages efficiently
## 3. Page Model
### 3.1 Source List Surface
A Source list surface should support:
1. listing source pages for a selected Document
2. sorting by page_number
3. opening a source detail or revision view
### 3.2 Source Detail Surface
A Source detail surface should show:
1. file preview (image or PDF)
2. source metadata
3. original transcription context
4. revision editor and revision state
## 4. Entry Points
Primary entry points:
1. from Job workflow, Add sources while creating or configuring a job
2. from Job detail, open source preview and revision editor
Current implementation note:
1. source interaction currently occurs in upload and job-detail flows
## 5. Create Source Flow
### 5.1 User Intent
The user wants to attach one or more files to a Document so each page can be processed and reviewed.
### 5.2 Create from Job Context
1. user starts from a job-creation or job-configuration flow
2. user can upload one or more files, or upload a whole folder
3. system creates Source rows linked to the selected Document
4. system creates JobSource links for the active Job as part of this flow
5. source creation fails if required Document or Job linkage cannot be established
### 5.3 Source Create Inputs
| UI Label | Schema Field | Input Type | Required | Notes |
|---|---|---|---|---|
| Source files | upload_name/filename/file_path | Multi-file upload or folder upload | Yes | User may select one file, many files, or a folder |
| Processing order | page_number assignment rule | System rule | Yes | If multiple files are uploaded, processing order is alphabetical by original filename |
| Document reference | document_id | Hidden/context | Yes | Comes from selected Document |
| Job reference | JobSource.job_id | Hidden/context | Yes | Required for first-release source creation |
### 5.4 Filename Strategy
1. store original user filename in upload_name
2. store persisted filename using UUID plus original extension only, in the form UUID.extension
3. this replaces the previous UUID-upload_name.extension pattern
### 5.5 Ordering Guidance
1. multi-file or folder uploads are processed alphabetically by original filename
2. UI should show a warning or helper note so users understand that filename conventions control order
Suggested helper text:
1. Files are processed alphabetically by original filename. Use leading numbers such as 001, 002, 003 to control page order.
### 5.6 System-Managed Values at Create
| Schema Field | User Editable | Notes |
|---|---|---|
| id | No | System-generated |
| date_uploaded | No | System-generated |
| raw_transcription | No | Filled later by processing |
| revised_text | No | Initially empty |
| date_revised | No | Initially null |
### 5.7 Expected Create Result
After successful source create:
1. Source is linked to the Document
2. Source appears in page order derived from alphabetical upload filename ordering
3. Source is linked to the Job through JobSource at create time
4. user can open preview and revision workflow
### 5.8 Source Creation Invariant
For first release:
1. every new Source must have a Document link (Source.document_id)
2. every new Source must have a Job link through JobSource (JobSource.job_id -> JobSource.source_id)
3. source creation is treated as part of transcription workflow, not a standalone document-only upload path
## 6. Read Source Journey
### 6.1 User Intent
The user wants to view each page file and understand file identity, processing context, and revision status.
### 6.2 Read Surface Expectations
The UI should show:
1. file preview for the current Source
2. upload_name as the original user-provided filename
3. filename as the stored system filename
4. file_path information, with the option to keep it internal or partially hidden for safety
5. page_number and ordering context
6. whether revised_text exists
7. original transcription output context
### 6.3 Read Empty and Missing States
If source is missing:
1. show clear not found or no source available messaging
If source has no revision:
1. show empty-state guidance and create-revision action
If source metadata is partially unavailable:
1. show fallback labels and keep preview and revision actions available where possible
## 7. Update Source Journey
### 7.1 User Intent
The user primarily updates page-level revision text while preserving raw machine output.
### 7.2 Intended Editable Fields
Editable in first release:
1. revised_text
Read-only in first release:
1. upload_name
2. filename
3. file_path
4. raw_transcription
5. page_number
6. date_uploaded
7. date_revised set by system on revision save
### 7.3 Revision Save Behavior
On save:
1. validate revision text is non-empty
2. persist revised_text
3. set date_revised
4. show success feedback
5. keep user in current source context
### 7.4 Revision Failure Behavior
If save fails:
1. show clear error feedback
2. keep user input where possible
3. allow retry
## 8. Delete Source Journey
### 8.1 User Intent
The user may need to remove incorrect or duplicate source files from a Document.
### 8.2 Guardrails
Delete is allowed when:
1. policy allows removal of related processing history
Delete is blocked when:
1. policy requires preserving dependent job-source execution records until explicit cleanup
### 8.3 Delete UX
When blocked:
1. explain dependency constraints
2. show cleanup guidance
When allowed:
1. confirm permanent removal
2. remove source
3. return to source list with success state
## 9. Relationship to Other Workflows
Source workflow integrates with:
1. Document workflow for ownership and page organization
2. Job workflow for processing status and outputs
3. revision workflow for human correction lifecycle
## 10. Relationship to Schema Mapping
The companion schema-mapping document should specify:
1. field visibility per CRUD action
2. current implementation status
3. intended behavior
4. gap-to-target items
## 11. Deferred Items
Deferred to future revisions:
1. bulk page reordering UX
2. multi-file upload progress and resumable upload UX
3. revision history versions beyond a single revised_text field
4. richer per-page status dashboards