v1.13.6 - #68
Merged
Merged
Conversation
Pending Actions and the my-rooms booking lists both led with the governing body, which is the least distinguishing thing about a row: every booking a body owns reads identically, so the summary said nothing about what the outstanding task was actually for. Both now lead with the booking's purpose -- the title someone typed for this specific booking -- and fall back to the body name only when a record has no purpose (membership requests, which have no title, keep the body name outright). lib/pending-actions.ts selects `purpose` alongside the existing embeds, so no extra round trip. An occurrence-scoped cancellation prefers that occurrence's purpose override, matching how its reference date is already resolved (#55). In my-rooms the calendar day list shows the body beside the title as secondary text; the list view's rows sit under a body heading already, so the room name takes that side slot instead of repeating the group name on every row. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
) Administrator had outgrown one tab strip: five tabs, one of which opened a second strip of five underneath it. Those five inner tabs also have a different audience -- they configure the system rather than run the week's bookings. Advanced Settings' sub-tabs (Users, Bodies, Audit, Archive, Other Settings) are now the main tabs of a new root page, Management, reachable only by the four high-access roles: EVP, VP of Operational Affairs, Digital Innovation Manager and Information Manager. That is the set already allowed to grant and revoke admin roles, so everything else on the page is downstream of a power they hold anyway; the other admin roles keep everything else. Administrator is renamed Bookings, in the sidebar and on the page itself. Its URL stays /administrator so existing links keep working. Supporting changes: - lib/admin-roles.ts holds the role lists in one place. It has no imports, so the client components can share it with the API route; ROLE_EDITORS in app/api/administrator/users/route.ts and users-tab.tsx were the same four names written twice, and are now that constant. - ShellIdentity carries adminRole, already present in the row it reads, so ManagementGuard resolves synchronously like AdminGuard does. - The booking forms' "create a semester in Advanced Settings" hint now points at Management -> Other Settings. ManagementGuard governs what the dashboard renders. The endpoints behind these tabs still authorize as they did before -- role editing is restricted to these same four roles, the rest accept any admin -- so narrowing them is a separate change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…64) Two follow-ups to the split. The route matches the name now: /administrator is /bookings, and the sidebar, ManagementGuard's fallback and the four cross-directory imports of its time-picker and booking-modal all point at the new path. next.config.ts redirects the old URL so year-old bookmarks keep resolving -- 307 rather than 308, because a permanent redirect is cached by the browser indefinitely and there is nothing here worth making that hard to walk back. Membership requests no longer appear in Pending Actions for admins who cannot resolve them. They are worked on Management > Users, so an admin outside MANAGEMENT_ROLES was being shown a task with nowhere to go. fetchPendingActions takes the caller's admin_role and skips the query outright rather than fetching rows to discard; omitting the role reads as "not a management role", so a caller that forgets to pass it hides the actions rather than leaking them. Its `now` parameter moved into that same options object. Nothing passed it, and two positional arguments where the second is a clock would have read badly. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… admin ManagementGuard decides what the dashboard renders. The endpoints behind those tabs were still authorizing on `app_metadata.is_admin` alone, so a Comptroller or Digital Innovation Project Member could read the user list, the audit log and the archive, edit app settings and bodies, resolve membership requests, and invite users -- by calling the routes directly. The gate was a rendering decision. Each of those handlers now runs isManagementRole() against the live admin_role that getAuthedUserWithLiveRoles() resolves from the users row, and answers 403. Users (GET/POST/PATCH), user memberships, resend-invite, membership requests, audit logs, archive and settings are gated whole, because every caller of each is under /management. Bodies is the exception: only POST and PATCH are gated. GET stays open to any admin because the Bookings page reads it for its body picker, and that page is open to every admin by design. POST /api/administrator/users is a role-grant path, not just a read: it accepts an admin_role and writes it to both the users row and the auth metadata, so an ungated Comptroller could have invited themselves a second account as Executive Vice President. The membership-request routes are the pair 54f5b7a stopped surfacing in Pending Actions for admins outside MANAGEMENT_ROLES. That hid the task; this closes the endpoints it pointed at. With the route-wide check in place, the ROLE_EDITORS branch inside PATCH is unreachable, so it and the const come out. Role editing is unchanged; the is_active and full_name branches are now narrowed too, which matches the one place they are called from. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Split Administrator into Bookings and a gated Management page (#64)
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This was
linked to
issues
Aug 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.