Skip to content

feat: flash catalog as assortment source of truth - #64

Merged
SteveSimonson merged 2 commits into
mainfrom
feature/flash-assortment-sot
Aug 2, 2026
Merged

feat: flash catalog as assortment source of truth#64
SteveSimonson merged 2 commits into
mainfrom
feature/flash-assortment-sot

Conversation

@SteveSimonson

Copy link
Copy Markdown
Owner

Fixes #63

Summary

Makes Flash Catalog the assortment controller for iBamboo (Phase A).

  • Shop/Home/PDP/Quiz/Vibe use flash-only products when the API is healthy
  • Static BSR/curated is emergency fallback only (no dual-shelf merge)
  • Default catalog base URL always present (amazon-flash-catalog…); npm run deploy always sets it
  • Mapper: short house names, reject truncated image hashes, stable slug suffix, no forced Flash badge on every SKU
  • Admin flash tab surfaces error + HTTP + probe URL
  • Worker flash status distinguishes non-JSON / non-OK upstream

Risk

  • Live shop may show fewer SKUs than the old static+flash merge (depends on flash refresh depth)
  • PDP slugs change for flash items (name + ASIN tail) — static SEO routeMeta still from build-time catalog

Test plan

  • npm test / npm run lint / production build
  • Deploy → hard refresh /shop shows live flash products
  • Admin → Flash tab shows OK + product count (or real error text)
  • Quiz results pull from live pool
  • With flash down, shop falls back to static with banner/error path

Follow-up (not this PR)

  • Deeper flash quotas / multi-image publish
  • SEO rebuild or Worker injection from flash
  • Network rollout

Flash owns shop membership when healthy: no static merge, always-on
catalog base URL, Quiz/Vibe/related rails on the live pool, clearer
admin probe errors, house-name + image quality mapping, and deploy
always bakes the flash control plane URL.
@SteveSimonson

Copy link
Copy Markdown
Owner Author

Independent code review (adversarial-lite) — PR #64

Scope: Flash Catalog as assortment source of truth (Phase A). Spot-checked SoT behavior, base URL, Quiz/Vibe/PDP pools, Admin error surfacing, secrets, local npm test / npm run lint.

Spot-checks

Check Result
useFlashCatalog flash-only when healthy (no static merge) PASSmergeFlashOverStatic removed; healthy path returns products: flashOnly only
DEFAULT_FLASH_CATALOG_BASE / flashCatalogBaseUrl always has a base PASS — env override or https://amazon-flash-catalog.tech-bf6.workers.dev; deploy script bakes the same default
Quiz / Vibe / Product related use flash.products PASS — Quiz buildQuizPicks, Vibe picks, PDP similarProducts / youMayAlsoLike / getProduct all take live pool
Admin shows flash.error on failure PASS — error text + HTTP status + probe URL; worker probe distinguishes non-JSON / non-OK
No secrets committed PASS — no secret files or credential patterns in diff; only public Worker base URL / .env.example

What looks solid

  • Clear SoT contract: flash owns assortment when mappable products exist; static is emergency fallback only.
  • Mapper quality: house names, ASIN-stable slugs, stricter image URL validation, no forced Flash badge on every SKU.
  • Cross-surface wiring: Home/Shop/Quiz/Vibe/PDP all consume the hook pool consistently.
  • Worker /admin flash status is more truthful (parse failures no longer look like empty OK payloads).
  • Local verification: npm test 21/21 pass, npm run lint clean. CI (at review time): unit tests, lint, and build steps green; cross-viewport layout gates still in progress.

Nits (non-blocking)

  1. Loading UX label — While loading and flash has not yet returned products, source === 'static', so Shop shows “Emergency static catalog · updating…” even though this is the normal first paint, not a real outage. Prefer e.g. “Loading live assortment…” until !loading, then flash vs emergency.

  2. Phase A tests are contract clonestests/flash-catalog.test.mjs reimplements houseNameFromTitle / isUsableFlashImage / isQualityFlashTitle instead of importing src/lib/flashCatalog.ts. Good regression documentation, weak against silent drift of the real module. Follow-up: import production helpers (or a shared pure package) when strip-types/import path allows.

  3. Dead !base branch — After always-on DEFAULT_FLASH_CATALOG_BASE, if (!base) in the hook is effectively unreachable. Harmless defensive code; can simplify later.

  4. Known/accepted risk (from PR body) — SEO routeMeta / sitemap remain build-time static while runtime slugs/names come from flash. Acceptable for Phase A; don’t treat as a merge blocker, but watch 404s/stale PDP SEO after deploy.

  5. Sitemap / routeMeta churn — Large lastmod-only / regenerated noise; fine if intentional from the weekly catalog rebuild, just makes review harder.

Verdict rationale

No blocking correctness or security issues on the Phase A contract. SoT, fallback, admin probe, and surface wiring match the stated intent. Nits are UX polish / test fidelity / known SEO follow-ups.

VERDICT: APPROVE_WITH_NITS

Playwright layout gates force flash offline so assortment falls back
to static deterministically. Shop status no longer claims emergency
catalog while still loading.
@SteveSimonson

Copy link
Copy Markdown
Owner Author

Addressed CI: e2e mocks flash offline for deterministic static fallback; shop loading banner nit fixed. CI green on latest commit.

@SteveSimonson
SteveSimonson merged commit c7dd75e into main Aug 2, 2026
1 check passed
@SteveSimonson
SteveSimonson deleted the feature/flash-assortment-sot branch August 2, 2026 22:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

iBamboo: flash catalog as assortment source of truth

1 participant