Remove duplicate app route preload path

This commit is contained in:
rcourtman 2026-04-29 18:11:36 +01:00
parent 0c8628c23e
commit b76664fb4f
6 changed files with 72 additions and 48 deletions

View file

@ -114,8 +114,9 @@ cloud-specific enforcement rules.
## Shared Boundaries
1. `frontend-modern/src/components/Settings/MonitoredSystemAdmissionPreview.tsx` shared with `agent-lifecycle`: the monitored-system admission preview is both a platform-connections lifecycle surface and a canonical cloud-paid monitored-system presentation boundary.
2. `internal/api/licensing_bridge.go` shared with `api-contracts`: commercial licensing bridge handlers carry both API payload contract and cloud-paid entitlement boundary ownership.
3. `internal/api/licensing_handlers.go` shared with `api-contracts`: commercial licensing handlers carry both API payload contract and cloud-paid entitlement boundary ownership.
2. `frontend-modern/src/useAppRuntimeState.ts` shared with `performance-and-scalability`: the authenticated app runtime bootstrap is both a hosted commercial org-context boundary and a protected app-shell performance boundary.
3. `internal/api/licensing_bridge.go` shared with `api-contracts`: commercial licensing bridge handlers carry both API payload contract and cloud-paid entitlement boundary ownership.
4. `internal/api/licensing_handlers.go` shared with `api-contracts`: commercial licensing handlers carry both API payload contract and cloud-paid entitlement boundary ownership.
That same shared licensing boundary also owns installation-version
continuity for authenticated v6 installs: `internal/api/router.go` and
`internal/api/licensing_handlers.go` must hand the canonical process
@ -123,8 +124,8 @@ cloud-specific enforcement rules.
and cloud-paid transport must send that value on activate, legacy exchange,
and grant refresh instead of inferring install version from browser state,
dev build metadata, or anonymous telemetry.
4. `internal/api/payments_webhook_handlers.go` shared with `api-contracts`: commercial payment webhook handlers carry both API payload contract and cloud-paid billing boundary ownership.
5. `internal/api/public_signup_handlers.go` shared with `api-contracts`: hosted signup handlers carry both API payload contract and cloud-paid hosted provisioning boundary ownership.
5. `internal/api/payments_webhook_handlers.go` shared with `api-contracts`: commercial payment webhook handlers carry both API payload contract and cloud-paid billing boundary ownership.
6. `internal/api/public_signup_handlers.go` shared with `api-contracts`: hosted signup handlers carry both API payload contract and cloud-paid hosted provisioning boundary ownership.
That shared monitored-system presentation boundary also owns disabled
provider-connection copy. Commercial entitlement surfaces must treat canonical
zero-delta and removal-only TrueNAS or VMware previews as non-consuming or

View file

