Hongjun An
λ 610 NM · WEB / CMS
Case 02 / 09한국어See it in 3D

The problem

It began as a touch-screen catalog for a trade-show booth. The same data then had to run a sales website and a USB edition that opens with no internet — and the staff had to edit all of it themselves.

Decisions

  1. Moving from static JSON to a database meant swapping one data-loader file. It rebuilds the old catalog.json shape and keeps four accessor signatures: page code untouched, a 21-product sample diffed to zero.
  2. Two builds, online and offline. The file:// limits — module CORS, blocked fetch, absolute paths — were solved with an IIFE build, inlined data, relative paths and self-hosted fonts.
  3. The kiosk’s existing idle timer now re-fetches the data, so edits appear with no new infrastructure.

What broke — and the fix

  1. On first real use, every save in the admin app failed. RLS was on for the admin table but it had no self-read policy, so “admins only” checks always saw nothing. One policy fixed it; a round-trip check now gates every release.
  2. The site was fixed but the USB still showed the old version: its shell was a prebuilt bundle committed to the repo. A check now fails when a prebuild is older than its source — proven by running it against the old shell.
  3. Card images were cropped, invisible in code. A headless measurement showed square 324 px images inside a 203 px 16:10 box. Reviews now measure rendered size, not code.

Results

  • 329 products · 4 categories · 26 subcategories · 758 images · 364 specs
  • 66 dimension tables read from 65 PDF pages (53 new)
  • 124 slides of client markup: 232 fixes applied, 0 missed
  • USB build about 43–45 MB: 860 images and 827 references, 0 missing
  • 57 offline pages: 0 broken images, 0 external requests
  • Permissions measured: anonymous read 200 / anonymous write 401
RoleSolo — data design to handover
DurationAbout 13 weeks (4 initial + 9 for detail pages, CMS, USB and handover)
StatusLive
StackVite · Vanilla JS · Next.js 16 · Supabase · Vercel · Playwright