Background
NEXUS's form builder replaces the external Google Form + sheet-sync pipeline for tournament and alumni-chapter data collection. It's being built as one PR across several tracking issues, each scoped to a coherent slice of the feature. This issue is the parent — it doesn't contain implementation detail, it exists so every sub-issue has one place to link back to and so scope boundaries between them stay visible.
Sub-issues
| Issue |
Covers |
| Forms Core Model |
Form/FormField/FormResponse/FormAnswer, single tournament-or-chapter ownership, status (draft/published/archived), hardcoded membership-required access on read/submit |
| Branching + Question Type Config Validation |
Per-type config shape validation, options validation, reserved field_key ↔ question_type enforcement, whole-form publish-time validation, conditional branching between questions |
| Lunch Structural Data + Write-Through |
MembershipAvailability (reuses TournamentShift, options group multiple shifts under one TD-labeled choice), TournamentMembershipLunch (date + category, no dedicated catalog), availability/lunch diff-sync on submission, TournamentShift deletion guard |
| Edit Lifecycle |
Bulk field replace route, archive-not-delete for fields/options on published forms, FormResponsePendingUpdate |
| Forms Builder Frontend |
The TD-facing editor UI for creating/editing forms and their fields — the first real client of the backend above |
Forms is deliberately "dumb" — it has no concept of tournament onboarding, phases, or membership side effects. That orchestration lives in a separate, sibling parent issue: Onboarding, which consumes Forms without Forms ever referencing it back.
Known future work (not yet issued)
- Whether responders must update an existing response after a published form's fields change (partially addressed by Edit Lifecycle's
FormResponsePendingUpdate, but what a consumer does with that signal — blocking UI, notification — is still undecided)
- Response review UI
- The respondent-facing fill-out experience and a TD preview-as-respondent view (Forms Builder Frontend only covers the editor)
- Embedding a form inside Tournament Onboarding — once Onboarding itself is being built
Out of Scope (permanently, not just deferred)
- Group forms: a single form spanning multiple tournaments and/or chapters — deferred indefinitely, not just "not yet issued." Group form distribution via join code depends on this and is deferred the same way.
- Response history — resubmitting a form always overwrites in place.
- A generic "custom question" escape hatch outside the typed
question_type list — every question type is explicitly modeled, not free-form.
Background
NEXUS's form builder replaces the external Google Form + sheet-sync pipeline for tournament and alumni-chapter data collection. It's being built as one PR across several tracking issues, each scoped to a coherent slice of the feature. This issue is the parent — it doesn't contain implementation detail, it exists so every sub-issue has one place to link back to and so scope boundaries between them stay visible.
Sub-issues
Form/FormField/FormResponse/FormAnswer, single tournament-or-chapter ownership,status(draft/published/archived), hardcoded membership-required access on read/submitconfigshape validation, options validation, reservedfield_key↔question_typeenforcement, whole-form publish-time validation, conditional branching between questionsMembershipAvailability(reusesTournamentShift, options group multiple shifts under one TD-labeled choice),TournamentMembershipLunch(date + category, no dedicated catalog), availability/lunch diff-sync on submission,TournamentShiftdeletion guardFormResponsePendingUpdateForms is deliberately "dumb" — it has no concept of tournament onboarding, phases, or membership side effects. That orchestration lives in a separate, sibling parent issue: Onboarding, which consumes Forms without Forms ever referencing it back.
Known future work (not yet issued)
FormResponsePendingUpdate, but what a consumer does with that signal — blocking UI, notification — is still undecided)Out of Scope (permanently, not just deferred)
question_typelist — every question type is explicitly modeled, not free-form.