PID-only scan labels break for products with no card_cache row #494

Open
opened 2026-08-28 02:41:55 +00:00 by gambit-admin · 0 comments
Owner

Follow-up from the #491 fix (PR #333).

/scan?pid= (the fallback QR printed when a card has no GCN, plus /p/{pid} short links from external_scan.py) now returns 404 'Card not found' when the pid has no card_cache row, where it previously rendered a card page.

This is a direct consequence of closing the #491 leak, not a new bug: with no card_cache row there is no non-tenant source of name, price or image, and the page only ever rendered by filling in from an arbitrary vendor's product row — which was the leak. A 404 is the honest answer; there is nothing safe to serve.

Worth sizing the affected population — suspected sealed products and Card Hedge sports, neither of which has a card_cache projection:

SELECT count(DISTINCT p.tcgplayer_product_id)
FROM inventory_items ii JOIN products p ON p.id = ii.product_id
WHERE ii.qty_on_hand > 0 AND p.tcgplayer_product_id IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM card_cache cc
WHERE cc.tcgplayer_id = p.tcgplayer_product_id);

If non-zero, options are (a) backfill card_cache for those products, or (b) stop printing PID-only labels and require a GCN. Option (b) also restores the 'Available copies' section for them, since a GCN carries the vendor.


Filed from a Claude Code session

Follow-up from the #491 fix (PR #333). /scan?pid= (the fallback QR printed when a card has no GCN, plus /p/{pid} short links from external_scan.py) now returns 404 'Card not found' when the pid has no card_cache row, where it previously rendered a card page. This is a direct consequence of closing the #491 leak, not a new bug: with no card_cache row there is no non-tenant source of name, price or image, and the page only ever rendered by filling in from an arbitrary vendor's product row — which was the leak. A 404 is the honest answer; there is nothing safe to serve. Worth sizing the affected population — suspected sealed products and Card Hedge sports, neither of which has a card_cache projection: SELECT count(DISTINCT p.tcgplayer_product_id) FROM inventory_items ii JOIN products p ON p.id = ii.product_id WHERE ii.qty_on_hand > 0 AND p.tcgplayer_product_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM card_cache cc WHERE cc.tcgplayer_id = p.tcgplayer_product_id); If non-zero, options are (a) backfill card_cache for those products, or (b) stop printing PID-only labels and require a GCN. Option (b) also restores the 'Available copies' section for them, since a GCN carries the vendor. --- Filed from a Claude Code session
gambit-admin added the bug label 2026-08-28 02:41:55 +00:00
gambit-admin added the 01 · scan & recognition label 2026-09-04 13:36:52 +00:00
Sign in to join this conversation.