@ -145,15 +145,16 @@ work extends shared components instead of creating new local variants.
119. `frontend-modern/src/stores/sessionPresentationPolicy.ts`
120. `frontend-modern/src/stores/licenseCommercial.ts`
121. `frontend-modern/src/useAppRuntimeState.ts`
122. `frontend-modern/src/stores/aiChat.ts`
123. `frontend-modern/scripts/header-audit.mjs`
124. `frontend-modern/src/components/Settings/DataHandlingPanel.tsx`
125. `frontend-modern/src/components/Settings/dataHandlingPanelModel.ts`
126. `frontend-modern/scripts/canonical-platform-audit.mjs`
127. `frontend-modern/src/utils/platformSupportManifest.generated.ts`
128. `frontend-modern/src/utils/platformSupportManifest.ts`
129. `frontend-modern/src/utils/sourcePlatformOptions.ts`
130. `frontend-modern/src/utils/sourcePlatforms.ts`
122. `frontend-modern/src/routing/routePreload.ts`
123. `frontend-modern/src/stores/aiChat.ts`
124. `frontend-modern/scripts/header-audit.mjs`
125. `frontend-modern/src/components/Settings/DataHandlingPanel.tsx`
126. `frontend-modern/src/components/Settings/dataHandlingPanelModel.ts`
127. `frontend-modern/scripts/canonical-platform-audit.mjs`
128. `frontend-modern/src/utils/platformSupportManifest.generated.ts`
129. `frontend-modern/src/utils/platformSupportManifest.ts`
130. `frontend-modern/src/utils/sourcePlatformOptions.ts`
131. `frontend-modern/src/utils/sourcePlatforms.ts`
## Shared Boundaries
@ -162,9 +163,10 @@ work extends shared components instead of creating new local variants.
3. `frontend-modern/src/components/Settings/GeneralSettingsPanel.tsx` shared with `security-privacy`: the general settings privacy panel is both a security/privacy control surface and a canonical settings-shell presentation boundary.
4. `frontend-modern/src/components/Settings/SecurityAuthPanel.tsx` shared with `security-privacy`: the authentication settings surface is both a security/privacy control surface and a canonical settings-shell presentation boundary.
5. `frontend-modern/src/components/Settings/SecurityOverviewPanel.tsx` shared with `security-privacy`: the security overview settings surface is both a security/privacy control surface and a canonical settings-shell presentation boundary.
6. `frontend-modern/src/stores/aiChat.ts` shared with `ai-runtime`: the assistant drawer and session store is both an AI runtime control surface and a canonical app-shell presentation boundary.
7. `frontend-modern/src/utils/platformSupportManifest.generated.ts` shared with `unified-resources`: the generated platform support projection is both a canonical unified-resource platform union boundary and a shared frontend source/platform vocabulary boundary.
8. `frontend-modern/src/utils/sourcePlatforms.ts` shared with `unified-resources`: the source platform normalizer is both a canonical unified-resource source adapter boundary and a shared frontend source/platform vocabulary boundary.
6. `frontend-modern/src/routing/routePreload.ts` shared with `performance-and-scalability`: the app-shell route preload registry is both a canonical frontend shell boundary and an authenticated hot-path performance boundary.
7. `frontend-modern/src/stores/aiChat.ts` shared with `ai-runtime`: the assistant drawer and session store is both an AI runtime control surface and a canonical app-shell presentation boundary.
8. `frontend-modern/src/utils/platformSupportManifest.generated.ts` shared with `unified-resources`: the generated platform support projection is both a canonical unified-resource platform union boundary and a shared frontend source/platform vocabulary boundary.
9. `frontend-modern/src/utils/sourcePlatforms.ts` shared with `unified-resources`: the source platform normalizer is both a canonical unified-resource source adapter boundary and a shared frontend source/platform vocabulary boundary.
## Extension Points

View file

