← Projects

Active · September 15, 2026

Beacon TCG.

Pokémon card price tracker with the US and EU markets side by side, a daily data pipeline and a free collection manager.

Beacon TCG card page: US and EU market prices for the same physical card

What it is

Beacon TCG is a website for Pokémon TCG collectors: look up any card and see its US ($) and EU (€) market prices on the same page, with the finish (regular, reverse holo, holo) and edition, price history, the biggest movers of the month, a Pokédex view, and a free collection and deck manager. It runs on a small self-hosted server.

Why I built it

As a collector I kept two tabs open — one for the US market, one for the European one — and still could not tell whether a card was cheap where I actually buy. I wanted one page per physical card, with both markets, that I could trust. It also became the place where I practise, end to end, the same craft I do at work: making data reliable.

How it works

  • Daily pipeline with seven stages: ingest from two public APIs (~177k listings, 1.1 M price rows, 830k price snapshots), normalise every field into columns (raw JSON kept only as an audit copy), link raw sets to a curated canonical catalogue, build one canonical card per physical card, run data-quality rules, download images, publish.
  • Two catalogues that do not match. The US and EU sources share no card ids and number cards differently, so cards are unified at a canonical layer with a second source for identity (name, number, rarity, artwork) and marketplace ids as the exact join key.
  • Data quality as a first-class layer: nine rules (shared images, duplicate slots, mismatched names or rarities, price outliers, missing images…) reconciled on every run with open/resolved counters, a review queue for uncertain matches, and manual overrides that survive rebuilds.
  • Operations: the build runs on my machine and ships as a Docker image to a 1.8 GB VPS; Caddy serves 13 GB of images statically; nightly backups with restore checks; a responsive audit with headless Chromium runs before each deploy.

AI in the build

  • Built with coding agents. Most of the code was written with AI coding agents; I owned what they cannot: the architecture, the data model (raw → normalised → canonical), the quality rules, the verification of every change against the real database and the deployment. Working this way is a data-quality job in itself — the agent is fast and confident, and the value is in checking.
  • LLM-generated news. A news pipeline turns source items into structured articles: the model returns a JSON object (title, summary, body, tags) that is validated against a schema and reviewed before publishing. Invalid output is rejected, never patched.
  • Matching as entity resolution. Unifying two catalogues that share no ids is the same problem as deduplicating customer accounts at work: normalise, block, score, and send the uncertain matches to a human review queue.

Screenshots

Home: search-first, the biggest movers of the month and the latest sets.

A set page: one tile per physical card with both markets and the price in your preferred market.

The Pokédex view: every printed card of a Pokémon, in the same order as the catalogue.

Status

Public MVP, free to use. Paid plans are on a waitlist until there are enough users to justify billing.