diff --git a/docs/ui_style_guide.md b/docs/invariant/ui_style_guide.md similarity index 100% rename from docs/ui_style_guide.md rename to docs/invariant/ui_style_guide.md diff --git a/docs/ui/test-bento-grid.py b/docs/test/test-bento-grid.py similarity index 100% rename from docs/ui/test-bento-grid.py rename to docs/test/test-bento-grid.py diff --git a/docs/ui/test_block-beta.md b/docs/test/test_block-beta.md similarity index 100% rename from docs/ui/test_block-beta.md rename to docs/test/test_block-beta.md diff --git a/docs/ui/test_flowchart.md b/docs/test/test_flowchart.md similarity index 100% rename from docs/ui/test_flowchart.md rename to docs/test/test_flowchart.md diff --git a/docs/ui/README.md b/docs/ui/README.md new file mode 100644 index 0000000..65712e0 --- /dev/null +++ b/docs/ui/README.md @@ -0,0 +1,59 @@ +# UI Documentation + +This folder contains UI-focused design and mapping documents that connect the database schema to user-facing workflows. + +## Document Types + +### user-journey.md + +A product and UX contract for a user-facing entity. + +Use this document to describe: +- what the user is trying to do +- which screen or action starts the workflow +- which fields the user sees and edits +- validation rules +- expected success and failure outcomes +- where the user goes next + +### schema-mapping.md + +A field-level mapping between schema, UI, and implementation. + +Use this document to describe: +- the authoritative schema fields for an entity +- which fields are shown, hidden, editable, or system-managed +- current implementation behavior +- intended target behavior +- implementation gaps between current code and intended UX + +## Organization Rules + +- Store documents under `docs/ui/entities//`. +- Create both `user-journey.md` and `schema-mapping.md` for user-facing entities. +- Create only `schema-mapping.md` for supporting tables that do not currently have standalone UI. +- Keep top-level `docs/` reserved for core architecture, requirements, schema, and system-wide reference material. + +## Current Entity Plan + +User-facing entities: +- `document` +- `person` +- `source` +- `job` + +Supporting entities: +- `document-person` +- `job-source` + +## Relationship to Core Docs + +These UI docs complement, but do not replace: +- `docs/schema_v2.md` +- `docs/requirements_v2.md` +- `docs/architecture_v2.md` + +When there is a conflict: +- schema definitions come from the database model and schema docs +- user interaction intent comes from the user-journey docs +- implementation truth comes from code and is recorded in schema-mapping docs as current-state evidence diff --git a/docs/ui/entities/document/schema-mapping.md b/docs/ui/entities/document/schema-mapping.md new file mode 100644 index 0000000..51ba5e3 --- /dev/null +++ b/docs/ui/entities/document/schema-mapping.md @@ -0,0 +1,234 @@ +# Document Schema-to-UI Mapping + +Purpose: Map the Document schema to the UI, while clearly separating intended target behavior from current implementation. + +Companion document: `user-journey.md` + +## 1. Entity Snapshot + +- Table: Document +- Primary key: `id` (UUID) +- Related entities: `Source`, `Job`, `DocumentPerson` +- Canonical schema references: + - `src/transcription/db/models.py` + - `docs/schema_v2.md` + +## 2. Mapping Rules + +This document uses three lenses: +1. Intended behavior: what the UX should support. +2. Current behavior: what the code supports today. +3. Gap to target: what must change to align implementation with the intended UX. + +## 3. Field Inventory + +| Field | DB Type | Nullable | Default/Auto Value | Intended UI Treatment | Notes | +|---|---|---|---|---|---| +| id | UUID | No | `uuid4()` | Hidden, system-managed | Primary key | +| name | str | No | None | Shown, editable on create and future edit | Required | +| document_type | str | Yes | None | Shown, editable on create and future edit | Required by intended UX | +| document_date | date | Yes | None | Shown, editable | Canonical exact date when present | +| document_date_raw | str | Yes | None | Shown, editable | Approximate or unknown date text | +| location_created | str | Yes | None | Shown, editable | Optional metadata | +| notes | str | Yes | None | Shown, editable | Optional metadata | +| archive_identifier | str | Yes | None | Shown, editable | Free text in first release | +| created_at | datetime | No | `datetime.now(UTC)` | Hidden or read-only | System-managed | +| updated_at | datetime | No | `datetime.now(UTC)` | Hidden or read-only | System-managed | + +## 4. CREATE Mapping + +### 4.1 Intended Create Flow + +Entry point: Document page +User action: Create new document +Success destination: new Document detail page + +| Field | Intended User Input | Required | Visible | Notes | +|---|---|---|---|---| +| name | Text input | Yes | Yes | Primary identifier used by the user | +| document_type | Text input | Yes | Yes | Free text in first release | +| document_date | Date input | No | Yes | Structured exact date | +| document_date_raw | Text input | No | Yes | Approximate or uncertain date | +| location_created | Text input | No | Yes | Optional | +| notes | Text area | No | Yes | Optional | +| archive_identifier | Text input | No | Yes | Free text | +| created_at | None | No | No | System-generated | +| updated_at | None | No | No | Not used during initial create | + +Related records during intended create: +- A related person may optionally be selected or created. +- If present, the system creates a `DocumentPerson` link. +- Jobs are not created during Document create. +- Sources are not created during Document create. + +### 4.2 Current Implementation + +Current entry point: upload page +Current user action: upload file via upload widget +Current backend path: upload page submit callback -> `create_upload_job()` -> `_create_upload_records()` + +| Field | Current Value at Create | Source | Visible to User | Evidence | +|---|---|---|---|---| +| id | Generated UUID | System | No | `Document` default factory in `src/transcription/db/models.py` | +| name | Basename of uploaded filename | User file name transformed by service | Indirectly | Set in `src/transcription/services/store.py` | +| document_type | `None` | Service default | No | Not set in `src/transcription/services/store.py` | +| document_date | `None` | Service default | No | Not set in `src/transcription/services/store.py` | +| document_date_raw | `None` | Service default | No | Not set in `src/transcription/services/store.py` | +| location_created | `None` | Service default | No | Not set in `src/transcription/services/store.py` | +| notes | `None` | Service default | No | Not set in `src/transcription/services/store.py` | +| archive_identifier | `None` | Service default | No | Not set in `src/transcription/services/store.py` | +| created_at | Current UTC timestamp | System | No | Default factory in `src/transcription/db/models.py` | +| updated_at | Current UTC timestamp | System | No | Default factory in `src/transcription/db/models.py` | + +Current related-record behavior: +- `Job` is created automatically. +- `Source` is created automatically. +- `JobSource` is created automatically. +- No `Person` or `DocumentPerson` records are created. + +### 4.3 Gap to Target + +To satisfy the intended Create flow, implementation must add: +1. a Document page and dedicated create form +2. user-entered metadata fields for `document_type`, `document_date`, `document_date_raw`, `location_created`, `notes`, and `archive_identifier` +3. optional Person lookup and inline Person creation +4. optional `DocumentPerson` link creation when a person is chosen +5. post-submit routing to a Document detail page +6. removal of the assumption that Document creation always starts with file upload + +## 5. READ Mapping + +### 5.1 Intended Read Behavior + +On the Document detail page, the user should be able to see: +1. Document metadata +2. linked people +3. a Sources section with empty-state behavior when no sources exist +4. a Jobs section with empty-state behavior when no jobs exist +5. future links to filtered Jobs and Sources views for the current document + +### 5.2 Current Implementation + +Current Document visibility in the UI is indirect. + +| Field | Current Rendering | Visible to User | Notes | Evidence | +|---|---|---|---|---| +| name | Indirect filename context in jobs list and job detail | Yes, indirect | The UI shows source/job filename, not a dedicated Document page | `src/transcription/ui/pages/jobs_page.py`, `src/transcription/ui/components/table/jobs.py` | +| id | Not shown as Document id | No | Job id is shown instead | `src/transcription/ui/pages/jobs_page.py` | +| document_type | Not rendered | No | Hidden metadata | no current UI field | +| document_date | Not rendered | No | Hidden metadata | no current UI field | +| document_date_raw | Not rendered | No | Hidden metadata | no current UI field | +| location_created | Not rendered | No | Hidden metadata | no current UI field | +| notes | Not rendered | No | Hidden metadata | no current UI field | +| archive_identifier | Not rendered | No | Hidden metadata | no current UI field | +| created_at | Not rendered as Document timestamp | No | Job timestamps are shown instead | `src/transcription/ui/components/table/jobs.py` | +| updated_at | Not rendered as Document timestamp | No | Job metadata is shown instead | `src/transcription/ui/components/transcript.py` | + +### 5.3 Gap to Target + +To satisfy the intended Read flow, implementation must add: +1. a Document detail page +2. metadata rendering for Document fields +3. linked people rendering +4. Sources and Jobs sections with empty states +5. filtered navigation from the detail page into document-specific Jobs and Sources views + +## 6. UPDATE Mapping + +### 6.1 Intended Update Behavior + +The user should eventually be able to edit Document metadata from the Document detail page or a dedicated edit flow. + +Intended editable fields: +- `name` +- `document_type` +- `document_date` +- `document_date_raw` +- `location_created` +- `notes` +- `archive_identifier` + +Intended system-managed fields: +- `id` +- `created_at` +- `updated_at` + +### 6.2 Current Implementation + +| Field | Updatable via UI | Updatable via Service | Notes | +|---|---|---|---| +| id | No | Practically no | Primary key should be treated as immutable | +| name | No | Yes | `DocumentService.update_document()` | +| document_type | No | Yes | `DocumentService.update_document()` | +| document_date | No | Yes | `DocumentService.update_document()` | +| document_date_raw | No | Yes | `DocumentService.update_document()` | +| location_created | No | Yes | `DocumentService.update_document()` | +| notes | No | Yes | `DocumentService.update_document()` | +| archive_identifier | No | Yes | `DocumentService.update_document()` | +| created_at | No | Technically yes | Should remain system-managed | +| updated_at | No | Technically yes | Should remain system-managed | + +### 6.3 Gap to Target + +Implementation must add: +1. Document edit controls in the UI +2. validation and save behavior for Document metadata +3. a consistent `updated_at` update policy if metadata edits are introduced + +## 7. DELETE Mapping + +### 7.1 Intended Delete Behavior + +The UI should eventually provide a delete action for Document with guardrails. + +Rules: +1. A Document can be deleted when it has no attached Jobs and no attached Sources. +2. If dependent Jobs or Sources exist, the UI should block deletion and explain that those related records must be removed first. +3. Delete confirmation should make it clear that the action is permanent. + +### 7.2 Current Implementation + +| Action | UI Exposed | Backend Capability | Notes | +|---|---|---|---| +| Delete Document | No | Yes | `DocumentService.delete_document()` exists, but no dedicated UI guard flow exists | + +### 7.3 Gap to Target + +Implementation must add: +1. a Document delete control in the UI +2. pre-delete dependency checks for Jobs and Sources +3. user-facing messaging when deletion is blocked +4. confirmation UX for successful delete attempts + +## 8. Hidden and System-Managed Fields + +| Field | Category | Why Hidden or Protected | +|---|---|---| +| id | System-managed | Internal identifier | +| created_at | System-managed | Audit timestamp | +| updated_at | System-managed | Audit timestamp | + +## 9. Traceability Anchors + +Schema and models: +- `docs/schema_v2.md` +- `src/transcription/db/models.py` + +Current implementation: +- `src/transcription/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: +- `docs/ui/entities/document/user-journey.md` + +## 10. Acceptance Checklist + +- Every Document schema field appears in the field inventory. +- Intended Create behavior matches the companion user journey. +- Current Create behavior reflects the existing upload-driven implementation. +- Gaps between intended and current behavior are explicit. +- Read, Update, and Delete sections distinguish target behavior from current code. diff --git a/docs/ui/entities/document/user-journey.md b/docs/ui/entities/document/user-journey.md new file mode 100644 index 0000000..7779395 --- /dev/null +++ b/docs/ui/entities/document/user-journey.md @@ -0,0 +1,287 @@ +# Document User Journey + +Purpose: Define how a user should interact with the UI to create and manage a Document record, including expected inputs, validation, results, and related record creation. + +Scope: This document describes intended user interaction for the Document UI. It is the UX contract for the Document entity. + +## 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. + +Creating a Document is a metadata-first workflow: +1. The user opens the Document page. +2. The user selects Create new document. +3. The user enters descriptive metadata about the document. +4. The user optionally links one related person. +5. The system creates the Document. +6. If a person was selected or created, the system links that Person to the Document through DocumentPerson. +7. The user sees a success state and lands on the new Document detail page. + +## 2. User Goal + +The user wants to create a new Document record that: +1. Has enough metadata to identify the historical artifact. +2. Can optionally be linked to a person. +3. Exists independently of transcription jobs and source uploads. +4. Is ready for later steps such as adding sources, starting jobs, and reviewing transcriptions. + +## 3. Page Model + +### 3.1 Document Page + +The Document page is the general UI surface where users manage documents. + +It should support: +1. listing or locating existing documents +2. starting the Create new document flow +3. navigating into a specific Document after it exists + +### 3.2 Document Detail Page + +The Document detail page is the page for one specific Document after it has been created. + +It should show: +1. the Document metadata +2. related people linked to the Document +3. a Sources section +4. a Jobs section +5. empty states when no sources or jobs exist yet + +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 + +## 4. Entry Point + +Entry point: Document page + +Primary action: Create new document + +Expected UI affordance: +1. A visible button, link, or primary action labeled Create new document. +2. Activation opens a dedicated form view, modal, or detail panel for creating a Document. + +Preferred first implementation: +1. A dedicated Document create page or panel. +2. A simple form with explicit labels. +3. Text inputs are acceptable for first release, even where future versions may use dropdowns or richer selectors. + +## 5. Create Document Form + +The Create Document form should contain the following fields. + +### 5.1 Required Fields + +| UI Label | Schema Field | Input Type | Required | Notes | +|---|---|---|---|---| +| Document name | name | Text input | Yes | Examples: Pioneer Days, Letter from Zenna to Omie | +| Document type | document_type | Text input | Yes | Examples: book, letter, enlistment papers, military record, other | + +### 5.2 Date Fields + +| UI Label | Schema Field | Input Type | Required | Notes | +|---|---|---|---|---| +| Exact date | document_date | Date input | No | Use when the exact date is known | +| Approximate date | document_date_raw | Text input | No | Use when exact date is uncertain, approximate, or unknown | + +Date handling rule: +1. The form may allow both fields to be entered. +2. If both fields are entered, `document_date` is the canonical structured date. +3. `document_date_raw` may still be retained as the user-entered descriptive form. +4. The UI should explain the distinction clearly. + +Examples: +1. Exact date: `07/13/1885` +2. Approximate date: `c. 1885` +3. Approximate date: `Fall 1925` +4. Approximate date: `unknown` + +### 5.3 Optional Metadata Fields + +| UI Label | Schema Field | Input Type | Required | Notes | +|---|---|---|---|---| +| Document location | location_created | Text input | No | Where the document was created | +| Notes | notes | Multiline text area | No | Freeform notes about the document | +| Archive identifier | archive_identifier | Text input | No | Free text for now; may represent inventory code, storage reference, or repository note | + +Archive identifier guidance: +1. First implementation should treat this as free text. +2. Helper text may explain that this can store a repository code, box or folder reference, or storage note. + +### 5.4 System Fields + +| Schema Field | User Editable | Notes | +|---|---|---| +| created_at | No | System-generated at creation time | +| updated_at | No | Not user-entered during creation | + +### 5.5 Optional Related Person + +The Create Document flow may optionally link one related person during first release. + +| UI Label | Schema Area | Input Type | Required | Notes | +|---|---|---|---|---| +| Related person | Person -> DocumentPerson | Search/select or create inline | No | Intended to support common author-like associations without making the field mandatory | + +First release behavior: +1. The user may save a Document without linking any person. +2. If a person is linked during create, only one person is supported in first release. +3. Additional people and recipient workflows are deferred to a future revision. + +### 5.6 Related Records Not Created Directly Here + +| Related Area | Included in Document Create | Notes | +|---|---|---| +| Jobs | No | Jobs are created later when transcription work begins | +| Sources | No | Sources are added later as uploaded pages or files | + +## 6. Related Person Workflow + +### 6.1 User Intent + +The user should be able to: +1. select an existing Person to associate with the Document +2. create a new Person if the person does not already exist +3. save the Document even if no person is linked + +### 6.2 Data Model Interpretation + +Person selection source: +1. The UI should select from Person records. +2. If a person is linked, the system should create a DocumentPerson record. +3. Role handling for non-author document relationships is deferred. +4. If the first release needs a persisted role immediately, the role can default to `author` until the relationship model is broadened. + +This means: +1. The user does not choose from DocumentPerson records. +2. DocumentPerson is the relationship created after the Person is chosen or created. + +### 6.3 Related Person UI Behavior + +Minimum acceptable first implementation: +1. Searchable or scrollable list of existing Person records. +2. Option to create a new Person inline or in a small secondary flow. +3. Clear display of the selected related person before submit. + +If the person does not exist: +1. User selects Create new person. +2. User enters the minimum required Person information. +3. System creates Person. +4. System returns to Document create flow. +5. System links the new Person if the user completes Document creation. + +## 7. Validation Rules + +### 7.1 Required Field Validation + +The form must reject submission if: +1. `name` is empty +2. `document_type` is empty + +### 7.2 Date Validation + +The form should allow: +1. `document_date` only +2. `document_date_raw` only +3. both `document_date` and `document_date_raw` +4. neither date field + +If both are present: +1. `document_date` is treated as the canonical exact date +2. `document_date_raw` is retained as descriptive context + +### 7.3 Related Person Validation + +The form must not require a linked person in first release. + +If a related person is selected or created: +1. the selected value must resolve to a valid Person record before final save +2. the DocumentPerson link must not be partially persisted on failure + +## 8. Submission Behavior + +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 + +Expected write sequence: +1. insert Document +2. insert Person only if needed +3. 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 + +## 9. Expected Result After Success + +After successful creation, the user should expect to see: +1. confirmation that the Document was created successfully +2. the Document name displayed in the resulting UI state +3. the Document metadata displayed on the new Document detail page +4. any linked person displayed in the resulting UI state +5. a Sources section showing an empty state when no sources exist yet +6. a Jobs section showing an empty state when no jobs exist yet +7. a clear next step, such as adding source files + +Recommended success route: +1. navigate to the new Document detail page +2. show Document summary metadata +3. show linked people section +4. show empty-state placeholders for Sources and Jobs + +## 10. Expected Result After Failure + +If submission fails, the user should expect: +1. clear error messaging +2. field-level validation feedback where applicable +3. no false success message +4. preservation of entered form values when possible + +Examples: +1. missing required name +2. missing required document type +3. failed person creation +4. failed DocumentPerson link creation +5. database or server error + +## 11. Non-Goals for This Flow + +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 + +Those actions belong to later workflows. + +## 12. Relationship to Other Workflows + +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 + +## 13. Relationship to Schema Mapping + +This document is the intended UX contract. + +The companion schema-mapping document should answer: +1. which schema field appears on which screen +2. whether the field is currently implemented +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 + +These topics are intentionally deferred to future revisions: +1. multiple linked people during create +2. recipient support during create +3. a broader role model for non-author document relationships +4. filtered Jobs and Sources list navigation details