Scene was dumping all 3 rooms' racks/crates/lights into one room, and the
served decals + portals were never rendered (trapped in booth-room).
- /virtual/scene scopes to ONE room (?space=, default = is_default space);
filters racks/crates/lights/cameras/portals/decals/covers by space_id
- render decals (image + canvas-text planes) and portal doorways; walk into
a portal -> loads the linked room
- portal links_to_id is the PAIRED portal's id, not a space — resolve through
it to the destination room (to_space)
- copy the 29 referenced decal webp/svg into webstore/assets (self-contained,
served /store/assets); rewrite WP /wp-content/uploads/ paths in the scene API
- skip the 17MB logo .glb mesh decal (flat logo-blue.webp covers branding)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reframed from backend-only to three layers (Lighthouse measures speed, not records-features):
A Discovery (clickable genre/artist/style/label, audio samples, find-in-store), B In-store ops
(item location, store map, A-Z refile/crate-reorg — the deepest moat, nothing else does it),
C Market intel (value/underpricing/scarcity/arbitrage — mostly Have today). Added per-feature
matrix (layer / today / RecordGod / Shopify+Discogs-sync can't / build effort) + Jackson as
co-design partner for the ops layer, not just a reference.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Data-driven dossier on waxmuseumrecords (Jackson, free-year test case). Key finding: their
Shopify is technically excellent (Lighthouse perf 99/SEO 100, no search-app tax) AND already
Discogs-sync-native (titles = Artist-Title(Format)(Grade), body = Media/Sleeve condition +
country/year) — so the pitch is NOT speed/cost, it's cross-store market intelligence on data
they already publish. DealGod under-captures it (condition 0%, release_id 26% despite perfect
titles). Includes honest do-NOT-pitch list, the underpricing/$ hook, read-only onboarding plan,
and DealGod-side ingest fixes (parse Media/Sleeve condition; lift Discogs-format match rate).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
POST /settings/test/{service} validates stored creds against the live service
(Discogs identity, Woo orders, DealGod /api/me) so "connected" means connected.
Dash gets per-service Test buttons with green/amber status.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Wraps migrate.py + migrate_virtual.py + build_disc_cache.py + pg_dump→VPS. Vault
(app_secret) excluded so dash credentials survive a refresh. Clean-rebuild for now;
make non-destructive once dash intake is in use (RECORDGOD_PLAN §6).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- schema: disc_cache (release_id→title/artist/thumb/weight); build_disc_cache.py populates it
from the full Discogs dump on ultra (30,694 stocked releases).
- app/mirror.py: enrich() now reads RecordGod's OWN disc_cache via the main DB — no live
discogs_full / dealgod-DB dependency. DealGod reached only via API key.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- app/mirror.py: centralised enrichment, DISCOGS_MIRROR_KIND selects full (ultra `release`)
vs vps (`discogs_release`); virtual.py + wowplatter_v1.py use it.
- Dockerfile + .dockerignore for the VPS container.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- app/vault.py: Fernet-encrypted credential store (app_secret table); key lives only in
RECORDGOD_SECRET_KEY (.env, gitignored) — refuses to store anything if the key is unset.
- app/settings_routes.py: admin-gated GET/POST /settings/secrets; values encrypted at rest,
NEVER returned. Known fields: Woo / Discogs / Cloudflare / DealGod credentials.
- site/index.html: recordgod.com landing. site/dash.html: control room (token gate +
paste-your-credentials form). main.py loads .env, mounts site at /, store at /store.
- Proven: 401 on bad token; DB holds ciphertext (gAAAA…), not plaintext.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
dig.js: enter a crate → records stand packed in a bin; scroll/drag riffles a damped
cursor through them; each sleeve hinges forward at its bottom edge as you pass (smoothstep
wave); tap the front sleeve to pull it out and inspect (price/condition/add-to-cart panel).
Depth-LOD cover loading (±8 around cursor). Procedural fwip/thunk audio, no asset files.
Wired into index.html: click crate → dig scene; render loop branches on dig.active.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- FastAPI twin of DealGod (async SQLAlchemy/asyncpg). wowplatter/v1: ping,
inventory/lookup, inventory/intake (enriches from discogs_full by release_id).
- schema v2: unified inventory (vinyl+general), slim crate, sales/sale_items.
Discogs catalog NOT copied — joined from discogs_full at read time.
- migrate.py: 34,543 shop rows moved (vs ~3.2M in the WowPlatter clone).
- Smoke test green; plan/readme carry the architecture + UI boundary.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>