Case / hyperlocal data hub
Kommunfotbollen
Next.js / Claude API / GitHub Actions
Kommunfotbollen aggregates standings, matches, and news for a town's football teams in one place, kept automatically up to date without anyone entering data by hand.
ProblemLocal football coverage was scattered across an external sports data source and several local newspapers. No single place aggregated leagues, matches, and goal scorers, and match reports existed only as unstructured free text.
SolutionI built a Next.js app with a source-agnostic ingest architecture that pulls leagues and matches, and an AI pipeline where Claude reads local newspaper match reports, judges whether an article is relevant to a given team, and extracts goal scorers from the unstructured text.
Technical decisionsSource-agnostic ingest architecture (MatchSource) so more data sources can be added without rewriting the rest of the app.Claude handles two separate AI tasks: news relevance filtering and goal-scorer extraction from match reports.Supabase Postgres via Drizzle instead of an embedded database, so data survives restarts independent of where the app runs.Sync moved from in-process timers to a scheduled GitHub Actions cron hitting an authenticated endpoint, keeping operations simple and stateless.Zod validation of external data to keep the data model reliable despite sources of varying quality.
What it showsThe project shows that I can build integrations against multiple external data sources, use AI for structured extraction from text, and make deliberate architecture choices to keep operating costs down.
TechNext.js 16TypeScriptDrizzle ORMSupabaseZodTailwind v4Anthropic SDKGitHub ActionsRender