From 825bbe7834419cd01ad7c89ded2b7c1f0bb1dfab Mon Sep 17 00:00:00 2001 From: Kagetora Dev Runner Date: Sat, 13 Jun 2026 22:09:34 -0400 Subject: [PATCH] fix(og): news permalink resolves share image via rollup parent POI (#475) findItemBySlugs filtered news by exact poi_id, but the news API expands boundary/org parents via getRollupPoiIds. After the 2026-06-09 seed refresh the first POI with media+news is a boundary/org POI whose news exists only via child rollup, so the lookup returned null, the middleware fell through, and Express served the static index.html brand-fallback og:image. Expand the news query to poi_id = ANY(getRollupPoiIds(...)) and resolve og:image against the slug-resolved parent POI (item._poi.id). --- backend/server.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/backend/server.js b/backend/server.js index f3d3a217..fc833dc4 100644 --- a/backend/server.js +++ b/backend/server.js @@ -2635,6 +2635,7 @@ async function findItemBySlugs(type, poiSlug, titleSlug) { `, [poi.id]); rows = q.rows; } else { + const poiIds = await getRollupPoiIds(pool, poi.id); const q = await pool.query(` SELECT n.id, n.title, n.summary, n.source_url, n.source_name, n.news_type, n.publication_date, n.collection_date, n.image_url, p.name AS poi_name, p.id AS poi_id, @@ -2642,10 +2643,10 @@ async function findItemBySlugs(type, poiSlug, titleSlug) { FROM poi_news n JOIN pois p ON n.poi_id = p.id LEFT JOIN poi_news_urls u ON u.news_id = n.id - WHERE n.poi_id = $1 AND n.moderation_status IN ('published', 'auto_approved') + WHERE n.poi_id = ANY($1) AND n.moderation_status IN ('published', 'auto_approved') GROUP BY n.id, p.name, p.id ORDER BY COALESCE(n.publication_date, n.collection_date) DESC - `, [poi.id]); + `, [poiIds]); rows = q.rows; } @@ -2803,7 +2804,7 @@ app.use(async (req, res, next) => { const safeDesc = escapeHtml(description.length > 200 ? description.substring(0, 197) + '...' : description); // Image priority: source article image, then POI primary photo, then brand. const sourceImage = isUsableSourceImage(item.image_url) ? item.image_url : null; - const ogImage = escapeHtml(sourceImage || await resolvePoiOgImage(item.poi_id, baseUrl)); + const ogImage = escapeHtml(sourceImage || await resolvePoiOgImage(item._poi.id, baseUrl)); const indexPath = path.join(staticPath, 'index.html'); let html = await fs.readFile(indexPath, 'utf-8');