diff --git a/docs/ui/entities/document/acceptance-criteria.md b/docs/ui/entities/document/acceptance-criteria.md index 1a98fb8..0605c7b 100644 --- a/docs/ui/entities/document/acceptance-criteria.md +++ b/docs/ui/entities/document/acceptance-criteria.md @@ -37,11 +37,13 @@ This checklist does not cover: ### RD-4 Sources section empty state 1. The page shows a Sources action for the current Document -2. The action routes to a document-scoped Sources view +2. The page shows a primary + Add Source action that opens job-create flow for this Document +3. The action routes to a document-scoped Sources view ### RD-5 Jobs section empty state 1. The page shows a Jobs action for the current Document -2. The action routes to a document-scoped Jobs view +2. The page shows a primary + Add Job action for the current Document +3. The action routes to a document-scoped Jobs view ### RD-6 Filtered navigation readiness 1. The detail page provides links or actions that can route to document-scoped Sources and Jobs views @@ -57,6 +59,8 @@ This checklist does not cover: 1. Given a loaded Document detail page 2. When the user chooses Edit document 3. Then editable controls are shown for allowed fields only, including the author relationship selector +4. The author selector includes No author, existing Person options, and a Create new item option +5. Selecting Create new item routes to Person create ### UP-2 Editable fields 1. Editable: name, document_type, document_date, document_date_raw, location_created, notes, archive_identifier diff --git a/docs/ui/entities/document/schema-mapping.md b/docs/ui/entities/document/schema-mapping.md index e5517b2..d7a2c3b 100644 --- a/docs/ui/entities/document/schema-mapping.md +++ b/docs/ui/entities/document/schema-mapping.md @@ -105,7 +105,7 @@ On the Document detail page, the user should be able to see: 2. linked people 3. a Sources section with empty-state behavior when no sources exist 4. a Jobs section with empty-state behavior when no jobs exist -5. future links to filtered Jobs and Sources views for the current document +5. filtered Jobs and Sources views for the current document ### 5.2 Current Implementation @@ -156,13 +156,13 @@ Intended system-managed fields: | Field | Updatable via UI | Updatable via Service | Notes | |---|---|---|---| | id | No | Practically no | Primary key should be treated as immutable | -| name | No | Yes | `DocumentService.update_document()` | -| document_type | No | Yes | `DocumentService.update_document()` | -| document_date | No | Yes | `DocumentService.update_document()` | -| document_date_raw | No | Yes | `DocumentService.update_document()` | -| location_created | No | Yes | `DocumentService.update_document()` | -| notes | No | Yes | `DocumentService.update_document()` | -| archive_identifier | No | Yes | `DocumentService.update_document()` | +| name | Yes | Yes | Editable from dedicated document edit page via `DocumentService.update_document()` | +| document_type | Yes | Yes | Editable from dedicated document edit page via `DocumentService.update_document()` | +| document_date | Yes | Yes | Editable from dedicated document edit page via `DocumentService.update_document()` | +| document_date_raw | Yes | Yes | Editable from dedicated document edit page via `DocumentService.update_document()` | +| location_created | Yes | Yes | Editable from dedicated document edit page via `DocumentService.update_document()` | +| notes | Yes | Yes | Editable from dedicated document edit page via `DocumentService.update_document()` | +| archive_identifier | Yes | Yes | Editable from dedicated document edit page via `DocumentService.update_document()` | | created_at | No | Technically yes | Should remain system-managed | | updated_at | No | Technically yes | Should remain system-managed | @@ -213,11 +213,10 @@ Schema and models: - `src/transcription/db/models.py` Current implementation: +- `src/transcription/ui/pages/documents_page.py` - `src/transcription/services/documents.py` - `src/transcription/services/store.py` -- `src/transcription/ui/pages/upload_page.py` - `src/transcription/ui/pages/jobs_page.py` -- `src/transcription/ui/components/table/jobs.py` - `src/transcription/ui/components/transcript.py` Companion UX spec: diff --git a/docs/ui/entities/document/user-journey.md b/docs/ui/entities/document/user-journey.md index 9dffd4a..27c73eb 100644 --- a/docs/ui/entities/document/user-journey.md +++ b/docs/ui/entities/document/user-journey.md @@ -49,10 +49,7 @@ It should show: 3. a linked-author summary when available 4. document-scoped navigation links for Sources and Jobs 5. filtered views for sources and jobs linked to the current document - -It should later support links to filtered views for: -1. jobs associated with the current document only -2. sources associated with the current document only +6. primary actions + Add Source and + Add Job ## 4. Entry Point @@ -167,10 +164,12 @@ Minimum acceptable first implementation: 1. Dropdown of existing Person records. 2. Clear display of the selected related person before submit. 3. Ability to change or clear the selected person in the Document edit flow. +4. A Create new item option in the author selector that routes to Person create. +5. A visible Create new person link near the selector. If the person does not exist: -1. The user should create the Person first from the Person page. -2. The Document create flow only links existing Person records in first release. +1. The user can use Create new item from the author selector and continue from Person create. +2. The Document create flow links existing Person records after selection. ## 7. Validation Rules @@ -205,18 +204,16 @@ If a related person is selected or created: When the user submits the form, the system should perform these logical steps: 1. validate form inputs 2. create the Document record -3. create a Person record only if the user chose to add a new related person -4. create one DocumentPerson record only if a related person was selected or created -5. persist all intended records successfully before reporting success to the user +3. create one DocumentPerson record only if an existing related person was selected +4. persist intended records successfully before reporting success to the user Expected write sequence: 1. insert Document -2. insert Person only if needed -3. insert DocumentPerson link only if a person is linked +2. insert DocumentPerson link only if a person is linked Recommended transactional behavior: -1. all related writes should succeed or fail together -2. the user should not end up with a partial create state where the Document exists but an intended person link does not +1. Document and optional DocumentPerson writes should succeed or fail together +2. Person creation is a separate workflow reached from the author selector and is not part of the same transaction ## 9. Expected Result After Success @@ -281,7 +278,7 @@ The Document detail page should include: 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 +3. filtered Sources and Jobs views scoped to the current document ### 11.4 Read Empty States diff --git a/docs/ui/entities/job/acceptance-criteria.md b/docs/ui/entities/job/acceptance-criteria.md index 578cf4c..6b4ac8c 100644 --- a/docs/ui/entities/job/acceptance-criteria.md +++ b/docs/ui/entities/job/acceptance-criteria.md @@ -81,7 +81,7 @@ This checklist does not cover: ### RD-4 Detail execution context visibility 1. provider, model, and prompt_name are displayed when known 2. status lifecycle value is visible -3. source-level transcription and revision context remains deferred in the current UI +3. source-level transcription and revision context is available through Source detail navigation from Job detail ### RD-5 Missing and invalid id states 1. Given an invalid job id format @@ -94,16 +94,17 @@ This checklist does not cover: ### UP-1 Revision edit entry 1. Given a job detail page 2. When the user opens the page -3. Then document-scoped navigation links are available +3. Then navigation links to job-scoped Sources are available +4. Then source rows can open Source detail revision workflow ### UP-2 Revision validation -1. source revision editing remains deferred in the current UI +1. revision save blocks empty trimmed text and shows warning feedback ### UP-3 Successful revision save -1. deferred until the source revision UI is restored +1. Source detail save persists revised text and shows success feedback ### UP-4 Revision save failure -1. deferred until the source revision UI is restored +1. Source detail save failure shows clear error feedback with retry path ### UP-5 Job lifecycle state update visibility 1. status changes from queued to processing to terminal states are reflected in UI @@ -113,19 +114,28 @@ This checklist does not cover: ## Delete Acceptance Criteria ### DL-1 Delete entry and confirmation -1. job deletion is deferred in the current UI +1. Given a job detail context +2. When the user opens job delete page +3. Then a permanent-action confirmation is shown for non-processing jobs ### DL-2 Dependency guardrails -1. deferred until a job delete flow is reintroduced +1. Delete is blocked while job status is processing +2. Related JobSource links are removed as part of allowed delete flow ### DL-3 Blocked delete behavior -1. deferred until a job delete flow is reintroduced +1. When blocked, the UI shows clear processing-state guidance +2. The user is offered navigation back to job or jobs list ### DL-4 Successful delete -1. deferred until a job delete flow is reintroduced +1. Given an allowed delete +2. When the user confirms delete +3. Then the job is removed and success feedback is shown +4. Then the user is returned to Jobs list ### DL-5 Delete failure -1. deferred until a job delete flow is reintroduced +1. Given backend failure during delete +2. Then clear error feedback is shown +3. Then the user remains in delete context with retry path ## Cross-Criteria Quality Gates diff --git a/docs/ui/entities/job/schema-mapping.md b/docs/ui/entities/job/schema-mapping.md index 47fd999..9fa5388 100644 --- a/docs/ui/entities/job/schema-mapping.md +++ b/docs/ui/entities/job/schema-mapping.md @@ -36,7 +36,7 @@ This document uses three lenses: | prompt_name | str | Yes | None | Visible when known; editable if create-time options are available | Prompt metadata | Related execution fields rendered in Job detail via relationships: -- none in the current simplified detail view beyond job metadata and document navigation links +- Job detail renders metadata and document links; source-level review/editing is reached through job-scoped Sources routes. ## 4. CREATE Mapping @@ -72,7 +72,7 @@ Current backend path: job create submit -> create_job_for_document() | Field | Current Value at Create | Source | Visible to User | Evidence | |---|---|---|---|---| | id | Generated UUID | System | Yes on jobs list/detail | src/transcription/ui/pages/jobs_page.py | -| document_id | Newly created Document id | Service | Indirectly | src/transcription/services/store.py | +| document_id | Selected existing Document id | User selection + service write | Indirectly | src/transcription/ui/pages/jobs_page.py, src/transcription/services/store.py | | status | queued | Service/model default | Yes | src/transcription/services/store.py, src/transcription/db/models.py | | retry_count | 0 | Model default | Yes | src/transcription/db/models.py, src/transcription/ui/pages/jobs_page.py | | date_created | current UTC timestamp | System | Yes | src/transcription/db/models.py, src/transcription/ui/pages/jobs_page.py | @@ -118,27 +118,27 @@ Current read behavior exists in jobs list and jobs detail routes. | date_created | Jobs list table | Yes | Included in row model | src/transcription/ui/components/table/jobs.py | | date_updated | Jobs list table | Yes | Included in row model | src/transcription/ui/components/table/jobs.py | | document_id | Not rendered directly as labeled field | Partial | Document context exists by relationship but limited direct display | src/transcription/ui/pages/jobs_page.py | -| provider/model/prompt_name | Not rendered as first-class labels | Partial | Stored in job records after processing updates | src/transcription/services/workflows.py | +| provider/model/prompt_name | Rendered as labeled fields in Job detail | Yes | Shows pending fallback when unset | src/transcription/ui/pages/jobs_page.py | Source-related read behavior: -1. one primary source preview is shown in detail. -2. original transcription and revision editor are rendered for source context. +1. Job detail exposes Sources navigation for current job context. +2. Source preview, transcription context, and revision editor are rendered in Source detail. 3. invalid or missing job ids show explicit UI states. ### 5.3 Gap to Target To satisfy intended Read flow, implementation must add: -1. richer per-source detail navigation if a later revision restores transcription review in Job detail. +1. optional in-page source summaries in Job detail if future UX requires fewer navigation steps. 2. richer filtering/search UX if needed. ## 6. UPDATE Mapping ### 6.1 Intended Update Behavior -Primary user updates in first release are source revision edits in job detail source context in the product plan, but the current UI no longer exposes that surface. +Primary user updates in first release are source revision edits in Source detail reached from Job detail. Intended editable scope (first release): -- Source.revised_text through Job detail review +- Source.revised_text through Source detail review Intended read-only Job fields in first release: - id @@ -156,7 +156,7 @@ Job metadata visibility policy: | Field/Area | Updatable via UI | Updatable via Service | Notes | |---|---|---|---| -| Source.revised_text from job detail | No | Yes | Saved via transcription service revision path, but the current UI does not expose the editor | +| Source.revised_text from Source detail | Yes | Yes | Saved via transcription service revision path from Sources page detail route | | status | No | Yes | Updated by workflow lifecycle services | | retry_count | No | Yes | Incremented by workflow retry logic | | provider/model/prompt_name | No | Yes | Set during transcription result finalization | @@ -167,13 +167,14 @@ Job metadata visibility policy: Implementation now includes: 1. create-mode handling for provider/model/prompt visibility and optional selection. 2. detail display for provider/model/prompt and document-scoped navigation links. -3. manual controls for retry and state transitions remain deferred. +3. source revision workflow through job-scoped Sources and Source detail pages. +4. manual controls for retry and state transitions remain deferred. ## 7. DELETE Mapping ### 7.1 Intended Delete Behavior -Job deletion is deferred in the current UI. +Job deletion is implemented as a dedicated delete route with processing-state guardrails. Rules: 1. deletion is allowed only when policy allows cleanup or retention handling for related JobSource records. @@ -184,14 +185,13 @@ Rules: | Action | UI Exposed | Backend Capability | Notes | |---|---|---|---| -| Delete Job | No | Yes | JobService.delete_job() exists; no dedicated UI delete flow | +| Delete Job | Yes | Yes | Job delete page confirms permanent action and blocks when processing | ### 7.3 Gap to Target -Implementation should add in a future revision: -1. delete control in Job detail. -2. dependency checks and blocked-delete messaging. -3. success navigation and confirmation UX. +Implementation may add in a future revision: +1. inline delete entry in Job detail header. +2. richer dependency messaging beyond processing-state guardrail. ## 8. Hidden and System-Managed Fields @@ -211,10 +211,11 @@ Schema and models: Current implementation: - src/transcription/ui/pages/jobs_page.py - src/transcription/ui/components/table/jobs.py -- src/transcription/ui/components/transcript.py +- src/transcription/ui/pages/sources_page.py - src/transcription/services/jobs.py - src/transcription/services/workflows.py - src/transcription/services/store.py +- src/transcription/services/transcription.py Companion UX spec: - docs/ui/entities/job/user-journey.md @@ -226,7 +227,7 @@ Acceptance checklist: - Every Job schema field appears in the field inventory. - Intended Create behavior matches the companion user journey. -- Current behavior reflects existing upload-first creation and jobs read surfaces. +- Current behavior reflects explicit jobs creation plus source review/editing through dedicated Sources routes. - Provider/model/prompt visibility intent is explicit for create and detail views. - 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/job/user-journey.md b/docs/ui/entities/job/user-journey.md index 359717e..0297b84 100644 --- a/docs/ui/entities/job/user-journey.md +++ b/docs/ui/entities/job/user-journey.md @@ -65,9 +65,9 @@ Primary entry points: 2. from Jobs page row selection, open existing Job detail Current implementation note: -1. current code path is upload-first and auto-creates Job records +1. current code path uses explicit /jobs/new creation 2. intended UX is explicit Create job from the Jobs page -3. current detail view is link-oriented and does not show per-source transcription or revision editing controls +3. current detail view is link-oriented and routes source review/editing through dedicated Source detail ## 5. Create Job Flow @@ -167,9 +167,13 @@ Optional first-release columns if available: The Job detail should show: 1. job status and summary metadata 2. selected Document context -3. per-source status (pending, transcribed, failed) -4. original transcription output per source -5. revision editor and latest revised content +3. document-scoped and job-scoped navigation links +4. source review entry through job-scoped Sources list + +Source detail should show: +1. source metadata and preview +2. original transcription output per source +3. revision editor and latest revised content ### 6.4 Read Empty and Missing States @@ -228,7 +232,7 @@ The user primarily updates job-related review outcomes by editing revised transc ### 8.2 First-Release Editable Scope Editable in first release: -1. source-level revised_text through job detail review +1. source-level revised_text through Source detail reached from job-scoped Sources navigation Read-only in first release: 1. Job.document_id after create @@ -256,10 +260,10 @@ The user may need to remove invalid or duplicate jobs safely. ### 9.2 First-Release Policy -Delete behavior is policy-controlled: -1. deletion may be blocked when related JobSource or source history must be retained -2. blocked delete must explain constraints and cleanup path -3. if allowed, delete requires explicit confirmation +Delete behavior uses explicit guardrails: +1. deletion is blocked while status is processing +2. blocked delete explains constraints and offers back navigation +3. allowed delete requires explicit confirmation and then returns to Jobs list with success feedback ## 10. Relationship to Other Workflows diff --git a/docs/ui/entities/person/acceptance-criteria.md b/docs/ui/entities/person/acceptance-criteria.md index 960e4de..d3bc5ef 100644 --- a/docs/ui/entities/person/acceptance-criteria.md +++ b/docs/ui/entities/person/acceptance-criteria.md @@ -35,6 +35,7 @@ This checklist does not cover: 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 +4. Portrait uploads persist under uploads/portraits/person and store a relative portrait_path ### CR-4 Successful create outcome 1. Given valid input @@ -60,6 +61,7 @@ This checklist does not cover: 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 3. portrait_path is rendered when available, including an image preview when possible +4. relative portrait_path values resolve through /uploads for image rendering ### RD-3 Linked documents section 1. Given no linked DocumentPerson rows diff --git a/docs/ui/entities/person/schema-mapping.md b/docs/ui/entities/person/schema-mapping.md index b79a07e..ef14f72 100644 --- a/docs/ui/entities/person/schema-mapping.md +++ b/docs/ui/entities/person/schema-mapping.md @@ -72,31 +72,31 @@ Related records during intended create: ### 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() +Current entry point: dedicated People page and Person create/edit flows +Current user action: open Person create page, fill form fields, optionally upload portrait +Current backend path: People page submit callbacks -> DocumentService.create_person() / update_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 | +| full_name | Form input | User input | Yes | src/transcription/ui/pages/people_page.py | +| display_name | Form input or None | User input | Yes | src/transcription/ui/pages/people_page.py | +| maiden_name | Form input or None | User input | Yes | src/transcription/ui/pages/people_page.py | +| birth_date | Form input or None | User input | Yes | src/transcription/ui/pages/people_page.py | +| birth_date_raw | Form input or None | User input | Yes | src/transcription/ui/pages/people_page.py | +| birth_place | Form input or None | User input | Yes | src/transcription/ui/pages/people_page.py | +| death_date | Form input or None | User input | Yes | src/transcription/ui/pages/people_page.py | +| death_date_raw | Form input or None | User input | Yes | src/transcription/ui/pages/people_page.py | +| death_place | Form input or None | User input | Yes | src/transcription/ui/pages/people_page.py | +| biography | Form input or None | User input | Yes | src/transcription/ui/pages/people_page.py | +| portrait_path | Relative upload path or manual path | Upload helper + user input | Yes | src/transcription/ui/pages/people_page.py, src/transcription/services/store.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: +To satisfy the intended Create flow, implementation now includes: 1. a Person page and dedicated create form 2. user-entered controls for Person fields 3. create validation and success/failure UX states @@ -113,24 +113,24 @@ On the Person detail page, the user should be able to see: ### 5.2 Current Implementation -Current Person visibility in the UI is not implemented as a dedicated page. +Current Person visibility is implemented in dedicated list/detail/edit/delete pages. | Field | Current Rendering | Visible to User | Notes | Evidence | |---|---|---|---|---| | full_name | Rendered in header and summary | Yes | Dedicated Person page exists | `src/transcription/ui/pages/people_page.py` | -| display_name | Not rendered | No | No current Person page | no Person page in src/transcription/ui | -| maiden_name | Not rendered | No | No current Person page | no Person page in src/transcription/ui | -| birth_date | Not rendered | No | No current Person page | no Person page in src/transcription/ui | -| birth_date_raw | Not rendered | No | No current Person page | no Person page in src/transcription/ui | -| birth_place | Not rendered | No | No current Person page | no Person page in src/transcription/ui | -| death_date | Not rendered | No | No current Person page | no Person page in src/transcription/ui | -| death_date_raw | Not rendered | No | No current Person page | no Person page in src/transcription/ui | -| death_place | Not rendered | No | No current Person page | no Person page in src/transcription/ui | -| biography | Not rendered | No | No current Person page | no Person page in src/transcription/ui | +| display_name | Rendered | Yes | Visible in detail and list contexts | src/transcription/ui/pages/people_page.py | +| maiden_name | Rendered | Yes | Visible in detail context | src/transcription/ui/pages/people_page.py | +| birth_date | Rendered | Yes | Visible in detail context | src/transcription/ui/pages/people_page.py | +| birth_date_raw | Rendered | Yes | Visible in detail context | src/transcription/ui/pages/people_page.py | +| birth_place | Rendered | Yes | Visible in detail context | src/transcription/ui/pages/people_page.py | +| death_date | Rendered | Yes | Visible in detail context | src/transcription/ui/pages/people_page.py | +| death_date_raw | Rendered | Yes | Visible in detail context | src/transcription/ui/pages/people_page.py | +| death_place | Rendered | Yes | Visible in detail context | src/transcription/ui/pages/people_page.py | +| biography | Rendered | Yes | Visible in detail context | src/transcription/ui/pages/people_page.py | | portrait_path | Rendered as text and image when available | Yes | Dedicated Person page exists | `src/transcription/ui/pages/people_page.py` | | metadata_ | Not rendered | No | Hidden advanced field | no current UI field | -| created_at | Not rendered | No | No current Person page | no Person page in src/transcription/ui | -| updated_at | Not rendered | No | No current Person page | no Person page in src/transcription/ui | +| created_at | Rendered read-only | Yes | Visible in detail context | src/transcription/ui/pages/people_page.py | +| updated_at | Rendered read-only | Yes | Visible in detail context | src/transcription/ui/pages/people_page.py | ### 5.3 Gap to Target @@ -171,17 +171,17 @@ Hidden in first release: | 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() | +| full_name | Yes | Yes | Editable from Person edit page via DocumentService.update_person() | +| display_name | Yes | Yes | Editable from Person edit page via DocumentService.update_person() | +| maiden_name | Yes | Yes | Editable from Person edit page via DocumentService.update_person() | +| birth_date | Yes | Yes | Editable from Person edit page via DocumentService.update_person() | +| birth_date_raw | Yes | Yes | Editable from Person edit page via DocumentService.update_person() | +| birth_place | Yes | Yes | Editable from Person edit page via DocumentService.update_person() | +| death_date | Yes | Yes | Editable from Person edit page via DocumentService.update_person() | +| death_date_raw | Yes | Yes | Editable from Person edit page via DocumentService.update_person() | +| death_place | Yes | Yes | Editable from Person edit page via DocumentService.update_person() | +| biography | Yes | Yes | Editable from Person edit page via DocumentService.update_person() | +| portrait_path | Yes | Yes | Editable manually and via portrait upload helper | | 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 | @@ -208,11 +208,11 @@ Rules: | Action | UI Exposed | Backend Capability | Notes | |---|---|---|---| -| Delete Person | No | Yes | DocumentService.delete_person() exists, but no dedicated UI guard flow exists | +| Delete Person | Yes | Yes | Dedicated delete page enforces linked-document guardrails before service delete | ### 7.3 Gap to Target -Implementation must add: +Implementation includes: 1. a Person delete control in the UI 2. relationship-aware pre-delete checks 3. user-facing blocked-delete messaging @@ -247,7 +247,8 @@ Schema and models: Current implementation: - src/transcription/services/documents.py -- src/transcription/ui (no dedicated Person pages yet) +- src/transcription/ui/pages/people_page.py +- src/transcription/services/store.py Companion UX spec: - docs/ui/entities/person/user-journey.md @@ -259,6 +260,6 @@ Acceptance checklist: - Every Person schema field appears in the field inventory. - Intended Create behavior matches the companion user journey. -- Current Create behavior reflects service-level implementation. +- Current Create behavior reflects dedicated UI form implementation with optional portrait upload handling. - 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 index 677732b..621f809 100644 --- a/docs/ui/entities/person/user-journey.md +++ b/docs/ui/entities/person/user-journey.md @@ -136,6 +136,7 @@ On submit: 2. The system creates the Person record 3. The system returns the user to the Person detail page 4. The system shows a success message +5. If portrait upload is used, the file is stored under uploads/portraits/person and portrait_path is set to that relative file path Recommended transactional behavior: 1. Person writes are atomic @@ -173,6 +174,7 @@ The Person detail page should show: 2. birth and death fields 3. biography summary 4. related documents list or empty state +5. portrait preview resolved from /uploads when portrait_path is a relative path ### 10.3 Read Empty State diff --git a/docs/ui/entities/source/acceptance-criteria.md b/docs/ui/entities/source/acceptance-criteria.md index 79082b2..e859fb8 100644 --- a/docs/ui/entities/source/acceptance-criteria.md +++ b/docs/ui/entities/source/acceptance-criteria.md @@ -59,14 +59,14 @@ This checklist does not cover: ## Read Acceptance Criteria ### RD-1 Source detail retrieval -1. Given a valid Source id in source context, typically via a document-scoped source list 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 if the detail UI exists in a later revision +1. Given a valid Source id in source context +2. When the user opens source detail +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 when the revision UI exists -2. Revision state is visible when the revision UI exists -3. If revised_text is absent, no revision yet messaging is shown when the revision UI exists +1. Original transcription context is visible read-only in Source detail +2. Revision state is visible in Source detail +3. If revised_text is absent, revision input opens as empty and can be edited ### RD-3 Missing source state 1. Given a missing source @@ -77,29 +77,29 @@ This checklist does not cover: ### 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 in a later revision of the UI +3. Then revised_text input is available in Source detail ### UP-2 Revision validation -1. revised_text cannot be saved as empty after trimming when the revision UI exists -2. Warning feedback is shown for invalid empty input when the revision UI exists +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 in a later revision of the UI +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 in a later revision of the UI +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 a later source detail view +1. Given a source in source context 2. When the user selects delete source 3. Then a permanent-action confirmation dialog appears @@ -135,7 +135,7 @@ This checklist does not cover: 2. No acceptance criterion contradicts first-release deferred items ### QG-3 First-release constraints -1. Source interaction may remain job-detail-centric initially +1. Source creation remains job-create-centric 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 +4. source delete management surfaces are phased in later diff --git a/docs/ui/entities/source/schema-mapping.md b/docs/ui/entities/source/schema-mapping.md index 3011908..be61da3 100644 --- a/docs/ui/entities/source/schema-mapping.md +++ b/docs/ui/entities/source/schema-mapping.md @@ -32,7 +32,7 @@ This document uses three lenses: | 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 indirectly or hidden | Immutable machine output context | -| revised_text | str | Yes | None | Hidden in current simplified UI | Human-authored correction | +| revised_text | str | Yes | None | Editable in Source detail | 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 | @@ -66,8 +66,8 @@ Current backend path: job create submit -> create_job_for_document() | 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 | +| document_id | Selected existing Document id | Job create selection + service write | Indirectly | src/transcription/ui/pages/jobs_page.py, src/transcription/services/store.py | +| page_number | Sequential assignment based on existing max and alphabetical upload order | Service | 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 | @@ -78,11 +78,11 @@ Current backend path: job create submit -> create_job_for_document() ### 4.3 Gap to Target -To satisfy intended Create flow, implementation must add: +To satisfy intended Create flow, implementation now includes: 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 +4. filename storage policy using UUID.extension ## 5. READ Mapping @@ -96,33 +96,33 @@ On Source detail/list surfaces, users should be able to see: ### 5.2 Current Implementation -Current Source reading is primarily embedded in a document-scoped source list and job create/navigation flow. +Current Source reading is centered on dedicated Sources list/detail routes with optional document/job filtering. | Field | Current Rendering | Visible to User | Notes | Evidence | |---|---|---|---|---| -| upload_name | Shown in document-scoped source list | Yes | Displayed in source list context | src/transcription/ui/pages/documents_page.py | -| filename | Shown in document-scoped source list | Yes | Source metadata shown in list | src/transcription/ui/pages/documents_page.py | -| file_path | Hidden from current simplified UI | No | Operational path remains internal | current UI pages | -| page_number | Shown in document-scoped source list | Yes | Ordering visible in document source list | src/transcription/ui/pages/documents_page.py | -| raw_transcription | Not shown in current simplified UI | No | Source preview/revision UI deferred | current UI pages | -| revised_text | Not shown in current simplified UI | No | Source revision UI deferred | current UI pages | -| date_uploaded | Not shown in current simplified UI | No | Operational metadata only | current UI pages | -| date_revised | Not shown in current simplified UI | No | Operational metadata only | current UI pages | +| upload_name | Shown in Sources list and Source detail | Yes | Displayed in source context | src/transcription/ui/pages/sources_page.py | +| filename | Shown in Sources list and Source detail | Yes | Source metadata shown in list/detail | src/transcription/ui/pages/sources_page.py | +| file_path | Hidden from direct text rendering | No | Used internally for preview rendering | src/transcription/ui/components/document_panzoom.py | +| page_number | Shown in Sources list and Source detail | Yes | Ordering visible in filtered/global list | src/transcription/ui/pages/sources_page.py | +| raw_transcription | Shown read-only in Source detail | Yes | Read from latest linked JobSource context | src/transcription/ui/pages/sources_page.py | +| revised_text | Shown and editable in Source detail | Yes | Saved through revision action | src/transcription/ui/pages/sources_page.py | +| date_uploaded | Shown in Source detail | Yes | Read-only metadata | src/transcription/ui/pages/sources_page.py | +| date_revised | Shown in Source detail | Yes | Read-only metadata after revision save | src/transcription/ui/pages/sources_page.py | ### 5.3 Gap to Target To satisfy intended Read flow, implementation must add: -1. richer source detail and revision surfaces if the review workflow returns later -2. optional page-specific navigation if needed beyond the document-scoped list +1. optional list filtering controls in-page (current filtering is URL/context based) +2. optional page-specific navigation enhancements beyond current list/detail pattern ## 6. UPDATE Mapping ### 6.1 Intended Update Behavior -Primary user update for Source is revised_text maintenance in the service layer; the current UI does not expose this flow. +Primary user update for Source is revised_text maintenance in Source detail. Intended editable fields (first release): -- revised_text, if the revision UI is restored later +- revised_text Intended read-only fields (first release): - document_id @@ -138,16 +138,15 @@ Intended read-only fields (first release): | Field | Updatable via UI | Updatable via Service | Notes | |---|---|---|---| -| revised_text | No | Yes | Saved via TranscriptionService.upsert_revision_for_source(), but not exposed in current UI | +| revised_text | Yes | Yes | Saved via TranscriptionService.upsert_revision_for_source() from Source detail | | 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 in a later revision: -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 +1. optional future controls for page ordering and metadata corrections +2. revision history and conflict-resolution UX beyond single revised_text updates ## 7. DELETE Mapping @@ -192,9 +191,10 @@ Schema and models: Current implementation: - src/transcription/services/store.py - src/transcription/services/transcription.py +- src/transcription/ui/pages/sources_page.py - src/transcription/ui/pages/jobs_page.py -- src/transcription/ui/components/transcript.py -- src/transcription/ui/components/job_detail.py +- src/transcription/ui/pages/documents_page.py +- src/transcription/ui/components/document_panzoom.py Companion UX spec: - docs/ui/entities/source/user-journey.md @@ -207,6 +207,6 @@ Acceptance checklist: - 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. +- Current behavior reflects upload-centric create flow and dedicated Sources list/detail review flow. - 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 index 48e70b8..757503e 100644 --- a/docs/ui/entities/source/user-journey.md +++ b/docs/ui/entities/source/user-journey.md @@ -15,7 +15,8 @@ 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 source lists by document and can navigate to the owning Document or Job. +4. The user reviews source lists from a dedicated Sources page. +5. The user opens Source detail to review preview, metadata, transcription text, and revision text. ## 2. User Goal @@ -32,22 +33,29 @@ The user wants to: ### 3.1 Source List Surface A Source list surface should support: -1. listing source pages for a selected Document +1. listing source pages globally or filtered by selected Document or Job 2. sorting by page_number 3. opening the owning Document or Job context +4. opening Source detail for a selected source ### 3.2 Source Detail Surface -Source detail and revision surfaces are deferred in the current UI. +Source detail supports: +1. pan/zoom image or PDF preview +2. read-only source metadata (page number, names, timestamps) +3. read-only original transcription text +4. editable revision text with save action ## 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 +2. from Job detail, open filtered Sources for the current Job +3. from Document detail, open filtered Sources for the current Document +4. from global navigation, open all Sources Current implementation note: -1. source interaction currently occurs in job-create and document-scoped source list flows +1. source interaction occurs in job-create flow and dedicated Sources list/detail flows ## 5. Create Source Flow @@ -120,11 +128,12 @@ The user wants to view each page file and understand file identity and processin ### 6.2 Read Surface Expectations The UI should show: -1. source lists grouped by Document +1. source lists for current context (all, document-filtered, or job-filtered) 2. upload_name as the original user-provided filename 3. filename as the stored system filename 4. page_number and ordering context 5. the owning Document and Job navigation context +6. direct action to open Source detail ### 6.3 Read Empty and Missing States @@ -143,7 +152,7 @@ The user primarily tracks page-level source records while preserving raw machine ### 7.2 Intended Editable Fields Editable in first release: -1. revised_text in a later revision, not in the current simplified UI +1. revised_text in Source detail Read-only in first release: 1. upload_name @@ -157,11 +166,11 @@ Read-only in first release: ### 7.3 Revision Save Behavior On save: -1. validate revision text is non-empty when the revision UI exists in a later release -2. persist revised_text when the revision UI exists -3. set date_revised when the revision UI exists -4. show success feedback when the revision UI exists -5. keep user in current source context when the revision UI exists +1. validate revision text is non-empty after trimming +2. persist revised_text +3. set date_revised +4. show success feedback +5. keep user in current source context ### 7.4 Revision Failure Behavior @@ -217,3 +226,4 @@ Deferred to future revisions: 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 +5. source delete UI with dependency-aware confirmation diff --git a/docs/ui/entities/traceability-matrix.md b/docs/ui/entities/traceability-matrix.md index ce2ff16..f85fc83 100644 --- a/docs/ui/entities/traceability-matrix.md +++ b/docs/ui/entities/traceability-matrix.md @@ -33,8 +33,8 @@ Status legend: |---|---|---|---|---| | Create entry and required links | CR-1, CR-2, CR-4, CR-5 | Implemented | src/transcription/services/store.py; src/transcription/ui/pages/jobs_page.py; src/transcription/ui/pages/upload_page.py; tests/services/test_store.py; tests/ui/test_jobs_page.py | Source upload/create is job-create-context only (legacy upload route redirects), with required Document and JobSource linkage enforced. | | Ordering and filename policy | CR-3 | Implemented | src/transcription/services/store.py; tests/services/test_store.py; tests/ui/test_jobs_page.py | Multi-file/folder uploads are ordered alphabetically by original filename, helper text is visible, and stored filenames use generated unique-id plus extension. | -| Read and navigation visibility | RD-1, RD-2, RD-3 | Partial | src/transcription/ui/pages/documents_page.py; src/transcription/ui/pages/jobs_page.py; tests/ui/test_documents_page.py; tests/ui/test_jobs_page.py | Source list context is now document-scoped and job detail is link-oriented; source preview and revision surfaces are deferred. | -| Revision update behavior | UP-1, UP-2, UP-3, UP-4 | Planned | src/transcription/services/transcription.py; tests/services/test_transcription_service.py | Revised text service support remains, but the current UI does not expose the editor. | +| Read and navigation visibility | RD-1, RD-2, RD-3 | Implemented | src/transcription/ui/pages/sources_page.py; src/transcription/ui/pages/documents_page.py; src/transcription/ui/pages/jobs_page.py; tests/ui/test_sources_page.py; tests/ui/test_documents_page.py; tests/ui/test_jobs_page.py | Dedicated Sources list/detail routes support global, document-filtered, and job-filtered navigation plus source metadata and preview rendering. | +| Revision update behavior | UP-1, UP-2, UP-3, UP-4 | Implemented | src/transcription/ui/pages/sources_page.py; src/transcription/services/transcription.py; tests/ui/test_sources_page.py; tests/services/test_transcription_service.py | Source detail exposes revision edit/save UX with non-empty validation, success feedback, and refreshed state after save. | | Delete and dependency guardrails | DL-1, DL-2, DL-3, DL-4, DL-5 | Planned | src/transcription/services/transcription.py; tests/services/test_transcription_service.py | Job-detail source delete UI was removed from the current simplified flow; backend guardrails remain for future reinstatement. | ## Job @@ -45,9 +45,9 @@ Status legend: | Source ordering and upload behavior | CR-3 | Implemented | src/transcription/services/store.py; src/transcription/ui/pages/jobs_page.py; tests/services/test_store.py; tests/ui/test_jobs_page.py | Multi-file and folder upload are supported through one widget, uploads are sorted alphabetically by original filename, and helper guidance is shown in create UI. | | Provider/model/prompt visibility | CR-4, RD-4 | Implemented | src/transcription/services/workflows.py; src/transcription/ui/pages/jobs_page.py; tests/ui/test_jobs_page.py | Provider/model/prompt fields are visible in create and detail flows when known (with pending fallback labels). | | Jobs list and detail read states | RD-1, RD-2, RD-3, RD-5 | Implemented | src/transcription/ui/pages/jobs_page.py; src/transcription/ui/components/table/jobs.py; tests/ui/test_jobs_page.py | Jobs list, detail route, document-scoped navigation, and invalid/missing id states are present. | -| Revision update behavior | UP-1, UP-2, UP-3, UP-4 | Planned | src/transcription/services/transcription.py; tests/services/test_transcription_service.py | Revision editing service support remains, but the current UI no longer exposes the editor. | +| Revision update behavior | UP-1, UP-2, UP-3, UP-4 | Implemented | src/transcription/ui/pages/jobs_page.py; src/transcription/ui/pages/sources_page.py; src/transcription/services/transcription.py; tests/ui/test_jobs_page.py; tests/ui/test_sources_page.py; tests/services/test_transcription_service.py | Job detail routes users to job-scoped Sources where Source detail provides revision edit/save workflow. | | Lifecycle visibility and retry indicators | UP-5 | Implemented | src/transcription/services/jobs.py; src/transcription/services/workflows.py; src/transcription/ui/pages/jobs_page.py; tests/ui/test_jobs_page.py | Job detail now surfaces lifecycle status plus retry/update metadata while lifecycle fields remain system-managed (no direct user edit controls). | -| Delete and dependency guardrails | DL-1, DL-2, DL-3, DL-4, DL-5 | Planned | src/transcription/services/jobs.py; tests/services/test_job_service.py | Job delete UI is deferred in the current simplified flow. | +| Delete and dependency guardrails | DL-1, DL-2, DL-3, DL-4, DL-5 | Implemented | src/transcription/ui/pages/jobs_page.py; src/transcription/services/jobs.py; tests/ui/test_jobs_page.py; tests/services/test_job_service.py | Job delete page enforces processing-state block, confirms allowed deletes, and routes back to jobs list on success. | ## Quality Gate Coverage @@ -74,5 +74,5 @@ Status legend: |---|---|---|---| | Document | None | src/transcription/ui/pages/documents_page.py; tests/ui/test_documents_page.py | Document criteria are covered by dedicated detail/edit/delete pages and document-scoped related views. | | Person | None | src/transcription/ui/pages/people_page.py; tests/ui/test_people_page.py | Person criteria are covered by dedicated create/detail/edit/delete pages with relationship-aware delete guardrails. | -| Source | None | src/transcription/services/store.py; src/transcription/ui/pages/jobs_page.py; tests/services/test_store.py; tests/services/test_transcription_service.py | Source criteria are covered by job-context create behavior, ordering/filename policy, revision flow, and delete guardrails. | +| Source | None | src/transcription/services/store.py; src/transcription/ui/pages/sources_page.py; src/transcription/ui/pages/jobs_page.py; tests/services/test_store.py; tests/ui/test_sources_page.py; tests/services/test_transcription_service.py | Source criteria are covered by job-context create behavior, ordering/filename policy, dedicated list/detail read flow, revision flow, and delete guardrails. | | Job | None | src/transcription/ui/pages/jobs_page.py; src/transcription/services/jobs.py; tests/ui/test_jobs_page.py; tests/services/test_job_service.py | Job criteria are covered by create/read/revision/lifecycle visibility and delete guardrails in dedicated routes. |