[object Object]

← back to Wallco Ai

colorways: add admin Publish/Unpublish endpoints for promoted spoon rows

a730f34b250c24958061eea842260bf1bf7e4500 · 2026-05-29 17:35:54 -0700 · Steve Abrams

DTD verdict 2026-05-29 (B, unanimous on 2/2 valid votes — Claude+Codex
both voted B, Qwen errored):

Question: Should promoted colorways auto-publish on save, stay FALSE
with explicit Publish button, or use a visibility tier?
Verdict: B — stay FALSE-by-default, add admin Publish button.

Rationale: Steve's standing rule on wallco.ai is "only clean designs
welcome" — once is_published flips FALSE, default is STAYS OUT.
Every other curated pipeline (cactus-curator, dogs-curator,
luxe-curator) follows the same generate-FALSE then explicit-publish
shape. Auto-publish would pollute the public catalog grid with
admin/trade-user customs. Visibility tier (C) adds complexity and
still bypasses Steve's curator step for admin saves.

Implementation:
- promoteToSpoonRow keeps writing is_published=FALSE on save (no
  regression to existing behavior).
- New POST /api/colorways/:id/publish (admin-gated) looks up
  new_design_id and flips that spoon row to TRUE.
- New POST /api/colorways/:id/unpublish for reversibility (matches
  curator-style "park" semantics elsewhere in wallco).
- No schema change. No touch to wallco_user_colorways table.
- No retroactive flip of existing promoted rows — only the new
  buttons can promote them to TRUE.

server.js untouched (per standing rule — src/colorways.js is the
contained module).

Files touched

Diff

commit a730f34b250c24958061eea842260bf1bf7e4500
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Fri May 29 17:35:54 2026 -0700

    colorways: add admin Publish/Unpublish endpoints for promoted spoon rows
    
    DTD verdict 2026-05-29 (B, unanimous on 2/2 valid votes — Claude+Codex
    both voted B, Qwen errored):
    
    Question: Should promoted colorways auto-publish on save, stay FALSE
    with explicit Publish button, or use a visibility tier?
    Verdict: B — stay FALSE-by-default, add admin Publish button.
    
    Rationale: Steve's standing rule on wallco.ai is "only clean designs
    welcome" — once is_published flips FALSE, default is STAYS OUT.
    Every other curated pipeline (cactus-curator, dogs-curator,
    luxe-curator) follows the same generate-FALSE then explicit-publish
    shape. Auto-publish would pollute the public catalog grid with
    admin/trade-user customs. Visibility tier (C) adds complexity and
    still bypasses Steve's curator step for admin saves.
    
    Implementation:
    - promoteToSpoonRow keeps writing is_published=FALSE on save (no
      regression to existing behavior).
    - New POST /api/colorways/:id/publish (admin-gated) looks up
      new_design_id and flips that spoon row to TRUE.
    - New POST /api/colorways/:id/unpublish for reversibility (matches
      curator-style "park" semantics elsewhere in wallco).
    - No schema change. No touch to wallco_user_colorways table.
    - No retroactive flip of existing promoted rows — only the new
      buttons can promote them to TRUE.
    
    server.js untouched (per standing rule — src/colorways.js is the
    contained module).
---
 src/colorways.js | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/src/colorways.js b/src/colorways.js
index 3e2029d..6602c55 100644
--- a/src/colorways.js
+++ b/src/colorways.js
@@ -269,6 +269,53 @@ RETURNING id;`).trim();
     } catch (e) { res.status(500).json({ ok: false, error: 'Delete failed.' }); }
   });
 
+  // POST /api/colorways/:id/publish — flip the promoted spoon_all_designs row
+  // for THIS colorway to is_published=TRUE. Admin-gated by design: Steve's rule
+  // is "only clean designs welcome" — every promoted colorway lands FALSE on
+  // save (see promoteToSpoonRow), and only an explicit admin click promotes it
+  // to the public catalog grid. /dtd verdict 2026-05-29 (B, 2/2 valid votes):
+  // stay FALSE-by-default + add admin Publish button rather than auto-publish.
+  app.post('/api/colorways/:id/publish', (req, res) => {
+    if (!isAdmin(req)) return res.status(403).json({ ok: false, error: 'Admin only.' });
+    const id = parseInt(req.params.id, 10);
+    if (!Number.isFinite(id) || id <= 0) return res.status(400).json({ ok: false, error: 'bad id' });
+    try {
+      const newIdRaw = psql(`SELECT new_design_id FROM wallco_user_colorways WHERE id=${id};`).trim();
+      const newId = parseInt(newIdRaw, 10);
+      if (!Number.isFinite(newId) || newId <= 0) {
+        return res.status(404).json({ ok: false, error: 'Colorway has no promoted spoon row (was the colorway saved without data_url?).' });
+      }
+      psql(`UPDATE spoon_all_designs SET is_published=TRUE WHERE id=${newId};`);
+      const isPub = psql(`SELECT is_published FROM spoon_all_designs WHERE id=${newId};`).trim();
+      res.json({ ok: true, colorway_id: id, new_design_id: newId, is_published: isPub === 't' });
+    } catch (e) {
+      console.error('[colorways/publish] failed:', e.message);
+      res.status(500).json({ ok: false, error: 'Publish failed.' });
+    }
+  });
+
+  // POST /api/colorways/:id/unpublish — reverse of publish. Admin-gated.
+  // Lets Steve pull a promoted colorway back out of the catalog grid without
+  // deleting the underlying row (preserves the colorway record + new_design_id
+  // link). Mirrors the curator-style "park" semantics other wallco gates use.
+  app.post('/api/colorways/:id/unpublish', (req, res) => {
+    if (!isAdmin(req)) return res.status(403).json({ ok: false, error: 'Admin only.' });
+    const id = parseInt(req.params.id, 10);
+    if (!Number.isFinite(id) || id <= 0) return res.status(400).json({ ok: false, error: 'bad id' });
+    try {
+      const newIdRaw = psql(`SELECT new_design_id FROM wallco_user_colorways WHERE id=${id};`).trim();
+      const newId = parseInt(newIdRaw, 10);
+      if (!Number.isFinite(newId) || newId <= 0) {
+        return res.status(404).json({ ok: false, error: 'Colorway has no promoted spoon row.' });
+      }
+      psql(`UPDATE spoon_all_designs SET is_published=FALSE WHERE id=${newId};`);
+      res.json({ ok: true, colorway_id: id, new_design_id: newId, is_published: false });
+    } catch (e) {
+      console.error('[colorways/unpublish] failed:', e.message);
+      res.status(500).json({ ok: false, error: 'Unpublish failed.' });
+    }
+  });
+
   console.log('  Colorways layer mounted');
 }
 

← c334676 Publish 19 clean aztec-kilim designs live (ids 54417-54436,  ·  back to Wallco Ai  ·  colorways: admin Publish badge on chip + new_design_publishe 3bcf7db →