Nota
Lead engineer, built it end to end
Nota is a padel score book for Dubai on iOS and Android: one player logs a match, the other team confirms it, and only then does anyone's rating move. Asif Alam was Nota's lead engineer at Qwerty and built it end to end; he ported the client's rating algorithm into Postgres, proved it against the original with tests and fixed its order-dependence flaw.
- Role
- Lead engineer, built it end to end
- When
- Since May 2025
- Platforms
- iOS · Android

- teams sign every score
- 2
- hours to confirm
- 24
- grades to climb
- 18
- one-sided scores
- 0
(01)
The problem
Self-reported scores are easy to inflate, and a rating built on them means nothing. Nota makes every result two-sided: nothing counts until the other team agrees (or a day passes in silence), and the database turns away results that cannot be real.
(02)
What it does
- Log a match in a few taps: court, time, the three other players, the sets
- The other team confirms, corrects or disputes; a correction hands the clock back to the other side
- Matches confirm themselves after 24 hours of silence, with a reminder two hours before
- Fix your own score within an hour of logging it
- A short quiz sets your starting level; after that, an 18-step letter grade and a leaderboard
- Friends and invite codes that work before the friend has signed up
- Match history, sharing, and push notifications you can tune by type
(03)
The hard parts
The rating, moved into Postgres
The client's rating is a Glicko-2 variant written in Python. I rebuilt it as Postgres functions, so ratings change in the same transaction that confirms a match. The old system had run a simpler Elo alongside a broken second job, so I wiped every rating and replayed every confirmed match in the order it was played, with a backup schema for the way back.
Fixing an order-dependence flaw
In the original, player one's rating was updated first, and player two was then weighed against player one's new rating, so the same match moved ratings differently depending on who was entered first. Now all four players update from their ratings before the match. Two more fixes came with it: a winner is decided by sets, not total games (the original called 6-0 3-6 3-6 a draw), and a match counts from when it was played, not when it was confirmed.
Proving it against the original
A generator imports the client's own Python and writes a 630-line SQL test: 24 matches pushed through the real database functions, checking every player's rating after every match against the Python, plus the deliberate differences above. It runs inside a transaction that rolls itself back.
A score with a clock on it
Every match carries a 24-hour deadline, reset for the other side whenever a score is corrected. A job every five minutes confirms what has expired and warns what is about to; ratings apply only once a match is final, and a flag stops them from ever applying twice.
Anti-cheat at the door
The database refuses a match before it exists if a player appears twice, it ends before it starts, it is logged more than seven days late, it overlaps another match for any player, or the same four players log more than three matches in 24 hours. Two teams recording the same match at once are serialised with a lock, and device test flows exercise the rules on a real phone.
(04)
Stack
- Expo
- React Native
- TypeScript
- NativeWind
- Supabase
- PostgreSQL
- pg_cron
- pg_net
- Edge Functions
- Maestro