Add movement gallery wings with period interiors and expand timeline features.
Movement galleries split large catalogs into chronological wings (~55 works), use era-themed 3D interiors with side-wall windows, wing navigator on the back exit, and front archways between wings. Also adds painting annotations, timeline event guides, portrait hover highlights, and documentation/API updates. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
0972b5df99
commit
df29848d89
+72
-5
@@ -76,6 +76,54 @@ Artists belonging to a single movement.
|
||||
|
||||
---
|
||||
|
||||
## `GET /api/movements/:id/gallery`
|
||||
|
||||
Full **movement gallery** payload for the 3D movement wings view (opened by clicking a movement name on the home page).
|
||||
|
||||
**Response**
|
||||
|
||||
```json
|
||||
{
|
||||
"movement": {
|
||||
"id": 34,
|
||||
"name": "Baroque",
|
||||
"start_year": 1600,
|
||||
"end_year": 1750,
|
||||
"era_id": 6,
|
||||
"era_name": "Baroque",
|
||||
"color": "#8B4513",
|
||||
...
|
||||
},
|
||||
"paintings": [
|
||||
{
|
||||
"id": 120,
|
||||
"title": "...",
|
||||
"year": 1640,
|
||||
"artist_id": 5,
|
||||
"artist_name": "Rembrandt",
|
||||
"image_path": "paintings/...",
|
||||
"thumbnail_path": "paintings/thumbs/...",
|
||||
"checkup_checked": false,
|
||||
"checkup_fixed": false,
|
||||
"has_influence_links": true,
|
||||
...
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Meaning |
|
||||
|-------|---------|
|
||||
| `movement.era_name` | Joined from `historical_eras` — used to pick period interior styling |
|
||||
| `paintings[].artist_name` | Artist display name for frame captions (`year · artist`) |
|
||||
| `paintings` order | Chronological: `year`, then `sort_order`, artist birth year, title |
|
||||
|
||||
Includes all paintings whose `artist.movement_id` matches `:id`. Returns **404** if the movement does not exist.
|
||||
|
||||
**Client:** `api.getMovementGallery(id)` in `client/src/api/client.ts`; rendered by `VirtualGallery` in `mode: 'movement'`.
|
||||
|
||||
---
|
||||
|
||||
## `GET /api/artists/:id`
|
||||
|
||||
Full artist profile for the bio page and 3D gallery entry.
|
||||
@@ -152,11 +200,13 @@ Up to 20 ranked portrait candidates for the **More** picker modal.
|
||||
"searchUrl": "https://…",
|
||||
"source": "google-custom-search",
|
||||
"results": [
|
||||
{ "imageUrl": "https://…", "thumbUrl": "https://…", "source": "google-custom-search" }
|
||||
{ "imageUrl": "https://…", "thumbUrl": "https://…", "source": "google-custom-search", "width": 1200, "height": 1600 }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Each result may include optional `width` and `height` (pixels). The **More** modal shows these under each thumbnail; when missing, the client probes dimensions via `GET /api/debug/image-proxy`.
|
||||
|
||||
---
|
||||
|
||||
## `POST /api/artists/:id/fix-portrait`
|
||||
@@ -206,7 +256,7 @@ Upload a local image (base64 JSON body). Validates with `sharp`, resizes to port
|
||||
}
|
||||
```
|
||||
|
||||
Max size 15 MB. **Response** — same as `fix-portrait`.
|
||||
Max decoded size 15 MB (JSON body limit 20 MB on the server). **Response** — same as `fix-portrait`.
|
||||
|
||||
---
|
||||
|
||||
@@ -286,7 +336,22 @@ Painting detail with influence graph neighbours.
|
||||
"period_start_year": 1905, "period_end_year": 1907
|
||||
}
|
||||
],
|
||||
"influenced": [ { "source_type": "painting", "id": 20, "title": "...", ... } ]
|
||||
"influenced": [ { "source_type": "painting", "id": 20, "title": "...", ... } ],
|
||||
"annotations": [
|
||||
{
|
||||
"id": 1,
|
||||
"label": "Central figure",
|
||||
"body": "Short art-history note…",
|
||||
"category": "subject",
|
||||
"pos_x": 42.5,
|
||||
"pos_y": 38.0,
|
||||
"source_author": "E.H. Gombrich",
|
||||
"source": "The Story of Art",
|
||||
"source_url": "https://…",
|
||||
"sort_order": 0,
|
||||
"confidence": "curated"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -427,11 +492,13 @@ Up to 20 ranked painting image candidates for the **More** picker modal.
|
||||
"searchUrl": "https://…",
|
||||
"source": "google-arts",
|
||||
"results": [
|
||||
{ "imageUrl": "https://…", "thumbUrl": "https://…", "source": "google-arts" }
|
||||
{ "imageUrl": "https://…", "thumbUrl": "https://…", "source": "google-arts", "width": 2400, "height": 1800 }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Optional `width` / `height` on each result — see portrait **more** endpoint above.
|
||||
|
||||
---
|
||||
|
||||
### `POST /api/paintings/:id/clear-image`
|
||||
@@ -464,7 +531,7 @@ Upload a local painting image (base64 JSON body). Validates with `sharp`, writes
|
||||
}
|
||||
```
|
||||
|
||||
Max size 15 MB. **Response** — same shape as `fix-image` (`imagePath`, `thumbnailPath`, `fixed`, `checked`).
|
||||
Max decoded size 15 MB (JSON body limit 20 MB on the server). **Response** — same shape as `fix-image` (`imagePath`, `thumbnailPath`, `fixed`, `checked`).
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user