Pure Web Audio, zero deps (site/decks.js, self-contained UI):
- deck A/B with waveform (client-computed peaks), click-to-seek, play/pause, CUE
- ±8% varispeed pitch (playbackRate — turntable behaviour, deliberately no keylock)
- channel gains + equal-power crossfader, DynamicsCompressor master limiter
- AudioContext lazily created on first load (autoplay policy safe)
Sources:
- local preview MP3s: PREVIEWS_DIR (default ./previews, gitignored) served at
/previews, discovered via GET /shop/local-previews/{release_id}
({release_id}.mp3 / {release_id}-*.mp3|.m4a); on prod bind-mount the collection
- Apple 30s previews: GET /shop/preview-proxy?u= (STRICT whitelist
*.itunes.apple.com / *.mzstatic.com) — Apple CDN sends no CORS, Web Audio needs it
- YouTube/Beatport/Bandcamp embeds untouched: iframes can never enter a mixer
release.html: A/B load buttons per track preview + local-cut rows.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
customers.sql (610KB phpMyAdmin dump: wp_rmp_users password hashes + real
customer names/emails/phones/addresses) sat untracked but matched NEITHER
.gitignore NOR .dockerignore, and Dockerfile does COPY . . — so it was one
'git add .' from history and already bakeable into the public image.
- .gitignore: customers*.sql (schema.sql stays tracked)
- .dockerignore: *.sql (startup DDL is inline in app/main.py; no .sql needed at runtime)
Working-tree customers.sql shredded. site-update.sql was already gitignored;
now dockerignored too.
NOTE: rebuild+redeploy the image to purge copies already baked into layers.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
site-update.sql is a full live-site export consumed locally for the 3D-store
racks/editor data work — never commit (same PII class as the purged distro dumps).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The RareWaves/Inertia scrapes (rarw*.txt, inertia.txt, the SOH .xlsx) were tracked
in git AND baked into the Docker image (COPY . . with no exclusion). They carry a live
RareWaves buyer JWT and a supplier contact email — they don't belong in either.
- git rm --cached the 7 dumps; moved to local-only ingest_raw/
- .gitignore + .dockerignore: ingest_raw/, rarw*.txt, inertia.txt, *.xlsx
- nothing reads them by path (the xlsx ingest takes a base64 upload), so no code change
NOTE: still present in history (ef37063, 926468a) — scrub separately if the JWT is live.
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>