← back to Costa Rica
app API: expose region_image_url so listings can fall back (additive)
26bd9e3e31ae25ca67378c204d1842a5c4bd7134 · 2026-09-12 08:48:07 -0700 · Steve
Every bookable listing renders imageless: places.image_url is null on all of
them, nothing has ever populated that column (every image ingest targets
regions), and the listings query had no fallback - it joined regions but took
only name and slug.
Measured: 8 of 9 bookable listings sit in a region that HAS a real Wikimedia
image (regions_with_image = 49 of 102); only Eden Atenas's region has none. So a
fallback is viable today, which is the cheap alternative to building the
per-listing image-sourcing pipeline that does not exist and that nobody asked
for.
Purely additive: image_url is unchanged, the new field is separately named, no
existing consumer breaks, and where a region has no image it is simply null -
strictly non-worsening. The client-side fallback is a separate change and is NOT
made here.
Refs TK-11518.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Files touched
Diff
commit 26bd9e3e31ae25ca67378c204d1842a5c4bd7134
Author: Steve <steve@designerwallcoverings.com>
Date: Sat Sep 12 08:48:07 2026 -0700
app API: expose region_image_url so listings can fall back (additive)
Every bookable listing renders imageless: places.image_url is null on all of
them, nothing has ever populated that column (every image ingest targets
regions), and the listings query had no fallback - it joined regions but took
only name and slug.
Measured: 8 of 9 bookable listings sit in a region that HAS a real Wikimedia
image (regions_with_image = 49 of 102); only Eden Atenas's region has none. So a
fallback is viable today, which is the cheap alternative to building the
per-listing image-sourcing pipeline that does not exist and that nobody asked
for.
Purely additive: image_url is unchanged, the new field is separately named, no
existing consumer breaks, and where a region has no image it is simply null -
strictly non-worsening. The client-side fallback is a separate change and is NOT
made here.
Refs TK-11518.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---
routes/app.js | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/routes/app.js b/routes/app.js
index 73030a1..72b43de 100644
--- a/routes/app.js
+++ b/routes/app.js
@@ -117,6 +117,12 @@ router.get('/listings', optionalAuth, async (req, res) => {
const page = 'LIMIT ' + lim + ' OFFSET ' + off; // clamped integers, no injection surface
const { rows } = await pool.query(
`SELECT p.slug, p.name, p.vertical, p.category, p.description, p.image_url, p.rating,
+ -- Nothing has ever populated places.image_url (every image ingest targets REGIONS),
+ -- so every listing renders imageless with no fallback. Expose the region image as a
+ -- clearly-named SEPARATE field so the client can fall back to it. Purely ADDITIVE:
+ -- image_url is unchanged, so no existing consumer breaks, and if a region has no
+ -- image this is simply null — strictly non-worsening. (TK-11518)
+ r.image_url AS region_image_url,
r.name AS region, r.slug AS region_slug, p.lat, p.lng,
pb.booking_type, pb.currency, pb.base_price, pb.cleaning_fee, pb.max_guests, pb.instant_book
FROM place_booking pb
← 5cf7dca costa-rica: fix date-dependent payouts test (113/113 green)
·
back to Costa Rica
·
costa-rica: bound live provider fetch with a timeout (PRE-FL a3d5084 →