[object Object]

← back to Wallco Ai

wallco.ai · POST /api/room — mirror admin-generated rooms into catalog JSONB

ece9e378363c37475ae969ee1b778e5f1c6387c8 · 2026-05-12 01:03:20 -0700 · SteveStudio2

The existing admin "Generate Room" button on /design/:id writes to wallco_rooms
+ uploads/rooms/. The new hover-preview on /designs reads from a different
column (spoon_all_designs.room_mockups JSONB) populated by scripts/.

Bridges them: after every successful POST /api/room, also write
data/rooms/design_<id>_<room>.png and merge {room: path} into the JSONB.
In-memory DESIGNS catalog reloads the updated room_mockups so /designs
surfaces the new room immediately without a server restart.

Isolated try/catch — bridge failures don't break gallery insert.
Reversible: ~20 lines, no schema changes.

Files touched

Diff

commit ece9e378363c37475ae969ee1b778e5f1c6387c8
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Tue May 12 01:03:20 2026 -0700

    wallco.ai · POST /api/room — mirror admin-generated rooms into catalog JSONB
    
    The existing admin "Generate Room" button on /design/:id writes to wallco_rooms
    + uploads/rooms/. The new hover-preview on /designs reads from a different
    column (spoon_all_designs.room_mockups JSONB) populated by scripts/.
    
    Bridges them: after every successful POST /api/room, also write
    data/rooms/design_<id>_<room>.png and merge {room: path} into the JSONB.
    In-memory DESIGNS catalog reloads the updated room_mockups so /designs
    surfaces the new room immediately without a server restart.
    
    Isolated try/catch — bridge failures don't break gallery insert.
    Reversible: ~20 lines, no schema changes.
---
 server.js | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/server.js b/server.js
index d842710..da8e615 100644
--- a/server.js
+++ b/server.js
@@ -4446,6 +4446,34 @@ app.post('/api/room', async (req, res) => {
       console.error('[wallco_rooms insert]', e.message);
     }
 
+    // Bridge to catalog hover-preview: every admin-generated room is also
+    // mirrored to data/rooms/design_<id>_<room>.png + merged into the
+    // spoon_all_designs.room_mockups JSONB column. This is what /designs
+    // reads to render the "In a room" filter chip + the .card-room overlay.
+    // Failures here don't break the gallery (try/catch isolated).
+    try {
+      const canonicalDir = path.join(__dirname, 'data', 'rooms');
+      if (!fs.existsSync(canonicalDir)) fs.mkdirSync(canonicalDir, { recursive: true });
+      const canonicalPath = path.join(canonicalDir, `design_${parseInt(design_id, 10)}_${roomType}.png`);
+      fs.writeFileSync(canonicalPath, buf);
+
+      const merged = psqlQuery(`UPDATE spoon_all_designs
+        SET room_mockups = COALESCE(room_mockups, '{}'::jsonb) || jsonb_build_object(${pgEsc(roomType)}, ${pgEsc(canonicalPath)})
+        WHERE id = ${pgEsc(parseInt(design_id, 10))}
+        RETURNING COALESCE(room_mockups, '{}'::jsonb)::text;`);
+      // Reflect in the in-memory DESIGNS catalog so /designs surfaces the new room
+      // without a server restart.
+      if (merged) {
+        try {
+          const obj = JSON.parse(merged);
+          const target = DESIGNS.find(x => x.id === parseInt(design_id, 10));
+          if (target) target.room_mockups = Object.keys(obj).sort();
+        } catch (_) { /* malformed JSONB — leave DESIGNS untouched */ }
+      }
+    } catch (e) {
+      console.error('[room_mockups bridge]', e.message);
+    }
+
     res.json({ ok: true, room_id, image_url, roomType, design_id });
   } catch (e) {
     res.status(500).json({ ok: false, error: e.message });

← d37c171 yolo backlog: T17 ledger update — R8 viewport meta tag fix +  ·  back to Wallco Ai  ·  wallco.ai · sortDesigns — boost has-room designs to top of e 47d55d2 →