← back to Wallco Ai
Fix AI-recolor publish gate: child SKUs land is_published=FALSE + carry parent_design_id (was auto-publishing orphans)
5b6ed8d842e46aa2d7bbfd4a1d170ccf364ec509 · 2026-06-12 07:41:54 -0700 · Steve Abrams
Files touched
Diff
commit 5b6ed8d842e46aa2d7bbfd4a1d170ccf364ec509
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Fri Jun 12 07:41:54 2026 -0700
Fix AI-recolor publish gate: child SKUs land is_published=FALSE + carry parent_design_id (was auto-publishing orphans)
---
server.js | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/server.js b/server.js
index f5ebfe4..7431856 100644
--- a/server.js
+++ b/server.js
@@ -25422,14 +25422,26 @@ app.post('/api/design/:id/recolor', sgRecolorGate, express.json(), async (req, r
? 'ARRAY[' + d.motifs.map(t => "'" + String(t).replace(/'/g, "''") + "'").join(',') + ']::text[]'
: "ARRAY[]::text[]";
const promptDesc = (newTitle + ' — ' + prompt).slice(0, 1800).replace(/'/g, "''");
+ // is_published=FALSE: every recolor is a CHILD SKU of an already-passed
+ // root, same prompt class. It lands unpublished — only an explicit admin
+ // click publishes it (mirrors promoteToSpoonRow + the /bake sibling). The
+ // old TRUE here was a gate bug (children must never auto-publish). Also
+ // carry parent_design_id so the child has lineage back to its root, and
+ // only set it when the source design actually exists in PG (prod PG is
+ // sparse — an id that isn't a real spoon row would orphan the FK-less ref).
+ let parentInPg = false;
+ try {
+ const chk = psqlQuery(`SELECT 1 FROM spoon_all_designs WHERE id=${id} LIMIT 1;`);
+ parentInPg = !!(chk && chk.trim());
+ } catch (e) { /* table/col may differ on this box → leave NULL */ }
const insertSql = `INSERT INTO spoon_all_designs
(kind, width_in, height_in, generator, prompt, seed, dominant_hex,
- local_path, image_url, category, motifs, tags, is_published, request_text)
+ local_path, image_url, category, motifs, tags, is_published, parent_design_id, request_text)
VALUES ('seamless_tile', 24, 24, 'gemini-2.5-flash-image-edit',
'${promptDesc}', ${seed}, ${domHex ? "'" + domHex + "'" : 'NULL'},
'${outPath.replace(/'/g, "''")}', '/designs/img/${filename}',
${"'" + (d.category || 'recolor') + "'"},
- ${motifsSql}, ${tagSql}, TRUE,
+ ${motifsSql}, ${tagSql}, FALSE, ${parentInPg ? id : 'NULL'},
'${("Tone-on-tone " + targetLabel + " recolor of design " + id).replace(/'/g, "''")}')
RETURNING id;`;
const newIdStr = psqlQuery(insertSql);
@@ -25448,7 +25460,8 @@ app.post('/api/design/:id/recolor', sgRecolorGate, express.json(), async (req, r
local_path: outPath,
generator: 'gemini-2.5-flash-image-edit',
seed,
- is_published: true,
+ is_published: false,
+ parent_design_id: parentInPg ? id : null,
created_at: new Date().toISOString(),
motifs: d.motifs || [],
tags: baseTags,
← a0a8321 Throttle overnight seam loop: max-retries default 8→4 (load
·
back to Wallco Ai
·
overnight-seam-loop: route DTD vote tally to stderr so it la f7ada02 →