25-Mar-2026 — navbar access levels, external committee file URLs, and unreferenced page fix #197
Navbar access-level visibility control
- Navbar items now support an
accessLevel field (public, loggedInMember, committee, hidden)
- Items are filtered from the navbar based on the current user's permissions
PageAccessGuard on dynamic routes prevents direct navigation to restricted pages
- When a user logs out while on a restricted page, they are redirected to the home page
- Access level column added to Pages Within Navbar table in System Settings
- Migration backfills all existing navbar items with
accessLevel: "public"
- Environment seed data includes access levels (Admin defaults to
committee)
System config refresh on login/logout
SystemConfigService now refreshes configuration on MEMBER_LOGIN_COMPLETE and
MEMBER_LOGOUT_COMPLETE events so permission-gated data (e.g. Brevo email details)
is reloaded when auth state changes
External URL support for committee files
CommitteeDisplayService.fileUrl() detects remote URLs via isRemoteUrl() and
returns them unchanged
- Committee file entries can reference external PDFs that have yet to be migrated to
internal S3 storage
committeeFileSlug() generates a kebab-case slug from file title and event date
Committee file notification improvements
- Send notification URL now uses slug-based query params instead of MongoDB IDs
(e.g.
?committee-file=agenda-december-12-2024&source-page=council/meetings/2024-12-12)
- Email "view on our site" link now uses the source page path with an absolute URL
PageService.titleFromPath() converts paths to human-readable titles (with unit tests)
- Source page title derived from path and passed through to email template
- FA icons added to Edit, Send Email, Delete, Confirm Delete, Cancel, and Back buttons
- Null guard on
toMemberFilterSelection when mailing list is not yet loaded
Unreferenced page detection fix
- Pages referenced by an album-index inside a shared fragment were incorrectly shown
as unreferenced
collectNestedAlbumIndexes now resolves shared fragment references and checks them
for album-index rows