Skip to content

Add missing submissions filter for broadcast audience targeting#415

Open
zacjones93 wants to merge 2 commits intomainfrom
claude/filter-emails-by-submissions-czQti
Open

Add missing submissions filter for broadcast audience targeting#415
zacjones93 wants to merge 2 commits intomainfrom
claude/filter-emails-by-submissions-czQti

Conversation

@zacjones93
Copy link
Copy Markdown
Contributor

@zacjones93 zacjones93 commented Apr 20, 2026

Summary

Adds a new "missing submissions" audience filter type to the broadcast system, allowing organizers to target athletes in a specific division who haven't submitted scores for all required events. This is useful for sending reminder notifications before submission windows close.

Key Changes

  • New filter type: Added missing_submissions to audienceFilterType with required divisionId parameter
  • Event requirement resolution: Implemented getDivisionRequiredTrackWorkoutIds() to determine which events are required for a division, respecting event-division mappings (unmapped events apply to all divisions; mapped events only apply to their specified divisions)
  • Submission checking: Implemented applyMissingSubmissionsFilter() to identify athletes missing submissions by batch-loading their scores and comparing against required events
  • Filter ordering: Applied missing submissions filter after question filters in both sendBroadcastFn and previewAudienceFn to preserve team inheritance logic (captains must remain in the pool for teammates to inherit their registration answers)
  • Pending invites: Pending-invite recipients (userId=null) are always included when any event is required, matching the behavior of the existing pending_teammates filter
  • UI updates: Added "Athletes Missing Submissions (by Division)" option to the audience type picker with appropriate validation
  • Schema documentation: Clarified that scoresTable.competitionEventId stores trackWorkoutId (not competitionEventsTable.id) with comments in both broadcast-fns.ts and submission-window.ts to prevent future bugs
  • Tests: Added validation tests for the new filter type requiring divisionId and supporting optional question filters

Notable Implementation Details

  • The filter respects event-division mappings: if mappings exist for a competition, only unmapped events (apply to all) or events explicitly mapped to the target division are considered required
  • Batch queries optimize the submission check by loading all scores for relevant users in a single query
  • The filter integrates seamlessly with existing question filters and team inheritance logic by running last in the recipient pipeline

https://claude.ai/code/session_01EGo1FxXpNr8M2jRR7RHfjT


Summary by cubic

Add a new “missing submissions” audience filter so organizers can target athletes in a division who haven’t submitted all required events. Also fixes a notification bug that mis-reported missed submissions.

  • New Features

    • Added missing_submissions filter (requires divisionId); resolves required events using division mappings (unmapped = all divisions; mapped = only those divisions).
    • Batch-checks athlete scores against required track workouts; pending invites are included when any event is required.
    • Runs after question filters to preserve team inheritance in both send and preview flows.
    • UI: new picker option, validation, and recipient count preview.
  • Bug Fixes

    • Fixed window-closed notification check to match scores by trackWorkoutId (the value stored in scoresTable.competitionEventId), not competitionEventsTable.id.
    • Updated helper signature and call sites, and documented the column’s semantics to prevent future mismatches.

Written for commit 8c490e8. Summary will update on new commits.

claude added 2 commits April 20, 2026 02:15
Organizers running online competitions can now target athletes who haven't
submitted scores for every event required of a division, without bothering
those who have already submitted everything. Honors event-division mappings
when scoping required events. Pending-invite teammates are always kept since
they have no user account to check submissions against.

Applied after question filters so team-inheritance in
applyAthleteQuestionFilters still has the captain row available to resolve
teammate matches. Recipient-level dedup already handles athletes registered
in multiple divisions (same userId collapses to one row).
…d false

scoresTable.competitionEventId stores the trackWorkoutId (not
competitionEventsTable.id) — every insert site writes data.trackWorkoutId
to that column. The submission-window notifier was passing event.id into
hasUserSubmittedScore, which meant the score lookup never matched and every
athlete was shown the "Missed Submission" subject and body even when they
had submitted on time.

Rename the helper's parameter to trackWorkoutId to make the semantic explicit,
pass event.trackWorkoutId at the call site, and document the scores column's
historical naming so this doesn't bite us again.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 20, 2026

Warning

Rate limit exceeded

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

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 14 minutes and 24 seconds.

⌛ 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.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 490196b5-89db-42d7-aee7-a820731a9a64

📥 Commits

Reviewing files that changed from the base of the PR and between e0d1319 and 8c490e8.

📒 Files selected for processing (6)
  • apps/wodsmith-start/src/db/schemas/scores.ts
  • apps/wodsmith-start/src/routes/compete/organizer/$competitionId/broadcasts.tsx
  • apps/wodsmith-start/src/server-fns/broadcast-fns.ts
  • apps/wodsmith-start/src/server/notifications/submission-window.ts
  • apps/wodsmith-start/test/server-fns/broadcast-fns.test.ts
  • lat.md/organizer-dashboard.md
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/filter-emails-by-submissions-czQti

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 6 files

Prompt for AI agents (unresolved 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/broadcast-fns.ts">

<violation number="1" location="apps/wodsmith-start/src/server-fns/broadcast-fns.ts:675">
P1: Missing-submissions division filtering ignores parent-event mapping inheritance, so recipients can be incorrectly flagged as missing scores.</violation>
</file>

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

)

return events
.filter((e) =>
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 20, 2026

Choose a reason for hiding this comment

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

P1: Missing-submissions division filtering ignores parent-event mapping inheritance, so recipients can be incorrectly flagged as missing scores.

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/broadcast-fns.ts, line 675:

<comment>Missing-submissions division filtering ignores parent-event mapping inheritance, so recipients can be incorrectly flagged as missing scores.</comment>

<file context>
@@ -614,6 +626,125 @@ async function partitionQuestionFilters(
+  )
+
+  return events
+    .filter((e) =>
+      !mappedEventIds.has(e.trackWorkoutId)
+        ? true
</file context>
Fix with Cubic

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