Summary
Before PR #2867, InvitationManager keyed invitation lookup on (event/workshop, member, role). Members subscribed as both student and coach accumulated two invitation rows per event or workshop — 387 members on the reported event (#2861). PR #2867 stops new duplicates but leaves existing rows untouched; no data migration was included.
Proposal
A data migration (or one-off rake task) that, per member per event/workshop:
- Keeps one invitation row
- Moves the attending/RSVP state from the discarded row if the member accepted on either (needs an explicit product decision if both rows have conflicting states)
- Preserves or merges associated records: waiting list entries (
waiting_lists.invitation_id, unique per invitation), feedback, invitation logs, email delivery history
Open questions
- Which row survives: Coach or Student? (The dual-role email choice issue applies to historical data too.)
- Do the duplicates carry any state we must merge rather than drop?
- Scope: events only, or workshops too?
A schema-level unique index without role (see companion issue) can only land after this cleanup.
Summary
Before PR #2867,
InvitationManagerkeyed invitation lookup on(event/workshop, member, role). Members subscribed as both student and coach accumulated two invitation rows per event or workshop — 387 members on the reported event (#2861). PR #2867 stops new duplicates but leaves existing rows untouched; no data migration was included.Proposal
A data migration (or one-off rake task) that, per member per event/workshop:
waiting_lists.invitation_id, unique per invitation), feedback, invitation logs, email delivery historyOpen questions
A schema-level unique index without
role(see companion issue) can only land after this cleanup.