@ -120,6 +120,8 @@ regression protection.
98. `frontend-modern/src/components/Infrastructure/useInfrastructureSummaryState.ts`
99. `frontend-modern/src/components/Infrastructure/infrastructureSummaryModel.ts`
100. `frontend-modern/src/utils/workloadsSummaryCache.ts`
101. `frontend-modern/src/routing/routePreload.ts`
102. `frontend-modern/src/useAppRuntimeState.ts`
103. `frontend-modern/src/components/Storage/StorageSummary.tsx`
104. `frontend-modern/src/utils/storageSummaryCache.ts`
105. `frontend-modern/src/pages/Workloads.tsx`
@ -140,7 +142,9 @@ regression protection.
12. `frontend-modern/src/components/Infrastructure/useInfrastructureSummaryState.ts` shared with `unified-resources`: infrastructure summary chart polling, cache hydration, and summary-state orchestration are both a canonical unified-resource consumer surface and a fleet-scale summary chart hot-path boundary.
13. `frontend-modern/src/components/Infrastructure/useUnifiedResourceTableState.ts` shared with `unified-resources`: unified resource table state, grouping, and windowing are both a canonical unified-resource consumer surface and a fleet-scale performance hot-path boundary.
14. `frontend-modern/src/components/Infrastructure/useUnifiedResourceTableViewportSync.ts` shared with `unified-resources`: unified resource table viewport sync and selected-row reveal are both a canonical unified-resource consumer surface and a fleet-scale performance hot-path boundary.
15. `internal/api/slo.go` shared with `api-contracts`: the SLO endpoint is both an API contract surface and a protected performance hot-path boundary.
15. `frontend-modern/src/routing/routePreload.ts` shared with `frontend-primitives`: the app-shell route preload registry is both a canonical frontend shell boundary and an authenticated hot-path performance boundary.
16. `frontend-modern/src/useAppRuntimeState.ts` shared with `cloud-paid`: the authenticated app runtime bootstrap is both a hosted commercial org-context boundary and a protected app-shell performance boundary.
17. `internal/api/slo.go` shared with `api-contracts`: the SLO endpoint is both an API contract surface and a protected performance hot-path boundary.
## Extension Points
@ -329,8 +333,8 @@ dashboard-specific overview, trend, or summary transport.
the org list from the shared `organizations_changed` event, but that refresh
must stay event-driven and route-safe rather than expanding into a second
full app bootstrap, a pre-auth org probe, or a deleted dashboard-route prewarm
that duplicates the canonical summary fetch path.
into another summary-fetch or org-bootstrap hot path.
that duplicates the canonical summary fetch path or expands into another
summary-fetch or org-bootstrap hot path.
The same protected hot path also owns Patrol route compatibility: if
`frontend-modern/src/App.tsx` keeps `/ai` as a legacy alias while `/patrol`
is canonical, that alias must stay a thin redirect and must not mount a
@ -345,6 +349,12 @@ dashboard-specific overview, trend, or summary transport.
canonical Infrastructure landing path instead of leaving the freshly
authenticated shell on a not-found page that immediately pays another cold
bootstrap.
App-shell route module preloading belongs to
`frontend-modern/src/routing/routePreload.ts` and the delayed authenticated
preload call in `frontend-modern/src/App.tsx`. `frontend-modern/src/useAppRuntimeState.ts`
must not keep page-local dynamic imports or a second route-preload cache,
because the runtime bootstrap already owns state, chart cache warming, org
hydration, and health probing.
The same protected hot path now also owns proof harness steadiness.
Store-backed chart SLO and benchmark helpers in `pkg/metrics/store_slo_test.go`,
`internal/api/slo_bench_test.go`, and `internal/monitoring/monitor_metrics_slo_test.go`

View file

