Skip to content

Stop a double-submit from creating duplicate registrations and people - #2465

Merged
jmilljr24 merged 4 commits into
mainfrom
maebeale/dedupe-duplicate-registration
Sep 1, 2026
Merged

Stop a double-submit from creating duplicate registrations and people#2465
jmilljr24 merged 4 commits into
mainfrom
maebeale/dedupe-duplicate-registration

Conversation

@maebeale

@maebeale maebeale commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

🤖 suggested review level: 5 Inspect 🔬 concurrency guard (MySQL named lock) + registration-flow change across the public registration path

A registrant who double-clicked Register (or came back and re-submitted) could end up with two people and two registrations for the same event — this closes both the accidental double-click and the underlying race, and stops re-submissions from silently losing earlier answers.

Duplicate registrations from a double-submit

  • Client guard: the public registration form now uses the existing submit-once Stimulus controller, so the button locks after the first click. This matters most on paid events, which opt out of Turbo (turbo: false) and so had no submitter disabling at all — the likely source of the "two registrations in the same minute" incident.
  • Server backstop: a genuine concurrent submission (two tabs, a proxy retry) still raced find_or_create_person, so the flow now serializes same-identity submissions behind a MySQL named lock (email + last name + event, namespaced by database so parallel test suites don't contend). The second request waits, then matches the first's committed person. Best-effort: a blank identity or an un-acquirable lock falls through rather than failing a real registration.

Re-registration no longer overwrites answers

  • A returning registrant reuses their one Person and one event registration, but re-submitting used to overwrite their prior FormSubmission in place, silently dropping the earlier answers. Each submission is now recorded on its own, preserving the full history (the admin registrants view already iterated multiple submissions).
  • The public confirmation view defaults to the most recent submission when none is named.

Tests

  • Same name + email → one person, one registration, two submissions.
  • File-upload specs updated: each submission is independent; the earlier one keeps its file, a blank re-submit adds a fileless submission.
  • Confirmation view defaults to the latest submission.
  • submit-once renders on free and paid events.
  • The identity lock is taken and released around the flow (a true thread race isn't unit-testable without flakiness).

@maebeale maebeale changed the title Append a new form submission on re-registration instead of overwriting Stop a double-submit from creating duplicate registrations and people Aug 31, 2026
@maebeale
maebeale marked this pull request as ready for review August 31, 2026 21:17
@maebeale
maebeale requested a review from jmilljr24 August 31, 2026 21:21
@maebeale maebeale changed the title Stop a double-submit from creating duplicate registrations and people JM: Stop a double-submit from creating duplicate registrations and people Aug 31, 2026
@jmilljr24

Copy link
Copy Markdown
Collaborator

This looks overcomplicated. I thought we just had a conversation about double submits.

maebeale and others added 3 commits August 31, 2026 23:22
A returning registrant (same name + email) reuses their existing Person
and single event registration, but re-submitting the form used to
overwrite their prior FormSubmission in place. That silently lost their
earlier answers. Each registration now records its own FormSubmission, so
the full history is preserved, and the public confirmation view defaults
to the most recent submission when none is named.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A double-click on the public registration form fired two POSTs. Worst on
paid events, which opt out of Turbo (turbo: false) and so had no submitter
disabling at all. Each POST ran find_or_create_person independently, neither
saw the other's uncommitted person, so both created a Person (and thus a
second registration the registrant_id unique index couldn't catch) — two
people, two registrations, same minute.

Two layers of defense:
- Client: attach the existing submit-once Stimulus controller to the form so
  the button locks after the first click, on both the Turbo (free) and
  non-Turbo (paid) variants.
- Server: serialize concurrent submissions for the same identity behind a
  MySQL named lock (keyed on email + last name + event, namespaced by
  database so parallel test suites don't contend), so the second request
  waits and matches the first's committed person. Best-effort — a blank
  identity or an un-acquirable lock falls through rather than failing a real
  registration.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Announce that repeat registration submissions no longer create duplicate
people/registrations, framed around repeat submissions generally (not just a
double-click) since it also covers registering again later.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@maebeale
maebeale force-pushed the maebeale/dedupe-duplicate-registration branch from 1a344bd to 1fea235 Compare September 1, 2026 03:24
@maebeale

maebeale commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator Author

@jmilljr24 happy to have you submit something different

@jmilljr24 jmilljr24 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The lock seemed excessive (same point I made when this double submit came up on a different form). The main issue was handle the turbo-false since it disables turbo handling the double submit. This form needs the option to disable turbo for the stripe checkout so the submit-once controller is sufficient for client side. That will catch 99% of the issues. The deduper can handle the rest since is it needed anyway for true duplicate submission since the person matching is pretty loose.

@jmilljr24
jmilljr24 merged commit 06f84f2 into main Sep 1, 2026
3 checks passed
@jmilljr24
jmilljr24 deleted the maebeale/dedupe-duplicate-registration branch September 1, 2026 14:58
@maebeale maebeale changed the title JM: Stop a double-submit from creating duplicate registrations and people Stop a double-submit from creating duplicate registrations and people Sep 1, 2026
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