Loading...
Loading...

Music analytics platform built with Next.js 16 and Supabase that goes well beyond what Spotify Wrapped gives you. Tracks your top 50 artists, tracks, and albums across three time ranges with daily snapshots, then runs that data through Postgres RPCs to surface things like which album is dominating your listening, who your most consistent artists are, and where the biggest rank shakeups happened. A floating Spotify player lets you listen without leaving the app — it uses the Web Playback SDK on desktop and falls back to polling on mobile where the SDK is unreliable. The friend system is request-based with Discord-style usernames, privacy tiers, and the ability to browse each other's stats. Installable as a PWA on both Android and iOS.
The player uses a dual-mode architecture: Web Playback SDK on desktop with real-time state events, and adaptive polling (2s playing, 5s paused, 10s idle) on mobile where the SDK is unreliable. A retry loop handles the device registration race by catching 404s and re-transferring playback. All recap computations run as Postgres RPCs with security-definer functions that enforce privacy at the database level — the React components receive pre-shaped JSONB and do zero data processing. The friend system stores relationships in its own table (not Spotify's follow API) with bidirectional .or() queries and an auto-accept path when both users have pending requests to each other. Genre rankings are computed server-side across all three time ranges in parallel via Promise.all, then passed to the client as a single payload for instant tab switching. Database types stay in sync through GitHub Actions running supabase gen types daily.
A deployed music analytics platform at statsforspotify-chi.vercel.app with in-browser Spotify playback, four recap insight cards backed by complex Postgres analytics, a request-based social system with privacy controls, genre breakdowns, and full artist/track/album detail pages with ranking history. Installable as a PWA on both mobile platforms. The whole thing runs on Supabase with RLS enforcing privacy at the database layer, auto-generated types keeping the frontend in sync, and Vercel Analytics tracking real usage.






