[object Object]

← back to Wallco Ai

wallco.ai · /api/designs/random?n=12&category=&seed= — random sample for 'Surprise me' rails + empty-state discovery · partial Fisher-Yates (O(n) not O(N)) · optional ?category= filter, optional ?seed= mulberry32 PRNG for reproducible shuffles · Cache-Control:no-store (randomness is the point) · verified: n=3→228-pool, category=floral→17-pool, seed=42→deterministic [208,173,265]

817e1364f14e61e70aeeb9f9a2daf7cdb0fb5917 · 2026-05-12 08:23:45 -0700 · SteveStudio2

Files touched

Diff

commit 817e1364f14e61e70aeeb9f9a2daf7cdb0fb5917
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Tue May 12 08:23:45 2026 -0700

    wallco.ai · /api/designs/random?n=12&category=&seed= — random sample for 'Surprise me' rails + empty-state discovery · partial Fisher-Yates (O(n) not O(N)) · optional ?category= filter, optional ?seed= mulberry32 PRNG for reproducible shuffles · Cache-Control:no-store (randomness is the point) · verified: n=3→228-pool, category=floral→17-pool, seed=42→deterministic [208,173,265]
---
 server.js | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/server.js b/server.js
index 898cc72..36dd5dc 100644
--- a/server.js
+++ b/server.js
@@ -294,6 +294,60 @@ app.get('/api/designs/search', (req, res) => {
   });
 });
 
+// ── /api/designs/random?n=12&category=floral&seed=42
+// Returns N random designs. Useful for "Surprise me" rails + empty-state discovery.
+// Optional ?category= filter. Optional ?seed= for reproducible shuffles (otherwise time-seeded).
+// Cache-Control: no-store — randomness is the point; caching defeats it.
+app.get('/api/designs/random', (req, res) => {
+  const n = Math.max(1, Math.min(50, parseInt(req.query.n || '12', 10)));
+  const category = String(req.query.category || '').toLowerCase().trim();
+  const seedRaw = req.query.seed;
+  const pool = category
+    ? DESIGNS.filter(d => (d.category || '').toLowerCase() === category)
+    : DESIGNS.slice();
+  // Deterministic seeded PRNG (mulberry32) if seed provided; else Math.random.
+  let rand;
+  if (seedRaw !== undefined && seedRaw !== '') {
+    let s = parseInt(seedRaw, 10) >>> 0;
+    rand = function() {
+      s |= 0; s = (s + 0x6D2B79F5) | 0;
+      let t = s;
+      t = Math.imul(t ^ (t >>> 15), t | 1);
+      t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
+      return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
+    };
+  } else {
+    rand = Math.random;
+  }
+  // Partial Fisher-Yates — picks first N positions of shuffle without touching the rest.
+  const sample = [];
+  const idx = pool.map((_, i) => i);
+  const k = Math.min(n, idx.length);
+  for (let i = 0; i < k; i++) {
+    const j = i + Math.floor(rand() * (idx.length - i));
+    [idx[i], idx[j]] = [idx[j], idx[i]];
+    const d = pool[idx[i]];
+    sample.push({
+      id: d.id,
+      title: d.title,
+      category: d.category,
+      handle: d.handle,
+      image_url: d.image_url,
+      dominant_hex: d.dominant_hex,
+      room_mockups: d.room_mockups || [],
+      url: `/design/${d.id}`,
+    });
+  }
+  res.setHeader('Cache-Control', 'no-store');
+  res.json({
+    n: k,
+    pool_size: pool.length,
+    category: category || null,
+    seed: seedRaw !== undefined && seedRaw !== '' ? parseInt(seedRaw,10) : null,
+    results: sample,
+  });
+});
+
 // ── Color sort helpers
 function hexToHSL(hex) {
   if (!hex) return [0, 0, 0.5];

← 340a3c9 wallco.ai · autocomplete dropdown now renders a 'Refine' mot  ·  back to Wallco Ai  ·  wallco.ai · empty /compare now renders a 'More designs to ex fe60c05 →