How it works

The engine behind the board

ATLive isn't a hand-kept list. A scheduled pipeline ingests, dedupes, and measures itself. Every number here is live from the database or the eval harness - nothing is typed in by hand.

1274
canonical events
4
sources aggregated
58
cross-source merges
96.7%
extraction accuracy

Architecture

ATLive ingestion pipeline architectureSix stages top to bottom: ingest sources, GitHub Actions cron every six hours, normalize, dedupe, Supabase, then the Next.js site on Vercel.01INGEST SOURCESTicketmaster · 529 · Variety · Terminal West02GITHUB ACTIONSscheduled ingest · every 6h03NORMALIZEpure parsers → CanonicalEvent[]04DEDUPEexact key → fuzzy → false-merge guard05SUPABASEevents 1─N event_sources06NEXT.JS · VERCELISR · revalidates hourly
The real path a listing travels, from source to screen. The dedupe and normalize steps are the measured ones below.

Next.js + Supabase + TypeScript, ingest in GitHub Actions. Full source on GitHub.

Extraction accuracy

29/30 fields correct (96.7%) vs hand-labeled ground truth across 10 events. Only artist, date, and venue have ground truth, so only they are charted.

The one miss is kept on purpose: the parser strips " - " tour suffixes but not ": " ones (feeble little horse: bitknot tour). An eval that always reads 100% is usually rigged.

Dedup & provenance

Match is exact-key first, then a token-set fuzzy fallback, guarded by a false-merge test so two different acts on the same night never merge. (No precision/recall here - there's no labeled dedup ground truth to score against, so it's not invented.)

Sources

Events contributed per source, with the last successful pull.

Ingest runs

Source rows pulled per run (10 recorded). Upserts are idempotent, so re-runs add few new rows by design - the value is consistency, not growth.
WhenStatusNewMergedBlurbs
18d agoerror000
19d agoerror000
19d agoerror000
20d agoerror000
20d agoerror000
20d agoerror000
20d agoerror000
21d agoerror000
21d agoerror000
21d agoerror000

Canonical logs: GitHub Actions.