Lot Builder
Lot Builder is the focused workbench for bundling remaining personal-collection cards into city / team / player / set lots and committing them to ToT in one click. Skips the full Strategist's allocator complexity — does ONE thing: turn the long-tail of inventory into coherent lot listings.
When to use it
- Singles already on ToT, storefront set up, but you have hundreds of sub-$15 cards still in personal
- You want to bundle them into city lots ("Dallas multi-sport lot — Cowboys + Mavs + Stars cards") without hand-grouping
- The full Strategist's preview is overkill — you just want lots → ToT → done
The flow
- Visit
/admin/lot-builderfrom the Ecosystem Command Center (or directly) - Click Build proposed lots — runs the allocator in lots-only mode (ToT enabled, ebay/whatnot/repacks off, lot_threshold=15, lot_max_size=25)
- Grid renders proposed lots: kind chip (CITY / TEAM / PLAYER / SET / SPORT), theme-team chips, 6-thumb grid, card count, total value
- Click cards to select. Filter chips at top: "CITY 8", "TEAM 5", "PLAYER 12" — click one to bulk-select that kind
- Sticky commit bar shows running totals + a green safety check ("✓ N unique · safe to commit") that verifies no card appears in 2+ selected lots
- Click Commit N lots to ToT — uses
POST /api/curator/strategist/commit - After commit, allocator re-runs so committed lots disappear and you can keep going
Header buttons
- Set all lots → 25%: one-shot retro update — calls ToT's
/api/admin/normalize-lot-spreadsendpoint to rewrite every existing lot Listing's FlipConfig spread to 25% (with recomputed winPrice/losePrice). For aligning legacy lots committed before the default changed. - Resync from ToT: pulls canonical state from ToT and clears any stale
card_channelsrows (cards SlabTrack thinks are on ToT but were manually removed there). Use after manually delisting on ToT.
Safety guards
Two layers prevent broken commits:
- Frontend safety chip: pre-commit dedup display. Counts unique card_ids across selected lots. Flips red if any card appears twice; Commit button disables.
- Backend hard guard: the commit endpoint validates BEFORE hydration:
- Duplicate card_ids across groups → 400 with collision details
- Cards already on a non-personal channel → 409 with conflict list
How lots get built
The lot-builder service (backend/services/strategist/lot-builder.js) tries grouping in priority order:
- City: groups cards whose team resolves to a city via
cityForTeam(team). "Dallas Cowboys", "Dallas Mavericks", "Dallas Stars", "Texas Rangers" all roll up to "Dallas". - Team: same team across years (cross-year team lot)
- Player: same player across sets/years
- Set: same set + year (set-builder lots)
- Sport: catch-all by sport for cards that don't lot any other way
Each card claims its FIRST match (city beats team beats player). A card already in a city lot won't also appear in a team lot — that's the safety against duplicates.
Lot caps
| Constraint | Default | Override |
|---|---|---|
| Min cards per lot | 3 | min_player_lot / min_team_lot / etc. |
| Max cards per lot | 25 | MAX_CARDS_PER_LOT in the route |
| Min lot total value | $15 | min_lot_value |
If the Strategist proposes a lot of 30+ cards (rare but happens with deep-team inventory), it gets silently skipped from publish. The bulk-list response includes a skipped array with reasons; check that array in the UI. To bundle a bigger group, manually split it into chunks of 25 in the Lot Builder UI before committing.
Auto-publish vs manual publish
After commit, the SlabTrack endpoint webhooks ToT. ToT's /api/webhook/ingest:
- Stages each card into a CollectionCard row
- Builds a Listing for each group directly (the new auto-publish behavior — no manual /collection click needed)
- Theme metadata flows through so city lots render with team chip pills
- Idempotent — group skipped if any card already on a Listing
So a Lot Builder commit lands on ToT's /browse within seconds.
Code references
- UI:
frontend/src/pages/LotBuilder.jsx - Allocator (lots-only mode):
backend/routes/curator.routes.js/strategist/allocate - Lot building:
backend/services/strategist/lot-builder.js - Auto-publish on receive:
thisorthat/src/app/api/webhook/ingest/route.ts