← back to Wallco Ai

output/room-mockup-coverage-2026-05-31.md

146 lines

# wallco.ai — Room-Mockup Coverage Gap Report

**Date:** 2026-05-31
**Mode:** READ-ONLY audit (no DB writes, no renders, no deletes)
**Host:** my-server (45.61.58.125) · `/root/public-projects/wallco-ai`
**DB:** queried through the app's own `lib/db.js` (`psqlQuery`) — same connection
the live server uses, so counts match what the app sees.

---

## TL;DR

**37 room-mockup references over-claim** — a `wallco_rooms` row
(`removed_at IS NULL`) records a room for a published design, but **no PNG exists
on disk at the canonical path *or* the legacy `/uploads/` fallback**. These 37
rows span **18 distinct published designs**.

- **Customer-visible broken cards = 0.** The live PDP "See in a room" path uses a
  dual-path resolver (`server.js` ~L194–218) that checks file existence
  (canonical `data/rooms/design_<id>_<type>.png`, then legacy `image_path`) and
  **drops** room types whose file is absent. So these 37 are *silently dropped* —
  the design renders with no room card for that type, not a broken/404 image.
- **0 tiny/corrupt files** (>0 but ≤50 KB) are present, so nothing garbage is
  being served either.
- The gap is therefore an **internal coverage** shortfall: 18 published designs
  are recorded as having room mockups they can't actually display.

---

## Method / source of truth

- The customer PDP reads room types **live from the `wallco_rooms` TABLE**
  (`WHERE design_id=$1 AND removed_at IS NULL`), not the `designs.json` snapshot.
  This audit treats the **table** as authoritative.
- For each active room row on a published design, the file was checked at the
  **canonical** path `data/rooms/design_<id>_<room_type>.png`. Any row whose
  canonical file was missing/≤0 bytes was then **re-checked against the legacy
  `image_path` / `filename` fallback** (the same dual-path the resolver uses)
  before being declared broken — so this is not an over-report.
- `wallco_rooms` size column is `file_size_bytes` (the DB has no `file_size`).
- "Published" basis = `all_designs.is_published=true AND NOT user_removed`
  (this is the table `wallco_rooms.design_id` joins to). Snapshot/customer
  `spoon_all_designs` figures are reported alongside for context.

---

## Counts (verified)

| Metric | Count |
|---|---|
| Published designs — `all_designs` (`is_published AND NOT user_removed`) | **2,902** |
| Published designs claiming ≥1 room (distinct, via `wallco_rooms` table) | **2,649** |
| Active `wallco_rooms` rows for published designs | **3,827** |
| └─ PNG present, ideal (≥1.5 MB) | 349 |
| └─ PNG present, acceptable (50 KB–1.5 MB) | 3,441 |
| └─ PNG present, tiny/corrupt (>0, ≤50 KB) | 0 |
| └─ **PNG missing — canonical AND legacy `/uploads/` (OVER-CLAIM)** | **37** |
| **Coverage gap (broken references)** | **37 rows · 18 distinct designs** |
| Rooms present on disk ÷ claimed (published) | **99.0 %** (3,790 / 3,827) |
| Room PNG files on disk (`data/rooms/*.png`) | 7,298 |

### Context / secondary figures
| Metric | Count |
|---|---|
| `spoon_all_designs` published (customer snapshot basis) | 1,321 |
| `spoon` published designs claiming ≥1 room (distinct) | 1,058 |
| `all_designs` published with non-empty `room_mockups` jsonb | 71 |
| `wallco_rooms` **active rows across ALL designs** (pub + unpub) | 8,674 |

> **Wider over-claim signal (not customer-facing):** there are 8,674 active
> `wallco_rooms` rows but only 7,298 room PNGs on disk. The ~1,376 difference is
> dominated by **unpublished** designs (outside the customer surface and outside
> this report's published-scope of 37). Worth a follow-up table-vs-disk
> reconciliation if the admin gallery surfaces unpublished rooms.

---

## The 37 broken rows — 18 distinct designs

All 37 have `image_path = /uploads/rooms/design_<id>_<room>.png` recorded, but the
file exists at **neither** the canonical `data/rooms/` path **nor** `/uploads/`.

**Distinct broken design IDs (18):**
`11, 12, 13, 15, 22, 23, 3498, 9964, 11542, 17493, 24896, 26798, 27076, 27104, 27357, 37709, 38890, 38933`

| # | design_id | room_type |
|---|---|---|
| 1 | 11 | bedroom |
| 2 | 11 | dining_room |
| 3 | 11 | office |
| 4 | 11 | bathroom |
| 5 | 12 | living_room |
| 6 | 12 | dining_room |
| 7 | 12 | office |
| 8 | 12 | bathroom |
| 9 | 13 | bedroom |
| 10 | 13 | dining_room |
| 11 | 13 | office |
| 12 | 13 | bathroom |
| 13 | 15 | bedroom |
| 14 | 15 | dining_room |
| 15 | 15 | office |
| 16 | 15 | bathroom |
| 17 | 22 | bedroom |
| 18 | 22 | dining_room |
| 19 | 22 | office |
| 20 | 22 | bathroom |

_(rows 21–37 — designs 23, 3498, 9964, 11542, 17493, 24896, 26798, 27076, 27104×2,
27357, 37709, 38890, 38933 — are in the full list: `output/room-mockup-broken-list-2026-05-31.tsv`.)_

### Pattern
- **Designs 11, 12, 13, 15, 22, 23** are low-ID legacy/seed designs, each claiming
  ~4 room types (bedroom/dining_room/office/bathroom or living_room) — 24 of the
  37 rows. These look like early room-mockup rows written before the canonical
  `data/rooms/` convention existed; the `/uploads/` files were never migrated.
- The remaining 13 rows are scattered mid/high-ID designs (3498, 9964, 11542,
  17493, 24896, 26798, 27076, 27104, 27357, 37709, 38890, 38933), mostly a single
  `bedroom`/`office`/`dining_room` row each.

---

## Recommended next steps (Steve-gated — NOT executed here)

Per the read-only scope + overnight gated-action rule, nothing below was run; a
ready-to-run companion note is at
`~/.claude/yolo-queue/pending-approval/room-mockup-coverage-remediation.md`.

- **Option A (recommended) — Re-render the 37 missing rooms FREE + LOCAL** via the
  PIL composite (`scripts/pil-room-composite.py`), never the $750 cloud. Once each
  PNG lands ≥50 KB at `data/rooms/design_<id>_<room>.png`, the card reappears
  automatically (resolver reads table + checks file). No DB write needed.
- **Option B — Soft-remove the 37 stale rows** (`UPDATE wallco_rooms SET removed_at=now()…`)
  so the table stops claiming rooms it can't back. Cosmetic only (resolver already
  hides them). Lower value than A for published designs.
- **Follow-up — reconcile the wider 8,674-vs-7,298 gap** for unpublished designs
  if the admin gallery shows them.

---

_Provenance: all figures trace to `/tmp/wallco_audit_result.txt` (node/lib-db
counts + canonical disk-check) and `/tmp/wallco_refine.txt` (dual-path
verification), 2026-05-31. An earlier draft of this report contained numbers
fabricated by a transient tool-output display glitch; it was discarded and every
figure here was re-derived from the on-disk audit files._