generated from john/python-template
V5.1 Modify Person table: split full name into first & last, added tags support
Quality Gate / gate (push) Failing after 11s
Quality Gate / gate (push) Failing after 11s
This commit is contained in:
@@ -33,7 +33,7 @@ uv run python tools/export_import_migration.py migrate --bundle-dir .migration-b
|
||||
|
||||
## What gets migrated
|
||||
|
||||
- Tables (in dependency order): `document_type`, `person_role`, `tag`, `document`, `person`, `photo`, `document_person`, `document_tag`, `job`, `source`, `job_source`, `execution_attempt`.
|
||||
- Tables (in dependency order): `document_type`, `person_role`, `tag`, `document`, `person`, `photo`, `document_person`, `document_tag`, `person_tag`, `job`, `source`, `job_source`, `execution_attempt`.
|
||||
- Media tree under `UPLOAD_DIR`.
|
||||
|
||||
The bundle contains:
|
||||
@@ -48,6 +48,7 @@ Legacy V4.x portrait/homepage backfill in the export step:
|
||||
- If the source DB has no `photo` table, the exporter synthesizes `photo` rows from legacy `person.portrait_path` values and from legacy homepage image files under `UPLOAD_DIR/homepage`.
|
||||
- Legacy portrait and homepage image files are copied into the unified `UPLOAD_DIR/photos/{photo_id}{suffix}` layout in the migration bundle.
|
||||
- Legacy homepage markdown is relocated from `UPLOAD_DIR/homepage/homepage.md` to `UPLOAD_DIR/homepage.md`.
|
||||
- Legacy `person.full_name` values are split into `given_names` + `last_name` for V5.1 schema compatibility.
|
||||
|
||||
## Cutover
|
||||
|
||||
|
||||
+27
-5
@@ -137,6 +137,25 @@ Migration policy for legacy installs:
|
||||
|
||||
---
|
||||
|
||||
## V5.1 — Person table structural redesign
|
||||
|
||||
- Replace `person.full_name` with split required fields:
|
||||
- `last_name`
|
||||
- `given_names` (first + middle)
|
||||
- Remove `display_name` and `maiden_name` from active schema/UI.
|
||||
- Keep `family_search_id` optional and unique (not required in this version).
|
||||
- Add `person_tag` many-to-many links so People use the same Tag registry as Documents.
|
||||
- Update Archival Entities: People list columns to:
|
||||
- Last Name
|
||||
- First & Middle
|
||||
- FamilySearch ID
|
||||
- Birth Date
|
||||
- Death Date
|
||||
- # Documents
|
||||
- Migration/export-import behavior backfills split names from legacy `full_name` values.
|
||||
|
||||
---
|
||||
|
||||
## V6.0 — Server Hosting Migration
|
||||
|
||||
Your stated approach (Postgres in Docker, app in Docker, Cloudflare Tunnel) is
|
||||
@@ -210,8 +229,11 @@ forecloses them later:
|
||||
|
||||
---
|
||||
|
||||
## Open items for you
|
||||
- V5.0 unified `photos` table: needs the follow-up design discussion you
|
||||
flagged (exact schema, how photos link to homepage vs. person context)
|
||||
before implementation.
|
||||
- Confirm this version numbering/grouping matches your intent before work starts.
|
||||
## Current status
|
||||
- V5.0 unified photos has been implemented with:
|
||||
- shared `photo` table (`person_id` nullable for homepage ownership),
|
||||
- flat media storage under `UPLOAD_DIR/photos/{photo_id}{suffix}`,
|
||||
- migration backfill from legacy Person portraits and homepage images,
|
||||
- homepage markdown relocated to `UPLOAD_DIR/homepage.md`.
|
||||
- Version numbering/grouping is now established by implementation and can
|
||||
proceed to V5.1 planning/execution.
|
||||
|
||||
+17
-3
@@ -22,9 +22,11 @@ erDiagram
|
||||
Document ||--o{ DocumentPerson : links
|
||||
Document ||--o{ DocumentTag : tagged
|
||||
Person ||--o{ DocumentPerson : links
|
||||
Person ||--o{ PersonTag : tagged
|
||||
Person ||--o{ Photo : owns
|
||||
PersonRole ||--o{ DocumentPerson : labels
|
||||
Tag ||--o{ DocumentTag : labels
|
||||
Tag ||--o{ PersonTag : labels
|
||||
Job ||--o{ JobSource : includes
|
||||
Source ||--o{ JobSource : participates
|
||||
JobSource ||--o{ ExecutionAttempt : attempts
|
||||
@@ -110,9 +112,8 @@ erDiagram
|
||||
| Field | Type | Notes |
|
||||
| :--- | :--- | :--- |
|
||||
| `id` | `UUID` | PK |
|
||||
| `full_name` | `str` | required |
|
||||
| `display_name` | `str \| None` | optional |
|
||||
| `maiden_name` | `str \| None` | optional |
|
||||
| `last_name` | `str` | required |
|
||||
| `given_names` | `str` | required |
|
||||
| `birth_date` | `date \| None` | optional |
|
||||
| `birth_date_raw` | `str \| None` | optional |
|
||||
| `birth_place` | `str \| None` | optional |
|
||||
@@ -164,6 +165,19 @@ Constraint:
|
||||
Constraint:
|
||||
- `UniqueConstraint(document_id, tag_id)` named `uq_document_tag`
|
||||
|
||||
### `PersonTag`
|
||||
|
||||
| Field | Type | Notes |
|
||||
| :--- | :--- | :--- |
|
||||
| `id` | `UUID` | PK |
|
||||
| `person_id` | `UUID` | FK -> `person.id`, indexed |
|
||||
| `tag_id` | `UUID` | FK -> `tag.id`, indexed |
|
||||
| `created_at` | `datetime` | default now |
|
||||
| `updated_at` | `datetime` | default now, onupdate |
|
||||
|
||||
Constraint:
|
||||
- `UniqueConstraint(person_id, tag_id)` named `uq_person_tag`
|
||||
|
||||
### `Job`
|
||||
|
||||
| Field | Type | Notes |
|
||||
|
||||
+12
-11
@@ -19,9 +19,9 @@ People manages reusable historical-person records. A Person may appear in many D
|
||||
|
||||
- The title is **Archival Entities: People**.
|
||||
- **Create new person** opens the create route.
|
||||
- The table defaults to Full Name order and supports search and column sorting.
|
||||
- Columns are Full Name, FamilySearch ID, Birth Date, Death Date, and # Documents.
|
||||
- Full Name is left-aligned; FamilySearch ID, date columns, and # Documents are centered.
|
||||
- The table defaults to Last Name order and supports search and column sorting.
|
||||
- Columns are Last Name, First & Middle, FamilySearch ID, Birth Date, Death Date, and # Documents.
|
||||
- Last Name and First & Middle are left-aligned; FamilySearch ID, date columns, and # Documents are centered.
|
||||
- # Documents reflects how many linked Documents each Person is connected to.
|
||||
- Birth and death values independently prefer exact date, then approximate date, then `Unknown`.
|
||||
- Selecting a row opens Person Detail.
|
||||
@@ -31,35 +31,36 @@ People manages reusable historical-person records. A Person may appear in many D
|
||||
|
||||
Required:
|
||||
|
||||
- Full name.
|
||||
- Last name.
|
||||
- First & middle names.
|
||||
|
||||
Optional:
|
||||
|
||||
- Display name and maiden name.
|
||||
- Exact and approximate birth/death dates.
|
||||
- Birth/death places.
|
||||
- Biography.
|
||||
- FamilySearch ID.
|
||||
- Tags.
|
||||
|
||||
Rules:
|
||||
|
||||
- Missing Full name blocks save with a warning.
|
||||
- Missing last name or first/middle names blocks save with a warning.
|
||||
- Exact date inputs are native browser date inputs.
|
||||
- FamilySearch IDs are normalized and validated by `PeopleService`.
|
||||
- Photos are managed on Person Detail (not in create/edit form fields).
|
||||
- Tags use the shared Tag registry and support inline add/select behavior.
|
||||
- Photos are managed from Person Detail via `/people/{person_id}/photos` (not in create/edit form fields).
|
||||
- Metadata JSON remains hidden.
|
||||
- Save success returns to Person Detail.
|
||||
|
||||
## Detail Behavior
|
||||
|
||||
- The header provides **New Document**, **Edit Person**, and **Delete**.
|
||||
- The header provides **New Document**, **Edit Person**, **Edit Photo(s)**, and **Delete**.
|
||||
- **New Document** opens Document creation with this Person requested for author preselection.
|
||||
- Person Detail shows a single-photo viewer with **Previous/Next** navigation; the page-level **Edit Photo(s)** header action opens photo management.
|
||||
- Photo management (upload, description edit, set-primary, delete) is intentionally moved to `/people/{person_id}/photos`.
|
||||
- Biographical Record shows names, compact birth/death dates, and places.
|
||||
- Biographical Record shows split names, computed full name, tags, compact birth/death dates, and places.
|
||||
- Birth and death place values are clickable links to Google Maps when present.
|
||||
- FamilySearch ID is shown as a metadata value and is clickable to the FamilySearch person details route when present.
|
||||
- Maiden Name is only shown in Biographical Record when a value exists.
|
||||
- Biography has an explicit empty value.
|
||||
- Linked Documents render as a table with **Document Name**, **Role**, and **Number of Pages**; selecting a row opens Document Detail.
|
||||
- No links shows both an empty state and guidance to link from a Document workflow.
|
||||
@@ -83,7 +84,7 @@ Rules:
|
||||
## Acceptance Checklist
|
||||
|
||||
- List fields, alignment, date fallback, search, sorting, and navigation match this contract.
|
||||
- Full name is enforced on create and edit.
|
||||
- Last name and first/middle names are enforced on create and edit.
|
||||
- FamilySearch ID validation and link generation use the fixed supported identifier format.
|
||||
- Photo upload and rendering remain constrained to supported media paths.
|
||||
- New Document carries the Person context.
|
||||
|
||||
Reference in New Issue
Block a user