From ee31c78db8740795fde0cbe220163aeac92c085f Mon Sep 17 00:00:00 2001 From: jubnl Date: Tue, 21 Apr 2026 00:46:29 +0200 Subject: [PATCH] fix(maps): null stale proxy image_url entries instead of writing unbacked proxy URLs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Migration 107 and the previous fix both wrote /api/maps/place-photo//bytes into places.image_url without ever fetching the photo bytes. photoService short-circuits on that URL prefix and hits /bytes directly, which 404s because nothing is on disk. - Add migration to null proxy image_url rows with no backing google_place_photo_meta entry — restores the normal fetch-and-cache flow for affected rows - Fix the previous legacy-URL migration to null instead of rewrite, so fresh installs don't hit the same 404 path Fixes #770 (follow-up) --- server/src/db/migrations.ts | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/server/src/db/migrations.ts b/server/src/db/migrations.ts index 85fe3490..91a2c203 100644 --- a/server/src/db/migrations.ts +++ b/server/src/db/migrations.ts @@ -1906,17 +1906,36 @@ function runMigrations(db: Database.Database): void { CREATE INDEX IF NOT EXISTS idx_day_accommodations_end_day_id ON day_accommodations(end_day_id); `); }, - // Migration: backfill remaining legacy Google photo URLs missed by Migration 107. - // Migration 107 matched /places/%/photos/% only; lh3.googleusercontent.com URLs use - // /place-photos/ or /places/ paths and were skipped. Rewrite any remaining - // google-hosted URL to the stable proxy form using the row's google_place_id. + // Migration: null out proxy image_url entries that have no backing disk cache. + // Migrations 107 and the migration below wrote /api/maps/place-photo//bytes + // into places.image_url without actually fetching/caching the photo bytes. The + // photoService short-circuits on that prefix and hits /bytes directly → 404. + // Rows with a confirmed disk cache entry in google_place_photo_meta are left alone; + // only stale proxy URLs (never actually fetched) are cleared so the normal + // fetch-and-cache flow can repopulate them. () => { db.exec(` UPDATE places - SET image_url = '/api/maps/place-photo/' || google_place_id || '/bytes', + SET image_url = NULL, updated_at = CURRENT_TIMESTAMP + WHERE image_url LIKE '/api/maps/place-photo/%/bytes' + AND google_place_id IS NOT NULL + AND NOT EXISTS ( + SELECT 1 FROM google_place_photo_meta + WHERE place_id = places.google_place_id + AND error_at IS NULL + ) + `); + }, + // Migration: clear legacy Google photo URLs missed by Migration 107. + // Migration 107 matched /places/%/photos/% only; lh3.googleusercontent.com URLs use + // /place-photos/ or /places/ paths and were skipped. NULL those stale URLs + // so the normal fetch-and-cache flow repopulates image_url with a real proxy URL. + () => { + db.exec(` + UPDATE places + SET image_url = NULL, updated_at = CURRENT_TIMESTAMP - WHERE google_place_id IS NOT NULL - AND image_url IS NOT NULL + WHERE image_url IS NOT NULL AND image_url != '' AND image_url NOT LIKE '/api/maps/place-photo/%' AND (