Add curator Movement links config with proof URLs and admin-gated delete votes.

Persist lineage in PostgreSQL, seed documented edges, and keep timeline/tree consumers API-backed with a static fallback.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Danila KhodjaefandCursor committed 2026-09-08 14:37:20 +03:00
1 parent 2b4cdc5a9f
commit 1b760faf0d
36 files changed
+2051 -43

No files matched your search

+32
View File
@@ -33,6 +33,8 @@ erDiagram
paintings ||--o{ painting_influence_sources : influenced_by
artists ||--o{ painting_influence_sources : artist_source
art_movements ||--o{ painting_influence_sources : movement_source
art_movements ||--o{ movement_lineage_links : source
art_movements ||--o{ movement_lineage_links : target
```
## Tables
@@ -213,6 +215,36 @@ Unique index on `(painting_id, source_type, source_painting_id, source_artist_id
**Canonical influence store.** Used by all API influence queries: painting detail (`influencedBy`, `influenced`), `has_influence_links`, and artist hall navigation (predecessors / successors). Legacy `painting_influences` rows are backfilled here on migration; new curated painting edges are written to both tables by `update-influences`.
### `movement_lineage_links`
Art-movement predecessor → successor edges for the timeline flow and Tree of Art. Migration: `db/migrate-movement-links.sql`.
| Column | Type | Notes |
|--------|------|-------|
| `id` | SERIAL PK | |
| `source_movement_id` | FK → `art_movements` | Predecessor |
| `target_movement_id` | FK → `art_movements` | Successor (must differ from source) |
| `link_year_approx` | INTEGER | Approximate transition year |
| `proof_url` | TEXT NOT NULL | Required literature / museum / web citation URL |
| `proof_label` | TEXT | Short display label for the proof |
| `notes` | TEXT | Optional curator note |
| `created_by` | FK → `users` | Curator who added the row |
| `created_at` / `updated_at` | TIMESTAMPTZ | |
Unique on `(source_movement_id, target_movement_id)`.
### `movement_lineage_delete_votes`
Curator votes requesting deletion of a lineage link. Only **admins** may hard-delete the link. Migration: `db/migrate-movement-link-delete-votes.sql`.
| Column | Type | Notes |
|--------|------|-------|
| `id` | SERIAL PK | |
| `link_id` | FK → `movement_lineage_links` | Cascade on link delete |
| `user_id` | FK → `users` | One vote per user per link |
| `reason` | TEXT NOT NULL | Min 10 characters (trimmed) |
| `created_at` | TIMESTAMPTZ | |
### `users`
Staff accounts (named logins). Anonymous site visitors do not have rows here. Migration: `db/migrate-auth.sql` + `db/migrate-user-roles.sql`.