# 01-Mar-2026 — admin: stale-while-revalidate area cache, skip migration check on password reset, and centralise admin paths [#146](https://github.com/nbarrett/ngx-ramblers/issues/146)

## [build 506](https://github.com/nbarrett/ngx-ramblers/actions/runs/22550256958) — [commit 089a5e8](https://github.com/nbarrett/ngx-ramblers/commit/089a5e86c2139fa71ea958468d8640457174ca1c)

_____

- Fix Fly.io shared IPv4 allocation using sharedIpAddress fallback for known GraphQL API bug
- Wire notification configs to built-in processes (forgot-password, walks, expenses, contact-us)
- Assign admin user to committee roles (membership, support) for email sender resolution
- Register admin as Brevo sender during environment creation
- Add admin password reset button to Modify Environment flow
- Allow password reset route to bypass maintenance mode guard
- Add seed endpoints for sample pages, notification configs, and Brevo templates
- Extract shared helpers: toGroupShortName, cleanIncorrectPageContent, runMigrations, registerBrevoSender
- Make notification config seeding idempotent with upsert pattern
- Fix arrow-parens lint violations across all server TypeScript files

## Platform admin gating
- Backup & Restore and Environment Setup now check `PLATFORM_ADMIN_ENABLED` on
init and display a consistent "Not Available" alert (icon + bold title) when
the flag is absent, matching the alert style used across the admin section
- Backup & Restore skips loading environments, backups, sessions and the
WebSocket connection when the flag is absent, avoiding unnecessary API calls
- Added the ngx-ramblers environment entry to the EnvironmentsConfig DB document
with `PLATFORM_ADMIN_ENABLED=true` in its secrets block so the flag survives
future deploys via `loadSecretsForEnvironmentFromDatabase`
## Setup API-key authentication
- Environment Setup routes now accept requests authenticated by either a valid
admin JWT (member/content/file/walk/social/treasury/finance admin roles) or
the `x-setup-api-key` header, enabling logged-in admins to use the page
without a separate setup key
- `isAdminRequest()` added to server routes — verifies the Bearer token with
`jsonwebtoken` and checks any admin-role claim before granting access
- `EnvironmentSetupService` gains a `setupApiKey` field and an `opts` getter;
all HTTP calls now forward the key in `x-setup-api-key` when present
- Component gains `requiresApiKey` / `setupApiKeyValue` / `setupApiKeyEntered`
state and a `submitSetupApiKey()` method so the UI can prompt for the key
when the server signals it is required (`status.requiresApiKey`)
## Defaults loading improvements
- `loadDefaults()` now loads system config first (normal session auth, never
401) and then loads environment defaults separately so a 401 on the defaults
endpoint does not prevent the Ramblers API key from being pre-filled
- `EnvironmentDefaults` model extended with `ramblers.apiKey` field
- `/defaults` endpoint populates `ramblers.apiKey` from
`national.walksManager.apiKey` in the system config so the Ramblers API key
is offered as a default without manual entry
## Mongoose reconnection fix
- `closeMigrationConnection()` calls `mongoose.disconnect()` after running
migrations, which left subsequent operations (`seedBrevoTemplatesFromLocal` ->
`configuredBrevo` -> `config.findOne`) failing with "Client must be connected
before running operations"
- Added `ensureMongoConnection()` after `initialiseDatabase()` returns so
mongoose reconnects to the main database before Brevo template population runs
## GitHub Secrets panel (Environment Settings → GitHub Secrets sub-tab)
- New `EnvironmentGitHubSecrets` standalone component shows the GitHub
`CONFIGS_JSON` secret staleness relative to the database, with per-environment
diff detail (new / removed / changed fields) and a one-click Push button
- `GET /api/environment-setup/github/status` compares DB environments against
the live `CONFIGS_JSON` value; matches by name first then appName fallback to
avoid cross-matching where multiple DB documents share the same fly.io app
- `POST /api/environment-setup/github/push` pushes DB → GitHub directly without
touching configs.json; after a successful push, `process.env.CONFIGS_JSON` is
updated in-process so subsequent status checks reflect what was pushed
- On first status check locally (no `CONFIGS_JSON` env var), the value is
initialised from the DB — same runtime behaviour as production where fly.io
injects it at startup — eliminating configs.json as a third piece of state
- `transformDatabaseToDeployConfig` now filters out orphan DB environment
documents (no flyio config), deduplicates by appName (first occurrence wins),
and is exported for reuse in the status route
- `EnvironmentSettingsSubTab.GITHUB` added; heading uses `with-vendor-logo`
style with the GitHub FA brand icon; `.thumbnail-heading.with-vendor-logo`
top offset corrected to -34px in frames.sass
## Dockerfile: GitHub CLI
- `gh` CLI installed in Docker image so the GitHub Secrets panel can fetch
secret metadata and push `CONFIGS_JSON` from the deployed environment
- `GH_TOKEN` and `PLATFORM_ADMIN_ENABLED=true` set as fly.io secrets on the
ngx-ramblers (staging) app to authenticate `gh` and enable the admin pages

### **admin**: stale-while-revalidate area cache, skip migration check on password reset, and centralise admin paths ([#146](https://github.com/nbarrett/ngx-ramblers/issues/146))

Area cache now always serves cached data immediately and refreshes
in the background when expired, preventing visible loading delays.
Replace banned Date.now() with dateTimeNowAsValue().
Skip migration status check when navigating to set-password URLs
so password resets work on newly provisioned environments with
pending migrations.
Centralise admin/set-password and admin/maintenance path strings
as shared constants in system.model.ts and update all TypeScript
references across frontend guards, services, and backend routes.