Files
Art-gallery/Documentation/API.md
T
Danila KhodjaefandCursor 08f99d7a29 Redesign 3D gallery as single hall per artist with exit navigation.
Restore React client source, add hall-to-hall navigation via painting influences grouped by movement, and update documentation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-19 10:10:13 +03:00

4.9 KiB
Raw Blame History

Art Gallery — REST API

Base URL in development:

  • Direct: http://localhost:3001
  • Via Vite proxy: http://localhost:5173 (same paths)

All JSON responses use Content-Type: application/json. Errors return { "error": "message" } with an appropriate HTTP status.

Static images are served at /images/<relative-path> from IMAGE_DIR.


GET /api/bounds

Returns the overall timeline year range used to initialise the zoomable timeline.

Response

{
  "min_year": -800,
  "max_year": 2100
}

min_year is the earliest art movement start; max_year is the latest of era ends, movement ends, and artist death years.


GET /api/timeline

Historical eras and art movements overlapping a year window.

Query

Param Type Default Description
start int -3000 Window start year
end int 2100 Window end year

Response

{
  "eras": [ { "id": 1, "name": "Renaissance", "start_year": 1300, "end_year": 1600, "start_definite": false, "end_definite": false, "description": "...", "sort_order": 3 } ],
  "movements": [ { "id": 5, "name": "Impressionism", "start_year": 1860, "end_year": 1890, "era_id": 6, "era_name": "Modern", "color": "#87CEEB", ... } ]
}

Movements are filtered to those with at least one artist active in the requested range.


GET /api/artists

Artists for timeline portraits and movement bands.

Query

Param Type Description
start int Only artists alive after this year
end int Only artists born before this year
movement_id int Filter by movement

Response — array of artist objects with joined movement_name and movement_color.


GET /api/movements/:id/artists

Artists belonging to a single movement.

Response — array of { id, name, birth_year, death_year, portrait_path, bio_short }.


GET /api/artists/:id

Full artist profile for the bio page and 3D gallery entry.

Response

{
  "artist": { "id": 1, "name": "...", "movement_name": "...", "bio_full": "...", ... },
  "periods": [ { "id": 1, "name": "Milan Period", "start_year": 1482, "end_year": 1499, ... } ],
  "paintings": [ { "id": 10, "title": "...", "year": 1498, "image_path": "...", "thumbnail_path": "...", ... } ]
}

GET /api/artists/:id/navigation

Related artists for hall-to-hall navigation at the exit doorway. Derived from painting_influences:

  • Predecessors — artists whose works influenced this artists paintings.
  • Successors — artists whose works were influenced by this artists paintings.

Both lists are grouped by art movement and exclude the current artist.

Response

{
  "predecessors": [
    {
      "movement_id": 4,
      "movement_name": "Early Renaissance",
      "movement_color": "#B8860B",
      "artists": [
        {
          "id": 12,
          "name": "Domenico Ghirlandaio",
          "birth_year": 1448,
          "death_year": 1494,
          "portrait_path": "portraits/Domenico_Ghirlandaio.jpg"
        }
      ]
    }
  ],
  "successors": []
}

POST /api/artists/:id/preload-images

Fast local scan: links paintings to files already on disk. Does not download from the internet (safe to call before opening the 3D gallery).

Response

{ "fetched": 12, "total": 15 }

fetched counts paintings with a resolvable local image after the scan.


GET /api/paintings/:id

Painting detail with influence graph neighbours.

Response

{
  "painting": { "id": 10, "title": "...", "artist_name": "...", "image_path": "...", ... },
  "influencedBy": [ { "id": 3, "title": "...", "artist_name": "...", "notes": "...", "aspects": "...", "quote": "...", "source_author": "...", ... } ],
  "influenced": [ { "id": 20, "title": "...", ... } ]
}

GET /api/paintings/:id/image

Serves a painting image file. Resolves and caches from external sources only when no local file exists.

Query

Param Values Default
size thumb, full thumb

Returns the image bytes with Cache-Control: public, max-age=86400, or 404 if unavailable.


Frontend helpers

The React client wraps these endpoints in client/src/api/client.ts:

Function Maps to
api.getBounds() GET /api/bounds
api.getTimeline(start, end) GET /api/timeline
api.getArtists(...) GET /api/artists
api.getArtist(id) GET /api/artists/:id
api.getArtistNavigation(id) GET /api/artists/:id/navigation
api.getPainting(id) GET /api/paintings/:id
preloadArtistImages(id) POST /api/artists/:id/preload-images
imageUrl(path) /images/<path> or placeholder
galleryImageUrl(painting) Local thumb/full only (3D)
paintingImageUrl(painting) Local file or on-demand API