Personal Project

Waveger

Billboard meets Fantasy Football: Predict the Hot 100, compete for accuracy.

Year

2025

Technologies

React 18, TypeScript, Supabase, PostgreSQL

Live Site

Visit

The Product

Waveger is fantasy football for music fans. Each week, users predict where songs will land on the Billboard Hot 100 and earn points based on accuracy. Predictions lock Friday at 5 AM GMT. When the official chart drops Saturday, scores calculate automatically and the leaderboard updates.

The original version was my final year project at the University of Leeds, built with Flask, vanilla JavaScript, and Bootstrap. It scored a First and was my first proper full-stack project. After graduating I decided to rebuild it from scratch with a modern stack: React, TypeScript, Supabase, proper testing. Same concept, completely different architecture.

If you spend any time on stan Twitter, you'll know the culture. Everyone's got opinions on whether their fave will debut top 10, whether a song's got the streams to hold #1, whether radio will tank a song's position. Accounts like @ChartData post midweek updates and the replies fill with predictions. But no one's keeping score of who called it right. I wanted to turn predictions into a competition.

Desktop homepage with hero tagline, current top 3 songs, and countdown timer

Features

Desktop drag-and-drop prediction interface with grid layout

Make Your Predictions

On desktop, users drag and drop songs in a grid using @dnd-kit. On mobile, they swipe through a card stack powered by Swiper.js. Both share the same prediction logic underneath, just different input methods.

A countdown timer ticks down to Friday 5 AM GMT. When the deadline hits, predictions lock server-side.

Automatic Scoring

When Billboard publishes charts every Saturday, scores calculate automatically for everyone at once. Points use a tiered system: 150 for an exact match, scaling down based on how close you were.

Desktop results page showing scored predictions with point breakdown
Desktop leaderboard with weekly rankings and profile analytics

Leaderboards & Profile Stats

Weekly and all-time leaderboards rank users by total points, with streak tracking for consecutive weeks of participation. Profiles show prediction history with Recharts line charts: points earned per week and accuracy percentage over time.

Apple Music Integration

Users can swap any Billboard song for a custom Apple Music song, handy for predicting songs that aren't on the current chart. Search uses Fuse.js for fuzzy matching.

Desktop Apple Music swap modal with search interface

How It's Built

Architecture Decisions

Server-Side Scoring: CRON-triggered Deno Edge Functions fired by GitHub Actions every Saturday. Uses Supabase service role keys to bypass Row Level Security. PostgreSQL's UNNEST operator writes all scores in a single query instead of one per prediction.

Three-Layer Caching: Chart data flows through Upstash Redis (7-day TTL), then PostgreSQL, then TanStack Query's client cache (30-minute stale time). Most requests never touch the external API.


Security

Row Level Security throughout: users can only touch their own predictions, leaderboards and charts are public read, Edge Functions use service role credentials for admin operations.


Performance

Route-based code splitting keeps the initial bundle around 180KB gzipped. Composite database indexes for fast queries.


Observability

Sentry error tracking with session replay. React error boundaries catch component failures and render recovery UI.


Accessibility

WCAG 2.1 AA compliant. Proper semantic HTML with landmark tags, ARIA labels on interactive elements, full keyboard support for drag-and-drop (Space to grab, Arrow keys to move), 4.5:1 minimum contrast ratio, and visible focus indicators throughout. Tested with VoiceOver on macOS and NVDA on Windows.


Testing

When your users are competitive pop fans who will absolutely notice if scoring is off by a single point, you can't cut corners. Unit tests with Vitest, component tests with React Testing Library, and E2E tests with Playwright running the full prediction flow against a staging database.


UX Polish

Native sharing via Web Share API with fallbacks to clipboard and Twitter intent links. Confetti celebrations for predictions and badge unlocks. Four achievement badges with progress tracking.


Tech Stack

Front End: React 18, TypeScript (strict), Vite + SWC, TanStack Query, shadcn/ui + Radix UI, Tailwind CSS, Swiper.js, Framer Motion, @dnd-kit, Recharts, Fuse.js, canvas-confetti

Back End: Supabase (PostgreSQL + Auth), Deno Edge Functions, Upstash Redis

APIs: RapidAPI Billboard Charts, Apple Music API, Resend

DevOps: GitHub Actions, Vercel, Sentry (with Session Replay), Codecov, Dependabot, Playwright, Vitest