/ Case study · Product
Por Tres — Padel groups, rankings and tournaments
Por Tres is a progressive web app (PWA) for padel groups and clubs: team draws, a ranking with levels and streaks, match history and tournaments. Each group has its own isolated data, and all authorization is resolved server-side without a custom backend. Clubs can run tournaments with QR sign-up, zones and brackets, club medals and metrics.
- Role
- Solo full-stack development: front end, data model, Firestore security rules and CI/CD.
- Duration
- Own product of KBRA Studio, in real use since July 2026
- Client
- KBRA Studio (own product)
- Year
- 2026
Screenshots

Home: next date, who signed up and each player's level 
Team draw, balanced by level, split across courts 
Ranking with streak badges and points from the last date 
Match history with the points won and lost in each game 
Player profile with level evolution and stats 
The same ranking in light mode 
Large screens: side navigation, ranking and group titles 
Desktop home in light mode, with the next date and best pair of the month
/ Try it
Play with the real ranking engine
This runs the same rules Por Tres uses: ELO-style points by expectation, a bonus for carrying a weaker partner, extra for ending an unstoppable streak, and the margin of the score. Add matches and watch the levels move. Nothing leaves your browser.
- Team A
- 72% to win
- Team B
- 28% to win
This result would move
- Ana+2
- Beto+2
- Caro−1
- Dani−1
Ranking
| # | Player | Level | W–L | Streak |
|---|---|---|---|---|
| 1 | Ana | 60−2 | 4–1 | −1 |
| 2 | Beto | 55+3 | 3–2 | +2 |
| 3 | Dani | 50+3 | 2–3 | +1 |
| 4 | Caro | 45−2 | 1–4 | Tilted |
Match history
- Beto + Dani 7–6 Ana + Caro+3 / −2
- Ana + Beto 6–1 Caro + Dani+3 / −2
- Ana + Dani 7–5 Beto + Caro+3 / −2
- Ana + Caro 6–4 Beto + Dani+3 / −2
- Ana + Beto 6–3 Caro + Dani+3 / −2
Simplified for the demo: no inactivity decay (the app takes 1 point per week after a month without playing). Same engine otherwise.
The problem
A padel group that organises matches over WhatsApp has no way to build balanced teams, keep a reliable ranking or guarantee that nobody can tamper with their own results or the group's.
The solution
A multi-group platform (one group's data never mixes with another's) with team draws, a ranking that is always recalculated from the full match history — nothing is precomputed — streaks and group-exclusive titles to gamify participation, and a role model (platform super admin, owner, time-limited admins, members) whose authorization is enforced server-side in Firestore rules, with no custom backend.
Technical details
Front end
- React 19
- React Router 7
- Vite
- Installable PWA (vite-plugin-pwa)
Back end / data
- Firebase Authentication (Google and email/password)
- Firestore as the single source of truth
- No custom backend: all authorization lives in firestore.rules
Features
- Team draws, random or balanced by level
- Dynamic ranking with levels (1–99) recalculated from the match history
- Streaks and group-exclusive titles (gamification)
- Match history and tournaments with their own ranking
- Club tournaments: QR sign-up, zones and brackets, club medals and metrics
- Invitation sign-up with codes that expire, renew or rotate
- Gradual permission roles: platform super admin, group owner, temporary admins, members
- Read-only, append-only audit log
- Directory of venues and courts
- Spanish and English, with light and dark mode
- Responsive layout with side navigation on large screens
Testing and CI/CD
- Vitest for business logic (ranking, courts, backups)
- Firestore rules tested against the emulator (~90 cases) with @firebase/rules-unit-testing
- GitHub Actions: lint + tests + build on every push and PR, automatic preview URL per PR
- Automatic deploy to Firebase Hosting on merge to master
- Automatic daily Firestore backup to JSON via GitHub Actions
Result
- Product in real use by padel groups
- ~150 test cases across business logic and security rules
- Critical authorization resolved entirely in Firestore rules, covered by tests