Summary
Improves perceived and actual loading velocity of the admin dashboard. Navigation between pages
was re‑rendering and re‑fetching on every click, several routes blocked on the previous page
during loads, two pages flashed two different skeletons, and token validation hit Postgres on
every authenticated request. This branch addresses all four.
No behavioral/API changes — these are rendering, caching, and loading‑UX improvements.
Motivation
- "Page reloads every time you navigate" — the client Router Cache wasn't retaining dynamic RSC
payloads, so back/forward and re‑visits paid a full server round‑trip each time.
- Slow / janky loading — many routes had no loading boundary (previous page froze during the
fetch), and the team‑detail snapshot ran avoidable serial DB round‑trips.
- Inconsistent skeletons — /settings/sso and /my-connections showed a route‑level skeleton
followed by a different client‑side skeleton.
- Auth hot path — validateAdminAccessToken resolved tenant FusionAuth application IDs from
Postgres on every request.
Changes
- Navigation caching (React Query + Router Cache)
- next.config.ts: enable experimental.staleTimes (dynamic: 60, static: 300) so the client Router
Cache reuses dynamic RSC payloads across navigations — instant back/forward and re‑visits within
the window.
- components/trpc-provider.tsx: raise React Query default staleTime 30s → 60s so re‑navigating a
recently‑viewed page serves from cache.
- next.config.ts: add @tanstack/react-query|react-table|react-virtual to optimizePackageImports
(smaller first‑load JS on table‑heavy routes).
- app/layout.tsx: kept export const dynamic = "force-dynamic" but documented why (every route is
already request‑dynamic via cookie‑based auth; explicit as defense‑in‑depth so a per‑user shell
is never statically prerendered).
- Loading UX / skeletons
- Added loading.tsx to data‑heavy routes that previously froze the prior page during navigation:
settings/auth-config, settings/policies (+ [id], new), settings/siem, settings/sso,
teams/[slug]/shared-connections.
- Fixed the double‑skeleton on /settings/sso, /settings/siem, and /my-connections: each page now
shows a single skeleton, shared between its route loading.tsx and its client component (new
SsoSettingsSkeleton, SiemSettingsSkeleton; /my-connections reuses ConnectionsPageSkeleton).
Removed the now‑redundant inline loaders in the connections table.
- Server‑side data fetching
- server/team-detail-snapshot.ts: parallelized the serial tail (active‑connection counts now run
alongside the user‑mapping lookup instead of after the FusionAuth email resolution), removing a
round‑trip from team‑detail page loads.
- Auth hot‑path caching
- New server/ttl-cache.ts — a minimal, lazily‑evicting in‑process TTL cache (with
ttl-cache.test.ts).
- auth-broker-validation.ts: cache resolved tenant → FusionAuth application IDs (5‑min TTL), so
token validation no longer queries Postgres on every authenticated request.
- fusionauth-tenant-key.ts: refactored onto the shared createTtlCache util.
- routers/organizations/update-current-org.ts: strip fusionauth from generic org‑settings updates
— these login application IDs are provisioning‑time and must stay immutable at runtime (this
guarantees the cache above can never serve a value an org‑admin rewrote, and prevents an admin
from corrupting their own login apps).
- Developer guidance (.claude/)
- Added App‑Router performance rules (server-cache-react, server-parallel-fetching,
server-dedup-props, server-hoist-static-io, server-no-shared-module-state, server-serialization,
…) plus supporting skills (Cache Components, frontend‑design, web‑design‑guidelines).
Documentation only — no runtime impact.
Performance impact (expected)
- Back/forward and re‑navigation within 60s: no server RSC round‑trip (served from Router Cache)
vs. a full re‑render before.
- One fewer Postgres query per authenticated request (tenant app‑ID lookup now cached).
- One fewer DB round‑trip on team‑detail pages.
- Instant loading feedback on the previously‑blocking routes; a single consistent skeleton on
SSO/SIEM/My‑Connections.
Testing
- bunx turbo check-types ✅ and bunx turbo lint ✅ (all packages)
- Unit tests pass: ttl-cache.test.ts, auth-broker-validation.test.ts,
team-detail-snapshot.test.ts, settings/sso/_components.test.tsx
- App boots and serves correctly (verified locally on :3002)
Risk / rollback
- Low risk; no schema or API changes. staleTimes/staleTime trade up to 60s of freshness for speed
— mutations already invalidate their own queries.
- TTL caches are per‑process and only hold provisioning‑time values (safe to serve briefly
stale); update-current-org enforces their immutability.
- Each change is independently revertable (config, skeletons, caching are separate commits).
@arthurterozendi-plank2d ago
@arthurterozendi-plank2d ago
@arthurterozendi-plank2d ago
@chatgpt-codex-connector[bot]agent1d ago
Codex Review: Didn't find any major issues. Bravo.
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
@arthurterozendi-plank1d ago
@arthurterozendi-plank1d ago