Skip to content
All work

Avurudu: a live festival scoreboard

A phone-first scoring and live leaderboard app for a Sri Lankan New Year community event on 18 April 2026, built in two days.

Status
Status: Shipped
Role
Sole developer: scope, design and build
When
April 2026
Stack
  • Next.js
  • Supabase
  • TanStack Query
  • Tailwind CSS
  • shadcn/ui
  • Motion
  • Vercel

A Sri Lankan New Year (Avurudu) community event on 18 April 2026 needed live scores for its traditional games. Game leaders had to score from their phones, and everyone else needed a leaderboard and a schedule without logging in. I built it as an installable web app over 17 and 18 April, finishing on the day of the event.

My role: sole developer. I scoped it, designed the data model and the interface, and built and shipped the app.

The brief

The plan was 20 players and 15 traditional games, some played solo and some in teams. The spec set two targets that everything else served:

  • a game leader records a place in three taps or fewer, and
  • the leaderboard updates within two seconds of a score being saved.

Everything else (gallery, animations, admin tools) stayed in scope only while those two held. Offline mode, push notifications and multi-event support were cut on purpose, so the build would fit the time.

Illustration of a family walking hand in hand down a festival street under bunting and balloons.
Festival artwork for the project, generated with Midjourney.

Who does what

Three roles, enforced in the database with row-level security as well as in the app.

RoleCan seeCan change
AdminEverything, including the activity logGames, schedule, teams, players, scoring rules, photos
Game leaderTheir assigned gamesScores for their own games only
Viewer (no login)Leaderboard, per-game results, schedule, TV mode, galleryNothing
The public home page before any scores: section headings in Sinhala with English beneath, for the top five, what is up next and recent activity.
The public home in Sinhala and English, before the first score.

From a score to every screen

Score to screen

The two-second figure was a design target; I did not record a measurement on the day.Select a step to see what it does.

Connections: Game leader's phone to Server action; Server action to Postgres; Server action to Activity log (logs the entry); Postgres to Realtime; Realtime to Leaderboard; Realtime to TV display.

A score never goes straight from the browser to a table. The server action checks the user's role and validates the payload, then calls one database function that writes every placing for the game at once. Row-level security decides whether this user leads that game, so the database is the real gate and the app check is a second layer. The action then writes the entry to the activity log, and Supabase Realtime pushes the change to every open leaderboard and the TV display.

The TV display for Tug of War: a podium with 56, 47 and 27 points and places four to eight listed below, with player names blurred.
The TV display on the day. Player names blurred.

Scoring rules as data

Each game carries its own scoring rule as configuration, so a game leader never does arithmetic and the admin can change a rule mid-event without a deploy. There are four rule types: by rank, by points, by time, and win or loss. Each has a weight multiplier and a flag for splitting team points between members. Here is a made-up game:

json
{
  "scoring_type": "rank",
  "points_per_place": [10, 7, 5, 3, 2, 1],
  "participation": 1,
  "weight": 1.0,
  "team_split": false
}

First place earns 10 points, sixth earns 1, and everyone who took part gets 1 more. A heavier final game could set weight to 1.5 without touching code.

Two days, from git

The build, in commit order

  1. 117 April, 1:41 pm: spec and schemaFirst commit: the written spec and a starter database schema.
  2. 217 April, afternoon: foundationNext.js scaffold, design tokens, Sinhala and Latin fonts, then the tables, row-level security and the leaderboard views.
  3. 317 April, evening: public views and loginLeaderboard, schedule, per-game pages and the TV display, all wired to Realtime, with role-based login built alongside.
  4. 418 April, after midnight: score entryThe three-tap entry flow, the validated scoring payload and the activity log.
  5. 518 April, early morning: admin and installAdmin screens for games, teams, players and schedule, then an installable app with a service worker and an iOS install prompt.
  6. 618 April, morning: login changeSwapped emailed sign-in links for email and password, with a reset flow.
  7. 718 April, 2:32 pm: last commitDebugging score validation on event day.
planned tasks done
41 of 42
One image-generation task deferred
Source: Project plan state, 18 April 2026
games planned
15
With 20 players; the counts on the day were not recorded
Source: Spec
leaderboard target
2 s
A design target, not a measurement
Source: Spec

What was still open

Not every check ran

Five human checks were still pending at the last update: installing on iOS and Android, contrast outdoors, a native review of the Sinhala text, and keyboard navigation. I have not recorded how many people used the app on the day.

The game content is bilingual: every game has an English and a Sinhala name and rules. The public interface is bilingual too: headings, navigation, filters and status messages carry Sinhala beside English. The admin screens (scoring, game editing) are mostly English, which was a deliberate cut.

What I'd do next

  • Measure the score-to-leaderboard time on a real event network, instead of trusting the target.
  • Close the five open checks before reusing it.
  • Turn the single hard-coded event into a template, so the next festival is a configuration change rather than a fork.
  • Status: In developmentRaava, my own company

    Raava's public site on Next.js and Payload CMS: editable content, a reusable page system and a motion layer that respects reduced motion.

    Evidence: Live; 436 commits to the site since 1 May 2026.

    Stack: Next.js · React · Payload · PostgreSQL

  • Status: In developmentRaava's own product

    An offline-first app for small Sri Lankan pharmacies: invoice-photo receiving, price-guarded billing and batch stock. Phase 1 is built and in testing.

    Evidence: Phase 1 built; user acceptance testing pending; no pilot yet.

    Stack: React · Vite · TypeScript · Tailwind CSS