diff --git a/docs/ui/entities/document/acceptance-criteria.md b/docs/ui/entities/document/acceptance-criteria.md new file mode 100644 index 0000000..77bf737 --- /dev/null +++ b/docs/ui/entities/document/acceptance-criteria.md @@ -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 diff --git a/docs/ui/entities/document/schema-mapping.md b/docs/ui/entities/document/schema-mapping.md index 51ba5e3..264a96a 100644 --- a/docs/ui/entities/document/schema-mapping.md +++ b/docs/ui/entities/document/schema-mapping.md @@ -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. diff --git a/docs/ui/entities/document/user-journey.md b/docs/ui/entities/document/user-journey.md index 7779395..0184695 100644 --- a/docs/ui/entities/document/user-journey.md +++ b/docs/ui/entities/document/user-journey.md @@ -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 diff --git a/docs/ui/entities/person/acceptance-criteria.md b/docs/ui/entities/person/acceptance-criteria.md new file mode 100644 index 0000000..ff83462 --- /dev/null +++ b/docs/ui/entities/person/acceptance-criteria.md @@ -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 diff --git a/docs/ui/entities/person/schema-mapping.md b/docs/ui/entities/person/schema-mapping.md new file mode 100644 index 0000000..6e029b0 --- /dev/null +++ b/docs/ui/entities/person/schema-mapping.md @@ -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. \ No newline at end of file diff --git a/docs/ui/entities/person/user-journey.md b/docs/ui/entities/person/user-journey.md new file mode 100644 index 0000000..5f248b6 --- /dev/null +++ b/docs/ui/entities/person/user-journey.md @@ -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 diff --git a/docs/ui/entities/source/acceptance-criteria.md b/docs/ui/entities/source/acceptance-criteria.md new file mode 100644 index 0000000..8be18be --- /dev/null +++ b/docs/ui/entities/source/acceptance-criteria.md @@ -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 diff --git a/docs/ui/entities/source/schema-mapping.md b/docs/ui/entities/source/schema-mapping.md new file mode 100644 index 0000000..c325839 --- /dev/null +++ b/docs/ui/entities/source/schema-mapping.md @@ -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. diff --git a/docs/ui/entities/source/user-journey.md b/docs/ui/entities/source/user-journey.md new file mode 100644 index 0000000..9628f17 --- /dev/null +++ b/docs/ui/entities/source/user-journey.md @@ -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