Astal Creates / Work / PredictsWorld
Live · 400+ users

PredictsWorld

Predict every World Cup 2026 match and compete with friends on live leaderboards.

Built withNext.js 15 ·React 19 ·PostgreSQL ·Supabase
PredictsWorld — product screenshot
Introduction

A full-stack prediction game for the FIFA World Cup 2026, where users predict match winners, first goal-scorers, and total-goals bands for all 104 matches, plus season-long picks for Champion, Golden Boot, and Golden Glove. Built for football fans who want to compete with friends via private invite-code groups as well as a global public leaderboard.

Context & user problem

Why it needed to exist

Casual World Cup prediction pools are usually run manually over WhatsApp or spreadsheets, with no automated scoring, no lock enforcement, and no fair way to settle disputes. PredictsWorld automates the entire prediction-to-scoring pipeline with server-enforced rules, so results are consistent and disputes are minimized.

What was built

Inside the product

Match predictions

Pick the winner, first goal-scoring team, and total-goals band for each match, locking automatically at kickoff.

Tournament-long picks

Champion, Golden Boot, and Golden Glove predictions worth up to 150 points, locked at the end of the group stage.

Server-enforced locking

Every prediction write re-checks the kickoff time against the server clock, not client state, so locks can't be bypassed.

Global + private leaderboards

Every signed-up user is ranked on a public leaderboard, and can create or join invite-code private groups that filter the same ranking.

Deterministic tiebreakers

Ties resolve through a fixed cascade: total points → correct tournament picks → correct winners → goals-band → first-scorer → earliest signup.

Passwordless auth

Sign-in via Supabase email OTP (one-time code), no passwords stored anywhere.

Admin panel

Manual and API-assisted management of teams, players, fixtures, knockout assignment, and result entry/finalization.

Automated result sync

A scheduled job pulls finished-match scores from a football data API into a review queue; an admin finalizes to trigger scoring.

How the system works

End to end

  1. A user signs in with an email OTP (no password) and picks a display name on first login.
  2. They browse the 104-match schedule and submit a prediction per match; the server rejects any write once that match's kickoff has passed.
  3. Once the group stage ends, tournament-long predictions (Champion / Boot / Glove) lock in the same server-enforced way.
  4. As matches finish, an admin (or the scheduled sync job) confirms the result and clicks Finalize, triggering an idempotent re-score of every prediction for that match.
  5. The global and per-group leaderboards recompute via a single ranked SQL query with the full tiebreaker cascade, so standings update automatically.
01User predictions
02Server Actions
03Validation & locking
04PostgreSQL
05Result finalization
06Scoring
07Leaderboards
Hardest engineering decision

PostgreSQL connection-pool exhaustion

Under real production traffic, the app hit intermittent 500s and infinite-loading pages caused by PostgreSQL connection-pool exhaustion against Supabase's transaction pooler (a hard 200-connection cap). The root cause was subtle: the pooled postgres.js client was being re-created per request in production instead of cached and reused across warm serverless invocations, and once that was fixed, an overly small pool caused concurrent requests to queue indefinitely. Because postgres.js has no built-in wait-timeout, a saturated pool made server components hang forever rather than fail visibly. The fix combined caching the pooled client correctly across invocations, tuning pool size and idle_timeout / connect_timeout, wrapping hot-path DB calls in an application-level timeout so failures surface as errors instead of spinners, and adding Next.js error.tsx boundaries so timed-out requests render a retry UI instead of hanging.

Result & current status

Where it stands

Live in production, deployed on Vercel with 400+ real users actively making predictions during the 2026 World Cup group stage and knockout rounds.

400+
real users
104
matches covered
Technology used

The full stack

  • Next.js 15 (App Router)
  • Server Actions
  • React 19
  • TypeScript
  • PostgreSQL
  • Drizzle ORM
  • postgres.js
  • Supabase (Auth + Postgres)
  • Zod
  • Tailwind CSS
  • Vercel (hosting + cron)
  • GitHub Actions
Next landmark

Continue along the river

Want something built like this?

This is one of several products shipped under Astal Creates. Tell me what you're building and I'll write back.