Our padel group is 17 people who play regularly, and that brings two problems. Matchmaking needs fair pairings, but any ranking someone keeps by hand drifts, and then people argue about it. And the social nights, Americano and Mexicano, are their own kind of fun and shouldn’t touch the serious rating.
The event log
The rating engine is event-sourced. Every match result and every admin correction is stored as an event, and current ratings come from replaying the whole log in order through the openskill engine. The same log always gives the same ratings. There’s no rating state sitting around waiting to drift, so an edit or a deletion just triggers a fresh replay, which takes milliseconds at 17 players. The engine is pure, with no I/O, and fully unit-tested.
Session nights
Session nights run on a separate data model with a pluggable pairing strategy. Sit-out rotation, scoring, medals and retention share one engine, and Americano and Mexicano are each just a function that generates the next round’s pairings. A ratings-balanced mode can drop into the same slot later. Session nights never write to the rankings.
It’s a React PWA on Vercel with Supabase behind it, including row-level security and an edge function for admin jobs like creating a member or resetting a PIN, all on the free tiers. The group uses it, and if a rating looks wrong, you fix the match and the rating follows.
The screenshots come from the app’s demo mode: our group’s real names with sample results, so the numbers aren’t anyone’s actual rating.