HoopRipple
Affiliate member portal built with TanStack Query, custom authentication, and idempotent request handling for money-moving actions.
- Role
- Frontend engineer
- Year
- 2024
- React
- TanStack Query
- Auth
- TypeScript
Problem
HoopRipple's members track referrals and payouts, so the portal handles actions that move money — the kind that must never fire twice, even on a flaky connection or an impatient double-click. The portal also needed session handling that degraded gracefully rather than logging people out mid-task.
- Payout and referral actions vulnerable to accidental duplication
- Session expiry interrupting members in the middle of a flow
- Server and client state drifting after mutations
Approach
I used TanStack Query as the server-state layer so lists, balances, and referral trees share a single cache with predictable invalidation after each mutation. On top of it I built a custom auth flow with silent token refresh, so sessions renew in the background instead of bouncing members to a login screen.
Every money-moving request carries a client-generated idempotency key, so a retry — whether from the user or an automatic one — collapses to a single server-side effect.
- TanStack Query for cache, invalidation, and optimistic updates
- Custom auth with silent refresh for uninterrupted sessions
- Idempotency keys on every mutating request
Tradeoffs
A custom auth flow meant carrying the security burden that an off-the-shelf provider would absorb — token storage, refresh races, and revocation all had to be reasoned through and tested. It was the right call for the portal's specific session behaviour, but it demanded rigour.
Optimistic updates make the UI feel instant but add reconciliation paths for the rare failure; I kept those explicit rather than hiding them.
Outcome
Members can move through referral and payout flows without being interrupted by session expiry, and duplicate submissions no longer produce duplicate effects. The shared query cache kept the UI consistent after every mutation without manual refetch plumbing.
- Duplicate-safe money-moving actions via idempotency keys
- Background session refresh — no mid-task logouts
- Consistent UI after mutations from a single shared cache