Skip to content

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:

#TypeWhatDate
96featOPTCG API ingest source + INGEST_TCG=onepiece dispatch2026-05-05
97feat/scan-compat enrichment for non-Pokémon TCGs (lookup /cards/:id)2026-05-05
98docsInitial CHANGELOG.md catch-up2026-05-05

Note 2026-05-06 (continued). After the #99 revert, a multi-phase plan was launched: Phase A (#103, card_embeddings_lab table + /scan-lab endpoint), Phase B (#105, variant-aware schema cards.base_id + cards.variant), Phase C (#107, variant-aware OP ingest via assignVariantIds). 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 in sets. ~2 727 rows in card_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:latest image rebuilt with the _fetch_backend_card from #97 (suffix-strip regex _pN only — 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  | 23159

Partial 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-vision

No 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.sql

Code 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 -d

Poké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 doc
  • tcg-collector-backend/CHANGELOG.md — ### Added — One Piece TCG end-to-end (#96, #97) entry