Automated swim practice registration for SCAQ teams on iClassPro.
Reggie turns SCAQ practice registration on iClassPro into one tap. Sign in once, pick a practice from the open classes, and Reggie completes the registration in the portal for you, promo code included. Built for swimmers who would rather swim than fight a registration page.
reggie-production.up.railway.app
- Python / Flask
- Playwright (browser automation)
- Railway
- Supabase (practice tally only — optional)
Each swimmer gets a running count of the practices Reggie registered them for, with an estimated yardage per practice (default 3,000, adjustable). Once a practice has finished, the app asks for that day's yardage on a slider. The home screen shows total yards on a rolling odometer, with miles and swims since the first one; the history screen filters by week, month, year to date or all time.
Private by default. A swimmer can opt in to share confirmed swims with the Artie crew dashboard; otherwise only they see their numbers.
Rows are keyed by HMAC-SHA256(TALLY_SECRET, lowercased email) — the table
stores no email addresses, one swimmer cannot derive another's key without the
server secret, and no endpoint lists or aggregates across swimmers. Because the
key is derived rather than random, it survives a reinstall or a new phone.
-
Run
sql/001_practices.sqlonce in the Supabase SQL editor. It creates thereggieschema and enables row-level security with no policies, so Supabase'sanonandauthenticatedroles can read nothing. -
Set two environment variables on Railway:
Variable Value TALLY_DB_URLSupabase Session pooler connection URI TALLY_SECRETpython3 -c "import secrets;print(secrets.token_hex(32))"TALLY_SECRETmust not change once there is history — rotating it orphans every existing row.
Leave either variable unset and the tally disappears from the UI entirely; registration is unaffected. Tally writes are best-effort by design: if Supabase is paused or unreachable, a swimmer loses a tally entry, never their spot in a class.
TALLY_TZ overrides the timezone used to decide when a practice is over
(default America/Los_Angeles).
Live and in active use.