Fix debug upload persistence and UX; exclude prod audit log from DB restore
Uploads and fixes now bust browser cache via file-mtime keys in API responses. Debug upload shows a centered loading overlay and blocks search while uploading. Prod DB restore skips curator_audit_log. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
62096e8210
commit
f78c14f307
+24
-7
@@ -17,6 +17,8 @@ All JSON responses use `Content-Type: application/json`. Errors return `{ "error
|
||||
|
||||
Static images are served at `/images/<relative-path>` from `IMAGE_DIR`.
|
||||
|
||||
**Caching:** `/images` responses use `Cache-Control: public, max-age=0, must-revalidate` with `ETag` / `Last-Modified`. Painting and artist JSON payloads include optional **`image_cache_key`** / **`thumbnail_cache_key`** (and **`portrait_cache_key`** / **`portrait_thumb_cache_key`** on artists) — Unix ms from the file’s `mtime` on disk. The client appends `?v=<key>` to image URLs so fix/upload/clear updates show immediately after reload even when the relative path is unchanged.
|
||||
|
||||
**Quick check:**
|
||||
|
||||
```powershell
|
||||
@@ -440,7 +442,18 @@ Painting detail with influence graph neighbours.
|
||||
|
||||
```json
|
||||
{
|
||||
"painting": { "id": 10, "title": "...", "artist_name": "...", "image_path": "...", "checkup_checked": false, "checkup_fixed": false, "has_influence_links": true, ... },
|
||||
"painting": {
|
||||
"id": 10,
|
||||
"title": "...",
|
||||
"artist_name": "...",
|
||||
"image_path": "paintings/Artist_Title.jpg",
|
||||
"thumbnail_path": "paintings/thumbs/Artist_Title_thumb.jpg",
|
||||
"image_cache_key": 1739123456789,
|
||||
"thumbnail_cache_key": 1739123456790,
|
||||
"checkup_checked": false,
|
||||
"checkup_fixed": false,
|
||||
"has_influence_links": true
|
||||
},
|
||||
"influencedBy": [
|
||||
{
|
||||
"source_type": "painting",
|
||||
@@ -600,6 +613,8 @@ Only `imageUrl` is required; optional fields improve fetch success for hotlinked
|
||||
{
|
||||
"imagePath": "paintings/Artist_Title.jpg",
|
||||
"thumbnailPath": "paintings/thumbs/Artist_Title_thumb.jpg",
|
||||
"image_cache_key": 1739123456789,
|
||||
"thumbnail_cache_key": 1739123456790,
|
||||
"fixed": true,
|
||||
"checked": true
|
||||
}
|
||||
@@ -660,7 +675,7 @@ Upload a local painting image (base64 JSON body). Validates with `sharp`, writes
|
||||
}
|
||||
```
|
||||
|
||||
Max decoded size 15 MB (JSON body limit 20 MB on the server). **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`, `image_cache_key`, `thumbnail_cache_key`, `fixed`, `checked`).
|
||||
|
||||
---
|
||||
|
||||
@@ -711,11 +726,13 @@ The React client wraps these endpoints in `client/src/api/client.ts`. All reques
|
||||
| `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) |
|
||||
| `galleryImageUrlWithRevision(painting, revision)` | Local URL with `?v=` cache buster after fix |
|
||||
| `paintingImageUrl(painting)` | Local file, on-demand API, or `null` when cleared (`checkup_fixed` + no paths) |
|
||||
| `portraitUrl(path, revision?)` | `/images/<path>` with optional `?v=` cache buster |
|
||||
| `imageUrl(path, revision?)` | `/images/<path>` or placeholder; optional `?v=` cache buster |
|
||||
| `paintingImageRevision(painting, sessionRevision?)` | Prefer API `image_cache_key` / `thumbnail_cache_key`, else in-session counter |
|
||||
| `galleryImageUrl(painting, sessionRevision?)` | Local thumb/full only (3D); auto `?v=` from cache keys |
|
||||
| `galleryImageUrlWithRevision(painting, sessionRevision?)` | Alias of `galleryImageUrl` |
|
||||
| `paintingImageUrl(painting, sessionRevision?)` | Local file, on-demand API, or `null` when cleared (`checkup_fixed` + no paths) |
|
||||
| `portraitUrl(path, revision?, artist?)` | `/images/<path>` with `?v=` from revision or artist cache keys |
|
||||
| `validateDebugUploadFile(file)` | Client-side size/type check before base64 upload |
|
||||
| `api.getPaintingCheckup()` | `GET /api/paintings/checkup` |
|
||||
| `api.updatePaintingCheckupFlags(id, flags)` | `PATCH /api/paintings/:id/checkup-flags` |
|
||||
| `api.getPaintingDebugImageSearch(id)` | `GET /api/paintings/:id/debug-image-search` |
|
||||
|
||||
Reference in New Issue
Block a user