feat(OUT-3702): fetch assignees via SWR in layout instead of SSR per page#1209
Conversation
Add a layout-level WorkspaceFetcher that uses SWR to populate authDetails.workspace from /api/workspace on the client. SSR pages ((home), detail, client, manage-templates, manage-templates/[id]) no longer block on copilot.getWorkspace() per request — they let the Redux store hydrate from the cached client fetch (60s deduping). Server-side route uses React cache() via getMemoizedWorkspace for per-request memoization. Workspace consumers (Sidebar, AppBridges, HeaderBreadcrumbs, TaskBoard) now read portalUrl from the store via selectAuthDetails instead of taking it as a prop. Add tsc script (tsc --noEmit) to package.json for type-only checks. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…s-app into workspace-fetch-optimization
…page Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThis PR replaces four per-page SSR
Confidence Score: 4/5Safe to merge with one regression: cold deep-links to manage-templates will show an empty assignee dropdown until the layout SWR resolves. The consolidation from four SSR fetchers to one layout-level SWR component is sound, but manage-templates lost its server-side assignee data without gaining the src/app/manage-templates/page.tsx — needs an Important Files Changed
Sequence DiagramsequenceDiagram
participant Browser
participant RootLayout
participant AssigneesFetcher
participant AssigneeCacheGetter
participant IndexedDB
participant Redux
participant API
Browser->>RootLayout: Navigate to any page
RootLayout->>AssigneesFetcher: mount (once per session)
RootLayout->>AssigneeCacheGetter: mount (home/client/detail only)
AssigneeCacheGetter->>IndexedDB: getAssignees(lookupKey)
IndexedDB-->>AssigneeCacheGetter: cached assignees
AssigneeCacheGetter->>Redux: setAssigneeList (pre-paint)
Note over AssigneesFetcher: tokenPayload arrives via Redux
AssigneesFetcher->>API: SWR /api/users or /api/users/client
API-->>AssigneesFetcher: users or clients
AssigneesFetcher->>Redux: setAssigneeList (fresh data)
AssigneesFetcher->>IndexedDB: setAssignees(lookupKey, combined)
Note over Browser: manage-templates cold deep-link
Browser->>RootLayout: Navigate to /manage-templates
Note over AssigneeCacheGetter: NOT mounted on manage-templates
AssigneesFetcher->>API: SWR /api/users
Note over Browser: Assignee dropdown empty until SWR resolves
|
Restore the AssigneeCacheSetter side-effect that was nested inside the deleted AssigneeFetcher. AssigneeCacheGetter still reads on cold load per page; without a Setter, IDB never refreshed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Deployment failed with the following error: Learn More: https://vercel.link/multiple-function-regions |
…it/out-3702-optimize-assignee-fetcher-to-be-once-per-session # Conflicts: # src/app/layout.tsx # src/app/manage-templates/page.tsx
fbdd3b3 to
9c2b703
Compare
- replace module-level hasFetched flag with Redux-state guard (assignee.length === 0) so HMR / store resets trigger refetch correctly - IDB write via setAssigneesIDB was already present
…s-app into anit/out-3702-optimize-assignee-fetcher-to-be-once-per-session
…s-app into anit/out-3702-optimize-assignee-fetcher-to-be-once-per-session
…s-app into anit/out-3702-optimize-assignee-fetcher-to-be-once-per-session
OUT-3702 — mirrors the workspace fetcher pattern, plus a scoped server-side cache for
getClients.Summary
AssigneesFetcher(client) mounted once in the root layout. Fires SWR against/api/usersor/api/users/clientbased ontokenPayload. Dispatches the existingsetAssigneeListaction — no new redux state.<AssigneeFetcher>from home, client, detail; removed inlinegetAssigneeListfrom manage-templates. Deleted the now-unusedAssigneeFetcher.tsx.AssigneeCacheGetter(still per-page) keeps pre-painting on cold load.Why
/api/usersfans out to 5 Copilot calls. It was firing on every navigation across 4 pages. After this: 1 fetch per session. The scopedgetClientscache eliminates the heaviest of the 5 fan-out calls for the allow-listed workspace.Test plan
/api/usersonce/clienthits/api/users/client/api/users2026-05-08.18-48-08.mov
2026-05-08.18-31-51.mov
🤖 Generated with Claude Code