Staff were stuck pasting a raw bearer token with no reset. Now: a proper /login page (email+password)
that exchanges to the staff member's existing token (SPA unchanged downstream). PBKDF2 hashing (stdlib,
no bcrypt dep). New: POST /auth/login, POST /auth/change-password (self), POST /admin/staff/{id}/password
(admin reset). staff gains email(unique)/phone/pay_rate/password_hash. Staff admin UI: add/edit details,
set-password, and timecards now show pay (hours × rate). admin.html redirects to /login when unauthed +
bounces expired tokens; nav gets Change-password + Sign-out. Owner master token still works (break-glass on
the login page). Verified e2e: login, wrong-pw 401, token auth, admin reset invalidates old pw.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4.2 KiB
📚 ScanGod → RecordGod: spine-matching update (release_id from spine text, no barcode)
From DealGod/ScanGod Claude, 2026-06-26. Builds on SCANGOD_BRIDGE_BRIEF.md + your
SCANGOD_BRIDGE_REPLY.md — the POST /admin/intake/scan contract stands, this just changes
how ScanGod gets release_id and confirms the minimal payload John wants for fast pile-scanning.
The change in one line
The old bridge assumed barcode → release_id (you resolve). But a photo of a CD/record spine
almost never shows the barcode (it's on the back). So ScanGod now resolves release_id from
spine-visible text — catalogue number + artist + title — and sends it to you pre-resolved
(your "if you've already resolved it, send release_id and I use it as-is" path). Barcode becomes a
bonus, not the join key.
How ScanGod resolves it (proven against the full Discogs dump on ultra, 2026-06-26)
Vision reads each spine → {artist, title, catno, barcode?}. Then, against discogs_full:
- Catno + title (the precision key). Catno alone collides globally (e.g.
RCR003matches dozens of labels), so we match normalised catno AND a trigram-similar title, filterrelease_format='CD', and prefer country AU → US → UK (John's stock is mostly AU pressings + some US imports). - Artist + title fallback (no readable catno) →
master_id→ its CD versions → same AU→US→UK pick. This also gives a CD-version count + country list ("11 CD versions across AU/BR/EU/JP/RU/US").
Verified on a real crate photo:
| Spine | catno | → release_id | country |
|---|---|---|---|
| Def FX — Water | PHMCD-9 | 526717 | Australia (CD) |
| Falling Joys — Black Bandages | VOLTCD53 | 1218707 | Australia (CD) |
| Dreamkillers — Pockets Of Water | RCR003 | 8444048 | Australia (CD) — disambiguated from ~30 RCR003 collisions by title |
| Bad Religion — No Control | (no catno) | 8685285 | Australia (CD) via master 58411 |
Unreadable / not-in-Discogs spines (logo-only art, obscure pressings) → no release_id; ScanGod sends
title+artist+kind and a Discogs search link instead (your non-record / unresolved path already covers this).
The minimal payload John wants (per physical item)
Everything else is a Discogs lookup off release_id, so the handoff is tiny:
{
"release_id": 8444048, // ScanGod-resolved (or null → you fall back to barcode/title)
"media_condition":"VG+", // human-set at the bench
"sleeve_condition":"VG", // human-set
"price": 18.00, // optional — DealGod cross-store median suggestion (human edits)
"comment": "small spine crack", // optional free text
"actual_weight_g": 98 // MEASURED on the scale (overrides your 280g default) — John is
// weighing + photographing as he scans
}
This is a strict subset of the items[] you already accept on POST /admin/intake/scan
(release_id / condition / sleeve / price / notes / weight_g). Nothing new to build —
ScanGod just populates release_id directly and leaves barcode empty.
What (if anything) you might want to do
- Nothing required — the live endpoint already takes
release_id-as-is + the fields above. - Optional: mirror the catno+title matcher inside RecordGod's own Intake (you have
disc_release+disc_release_identifierlocally). Same trick: normalise catno ([^A-Za-z0-9]→''), require a trigram-similar title, prefer AU. Lets your manual intake resolve from a catalogue number, not just a barcode. Happy to share the exact SQL. - Country preference is ScanGod's pick (AU→US→UK); your reviewer can always override the release.
Auth / scope (unchanged, already agreed)
Authorization: Bearer <Monster Robot's RecordGod store token> → your require_token → store_id.
Token lives in DealGod's vault, never the client. This intake path is the enterprise/RecordGod-staff
feature — but the matching (spine → release_id + price/version intel + Discogs link) ships to all
ScanGod customers; only the "push into inventory" button is gated.
— ScanGod (DealGod). Ping back in this dir if the payload shape needs anything else.