Apex Setup Vault
Problem
Track riders make setup changes under pressure. Notes end up in screenshots, group chats, memory, or disconnected documents. That makes the next session harder to reason about.
Apex treats the iteration loop as the product:
Bike current setup -> Adjustment -> Session outcome -> next Adjustment
What riders can do
Riders can keep their bikes in a garage, save reusable setup presets, record adjustments, submit sessions with a snapshot of the setup they actually ran, review their history and maintenance, and monitor Recall Watch matches.
They can keep that data private or share selected sessions, browse the community feed, compare lap and sector times for the same track and layout, manage a rider profile, and block or report other users. Shops have a separate workspace for customer bikes, setup recommendations, and conversations.
Security model
The current security model is layered. Supabase Auth owns credentials and issues
the JWT, FastAPI validates it, then each request transaction switches to the
authenticated database role and installs both the full claims payload and
sub. Postgres RLS is still the final authority, which matters because adding a
new route should not quietly create a second authorization model.
The normal API only gets a least-privileged runtime connection. Migrations use a separate privileged connection, and the Supabase service-role key is isolated to the short-lived account-deletion worker instead of living in the API or either client.
Private session photos take a separate path: a private R2 bucket, short-lived signed Worker URLs, type, size, checksum, dimension, and pixel validation, decode and re-encode into fixed WebP variants, then prefix cleanup during deletion. Social sharing, blocking, reports, moderation, and audit history now have explicit database authorization paths too.
There is one important exception that is not production-ready: Recall Watch
needs cross-rider batch access, so its proposed worker role uses BYPASSRLS with
a narrow column allow-list. The repo has a strict preflight for that role, but
production verification is still a blocker, so I am not presenting it as
solved.
Tradeoffs
Apex is a modular monolith. The setup loop, social layer, shops, moderation, and Recall Watch all share enough data that adding services and an event bus right now would mostly create more places for state to disagree. Shared transactions and one deployment are useful until real load proves otherwise.
The Recall Watch worker is probably the biggest tradeoff here. A batch process obviously can’t pretend to be a single rider, so cross-rider access has to exist somewhere. The proposed role gets around RLS, but it’s still locked down to a really narrow set of bike and recall columns, with no access to profiles or sessions, plus a preflight that catches any role drift. Until we can actually verify that’s working correctly in prod, the worker stays blocked.
Outcome
The biggest outcome is that Apex stopped being a setup-log demo and turned into a real product surface: the rider loop works across web and native, offline submissions are durable, private photos have an actual delivery path, and the community layer now includes sharing, blocking, reporting, moderation, leaderboards, profiles, and shop workspaces.
The part I care about more is that getting there did not require abandoning the original privacy model. If adding feeds, shops, media, and moderation meant giving the normal API a service-role key, then the design had kinda failed, right? It did not. Those features still route through request claims, constrained database roles, and RLS, with privileged jobs split into explicit paths.