Skip to content

Validate that an event's course belongs to the event group's organization - #2241

Merged
moveson merged 2 commits into
masterfrom
oveson/claude/event-course-organization-validation
Aug 24, 2026
Merged

Validate that an event's course belongs to the event group's organization#2241
moveson merged 2 commits into
masterfrom
oveson/claude/event-course-organization-validation

Conversation

@moveson

Copy link
Copy Markdown
Collaborator

Summary

The hardening PR from #2235, written TDD-style (failing specs committed first). Two pieces:

1. The validation.Event now validates that its course belongs to its event group's organization. This closes every path that could mint new cross-organization relics — UI, API, imports, and DuplicateEventGroup (which copies events into a group in the same organization, so it passes naturally). The validation skips when course or event group is absent, leaving those to the presence validations.

2. The nil-course guard (carried over from closed#2234).conform_changed_course bails when the course is blank, so a nil course_id (e.g., an API PATCH with course_id: null) produces the belongs_to presence validation's 422 instead of an ArgumentError 500 from ChangeEventCourse.

Deployment note

Merge only after the staging data repair from #2235 is complete. Production audited clean, so no production data blocks this — but the eight staging relics would fail validation on their next save. (Existing invalid rows don't break reads; they'd surface only when someone edits one.)

Factory and spec fallout

The event factory previously built course and event_group independently, each minting its own organization — so every factory event was cross-organization by default. The factory now builds the course in the event group's organization (course { association :course, organization: event_group&.organization }), which fixed most of the suite automatically. Twelve spec files that explicitly paired independently-built courses and event groups now thread a single organization through their setup (a one-line change per site). Rubocop's whole-file CI check also swept the touched API controller specs (response.parsed_body conversions and the like).

Testing

  • New event specs: cross-organization course is invalid (build and persisted-change paths, with the change confirmed not to persist); same-organization is valid; factory events are consistent by construction; nil course on a persisted event is invalid rather than raising. Four behavior-differentiating examples verified to fail pre-change.
  • Full affected sweep: all 93 non-system spec files referencing the event factory plus the plan-effort system spec — 1,762 examples, 0 failures.
  • rubocop clean on touched files.

🤖 Generated with Claude Code

movesonand others added 2 commits August 24, 2026 14:34
Covers the cross-organization course validation, the factory default,
the persisted-change rejection, and the nil-course guard from #2234.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tion
Courses were originally organization-less, and relic events pointing at
another organization's course still exist on staging (#2235). Such
events break the event edit form, whose course selector offers only the
event group organization's courses and silently blanks course_id.
Validate the consistency so no path (UI, API, imports, duplication) can
create new relics.
Also bail out of conform_changed_course when the course is blank, so a
nil course_id yields the belongs_to presence validation's 422 instead
of an ArgumentError 500 (the guard from #2234).
The event factory now builds its course in the event group's
organization, and specs that explicitly paired independently-built
courses and event groups thread a single organization through.
Resolves#2235
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@moveson
moveson merged commit 643de1e into masterAug 24, 2026
7 checks passed
@moveson
moveson deleted the oveson/claude/event-course-organization-validation branch August 24, 2026 23:19
Sign up for freeto 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.

1 participant

@moveson