@ -361,6 +361,14 @@
"api-contracts"
]
},
{
"path": "frontend-modern/src/routing/routePreload.ts",
"rationale": "the app-shell route preload registry is both a canonical frontend shell boundary and an authenticated hot-path performance boundary",
"subsystems": [
"frontend-primitives",
"performance-and-scalability"
]
},
{
"path": "frontend-modern/src/stores/aiChat.ts",
"rationale": "the assistant drawer and session store is both an AI runtime control surface and a canonical app-shell presentation boundary",
@ -369,6 +377,14 @@
"frontend-primitives"
]
},
{
"path": "frontend-modern/src/useAppRuntimeState.ts",
"rationale": "the authenticated app runtime bootstrap is both a hosted commercial org-context boundary and a protected app-shell performance boundary",
"subsystems": [
"cloud-paid",
"performance-and-scalability"
]
},
{
"path": "frontend-modern/src/utils/agentInstallCommand.ts",
"rationale": "the shared frontend install-command helper is both an agent lifecycle control surface and a canonical API/install transport contract boundary",
@ -2992,6 +3008,7 @@
"frontend-modern/src/hooks/createNonSuspendingQuery.ts",
"frontend-modern/src/index.css",
"frontend-modern/src/pages/Operations.tsx",
"frontend-modern/src/routing/routePreload.ts",
"frontend-modern/src/stores/aiChat.ts",
"frontend-modern/src/utils/aiSettingsPresentation.ts",
"frontend-modern/src/utils/diagnosticsPresentation.ts",
@ -3176,6 +3193,7 @@
"frontend-modern/src/components/Settings/useReportingPanelState.ts",
"frontend-modern/src/components/Settings/useSystemLogsPanelState.ts",
"frontend-modern/src/pages/Operations.tsx",
"frontend-modern/src/routing/routePreload.ts",
"frontend-modern/src/utils/reportableResourceTypes.ts",
"frontend-modern/src/utils/reportingPresentation.ts",
"frontend-modern/src/utils/reportingResourceTypes.ts"
@ -3192,6 +3210,7 @@
"frontend-modern/src/pages/__tests__/Operations.helpers.test.ts",
"frontend-modern/src/pages/__tests__/Recovery.test.tsx",
"frontend-modern/src/pages/__tests__/Workloads.helpers.test.ts",
"frontend-modern/src/routing/__tests__/routePreload.test.ts",
"frontend-modern/src/utils/__tests__/frontendResourceTypeBoundaries.test.ts",
"frontend-modern/src/utils/__tests__/reportableResourceTypes.test.ts",
"frontend-modern/src/utils/__tests__/reportingPresentation.test.ts",
@ -4173,6 +4192,8 @@
"frontend-modern/src/components/Workloads/workloadTopology.ts",
"frontend-modern/src/components/Workloads/workloadUrlSyncModel.ts",
"frontend-modern/src/pages/Workloads.tsx",
"frontend-modern/src/routing/routePreload.ts",
"frontend-modern/src/useAppRuntimeState.ts",
"frontend-modern/src/utils/thresholdSliderPresentation.ts",
"frontend-modern/src/utils/throughputPresentation.ts",
"frontend-modern/src/utils/workloadsSummaryCache.ts",
@ -4231,6 +4252,22 @@
"pkg/metrics/store_slo_test.go"
]
},
{
"id": "app-shell-route-preload",
"label": "app-shell route preload proof",
"match_prefixes": [],
"match_files": [
"frontend-modern/src/routing/routePreload.ts",
"frontend-modern/src/useAppRuntimeState.ts"
],
"allow_same_subsystem_tests": false,
"test_prefixes": [],
"exact_files": [
"frontend-modern/src/__tests__/App.architecture.test.ts",
"frontend-modern/src/__tests__/useAppRuntimeState.test.ts",
"frontend-modern/src/routing/__tests__/routePreload.test.ts"
]
},
{
"id": "workloads-hot-path",
"label": "Workloads hot-path proof",

View file

@ -37,6 +37,9 @@ describe('App architecture', () => {
expect(routePreloadSource).toContain('RECOVERY_ROUTE_PATH,');
expect(routePreloadSource).toContain('PATROL_PATH,');
expect(appSource).toContain('await preloadRouteModule(route);');
expect(appRuntimeStateSource).not.toContain('preloadLazyRoutes');
expect(appRuntimeStateSource).not.toContain("import('@/pages/Alerts')");
expect(appRuntimeStateSource).not.toContain("import('@/components/Settings/Settings')");
expect(appSource).toContain('const timeoutId = window.setTimeout(() => {');
expect(appSource).toContain('void preloadAppShellRoutes();');
expect(appSource).toContain(

View file

@ -103,7 +103,6 @@ export const useAppRuntimeState = () => {
};
const alertsActivation = useAlertsActivation();
let hasPreloadedRoutes = false;
let hasFetchedVersionInfo = false;
let hasPrewarmedInfrastructureCharts = false;
let hasPrewarmedWorkloadsCharts = false;
@ -194,23 +193,6 @@ export const useAppRuntimeState = () => {
prewarmWorkloadsCharts();
};
const preloadLazyRoutes = () => {
if (hasPreloadedRoutes || typeof window === 'undefined') {
return;
}
hasPreloadedRoutes = true;
const loaders: Array<() => Promise<unknown>> = [
() => import('@/pages/Alerts'),
() => import('@/components/Settings/Settings'),
];
loaders.forEach((load) => {
void load().catch((error) => {
logger.warn('Preloading route module failed', error);
});
});
};
const fallbackState: State = {
connectedInfrastructure: [],
metrics: [],
@ -496,17 +478,6 @@ export const useAppRuntimeState = () => {
}
});
createEffect(() => {
if (!isLoading() && !needsAuth()) {
if (typeof window === 'undefined') {
return;
}
if (!hasPreloadedRoutes) {
window.setTimeout(preloadLazyRoutes, 0);
}
}
});
createEffect(() => {
if (
isLoading() ||