[object Object]

← back to Designer Wallcoverings

Daisy Bennett: room-QA sweep (Gemini vision) — 62/62 rooms, 0 people/distortion; soft flags are patterned/metallic naturals (not defects)

3c20ad3b44e939413c71860d2876b3e58ebb4cc3 · 2026-07-06 14:47:33 -0700 · Steve

Files touched

Diff

commit 3c20ad3b44e939413c71860d2876b3e58ebb4cc3
Author: Steve <steve@designerwallcoverings.com>
Date:   Mon Jul 6 14:47:33 2026 -0700

    Daisy Bennett: room-QA sweep (Gemini vision) — 62/62 rooms, 0 people/distortion; soft flags are patterned/metallic naturals (not defects)
---
 .../wallquest-refresh/room-qa-daisy-bennett.cjs    | 29 ++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/scripts/wallquest-refresh/room-qa-daisy-bennett.cjs b/scripts/wallquest-refresh/room-qa-daisy-bennett.cjs
new file mode 100644
index 00000000..2149921f
--- /dev/null
+++ b/scripts/wallquest-refresh/room-qa-daisy-bennett.cjs
@@ -0,0 +1,29 @@
+// Gemini vision QA on the 62 generated room images. Flags: prominent person/face, distortion,
+// missing/wrong wallcovering on the feature wall. Writes /tmp/room-qa.json.
+const fs = require('fs'); const https = require('https');
+const KEY = process.env.GEMINI_API_KEY; const MODEL = 'gemini-3.5-flash';
+const URL_ = `https://generativelanguage.googleapis.com/v1beta/models/${MODEL}:generateContent?key=${KEY}`;
+const DIR = '/tmp/rooms-out';
+const PROMPT = `This is an AI-generated interior room photo meant to show a WOVEN NATURAL WALLCOVERING (grasscloth/paperweave/raffia/linen) applied to a feature wall. QA it. Return STRICT JSON only:
+{"ok": true/false,
+ "has_person": true/false (any prominent person or face visible),
+ "wall_covering_visible": true/false (a textured natural wallcovering clearly on a wall),
+ "distorted": true/false (obvious warping, melted furniture, garbled artifacts),
+ "issue": "short phrase or 'none'"}
+ok = true ONLY if wall_covering_visible AND NOT has_person AND NOT distorted. Return ONLY the JSON.`;
+const sleep = ms => new Promise(r => setTimeout(r, ms));
+function gem(b64){const payload={contents:[{parts:[{text:PROMPT},{inline_data:{mime_type:'image/jpeg',data:b64}}]}],generationConfig:{temperature:0.1,maxOutputTokens:600,responseMimeType:'application/json'}};return new Promise((res,rej)=>{const u=new URL(URL_);const body=JSON.stringify(payload);const r=https.request({hostname:u.hostname,path:u.pathname+u.search,method:'POST',headers:{'Content-Type':'application/json','Content-Length':Buffer.byteLength(body)},timeout:40000},rs=>{let d='';rs.on('data',c=>d+=c);rs.on('end',()=>{try{const j=JSON.parse(d);if(j.error)return rej(new Error(j.error.message));let t=(j.candidates?.[0]?.content?.parts?.[0]?.text||'').trim();const m=t.match(/\{[\s\S]*\}/);res(JSON.parse(m?m[0]:t))}catch(e){rej(e)}})});r.on('error',rej);r.on('timeout',()=>{r.destroy();rej(new Error('timeout'))});r.write(body);r.end()})}
+(async()=>{
+  const files = fs.readdirSync(DIR).filter(f=>f.endsWith('.jpg'));
+  const out=[]; let ok=0, bad=0, err=0;
+  for (const f of files) {
+    const sku=f.replace('.jpg','');
+    try { const b64=fs.readFileSync(`${DIR}/${f}`).toString('base64'); const g=await gem(b64);
+      out.push({sku, ...g}); g.ok?ok++:bad++;
+      if(!g.ok) console.log(`  ⚠ ${sku}: ${g.issue} (person=${g.has_person} distorted=${g.distorted} wall=${g.wall_covering_visible})`);
+    } catch(e){ out.push({sku, ok:false, issue:'qa-error:'+String(e).slice(0,40)}); err++; bad++; }
+    await sleep(500);
+  }
+  fs.writeFileSync('/tmp/room-qa.json', JSON.stringify(out,null,2));
+  console.log(`\nQA DONE ok=${ok} bad=${bad} (err=${err}) → /tmp/room-qa.json`);
+})();

← 52637906 wallquest crawl: priced-first ordering + full-catalog (every  ·  back to Designer Wallcoverings  ·  wallquest→PR: Lillian August onboard + per-yard/8yd model + a0933e5b →