Give the registration policy editor real bucket ids - #11900
Conversation
RegistrationPolicyBucket#as_json now includes id, and the editor's EditingRegistrationBucket/BucketForRegistrationPolicyUtils types carry it through, so RegistrationPolicy#sync_buckets_from_hash! can correlate edited buckets by id instead of falling back to key. Also converts the handful of RegistrationPolicyBucket#key usages that were directly convertible to id with no backend/schema changes: React list keys, the SignupOption identity, one bucket-to-bucket comparison, the CreateMySignup/CreateSignupRequest/CreateSignupRankedChoice/ CreateUserSignup mutations (switching off the deprecated requested_bucket_key argument), and a few dead `name ?? key` display fallbacks. The much larger sweep of business logic that reads bucket_key/ requested_bucket_key off Signup/SignupRequest/SignupRankedChoice/ SignupChange/GroupedSignupCount is filed separately as #11899, since it touches nearly every signup-admin/signup-moderation/event-page screen and deserves its own review. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The name column is text NOT NULL at the database level, with no custom resolver or presence validation that could produce nil, so the existing null: true was stricter than reality. Tightening the schema here removes the now-unnecessary bucket.name ?? '' fallback this PR introduced in RunSignupsTable.tsx. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Pushed a follow-up commit in response to a review question about Comment written by Claude |
Now that RegistrationPolicyBucket#name is non-null in the schema, these ?? fallbacks (in buildSignupOptions.ts, RegistrationBucketRow.tsx, RegistrationPolicyUtils.ts, and RegistrationPolicyPreview.tsx) were dead code. Left the ones elsewhere that guard against a bucket lookup itself returning undefined (SignupUtils.ts, UserSignupQueueItem.tsx, RegistrationPolicyItemChangeDisplay.tsx) -- those are real, unrelated to name's old nullability. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Since RegistrationPolicyBucket#as_json now includes id, RegistrationPolicy.build_from_hash(source.as_json) -- used by create_event_proposal.rb and accept_event_proposal_service.rb to clone a policy into an unrelated record -- started carrying the source's real bucket ids into the clone. Persisting that clone then collided with the still-existing source rows on the registration_policy_buckets primary key. Added build_from_hash_as_clone, which strips bucket ids before delegating to build_from_hash, and switched both cloning call sites to it. build_from_hash itself keeps its original signature/behavior (no id stripping) since sync_buckets_from_hash! still needs it for the edit-in-place flow this PR is about; a keyword argument would have been simpler but breaks build_from_hash's many bare-hash-literal callers (Ruby can't parse a bare hash as one positional argument once the method also declares a keyword parameter). Also fixed two FormResponseChange tests whose expected new_value was built from a policy that's never itself persisted (so its buckets have no id), compared against the real persisted state (which now has real ids) -- switched to equivalent_to? (content, not identity) comparisons. Added a regression test for the accept-proposal cloning path mirroring the existing create-proposal one. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Fixed the Minitest CI failure. Root cause: since Fix: added Also fixed two now-fragile Full suite (1169 tests) and CI's Minitest job should now be green. Comment written by Claude |
Code Coverage Report: Only Changed Files listed
Minimum allowed coverage is |
Fixes #11895
Summary
RegistrationPolicyBucket#as_jsonnow includes"id", so the registration policy editor can round-trip a bucket's real id throughform_response_attrs_json.EditingRegistrationBucket/BucketForRegistrationPolicyUtilscarry an optionalid(absent for a bucket added in the current edit session) soRegistrationPolicy#sync_buckets_from_hash!can correlate edited buckets by id instead of falling back to key.RegistrationPolicyBucket#keybusiness-logic usages that were directly convertible toidwith no backend/schema changes:EventCapacityDisplay.tsx/RunCapacityGraph.tsxSignupOption's identity inbuildSignupOptions.tsSignupAdmin/$id/route.tsxCreateMySignup/CreateSignupRequest/CreateSignupRankedChoice/CreateUserSignupmutations, switching from the deprecatedrequested_bucket_keyargument torequested_bucket_idbucket.name ?? bucket.keydisplay fallbacks (nameisNOT NULL, so the fallback branch was unreachable)bin/rails graphql:updateto regenerate the frontend generated files after the.graphqlquery/mutation edits (no backend schema changes — verifiedschema.graphql/schema.jsonare unchanged).Scope note
Filed #11899 separately for a much larger, related sweep: nearly every
Signup/SignupRequest/SignupRankedChoice/SignupChange/GroupedSignupCountconsumer across signup-admin, signup-moderation, and the event page still reads the deprecatedbucket_key/requested_bucket_keyscalar fields instead of the already-availablebucket/requestedBucketrelations. That's a ~20-file migration in its own right and deserves its own review rather than being folded into this PR.Test plan
bin/rails test test/models/registration_policy_bucket_test.rb test/models/registration_policy_test.rbyarn run tsc --noEmityarn vitest run test/javascript(187 passed, 1 skipped)yarn eslinton all changed files (0 errors)🤖 Generated with Claude Code