Register

The register app is the registration engine — the largest and most central tenant app. It covers the full registration lifecycle: building the form, collecting a submission, taking payment, assigning a badge, and checking the attendee in at the door.

What it does

  • Form builderRegistrationForm.fields stores a JSON schema of field definitions that the Angular form-factory renders (see the custom form system). The same engine powers vendor/schedule/shop forms.

  • Levels & merchandiseRegistrationLevel (a ticket tier, linked to a Stripe price) and RegistrationItem (purchasable/add-on merchandise, with configurable options like shirt size). A level can include a set of merch.

  • SubmissionsRegistration stores the filled form as a data JSONField, plus payment state (is_paid, stripe_checkout_id), a QR code, and check-in state.

  • Check-in — multiple paths: standard register-checkin (form viewer, flags, QR), register-rapid-checkin terminals (POS-style with audio feedback), and a configurable check-in procedure authored via EventProperty register.checkin_procedure.

  • Badge numbers — event-level EventBadgeSettings (automatic vs. manual assignment), global + tier-specific number sequences, blackout numbers, and a full BadgeNumberAuditLog.

  • Merchandise operationsregister-merch-pick / register-merch-summary for at-show merch distribution, and an admin Merchandise Adjustment tool that mutates the Registration.data snapshot under transaction.atomic() + select_for_update() with a RegistrationMerchAdjustmentLog audit row.

  • Metrics & reportingregister-metrics2 (live + year-over-year charts), a reports center, and a superadmin Stripe-transactions view.

  • Staff ↔ management ping — a discreet messaging channel from check-in staff to management (StaffManagementMessage).

  • Audit trailRegistrationEditLog captures edits/forwards; merch and tier-upgrade have their own audit logs.

The registration flow (critical path)

form selection → fill (data JSON) → tier/merch selection → Stripe checkout
   → Registration created + confirmation QR
   → check-in (rapid or manual)
   → badge number assignment (auto/manual, blackout + sequences)
   → merch pick

Why “mutate the snapshot” matters

Tier-included merchandise is snapshotted into Registration.data at registration time. Editing a RegistrationLevel.included_merch afterward does not retroactively change existing registrations. That’s why there’s an admin Merchandise Adjustment tool — it’s the safe, audited way to correct a registration’s merch after the fact. This snapshot principle recurs across the app and is explained in Audit logging & the snapshot pattern.

Key models (subset)

Event
  └─ RegistrationForm (fields: JSONField schema)
        └─ Registration (data: JSONField, is_paid, qr_code, checkin_time, …)
              └─ → RegistrationLevel (Stripe price, included_merch)
              └─ → RegistrationItem (merchandise, options)
  └─ EventBadgeSettings / BadgeNumberSequence / BadgeNumberAuditLog
  └─ RegistrationMerchAdjustmentLog / RegistrationTierUpgradeAuditLog
  └─ RegistrationEditLog
  └─ StaffManagementMessage
  └─ RapidCheckinTerminal / CheckinKiosk

Where to look

  • Models: register/models.py

  • Views (REST + page routes): register/views.py

  • URLs (mounted under /app/register/): register/urls.py

  • WebSockets: register/consumers.py, register/routing.py

  • Frontend: ui/src/app/apps/register/

  • Merch summary reference logic: register/management/commands/register__merch_summary.py

  • Deep-dive data model + API: see Reference.