feat(photos): add 1h disk cache for remote thumbnails and keep tabs mounted

Closes #686

- Add trekPhotoCache service: SHA1-keyed disk cache under uploads/photos/trek/,
  1h TTL, in-flight dedup map to prevent stampedes on concurrent requests
- Add migration 108: trek_photo_cache_meta table
- Hook cache into streamPhoto for Immich/Synology thumbnail path;
  originals bypass cache
- Add fetchImmichThumbnailBytes / fetchSynologyThumbnailBytes returning
  Buffer instead of piping, used by the cache layer
- Add scheduler entry (every 2h + startup sweep) to evict expired disk
  files and DB rows via sweepExpired()
- Client: convert journey tab conditional-mount to hidden-toggle so
  img elements stay in DOM across tab switches, preventing redundant
  thumbnail requests on rapid tab changes
- Expose invalidateSize() on JourneyMapHandle; call it on map tab
  activation to fix Leaflet rendering in previously-hidden container
This commit is contained in:
jubnl
2026-04-17 20:49:38 +02:00
parent ae4dfc48cc
commit b5b1d32b31
9 changed files with 268 additions and 16 deletions
+1
View File
@@ -49,6 +49,7 @@ const server = app.listen(PORT, () => {
scheduler.startVersionCheck();
scheduler.startDemoReset();
scheduler.startIdempotencyCleanup();
scheduler.startTrekPhotoCacheCleanup();
const { startTokenCleanup } = require('./services/ephemeralTokens');
startTokenCleanup();
import('./websocket').then(({ setupWebSocket }) => {