Appearance
Rollback — One Piece integration
Procedure to follow if the One Piece addition (May 2026) breaks something in production and we need to revert to a Pokémon-only state.
Date: 2026-05-06.
What was shipped
Three PRs on snag-tcg/tcg-collector-backend, merged to main on 2026-05-05:
| # | Type | What | Date |
|---|---|---|---|
| 96 | feat | OPTCG API ingest source + INGEST_TCG=onepiece dispatch | 2026-05-05 |
| 97 | feat | /scan-compat enrichment for non-Pokémon TCGs (lookup /cards/:id) | 2026-05-05 |
| 98 | docs | Initial CHANGELOG.md catch-up | 2026-05-05 |
Note 2026-05-06 (continued). After the #99 revert, a multi-phase plan was launched: Phase A (#103,
card_embeddings_labtable +/scan-labendpoint), Phase B (#105, variant-aware schemacards.base_id+cards.variant), Phase C (#107, variant-aware OP ingest viaassignVariantIds). See Plan — /scan-lab pgvector validation.
Cumulative runtime side-effects (post Phase C):
- Postgres: 2 967 rows in
cards(tcg='onepiece') — 2 135 base + 832 variants (674 v2 / 120 v3 / 34 v4 / 4 v5). 20 rows insets. ~2 727 rows incard_images(1 999 base + 728 new variants). - Disk: ~1 159 MB under
data/images/OP-*/,data/images/EB-*/,data/images/PRB-*/(819 MB base + 340 MB variants). tcg-vision-api:latestimage rebuilt with the_fetch_backend_cardfrom #97 (suffix-strip regex_pNonly — Phase C didn't touch tcg-vision since we're building our own stack in parallel).
Verify the current state before touching anything
bash
cd tcg-collector-backend
sudo docker ps --filter name=tcg --format 'table {{.Names}}\t{{.Status}}'
sudo docker compose --env-file .env -f docker/compose.yml exec -T postgres \
psql -U tcg -d tcg -c "SELECT tcg, COUNT(*) FROM cards GROUP BY tcg;"Expected in "OP shipped" state (post Phase C):
tcg | count
----------+-------
onepiece | 2967
pokemon | 23159Partial rollback — disable OP scan enrichment (fast, non-destructive)
If tcg-vision /scan-compat errors on OP scans, you can short-circuit PR #97 without touching the rest:
bash
# Disables the backend lookup for non-Pokémon TCGs
# → /scan-compat falls back to legacy behaviour (cardDetails: null)
# → Pokémon keeps working as before
echo "BACKEND_API_URL=" >> .env # or edit the existing value
sudo docker compose --env-file .env -f docker/compose.yml up -d tcg-visionNo data loss. To re-enable: set BACKEND_API_URL=http://api:3000 in .env and restart.
Partial rollback — block future OP ingests (fast, non-destructive)
If you want to prevent future INGEST_TCG=onepiece runs while keeping what's already in the DB:
bash
# Nothing to do — INGEST_TCG defaults to 'pokemon'.
# Just verify scheduler/cron invocations don't override the value.
grep -r "INGEST_TCG" .env scripts/Full rollback — purge One Piece data from Postgres + disk
Use only if you really want to wipe everything. Migrations stay in place (they're neutral for Pokémon).
bash
cd tcg-collector-backend
# 1. Defensive backup (~30 seconds)
sudo docker compose --env-file .env -f docker/compose.yml exec -T postgres \
pg_dump -U tcg -d tcg -t cards -t sets -t card_images -t card_embeddings \
> /tmp/tcg-pre-op-rollback.sql
# 2. Delete OP rows (FK ON DELETE CASCADE → card_images follows)
sudo docker compose --env-file .env -f docker/compose.yml exec -T postgres \
psql -U tcg -d tcg <<'SQL'
BEGIN;
DELETE FROM cards WHERE tcg = 'onepiece';
DELETE FROM sets WHERE tcg = 'onepiece';
COMMIT;
SQL
# 3. Verify Pokémon row count is intact
sudo docker compose --env-file .env -f docker/compose.yml exec -T postgres \
psql -U tcg -d tcg -c "SELECT tcg, COUNT(*) FROM cards GROUP BY tcg;"
# 4. Purge OP images from disk (~819 MB freed)
sudo rm -rf data/images/OP-* data/images/EB-* data/images/PRB-*Restore from dump if needed:
bash
sudo docker compose --env-file .env -f docker/compose.yml exec -T postgres \
psql -U tcg -d tcg < /tmp/tcg-pre-op-rollback.sqlCode rollback — revert the PRs
If the code itself causes an issue (typo, undetected Pokémon regression, etc.):
bash
cd tcg-collector-backend
# Option A — soft revert via PR (recommended in prod)
gh pr create --title "revert: One Piece ingest + scan enrichment" --body "..." \
--base main --head revert/onepiece
# Then manually: git revert 1497a89 <sha-pr-97> <sha-pr-98>
# Option B — checkout at the pre-OP commit, force push (avoid except in emergencies)
git log --oneline | grep -B1 "feat(ingest): add One Piece"
# Note the SHA before 1497a89, e.g. 0521575
# git reset --hard 0521575 # destructive!After revert:
bash
sudo docker compose --env-file .env -f docker/compose.yml build ingest tcg-vision
sudo docker compose --env-file .env -f docker/compose.yml up -dPokémon non-regression checks
Run these after any rollback to verify the Pokémon path stays green:
bash
# 1. API still answers
curl -s -m 5 "http://localhost:8080/cards?tcg=pokemon&limit=1" | python3 -m json.tool | head -10
# 2. scan-compat still answers on a Pokémon card
curl -s -m 30 -X POST -F "photo=@<a-pokemon-jpeg>" \
http://localhost:8000/scan-compat | python3 -m json.tool | head -20
# Expected: match.name non-null (real card name), cardDetails non-null
# 3. Card count intact
sudo docker compose --env-file .env -f docker/compose.yml exec -T postgres \
psql -U tcg -d tcg -c "SELECT COUNT(*) FROM cards WHERE tcg='pokemon';"
# Expected: 23 159 (or more if ingest ran since)See also
- Card scan architecture — pipeline overview
tcg-collector-backend/docs/INGEST.md§One Piece — integration tech doctcg-collector-backend/CHANGELOG.md—### Added — One Piece TCG end-to-end (#96, #97)entry