Skip to content

Add series question exclusion feature for competitions#303

Open
zacjones93 wants to merge 1 commit intomainfrom
claude/optional-series-questions-56Ros
Open

Add series question exclusion feature for competitions#303
zacjones93 wants to merge 1 commit intomainfrom
claude/optional-series-questions-56Ros

Conversation

@zacjones93
Copy link
Copy Markdown
Contributor

@zacjones93 zacjones93 commented Feb 25, 2026

Summary

This PR adds the ability for competition organizers to selectively exclude inherited series-level registration questions from specific competitions. Previously, all series questions were automatically included in every competition within that series.

Key Changes

Database Schema

  • Added competitionExcludedSeriesQuestionsTable to track which series questions are excluded from specific competitions
  • Includes unique constraint on (competitionId, questionId) to prevent duplicate exclusions
  • Added relations between competitions and excluded series questions

Server Functions

  • New functions:

    • getExcludedSeriesQuestionIdsFn: Retrieves excluded question IDs for a competition (requires MANAGE_PROGRAMMING permission)
    • toggleSeriesQuestionExclusionFn: Toggles a series question's exclusion status for a competition
  • Updated functions:

    • getCompetitionQuestionsFn: Now filters out excluded series questions when fetching questions for a competition
    • validateRequiredQuestions: Excludes validation for questions that are marked as excluded for the competition

UI Components

  • Added Switch component (Radix UI) for toggle controls
  • Updated Athletes page to display all series questions with toggle switches
  • Organizers can now include/exclude individual series questions per competition
  • Visual feedback: excluded questions show strikethrough text and "Excluded" badge
  • Optimistic UI updates with loading states and error handling

Data Loading

  • Athletes page loader now fetches all series questions and excluded question IDs in parallel
  • Improved performance by batching database queries

Implementation Details

  • Exclusions are stored at the competition level, allowing different competitions in the same series to have different question sets
  • Excluded questions are filtered out during registration validation and question retrieval
  • UI provides immediate feedback with optimistic updates and proper error recovery
  • All exclusion operations require MANAGE_PROGRAMMING team permission

https://claude.ai/code/session_01NLCnfEt4nVtxfCpJ39n5Hx


Summary by cubic

Added per-competition toggles to include/exclude series-level registration questions. Excluded questions are hidden during registration and skipped in validation.

  • New Features

    • Added competition_excluded_series_questions table to track per-competition exclusions.
    • New server functions to list and toggle exclusions (requires MANAGE_PROGRAMMING).
    • Updated question fetch and required-question validation to respect exclusions.
    • Athletes page shows series questions with Switch toggles, optimistic updates, and clear badges/states.
    • Loader fetches series questions and excluded IDs in parallel for faster renders.
  • Migration

    • Run database migrations to create the new exclusions table.
    • No breaking changes; competitions default to include all series questions until toggled.

Written for commit b00ed6a. Summary will update on new commits.

Add ability for organizers to toggle individual series-level registration
questions on/off for specific competitions. This supports the use case
where a series defines questions (e.g., shirt size) that don't apply to
every competition (e.g., a $20 online comp that doesn't include a shirt).

Changes:
- Add competition_excluded_series_questions junction table
- Add getExcludedSeriesQuestionIdsFn and toggleSeriesQuestionExclusionFn
  server functions
- Update getCompetitionQuestionsFn to filter out excluded series questions
- Update validateRequiredQuestions to skip excluded questions
- Add Switch toggle UI on competition athletes page for each series
  question with optimistic updates

https://claude.ai/code/session_01NLCnfEt4nVtxfCpJ39n5Hx
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 25, 2026

Warning

Rate limit exceeded

@zacjones93 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 3 minutes and 5 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 24b9c71 and b00ed6a.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • apps/wodsmith-start/package.json
  • apps/wodsmith-start/src/components/ui/switch.tsx
  • apps/wodsmith-start/src/db/schemas/competitions.ts
  • apps/wodsmith-start/src/routes/compete/organizer/$competitionId/athletes.tsx
  • apps/wodsmith-start/src/server-fns/registration-fns.ts
  • apps/wodsmith-start/src/server-fns/registration-questions-fns.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/optional-series-questions-56Ros

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 7 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/wodsmith-start/src/server-fns/registration-fns.ts">

<violation number="1" location="apps/wodsmith-start/src/server-fns/registration-fns.ts:178">
P2: The exclusion filter removes any required question by ID, including competition-specific questions. That can let required competition questions be skipped if their IDs are mistakenly added to the exclusion table. Limit exclusions to series-level questions only.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment on lines +178 to +180
const activeRequiredQuestions = requiredQuestions.filter(
(q) => !excludedIds.has(q.id),
)
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The exclusion filter removes any required question by ID, including competition-specific questions. That can let required competition questions be skipped if their IDs are mistakenly added to the exclusion table. Limit exclusions to series-level questions only.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/wodsmith-start/src/server-fns/registration-fns.ts, line 178:

<comment>The exclusion filter removes any required question by ID, including competition-specific questions. That can let required competition questions be skipped if their IDs are mistakenly added to the exclusion table. Limit exclusions to series-level questions only.</comment>

<file context>
@@ -141,26 +144,47 @@ async function validateRequiredQuestions(
 
+	// Filter out excluded series questions
+	const excludedIds = new Set(excludedRows.map((r) => r.questionId))
+	const activeRequiredQuestions = requiredQuestions.filter(
+		(q) => !excludedIds.has(q.id),
+	)
</file context>
Suggested change
const activeRequiredQuestions = requiredQuestions.filter(
(q) => !excludedIds.has(q.id),
)
const activeRequiredQuestions = requiredQuestions.filter(
(q) =>
!(
q.groupId &&
!q.competitionId &&
excludedIds.has(q.id)
),
)
Fix with Cubic

zacjones93 pushed a commit that referenced this pull request Mar 1, 2026
…riesSettingsTable

Replace the narrow competitionExcludedSeriesQuestionsTable from PR #303 with a
generalized competitionExcludedSeriesSettingsTable that supports excluding any type
of series-inherited setting (registration questions, waivers, etc.) via a settingType
discriminator column. This avoids needing separate exclusion tables per setting type.

- Add competitionExcludedSeriesSettingsTable with (competitionId, settingType, settingId)
- Add SERIES_SETTING_TYPES constant with REGISTRATION_QUESTION and WAIVER
- Add getExcludedSeriesQuestionIdsFn and toggleSeriesQuestionExclusionFn server functions
- Update getCompetitionQuestionsFn to filter out excluded series questions
- Update validateRequiredQuestions to skip excluded series questions
- Add Switch UI component and series question toggle controls on organizer athletes page

https://claude.ai/code/session_01RUHL6Z3Nv8PSBhFsK7o26U
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants