Add Russian i18n with DB translations, locale API, and curator review UI.
UI chrome via react-i18next, catalog text in entity_translations with ru.wikipedia seeding, locale-aware search, and Translations page for publish workflow. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
f247b418d8
commit
ca58c43648
@@ -171,6 +171,32 @@ Movements are filtered to those with at least one artist active in the requested
|
||||
|
||||
---
|
||||
|
||||
## Locale (`?locale=ru`)
|
||||
|
||||
Public catalog endpoints accept optional **`locale`** query param (`en` default, `ru` supported) or `Accept-Language: ru`.
|
||||
|
||||
Affected routes: `/api/catalog/bootstrap`, `/api/timeline`, `/api/search`, `/api/artists`, `/api/artists/:id`, `/api/paintings/:id`, `/api/movements/:id/gallery`, `/api/movements/:id/artists`, `/api/artists/:id/navigation`.
|
||||
|
||||
Responses include `"locale": "ru"` when resolved. Display field names are unchanged; values come from `entity_translations` when `status = published`, else canonical English.
|
||||
|
||||
Full guide: [i18n-russian.md](i18n-russian.md).
|
||||
|
||||
---
|
||||
|
||||
## Translations (curator)
|
||||
|
||||
Requires curator session. Base path: `/api/translations`.
|
||||
|
||||
| Method | Path | Purpose |
|
||||
|--------|------|---------|
|
||||
| `GET` | `/api/translations/coverage?locale=ru` | Coverage stats |
|
||||
| `GET` | `/api/translations/worklist/:entityType?locale=ru` | Artists/paintings/movements with translation status |
|
||||
| `GET` | `/api/translations/:entityType/:id` | Canonical + all translation rows |
|
||||
| `PUT` | `/api/translations/:entityType/:id` | Upsert fields `{ locale, fields, status }` |
|
||||
| `POST` | `/api/translations/:entityType/:id/publish` | Publish all draft/reviewed rows for locale |
|
||||
|
||||
---
|
||||
|
||||
## `GET /api/search`
|
||||
|
||||
Public catalog search over **artists**, **paintings**, and **art movements**. Used by the timeline header search bar (`CatalogSearchBar.tsx`).
|
||||
@@ -182,6 +208,7 @@ Public catalog search over **artists**, **paintings**, and **art movements**. Us
|
||||
| `q` | string | — | Search text (min **2** characters after trim; shorter returns `{ q, results: [] }`) |
|
||||
| `limit` | int | 20 | Max results total (capped at **50**) |
|
||||
| `types` | string | all | Optional comma list: `artist`, `painting`, `movement` |
|
||||
| `locale` | string | `en` | `ru` — search and return published Russian aliases when available |
|
||||
|
||||
**Matching (case-insensitive `ILIKE`):**
|
||||
|
||||
@@ -190,6 +217,7 @@ Public catalog search over **artists**, **paintings**, and **art movements**. Us
|
||||
| Artist | `name`, `wikipedia_title`, movement name |
|
||||
| Movement | movement `name`, era name |
|
||||
| Painting | `title`, `wikipedia_title`, `year` (as text), artist name, movement name |
|
||||
| All (when `locale=ru`) | Published rows in `entity_translations` for `name` / `title` |
|
||||
|
||||
Prefix matches on primary labels (`name` / `title`) rank before substring matches.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user