Skip to content

WAIT: Make event registrations deletable only when safe#1862

Draft
maebeale wants to merge 3 commits into
mainfrom
maebeale/event-registration-deletable
Draft

WAIT: Make event registrations deletable only when safe#1862
maebeale wants to merge 3 commits into
mainfrom
maebeale/event-registration-deletable

Conversation

@maebeale

Copy link
Copy Markdown
Collaborator

What is the goal of this PR and why is this important?

  • Prevent event registrations from being deleted when doing so would orphan financial records or erase attendance history.
  • allocations (payments and scholarships) have no dependent: :destroy, so deleting such a registration leaves dangling records; attended/incomplete-attendance registrations are kept as a record.

How did you approach the change?

  • Added EventRegistration#deletable? (!allocations.exists? and not an attended status) as the single source of truth.
  • Hid the Delete button on the admin edit form and the public "De-register" button when not deletable, and enforced the same guard server-side in both EventRegistrationsController#destroy and Events::RegistrationsController#destroy (hiding a button alone leaves the DELETE route open).

UI Testing Checklist

  • Admin edit form: Delete button hidden for a registration with a payment, scholarship, or attended status; shown for a plain registered/cancelled one.
  • Public event page: "De-register" hidden once a registrant has paid or attended; the "Registered" badge still shows.
  • Attempting the DELETE directly when not deletable shows an alert and does not destroy the record.

Anything else to add?

  • Rebased onto current main; reconciled with main's newer attended? (used by certificate/joinable logic) by inlining the attendance check in deletable? rather than redefining the method.

maebeale and others added 3 commits June 22, 2026 08:20
…ndance records

Hiding the Delete button alone leaves the DELETE route open to admins/owners,
so deletability is enforced in the model, view, and controller.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Main's registration-suite added a public De-register button that hard-deletes
the registration; without the same guard a paid registrant could orphan their
allocation. Hide the button and refuse the destroy when not deletable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Main added its own attended? (status == "attended", used by certificate and
joinable logic). Drop the duplicate this branch introduced and inline the
attendance check in deletable? so it still blocks both attended and
incomplete_attendance without clobbering main's method.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
!allocations.exists? && !status.in?(%w[ attended incomplete_attendance ])
end

def checked_in?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

🤖 From Claude: Single source of truth for both delete paths. allocations has no dependent: :destroy, so deleting a registration with payments/scholarships would orphan those rows — hence the guard rather than a cascade.


authorize! @event_registration

unless @event_registration.deletable?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

🤖 From Claude: Enforced server-side here (not just by hiding the button) because the DELETE route stays reachable for authorized users. Points the registrant to cancel, which is a soft status change that preserves the payment record.

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.

1 participant