Skip to content

Give the registration policy editor real bucket ids (phase 1 of dropping RegistrationPolicyBucket#key) #11895

Description

@nbudin

Background

#11870 (merged in #11891) and #11892 (merged in #11893) removed RegistrationPolicyBucket#key as the identity mechanism used internally by signup simulation, occupancy checks, and editing correlation. What's left is external: the browser-based registration policy editor (RegistrationPolicyEditor/RegistrationBucketRow, rendered via RegistrationPolicyItemInput on the event edit form) never sends bucket id at all, for either existing or new buckets.

This isn't just an internal-cleanup gap -- it's the one remaining reason RegistrationPolicyBucket#key still needs to be a real, persisted, unique database column:

  • RegistrationPolicy#sync_buckets_from_hash! already prefers matching an incoming bucket hash by id, falling back to key only when no id is supplied (app/models/registration_policy.rb). Every edit made through the current UI takes that fallback path, because the UI never supplies an id.
  • RegistrationPolicy#build_from_hash and IGNORED_BUCKET_HASH_KEYS already keep a bucket's id if the incoming hash has one -- this was built for exactly this purpose in Correlate registration policy buckets by id instead of key when editing/simulating policy changes #11870, but nothing has fed it real data yet.
  • The reason the browser never sees a bucket's id in the first place: RegistrationPolicyBucket#as_json (used to populate form_response_attrs_json, the only way the edit form receives registration policy data) deliberately omits id, and the frontend's EditingRegistrationBucket type (app/javascript/RegistrationPolicy/RegistrationBucketRow.tsx) explicitly excludes id from its editing state.

Separately, RegistrationPolicyBucketType#key (the bucket's own read-only GraphQL field, app/graphql/types/registration_policy_bucket_type.rb) is queried and used as a business-logic lookup key (not just displayed) in several other frontend query paths, unrelated to the editor:

  • app/javascript/EventsApp/ScheduleGrid/queries.graphql -> AvailabilityUtils.tsx
  • app/javascript/EventsApp/EventPage/queries.graphql -> buildSignupOptions.ts, EventPageRunCard.tsx, CreateModeratedSignupModal.tsx, RunCapacityGraphBucket.tsx, EventCapacityDisplay.tsx, RunCapacityGraph.tsx
  • app/javascript/EventsApp/MySignupQueue/queries.graphql -> UserSignupQueueItem.tsx
  • app/javascript/EventsApp/SignupAdmin/queries.graphql -> SignupUtils.ts (findBucket), BucketInput.tsx, route.tsx, RunSignupsTable.tsx, RunEmailList.tsx
  • app/javascript/SignupModeration/queries.graphql -> CreateSignupRunCard.tsx, SignupModerationQueue.tsx
  • app/javascript/EventAdmin/queries.graphql -> BucketKeyRemappingModal.tsx, useBucketKeyRemapping.tsx
  • app/javascript/Reports/queries.graphql -> Tables/BucketChangeCell.tsx (via SignupUtils.ts)

Almost all of these are find/lookup/Object.fromEntries/React key= prop usages, directly convertible to bucket.id. A few (RunSignupsTable.tsx, RunEmailList.tsx, BucketKeyRemappingModal.tsx) fall back to bucket.name ?? bucket.key for display text -- since name is a NOT NULL database column, that fallback branch is already dead code and can just become bucket.name.

Proposed Change

  1. RegistrationPolicyBucket#as_json (app/models/registration_policy_bucket.rb): add "id" => id to the hash. This also changes the shape of future FormResponseChange audit records (additive only -- existing readers that only look at key/name/etc. are unaffected).
  2. RegistrationPolicyEditor.tsx/RegistrationBucketRow.tsx/app/javascript/RegistrationPolicy/RegistrationPolicy.ts: extend EditingRegistrationBucket (and the add/update/remove helpers) to carry an optional id -- undefined for a bucket added in the current edit session, the real id for anything loaded from the server. Thread it through into the hash sent back as form_response_attrs_json.
  3. Convert the business-logic lookups in the file list above from bucket.key to bucket.id. Fix the bucket.name ?? bucket.key display fallbacks to just bucket.name.

Benefits

Tradeoffs

  • Changes the shape of future FormResponseChange audit JSON (adds an id key) -- additive, but worth calling out since a prior comment on RegistrationPolicy#as_json was explicit about protecting that shape.
  • This is a real frontend state-management change (not just a mechanical rename) across several components; should be reviewed carefully for regressions in the registration policy editor, bucket key remapping modal, and signup admin bucket pickers.

References


Issue drafted by Claude

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions