← back to Wallco Ai
PDP: '✓ smart-fix → #child' pill linking a design to its published smart-fixed child (parent_design_id). Server-side, works on monolith + theme PDPs + unpublished parents; /api/design exposes smartfix_child.
0bbf5baccc807bd72ea40403279b97e3160e7a07 · 2026-06-02 08:34:31 -0700 · Steve Abrams
Files touched
Diff
commit 0bbf5baccc807bd72ea40403279b97e3160e7a07
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue Jun 2 08:34:31 2026 -0700
PDP: '✓ smart-fix → #child' pill linking a design to its published smart-fixed child (parent_design_id). Server-side, works on monolith + theme PDPs + unpublished parents; /api/design exposes smartfix_child.
---
server.js | 37 ++++++++++++++++++++++++++++++++++++-
1 file changed, 36 insertions(+), 1 deletion(-)
diff --git a/server.js b/server.js
index 2c5a8ea..68e71d9 100644
--- a/server.js
+++ b/server.js
@@ -494,6 +494,13 @@ app.get('/api/design/:id', (req, res) => {
// the name can never disagree with the color shown (a #FFCFD8 blush design
// must not read "Midnight Navy"). See lib/hex-colorname.js. (Steve 2026-06-01)
applyHexConsistentNaming(merged);
+ // Surface a published smart-fix child (parent_design_id=id) so the PDP can link
+ // parent → its fixed/published version (Steve 2026-06-02: "✓ smart-fix → #child").
+ try {
+ const c = psqlQuery(`SELECT id FROM spoon_all_designs WHERE parent_design_id=${id} AND is_published=TRUE AND user_removed IS NOT TRUE ORDER BY created_at DESC, id DESC LIMIT 1`);
+ const cid = parseInt(c, 10);
+ if (Number.isFinite(cid) && cid > 0 && cid !== id) merged.smartfix_child = cid;
+ } catch { /* PG hiccup — omit the link */ }
res.json({ ok: true, design: merged });
});
@@ -536,6 +543,33 @@ app.get('/design/:id/tabs', (req, res) => {
// Theme variants are standalone HTML. Inject the standard site chrome — login
// header + nav + footer — so every theme has the login and the same info as the
// rest of the site (Steve 2026-06-01). One injection point covers all variants.
+// Inject a "✓ smart-fix → #child" link into a theme PDP, server-side with the
+// concrete child id baked in (works even when the parent is unpublished and its
+// /api/design 404s). Child = newest published design with parent_design_id=id.
+// Steve 2026-06-02. Raw theme file cached; only the per-id link is appended.
+// Returns the "✓ smart-fix → #child" pill <a> for a design that has a published
+// smart-fix child (parent_design_id=id), else ''. Server-side so it works even
+// for unpublished parents. Used by both the theme PDP and the monolith PDP.
+function smartFixLinkFor(id) {
+ let childId = null;
+ try {
+ const c = psqlQuery(`SELECT id FROM spoon_all_designs WHERE parent_design_id=${parseInt(id, 10)} AND is_published=TRUE AND user_removed IS NOT TRUE ORDER BY created_at DESC, id DESC LIMIT 1`);
+ const cid = parseInt(c, 10);
+ if (Number.isFinite(cid) && cid > 0 && cid !== id) childId = cid;
+ } catch { /* PG hiccup — no link */ }
+ if (!childId) return '';
+ return `<a href="/design/${childId}" title="View the published smart-fixed version" style="position:fixed;top:88px;right:16px;z-index:99999;background:#c79a3a;color:#3a2a00;padding:8px 14px;border-radius:999px;font:600 12px system-ui,-apple-system,sans-serif;text-decoration:none;box-shadow:0 2px 10px rgba(0,0,0,.28)">✓ smart-fix → #${childId}</a>`;
+}
+const _pdpThemeRawCache = {};
+function injectSmartFixLink(file, id) {
+ const full = path.join(__dirname, 'public', 'theme-variants', file);
+ let html = _pdpThemeRawCache[file];
+ if (html === undefined) { try { html = fs.readFileSync(full, 'utf8'); } catch { return '<h1>404</h1>'; } _pdpThemeRawCache[file] = html; }
+ const link = smartFixLinkFor(id);
+ if (!link) return html;
+ return /<\/body>/i.test(html) ? html.replace(/<\/body>/i, link + '\n</body>') : html + link;
+}
+
const _themeVariantCache = {};
function themeVariantSend(req, res, file) {
const id = parseInt(req.params.id, 10);
@@ -12756,7 +12790,7 @@ app.get('/design/:id', (req, res) => {
? req.query.theme : null;
const liveSlug = req.query.classic === '1' ? null : (previewSlug || getActivePdpTheme());
if (liveSlug && THEME_FILE_MAP[liveSlug]) {
- return res.sendFile(path.join(__dirname, 'public', 'theme-variants', THEME_FILE_MAP[liveSlug]));
+ return res.type('html').send(injectSmartFixLink(THEME_FILE_MAP[liveSlug], id));
}
}
@@ -13027,6 +13061,7 @@ app.get('/design/:id', (req, res) => {
})}
<body>
${htmlHeader('/designs')}
+${smartFixLinkFor(id)}
<main class="detail-main" id="detail-main"${_isAdmin ? ' data-page-theme="theme2"' : ''}>
${_isAdmin ? `
<!-- Theme toggle (theme1 / theme2) — ADMIN-ONLY preview surface
← c198fff generator: every new design self-archives TIF+SVG via build-
·
back to Wallco Ai
·
color-dots: Save targets the last-recolored image, not the t 3535426 →