Skip to content

v1.13.6 - #68

Merged
pataniaeli merged 7 commits into
mainfrom
dev
Aug 30, 2026
Merged

v1.13.6#68
pataniaeli merged 7 commits into
mainfrom
dev

Conversation

@pataniaeli

Copy link
Copy Markdown
Collaborator

No description provided.

pataniaeli and others added 7 commits August 30, 2026 17:45
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>
…tles

Title pending actions and booking rows by purpose (#63, #65)
Split Administrator into Bookings and a gated Management page (#64)
@pataniaeli pataniaeli self-assigned this Aug 30, 2026
@vercel

vercel Bot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
chambers Ready Ready Preview Aug 30, 2026 10:37pm

@pataniaeli pataniaeli added bug Something isn't working enhancement New feature or request labels Aug 30, 2026
@pataniaeli
pataniaeli merged commit f26f678 into main Aug 30, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

List bookings prioritize purpose Split the administrator tab PA summary should point to event title

1 participant