Skip to content

Image Gallery

The old React front-end had a dedicated image gallery feature (upload, browse, and select images for use as client logos, brand images, and so on), backed by an ImageGallery component and an ImageSelectionModal. That frontend feature has not been carried over to tracker-frontend-svelte or tracker-admin-svelte. There is currently no gallery grid, upload button, or image-selection modal in either Svelte app — a search of tracker-frontend-svelte/src, tracker-admin-svelte/src, and packages/tracker-shared/src turns up no gallery/upload UI code.

What still exists

Backend

The backend image API is unchanged and still fully functional (app/api/routes/images.py). Images are stored in the filesystem under STATIC_DIR/images (served at the /static/images/... URL prefix) with endpoints for:

  • Listing images (paginated)
  • Uploading images (validated against a fixed set of allowed MIME types: JPEG, PNG, GIF, WebP, SVG)
  • Retrieving a single image's metadata
  • Deleting images

Image metadata is stored in the database, including the original filename, a UUID-based storage filename, MIME type, size, dimensions, and URL path.

Data model usage

Some entities still carry an image_url field that resolves to a /static/... URL served by the backend — for example, ProductionRun (packages/tracker-shared/src/api/production-runs.ts) has an image_url: string | null field. However, none of the current campaign, brand, or client editor modals in packages/tracker-shared/src/components/ (CampaignEditorModal.svelte, clients/BrandEditorModal.svelte, clients/ClientEditorModal.svelte) expose a way to set or change that field today — there is no image field, upload input, or gallery button in any of them. The value can currently only be set directly through the API.

nginx /static/ routing

Because production-run images resolve to real /static/... URLs, the /static/ location block is deliberately kept in the Svelte apps' nginx config even though most of the old React-era special-cased location = blocks were removed as redundant — see tracker-admin-svelte/docker/nginx.conf and docs/development/svelte-staging-cutover-todo.md for the history of that cleanup.

Adding image selection back

If a future feature needs image upload/selection in the Svelte apps, the backend contract (app/api/routes/images.py / schemas.ImagesResponse) is still there to build against. There is no existing Svelte component to follow as a pattern (unlike the old React ImageSelectionModal.tsx), so a new component would need to be built from scratch — a reasonable home would be packages/tracker-shared/src/components/ if both apps need it, following the pattern of the existing shared editor modals (e.g. CampaignEditorModal.svelte) for modal structure and daisyUI styling.

Troubleshooting

If you're debugging a broken image_url on a production run/brand/client:

  1. Check that the image file exists on disk under STATIC_DIR/images/
  2. Verify the image record exists in the database
  3. Confirm nginx's /static/ location is present and proxying to the API container
  4. Check browser network requests for 404s when loading the image URL
  5. Remember there is no in-app UI to change these values today — they are set via direct API calls only