Developer handoff · pick-up point

One page a new owner can continue this work from: the goal, what's done vs left, where everything lives (PRs, plans, demo), and the decisions still open. Reads alongside the summary and full technical plan. Edit the content in apps/docs/src/app/plan/matches-programs-openrally-handoff/page.tsx (single source — no separate data file).

Matches & Programs via OpenRally — Handoff

Purpose: a single page a new owner can pick this up from. What the goal is, what's already done, what's left, where everything lives, and what must be decided next. The companion plans are the summary and the full technical plan.

The goal (one line)

Let Setpoint clubs run open matches, programs (clinics / leagues / camps) and events, and let TPS players discover, join and pay for them from the app — the same way they already book courts and coaches. The bridge between the two systems is the OpenRally protocol (TPS never talks to Setpoint directly).

The plan in five steps

  1. Turn the features back on in the Setpoint admin. Open Matches, Programs and Events were built but parked/disabled — un-hide and finish the gaps. ("Matches" is "Events": same feature, different label — there is no separate Events entity.)
  2. Take payment when a player joins, exactly like a court booking: hold a spot → pay → confirm. This is the one genuinely unfinished piece, and it is the hard gate — it must land before any paid path is exposed (TPS charges real Stripe while Setpoint still runs test keys).
  3. Publish over OpenRally as a neutral, opaque session_* family, so other apps can read matches/programs without seeing private player data (names, levels, scores).
  4. Wire the TPS side so these sessions render natively in the app and a player can join + pay with their saved card (money lands in the club's connected Stripe account).
  5. Rename Lessons → "Coaching Sessions" and add the event typology.

Status

PieceState
The plan itself (summary + full)✅ written + merged to main (deployed to the docs site)
Admin revival + payment reconciliation (hold → pay → confirm)🟡 built + tested locally, in PR #726 — open, ready for review (not yet merged)
OpenRally session discovery endpoint (read side)🟡 built + curl-tested locally, in PR #727 — open, ready for review (stacked on #726)
OpenRally publish/push to TPS (the write side)⏳ not started
TPS consumer side (render + join + pay)⏳ not started
Event typology · Lessons → Coaching rename⏳ planned

Roadmap — what's left (in order)

A simple map of the remaining work, in the order it should happen.

  1. Merge the foundation (ready now — both PRs are open and ready for review). This turns on the revived admin (Open Matches + Programs), the join → pay → confirm payment flow, and the OpenRally read endpoint. Order matters — #727 is stacked on #726:
    • Merge #726 first (admin + DB, base main). On merge, Vercel auto-deploys the admin; then manually run its migration: supabase db query --linked --file supabase/migrations/20260605094626_events_payment_reconciliation.sql (per the prod rule — new migration files only).
    • Then #727 (OpenRally read endpoint, Rust). It's stacked on #726's branch, so GitHub auto-retargets it to main once #726 merges — it can only land after #726. On merge, deploy it: cd protocol/server && flyctl deploy --remote-only.
  2. Publish to TPS — the push side (not started) — when a match or program is created or changes, Setpoint sends an opaque session_* event to TPS over a webhook, reusing the same mechanism that already pushes court bookings and coaches. No private player data leaves Setpoint.
  3. Join + pay from TPS (not started) — TPS shows these sessions natively and lets a player join and pay with their saved card; the money lands in the club's connected Stripe account.
  4. Events + rename (not started) — add the event typology, and rename "Lessons" to "Coaching Sessions".
  5. Turn on real payments (when ready) — Stripe runs on test keys today (on purpose); flip to live keys once the club is ready to charge real cards.

Links

Decisions needed before the next build

  1. Scope — matches first, or matches + programs together?
  2. Money — free at launch, or charge-on-join from day one?
  3. Direction — Setpoint pushes to TPS (webhook), or TPS pulls (the discovery endpoint already exists)?
  4. Merge posture — #726 and #727 are open and ready for review; merge + deploy now, or hold for further review?
  5. The wire contract — sign off the neutral session_* shape (deliberately strips player names / levels / scores so no PII leaks to a consumer).

Gotchas for whoever picks this up

  • The 13 data-testids added to the match/program forms for the demo are local in the #726 worktree, not yet committed/pushed — they're only needed to re-run the demo, not to build the feature.
  • The admin create-match form still requires a court (it creates a court booking). Only the join/payment path was made court-optional so far; the create form was not.
  • Onboarding a club to OpenRally needs two webhook subscriptions (booking_* and lesson_*); the admin UI defaults to one row, so the split is easy to miss.