fix(locations): send venue/room ids when resyncing a room to the materializer - #1026
fix(locations): send venue/room ids when resyncing a room to the materializer#1026caseylocker wants to merge 1 commit into
Conversation
…rializer The Resync Room button sent venue and room NAMES. The materializer's per-room route stopped accepting names in dropbox-materializer PR #24 (merged 2026-06-15), which replaced sync/materialize/<int:summit_id>/<str:venue>/<str:room>/ with sync/materialize/<int:summit_id>/<int:venue_id>/<int:room_id>/ and shipped no name-based fallback. That PR's own commit message called for a coordinated change here; it was never made. Since the materializer deployed, every click has 404'd and shown a "Not Found" dialog instead of resyncing. LocationForm already receives the room id and was discarding it to look the room's name back up, so no new data is needed. It now passes this.props.entity.id (the persisted venue, so an unsaved rename in the form cannot become the target) and the room id straight through, guarding against a venue that has never been saved (id 0). The existing action tests only asserted that postRequest was called, never the URL, which is why they stayed green through the regression. Added a test pinning the built URL, and a LocationForm test that opens the Rooms panel, clicks the real resync action and asserts the ids reach onRoomResync. Both fail if the old behavior is restored. Full suite: 154 suites, 1410 tests, green. Co-Authored-By: Claude <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe room resync flow now uses integer venue and room IDs throughout ChangesRoom resync ID contract
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Fixes the “Resync Room” action on the Locations page by aligning summit-admin’s request shape with the materializer’s updated route contract (integer venue/room IDs instead of names), preventing production 404s after the materializer’s destination-path restructure.
Changes:
- Updated the resync call chain (LocationForm → EditLocationPage → Redux action) to pass
venueId/roomIdinstead ofvenueName/roomName. - Updated the materializer URL construction to use integer IDs (and removed
encodeURIComponentname interpolation). - Added tests to pin the exact resync URL and verify the UI callback receives the correct IDs.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/pages/locations/edit-location-page.js | Updates handleRoomResync to forward venue/room IDs to the thunk. |
| src/components/forms/location-form.js | Sends persisted venue ID + room ID when invoking onRoomResync (no name lookup). |
| src/components/forms/tests/location-form.test.js | Adds UI test asserting the resync action calls onRoomResync(venueId, roomId). |
| src/actions/dropbox-sync-actions.js | Changes resyncRoom thunk signature and URL to /materialize/{summitId}/{venueId}/{roomId}/. |
| src/actions/tests/dropbox-sync-actions.test.js | Adds assertion pinning the constructed resync URL to the integer-ID route. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
ref: https://app.clickup.com/t/86bb4r5df
What's broken
The Resync Room action on the Locations page has been 404ing in production since the materializer's destination-path restructure deployed.
We send the venue and room by name:
The materializer only accepts integers:
Django's
intconverter refuses a non-numeric segment, so the URL does not resolve. There is no name-based fallback. uicore'sauthErrorHandlerrenders a "Not Found" dialog on the 404, so the user sees an error and the resync never runs.How it happened
dropbox-materializer PR #24 (
5bb2d5e, merged 2026-06-15) replaced<str:venue>/<str:room>with<int:venue_id>/<int:room_id>. Its own commit message asked for this change:It was never made. This repo last touched that URL in PR #833, months before the contract changed. It stayed invisible because production ran pre-#24 materializer code until recently; the deployed container now has the ID-based build, so the mismatch is live.
The change
LocationFormwas already handed the room id and threw it away to look the room's name back up, so no new data is needed.location-form.js::handleRoomResyncnow passesthis.props.entity.idandroomId. Reading the venue id offprops(notstate) keeps an unsaved rename in the form from becoming the target, matching what the old code did withpersistedVenueName. Guarded so a never-saved venue (id: 0) does not fire.edit-location-page.js::handleRoomResyncanddropbox-sync-actions.js::resyncRoomrenamed tovenueId/roomId; the URL drops theencodeURIComponentname interpolation.Prettier reflowed the body of
resyncRoombecause the shortened signature now fits on one line. That islint-staged's own output, not a hand edit.No materializer change is needed. It has accepted and tested integer ids since #24:
MaterializeRoomViewbuildsroom_filter = "{venue_id}/{room_id}", which matchesbuild_schedule's keys.Tests
The existing action tests only asserted that
postRequestwas called, never the URL — which is exactly why they stayed green through this regression. Added:.../sync/materialize/1/12/345/LocationFormtest that opens the Rooms panel, clicks the real resync action, and assertsonRoomResyncreceives the two idsBoth were mutation-tested: restoring the old name-based behavior fails them (
Expected: 781, 5002 / Received: "International Barcelona Convention Center", "Room A").The existing inline props in
location-form.test.jswere lifted into abuildProps()factory so both describes share them; the pre-existing test is otherwise untouched.Full suite: 154 suites, 1410 tests, green.
Worth a manual check
Nothing automated crosses the two repos, so a click-through on staging after merge would be worth it.
Summary by CodeRabbit
Bug Fixes
Tests
Convention pass
Run against
skills/react-frontend.md§§1–7 andpatterns/show-admin/summit-admin-testing-patterns.md, by grep rather than eyeball.Clean on §1 (no URL/query built in a component — this change moves toward it, deleting the name lookup from the form), §2 (no new
utils/files), §3/§4 (no reimplemented formatters, no hand-rolled date/money, no new strings), §5 magic numbers (the only literals areVENUE_ID/ROOM_IDnamed constants in a test), §6 (no.css), §7 (full suite, not just the focused files).Two notes for the reviewer, both deliberate:
The bare
returnguard inresyncRoomis not a §5 violation. §5 asks thunks to return a thenable on every branch, and the diff showsif (!baseUrl || !summitId) return;as an added line — but only because prettier reindented the body when the shortened signature collapsed onto one line. Every thunk in this file isasync, so a barereturnalready yields a resolved promise; the rule's concern (undefined returned synchronously while the happy path returns a Promise) does not arise. I confirmed this by mutation: changing it toPromise.resolve()and back leaves behavior and tests identical. Left as-is rather than adding a no-op.The new component test queries by
data-tip, not role/name. The testing playbook prefersgetByRole("button", { name }). uicore'sTablerenders custom row actions as<a href="" data-tip={tooltip}><i className="fa fa-refresh" /></a>— icon-only, no accessible name — so role/name is not reachable without adding anaria-labelto production markup purely for the test, which the same playbook rules out. The selector is commented in place.