Freelance / Client project · 2026
Copon
Private football prediction tournaments
Platform to run private football prediction pools (prode) with automatic scoring and live standings. Online at copon.com.ar running its first tournaments.
Technologies: Next.jstRPCDrizzle ORMSupabaseTanStack QueryBetter-AuthTailwindshadcn/ui
Overview
Copon is a web platform to run private football prediction tournaments among friends, coworkers or a community. Whoever organizes the pool creates a tournament, invites people with a link, and the app scores every matchday on its own. It is not a betting site: it is the tool that replaces the spreadsheet.
The problem
A client came to me with the pool of his group running on an Excel file and a WhatsApp thread. Somebody had to load every result by hand, recalculate the table, and settle arguments about who predicted what and when. Predictions arrived late, points came out wrong, and nobody could see the standings without asking for the file.
What was needed was not a bigger spreadsheet: it was predictions that close on a deadline, scoring computed by the system, and a standings table anyone can open from their phone.
Joining a tournament
Decisions
- Scoring and standings as a pure module (@repo/core): it is the part that has to be right, so it lives with no framework around it, returns Result<T,E> instead of throwing, and is unit tested with Vitest before anything renders.
- tRPC instead of a REST layer: one developer, one codebase, and every router typed from server to client, so a change in a payload breaks the build and not the pool.
- Drizzle ORM over Supabase Postgres: the schema is TypeScript, migrations stay versioned in the repo, and the queries read next to the business logic.
- T3-turbo monorepo split by responsibility (@repo/db, @repo/api, @repo/auth, @repo/core, @repo/ui, @repo/validators): the pure logic never imports Next.js, so it stays testable and portable.
- Better-Auth with invite links: joining a tournament had to be one tap from WhatsApp, not a signup form plus a code.
- Three configurable formats (round robin League, Groups plus Knockout, Knockout only) with custom or real teams, editable fixtures and configurable point systems: every group scores its pool differently, and the app had to absorb that instead of imposing one rulebook.
- TanStack Query on the client: standings and matchdays change while people are watching the match, so the cache refetches instead of the user reloading.
Result
Copon is online at copon.com.ar running the pools of the client's group, starting with the 2026 World Cup group stage. Nobody loads points by hand any more: results come in, the table updates, and the round based pot is settled by the same code that is covered by tests.
What it confirmed for me is that keeping business logic pure pays off in the first week: every argument about scoring was closed by reading a test, not by reading the interface.