Skip to content

Add spreadsheet importer for event registrants - #2377

Draft
maebeale wants to merge 3 commits into
mainfrom
maebeale/registrant-xlsx-importer
Draft

Add spreadsheet importer for event registrants#2377
maebeale wants to merge 3 commits into
mainfrom
maebeale/registrant-xlsx-importer

Conversation

@maebeale

Copy link
Copy Markdown
Collaborator

🤖 suggested review level: 5 Inspect 🔬 substantive logic — new importer service creating people + registrations from an upload

What

Admin-only importer that bulk-adds attended registrants to an event from a spreadsheet.

  • New page event_registrations/import (link on the registrants index): pick an event, upload .xlsx/.csv/.xls, preview, confirm.
  • EventRegistrationImporter service: one attended registration per row.
    • People matched on lower(email) + lower(last_name) (PublicRegistration's rule) — created only on a miss, never duplicated.
    • Organizations matched by name and linked to the registration; never created — unrecognized names are flagged in the preview.
    • Existing non-attended registration is promoted to attended.
    • Within-file duplicate rows and rows missing name/email are skipped with a reason.
  • Preview interstitial = a dry_run that rolls back the transaction, mirroring the WordPress StoryImporter flow (file stashed as an ActiveStorage blob between preview and confirm).

Why

Staff have rosters of training attendees (e.g. the "2026 On-Demand Trainees" export) and need them in the portal as attended registrations without hand-entering each person or creating duplicates.

Notes

  • Adds the roo gem for spreadsheet parsing (no parser existed).
  • Gated by EventRegistrationPolicy#import? (admins only).

maebeale and others added 3 commits August 25, 2026 11:17
Admins pick an event and upload an .xlsx/.csv roster; every row becomes an
attended registration, matching existing people by email + last name so no
duplicates are created. Organizations are matched by name and linked (never
created). Preview interstitial (dry-run) before any writes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Scope the create-action rescue to file parsing so a non-admin still hits
the policy redirect. Add service + request specs, a CSV fixture, the
features.yml catalog entry, AGENTS.md service note, and page_bg_class mapping.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Keeps the importer service a plain-text file (git was treating it as
binary), no behavior change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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