V4.1 Mostly UI adjustments by GC

This commit is contained in:
Jim Lancaster
2026-08-12 13:11:50 -05:00
parent 1e8d8572d4
commit 89cf69f8a2
29 changed files with 1261 additions and 404 deletions
+146
View File
@@ -0,0 +1,146 @@
# Implementation Plan (Version 4.1)
## Goal
Deliver the V4.1 usability revision as a small, behavior-safe increment over the V4 baseline.
## Implementation Principles
- Keep presentation formatting in UI components and route orchestration in pages.
- Keep persistence and cross-record queries behind service boundaries.
- Reuse shared table and date-label helpers instead of duplicating fallback logic.
- Make the FamilySearch schema change additive and nullable.
- Add focused tests for changed behavior before broad regression verification.
## Current Project Impact
| Area | Expected impact |
| --- | --- |
| Persistence | Add nullable `Person.family_search_id`; provide the repository's supported schema-upgrade path for existing databases. |
| People service | Normalize and validate FamilySearch IDs at the domain/service boundary if model validation does not fully cover writes. |
| Documents UI | Add table data, improve relationship labels/links, compact date display, and combine processing navigation. |
| People UI | Add table date fields, Person-first Document creation, compact date display, and FamilySearch controls. |
| Sources service/UI | Query adjacent document Sources and add bounded navigation; revise list columns and wrapping. |
| Jobs UI | Refresh the active detail read model on a timer until terminal status. |
| Shared UI | Add reusable constrained/wrapped table presentation and compact date formatting where appropriate. |
| Tests | Update model/service and UI coverage for all affected workflows. |
## Implementation Phases
### 1. Add Shared Presentation Rules
- Review `ui/components/table/common.py` and packaged theme CSS for the narrowest reusable table-width solution.
- Add reusable styles or column slots for constrained, wrapping, left-aligned text.
- Add a shared formatter for exact/approximate/unknown dates if it can be reused without coupling components to persistence.
- Preserve sorting and search behavior for rendered display values.
### 2. Update Archival List Tables
- Extend the Document table read model with author names and the compact document date.
- Build author display from eagerly loaded document-person links using the `author` role.
- Apply title/type alignment and constrained title wrapping.
- Extend the Person table read model with compact birth and death date values.
- Apply Display Name and Maiden Name alignment.
- Remove Stored Filename from the Source table read model only if no other list behavior consumes it; always remove its rendered column.
- Constrain and left-align the requested Source columns.
- Add or update UI component tests for serialized rows, columns, and fallback formatting.
### 3. Improve Document Relationship Workflows
- Introduce one person-label formatter that combines preferred Display Name, Full Name context, and known birth year without implying uniqueness.
- Use Person UUIDs as selector values.
- Apply the formatter to every relationship role selector.
- Change Related People rows into actions that navigate to `/people/{person_id}`.
- Replace separate exact/approximate rows in view mode with one conditional Document Date row.
- Combine Pipeline Jobs and Sources into one related-processing card beneath Related People.
- Preserve existing job/source counts and navigation actions.
### 4. Add the Person-First Document Workflow
- Add a New Document action on Person Detail.
- Pass the Person UUID through a narrowly defined query parameter to `/documents/new`.
- Validate the requested UUID against the loaded people list.
- Preselect that person in the intended default relationship role. Use `author` unless a different role is explicitly encoded later.
- Ignore invalid or unavailable preselection values with the application's normal visible error/notification behavior.
- Confirm ordinary `/documents/new` behavior remains unchanged.
### 5. Add FamilySearch Person References
- Add nullable, unique `family_search_id` to the `Person` model and schema.
- Implement a non-destructive upgrade for existing SQLite and PostgreSQL databases using the repository's established schema-management approach.
- Normalize values by trimming and uppercasing.
- Validate the `XXXX-XXX` alphanumeric identifier shape and return a clear validation error for malformed input.
- Report duplicate identifiers as a deterministic conflict rather than a generic persistence failure.
- Add the field to Person create/edit forms and preserve it during updates.
- Add a URL builder that safely inserts only a validated identifier into the fixed FamilySearch details URL.
- Render a FamilySearch action on Person Detail only when an identifier is present.
- Add persistence, normalization, validation, form, and link-generation tests.
### 6. Add Source Page Navigation
- Add a Sources service query that returns previous/current/next context for a Source within its Document.
- Define ordering by `page_number`, with a stable secondary key such as Source UUID for defensive determinism.
- Keep navigation bounded to the current `document_id`.
- Render previous and next actions adjacent to the source viewer or detail header.
- Disable or omit unavailable boundary actions.
- Test first, middle, last, single-page, and cross-document cases.
### 7. Add Job Detail Auto-Refresh
- Make Job Detail content refreshable without rebuilding unrelated global navigation.
- Start a NiceGUI timer only for queued or processing jobs.
- On each tick, re-read the Job through `JobService` and refresh the detail content.
- Use a 4-second default interval.
- Stop or deactivate the timer when status becomes completed, partial success, failed, or cancelled, according to the model's actual terminal states.
- Prevent overlapping refresh callbacks.
- Retain existing error presentation if a refresh read fails.
- Add UI tests for timer creation, refresh, and terminal-state stopping.
### 8. Simplify View-Mode Date Rows
- On Document Detail, show exact date, else approximate date, else one not-set value.
- On Person Detail, apply the same independent rule to birth and death.
- Do not hide either input in create/edit mode.
- Test each exact, approximate, and absent state.
### 9. Verification and Documentation Alignment
- Run the focused model/service/UI tests covering changed surfaces.
- Run the existing regression suite appropriate to persistence and UI changes.
- Confirm SQLite and PostgreSQL model compatibility at the schema-definition level.
- Update V4.1 documentation if implementation reveals a necessary boundary change; do not silently expand scope.
## Recommended Delivery Order
1. Shared formatters and table presentation.
2. Additive Person schema change and FamilySearch validation.
3. Document and Person list/detail changes.
4. Person-first Document workflow.
5. Source navigation.
6. Job polling.
7. Focused and regression verification.
## Done When
- Every V4.1 acceptance criterion is demonstrated or covered by a focused test.
- Existing Person rows remain valid after the nullable schema addition.
- Duplicate FamilySearch references cannot be assigned to multiple local Person records.
- FamilySearch links are generated only from normalized, validated IDs.
- Auto-refresh performs no polling after a terminal job state.
- Adjacent Source navigation never crosses Document boundaries.
- The existing V4 workflows remain operational.
## Out of Scope
- Page reordering.
- Settings management.
- External genealogy API integration.
- Raw `.env` editing.
- Theme editing.
## Related Local References
- [V4.1 Scope Boundary](scope_boundary_v4_1.md)
- [V4 Implementation Plan](../ver4/implementation_plan_v4.md)
- [V4 Requirements](../ver4/requirements_v4.md)
- [V4 Error Handling Policy](../ver4/error_handling_v4.md)
+142
View File
@@ -0,0 +1,142 @@
# V4.1 Scope Boundary
This document defines the scope of the first incremental revision to Version 4. V4 remains the product and architecture baseline; V4.1 adds focused usability improvements and one additive Person field.
## Purpose
- Improve common archival record workflows without redesigning the application.
- Resolve table overflow, ambiguous person selection, and unnecessary navigation.
- Add a manually maintained FamilySearch person reference without introducing external API integration.
## In Scope
### 1. Archival Documents List
- Keep every table column within the available page width.
- Limit and wrap long Document Title values.
- Left-align Document Title and Type.
- Add Author and Document Date columns.
- Display all people linked through the `author` role in the Author column.
- Display exact document date when present, otherwise approximate date when present, otherwise `Unknown`.
### 2. Document Detail and Editing
- Use an unambiguous label in person selectors. The label should prefer Display Name, retain Full Name for context, and include the birth year when known.
- Do not require Display Name to be unique.
- Link each Related People entry to its Person Detail page.
- In view mode, display only the populated exact or approximate document date row. Display a single unknown/not-set state when neither exists.
- Keep both exact and approximate inputs available in create/edit mode.
- Move source navigation out from beneath the media viewer.
- Present Pipeline Jobs and Sources together in one related-processing card with counts and actions.
### 3. People List
- Left-align Display Name and Maiden Name.
- Display exact birth date when present, otherwise approximate birth date when present, otherwise `Unknown`.
- Add a Death Date column with the same fallback rule.
### 4. Person Detail and Editing
- Add a New Document action that opens Document creation with the current person preselected.
- Preserve the existing Document-first workflow.
- In view mode, display only the populated exact or approximate row for each of birth and death date. Display a single unknown/not-set state when neither value exists.
- Keep both exact and approximate inputs available in create/edit mode.
### 5. FamilySearch Reference
- Add a nullable, unique `family_search_id` field to `Person`.
- Allow the field to be entered and changed in Person create/edit flows.
- Trim whitespace, normalize the identifier to uppercase, and validate it against the supported
`XXXX-XXX` alphanumeric shape before persistence.
- When an identifier exists, show a FamilySearch action on Person Detail linking to:
`https://www.familysearch.org/tree/person/details/{family_search_id}`
- Construct the URL in application code; do not persist the full URL.
### 6. Source List and Detail
- Keep every Source Asset Records table column within the available page width.
- Limit and wrap long Document Name, Upload Title, and Error Detail values.
- Left-align Document Name, Upload Title, and Error Detail.
- Remove Stored Filename only from the Source Asset Records table. Continue storing it and showing it on Source Detail.
- On Source Detail, add previous and next navigation for Sources belonging to the same Document, ordered by `page_number`.
- Disable or omit the previous/next action at the first/last page.
### 7. Job Detail
- Automatically refresh Job Detail while the job is in a non-terminal state.
- Use a modest interval in the 3-5 second range.
- Stop polling when the job reaches a terminal state or the page is no longer active.
- Preserve manual navigation and existing job actions.
### 8. Homepage Storage Decision
- Continue treating homepage markdown and images as mutable application data, not prompt artifacts or packaged source assets.
- Keep homepage content separate from `prompts`.
- Defer relocation to a configurable application-data root unless the existing location prevents normal installed or deployed operation.
## Out of Scope
- Source page renumbering or reordering.
- A Settings page.
- Editing `.env` or secrets through the UI.
- Runtime theme editing.
- FamilySearch authentication, API calls, search, import, synchronization, or conflict resolution.
- Ancestry references or other genealogy providers.
- Google Maps links from place fields.
- Enforcing unique Display Name values.
- Changes to transcription execution or provider behavior.
- Changes to the V4 API solely to expose the V4.1 presentation enhancements.
## Locked Design Decisions
### A. Person Selector Identity
- Selection values remain internal Person UUIDs.
- Display labels provide disambiguating context but are not identity keys.
- Duplicate Full Name and Display Name values remain valid.
### B. Date Presentation
- Exact dates take precedence over approximate/raw dates for compact list and view presentation.
- Create/edit forms retain both fields so either representation can be maintained.
- V4.1 does not introduce a new mutual-exclusion database constraint.
### C. FamilySearch Storage
- Store only the FamilySearch person identifier.
- Treat a FamilySearch person identifier as unique across local Person records.
- Use one dedicated nullable Person field while FamilySearch is the only supported external genealogy reference.
- Reconsider a generic external-reference model only when a second provider or multiple references per person are required.
### D. Stored Filename
- Stored Filename remains part of the Source model and Source Detail diagnostics.
- Only the list-table column is removed.
## Data and Compatibility Policy
- The `family_search_id` addition must be nullable and non-destructive for existing Person rows.
- Existing records, routes, relationships, jobs, Sources, prompt provenance, and uploaded media remain valid.
- UI changes must preserve both Document-first and Person-first workflows.
- V4.1 must remain portable across SQLite and PostgreSQL.
## Acceptance Criteria
1. Document, Person, and Source tables fit their page containers at supported desktop widths without losing requested columns.
2. Long table text wraps or is constrained without forcing important columns outside the table container.
3. Duplicate-named people can be distinguished in every document relationship selector.
4. Related People entries navigate to the correct Person Detail page.
5. Compact date displays consistently use exact, then approximate, then unknown fallback behavior.
6. Starting from Person Detail can create a Document with that person preselected without breaking normal Document creation.
7. A valid FamilySearch ID is persisted and produces the correct Person Detail hyperlink; absent IDs produce no action.
8. Source previous/next actions remain within the same Document and follow `page_number`.
9. Active Job Detail pages update without manual refresh and stop polling after terminal status.
10. Stored Filename is absent from the Source list table but remains available on Source Detail.
11. Focused automated tests pass and unaffected V4 behavior remains intact.
## Related Local References
- [V4.1 Implementation Plan](implementation_plan_v4_1.md)
- [V4 Scope Boundary](../ver4/scope_boundary_v4.md)
- [V4 Architecture](../ver4/architecture_v4.md)
- [V4 Schema](../ver4/schema_v4.md)