Skip to content

feat: tournament onboarding #65

Description

@ethnjs

Background

Tournament onboarding needs orchestration that Forms deliberately doesn't provide: deciding which forms a member must complete to be considered onboarded, in what order, and what to do once they've finished them all. This is a separate feature sitting on top of Forms, not a sub-feature of it — Onboarding references Forms constructs (form_id), Forms never references Onboarding, with one deliberate, narrow exception (see Proposed changes).

The original scope for this issue (an OnboardingPhase/OnboardingPhaseForm model with typed visibility conditions and a TournamentMembershipTrackStatus table) turned out to be more than the actual need called for. It's been replaced during implementation with a flatter model, described below. Most of it has since shipped.

Motivation

TDs need to change what's required to become an official tournament member as the season progresses (e.g. fall: test-writing interest + day-of interest; winter: day-of interest only; pre-tournament: confirmation + logistics) without engineering involvement each time, and without members who already cleared an earlier requirement set being incorrectly bounced back to "incomplete."

Proposed changes

Backend model — TournamentForm: a 1:1 companion row every tournament-scoped Form gets at creation (backend/app/models/models.py). is_onboarding (bool) + order (int, set only for onboarding rows) drive the sequence; form_id is its own primary key. TournamentMembership.onboarded_at (nullable timestamp) snapshots completion — set once a member has answered every currently-onboarding-flagged published form, and permanent from then on: removing/archiving an onboarding form later never unsets it, only adding a new onboarding form clears it tournament-wide (a genuine expansion of the requirement, unlike passive list churn).

Backend routes (backend/app/api/routes/tournament/onboarding.py):

  • TD management: GET/POST /tournaments/{id}/onboarding-forms/, PATCH .../reorder/, DELETE .../{form_id}/. Add requires the form be published; reorder validates a contiguous 1..N sequence.
  • Member-facing: POST /tournaments/{id}/onboarding/progress/ — finds the next unanswered published onboarding form, snapshots onboarded_at once none remain.
  • One exception to the Forms/Onboarding dependency direction: _reject_if_onboarding in backend/app/api/routes/forms.py blocks archiving or hard-deleting a form still flagged is_onboarding — it must be removed from onboarding first.

Frontend — drag-and-drop config page under tournament Forms → Onboarding tab (frontend/app/dashboard/tournaments/[id]/forms/onboarding/page.tsx); /join now routes into /tournaments/{id}/onboarding, which resolves to the next required form and advances automatically on submit (frontend/app/tournaments/[id]/onboarding/**).

Design decisions replacing the original scope:

  • No OnboardingPhase — a phase is just how a TD talks about the sequence, not a modeled concept. One flat, ordered list of onboarding forms, managed directly.
  • No visibility conditions for onboarding forms — order + published status is the only gate. Role/availability-based gating is deferred to standard (non-onboarding) forms as a prerequisites mechanism, not built yet.
  • No creates_membership_on_submit side-effect — unnecessary, since a TournamentMembership already exists (status="interested") from the moment someone joins, before onboarding starts.

What will not change

  • Forms itself (Form/FormField/FormResponse/FormAnswer, question types, branching, write-through mechanics) stays unaware of Onboarding, aside from the one archive/delete guard above.

Completion criteria

  1. TournamentForm model + migration (with backfill for pre-existing forms)
  2. Archive/delete guard for onboarding-linked forms
  3. TD management routes (add / reorder / remove)
  4. Member progress endpoint + onboarded_at snapshot semantics
  5. Drag-and-drop config page
  6. /join routes into the onboarding flow and advances on submit
  7. Test coverage for config CRUD and member progress (backend/tests/api/tournament/test_onboarding.py)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

  • Status
    Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions