Files
git.stella-ops.org/src/Web/StellaOps.Web/src/app/routes/administration.routes.ts
2026-03-08 02:16:20 +02:00

407 lines
12 KiB
TypeScript

/**
* Administration Domain Routes
* Sprint: SPRINT_20260218_007_FE_ui_v2_rewire_administration_foundation (A2-01 through A2-05)
*
* Canonical Administration IA v2 route tree.
* Sub-area ownership per docs/modules/ui/v2-rewire/source-of-truth.md:
* A0 Overview / shell
* A1 Identity & Access (IAM)
* A2 Tenant & Branding
* A3 Notifications
* A4 Usage & Limits
* A5 Policy Governance (Administration-owned; RC is a consumer)
* A6 Trust & Signing
* A7 System
*
* Legacy /settings/* paths continue to resolve via app.routes.ts V1 alias entries
* until SPRINT_20260218_016 cutover; this file owns the /administration/* canonical paths.
*/
import { inject } from '@angular/core';
import { Router, Routes } from '@angular/router';
function redirectToDecisioning(path: string) {
return ({
params,
queryParams,
fragment,
}: {
params: Record<string, string>;
queryParams: Record<string, string>;
fragment?: string | null;
}) => {
const router = inject(Router);
let targetPath = path;
for (const [name, value] of Object.entries(params ?? {})) {
targetPath = targetPath.replaceAll(`:${name}`, encodeURIComponent(value));
}
const target = router.parseUrl(targetPath);
target.queryParams = { ...queryParams };
target.fragment = fragment ?? null;
return target;
};
}
function redirectToEvidence(path: string) {
return ({
params,
queryParams,
fragment,
}: {
params: Record<string, string>;
queryParams: Record<string, string>;
fragment?: string | null;
}) => {
const router = inject(Router);
let targetPath = path;
for (const [name, value] of Object.entries(params ?? {})) {
targetPath = targetPath.replaceAll(`:${name}`, encodeURIComponent(value));
}
const target = router.parseUrl(targetPath);
target.queryParams = { ...queryParams };
target.fragment = fragment ?? null;
return target;
};
}
export const ADMINISTRATION_ROUTES: Routes = [
// A0 — Administration overview
{
path: '',
data: { breadcrumb: 'Administration' },
loadComponent: () =>
import('../features/administration/administration-overview.component').then(
(m) => m.AdministrationOverviewComponent
),
},
// A1 — Identity & Access (IAM)
{
path: 'identity-access',
title: 'Identity & Access',
data: { breadcrumb: 'Identity & Access' },
loadComponent: () =>
import('../features/settings/admin/admin-settings-page.component').then(
(m) => m.AdminSettingsPageComponent
),
},
{
path: 'identity-access/:page',
title: 'Identity & Access',
data: { breadcrumb: 'Identity & Access' },
loadComponent: () =>
import('../features/settings/admin/admin-settings-page.component').then(
(m) => m.AdminSettingsPageComponent
),
},
// Profile sub-path (formerly /console/profile)
{
path: 'profile',
title: 'Profile',
data: { breadcrumb: 'Profile' },
loadComponent: () =>
import('../features/console/console-profile.component').then(
(m) => m.ConsoleProfileComponent
),
},
// Admin sub-paths (formerly /admin/:page, /console/admin/:page)
{
path: 'admin',
title: 'Administration',
data: { breadcrumb: 'Administration' },
loadComponent: () =>
import('../features/settings/admin/admin-settings-page.component').then(
(m) => m.AdminSettingsPageComponent
),
},
{
path: 'admin/:page',
title: 'Administration',
data: { breadcrumb: 'Administration' },
loadComponent: () =>
import('../features/settings/admin/admin-settings-page.component').then(
(m) => m.AdminSettingsPageComponent
),
},
// A2 — Tenant & Branding
{
path: 'tenant-branding',
title: 'Tenant & Branding',
data: { breadcrumb: 'Tenant & Branding' },
loadComponent: () =>
import('../features/settings/branding/branding-settings-page.component').then(
(m) => m.BrandingSettingsPageComponent
),
},
// A3 — Notifications
{
path: 'notifications',
title: 'Notifications',
data: { breadcrumb: 'Notifications' },
loadChildren: () =>
import('../features/admin-notifications/admin-notifications.routes').then(
(m) => m.adminNotificationsRoutes
),
},
// A4 — Usage & Limits
{
path: 'usage',
title: 'Usage & Limits',
data: { breadcrumb: 'Usage & Limits' },
loadComponent: () =>
import('../features/settings/usage/usage-settings-page.component').then(
(m) => m.UsageSettingsPageComponent
),
},
// A5 — Policy Governance (Administration-owned)
{
path: 'policy-governance',
title: 'Policy Governance',
data: { breadcrumb: 'Policy Governance' },
redirectTo: redirectToDecisioning('/ops/policy/governance'),
pathMatch: 'full',
},
{
path: 'policy-governance/exceptions',
title: 'Exceptions',
data: { breadcrumb: 'Exceptions' },
redirectTo: redirectToDecisioning('/ops/policy/vex/exceptions'),
pathMatch: 'full',
},
{
path: 'policy-governance/exceptions/:id',
title: 'Exception Detail',
data: { breadcrumb: 'Exception Detail' },
redirectTo: redirectToDecisioning('/ops/policy/vex/exceptions/:id'),
pathMatch: 'full',
},
{
path: 'policy-governance/:page',
title: 'Policy Governance',
data: { breadcrumb: 'Policy Governance' },
redirectTo: redirectToDecisioning('/ops/policy/governance/:page'),
pathMatch: 'full',
},
{
path: 'policy-governance/:page/:child',
title: 'Policy Governance',
data: { breadcrumb: 'Policy Governance' },
redirectTo: redirectToDecisioning('/ops/policy/governance/:page/:child'),
pathMatch: 'full',
},
{
path: 'policy',
title: 'Policy Governance',
data: { breadcrumb: 'Policy Governance' },
redirectTo: redirectToDecisioning('/ops/policy/governance'),
pathMatch: 'full',
},
{
path: 'policy/packs',
title: 'Policy Packs',
data: { breadcrumb: 'Policy Packs' },
redirectTo: redirectToDecisioning('/ops/policy/packs'),
pathMatch: 'full',
},
{
path: 'policy/exceptions',
title: 'Exceptions',
data: { breadcrumb: 'Exceptions' },
redirectTo: redirectToDecisioning('/ops/policy/vex/exceptions'),
pathMatch: 'full',
},
{
path: 'policy/exceptions/:id',
title: 'Exception Detail',
data: { breadcrumb: 'Exception Detail' },
redirectTo: redirectToDecisioning('/ops/policy/vex/exceptions/:id'),
pathMatch: 'full',
},
{
path: 'policy/packs/:packId',
title: 'Policy Pack',
data: { breadcrumb: 'Policy Pack' },
redirectTo: redirectToDecisioning('/ops/policy/packs/:packId'),
pathMatch: 'full',
},
{
path: 'policy/packs/:packId/:page',
title: 'Policy Pack',
data: { breadcrumb: 'Policy Pack' },
redirectTo: redirectToDecisioning('/ops/policy/packs/:packId/:page'),
pathMatch: 'full',
},
{
path: 'policy/packs/:packId/explain/:runId',
title: 'Policy Explain',
data: { breadcrumb: 'Policy Explain' },
redirectTo: redirectToDecisioning('/ops/policy/packs/:packId/explain/:runId'),
pathMatch: 'full',
},
{
path: 'policy/governance',
title: 'Policy Governance',
data: { breadcrumb: 'Policy Governance' },
redirectTo: redirectToDecisioning('/ops/policy/governance'),
pathMatch: 'full',
},
{
path: 'policy/governance/:page',
title: 'Policy Governance',
data: { breadcrumb: 'Policy Governance' },
redirectTo: redirectToDecisioning('/ops/policy/governance/:page'),
pathMatch: 'full',
},
{
path: 'policy/governance/:page/:child',
title: 'Policy Governance',
data: { breadcrumb: 'Policy Governance' },
redirectTo: redirectToDecisioning('/ops/policy/governance/:page/:child'),
pathMatch: 'full',
},
// A6 — Trust & Signing
{
path: 'audit',
title: 'Unified Audit Log',
data: { breadcrumb: 'Unified Audit Log' },
redirectTo: redirectToEvidence('/evidence/audit-log'),
pathMatch: 'full',
},
{
path: 'audit/:page',
title: 'Unified Audit Log',
data: { breadcrumb: 'Unified Audit Log' },
redirectTo: redirectToEvidence('/evidence/audit-log/:page'),
pathMatch: 'full',
},
{
path: 'audit/:page/:child',
title: 'Unified Audit Log',
data: { breadcrumb: 'Unified Audit Log' },
redirectTo: redirectToEvidence('/evidence/audit-log/:page/:child'),
pathMatch: 'full',
},
{
path: 'trust-signing',
title: 'Trust & Signing',
data: { breadcrumb: 'Trust & Signing' },
loadChildren: () =>
import('../features/trust-admin/trust-admin.routes').then(
(m) => m.trustAdminRoutes
),
},
// Legacy trust sub-paths (formerly /admin/trust/*)
{
path: 'trust',
title: 'Trust & Signing',
data: { breadcrumb: 'Trust & Signing' },
loadComponent: () =>
import('../features/settings/trust/trust-settings-page.component').then(
(m) => m.TrustSettingsPageComponent
),
},
{
path: 'trust/:page',
title: 'Trust & Signing',
data: { breadcrumb: 'Trust & Signing' },
loadComponent: () =>
import('../features/settings/trust/trust-settings-page.component').then(
(m) => m.TrustSettingsPageComponent
),
},
{
path: 'trust/issuers',
title: 'Issuers',
data: { breadcrumb: 'Issuers' },
loadChildren: () =>
import('../features/issuer-trust/issuer-trust.routes').then(
(m) => m.issuerTrustRoutes
),
},
// Legacy alias: /administration/identity-providers → /settings/identity-providers
{
path: 'identity-providers',
redirectTo: '/settings/identity-providers',
pathMatch: 'full',
},
// A7 — System
{
path: 'system',
title: 'System',
data: { breadcrumb: 'System' },
loadComponent: () =>
import('../features/settings/system/system-settings-page.component').then(
(m) => m.SystemSettingsPageComponent
),
},
{
path: 'offline',
title: 'Offline Settings',
data: { breadcrumb: 'Offline Settings' },
loadComponent: () =>
import('../features/offline-kit/components/offline-dashboard.component').then(
(m) => m.OfflineDashboardComponent
),
},
// Configuration pane (formerly /console/configuration)
{
path: 'configuration-pane',
title: 'Configuration',
data: { breadcrumb: 'Configuration' },
loadChildren: () =>
import('../features/configuration-pane/configuration-pane.routes').then(
(m) => m.CONFIGURATION_PANE_ROUTES
),
},
// Security Data settings (A7 diagnostic sub-path)
{
path: 'security-data',
title: 'Security Data',
data: { breadcrumb: 'Security Data' },
loadComponent: () =>
import('../features/settings/security-data/security-data-settings-page.component').then(
(m) => m.SecurityDataSettingsPageComponent
),
},
{
path: 'security-data/trivy',
title: 'Trivy DB Settings',
data: { breadcrumb: 'Trivy DB' },
loadComponent: () =>
import('../features/trivy-db-settings/trivy-db-settings-page.component').then(
(m) => m.TrivyDbSettingsPageComponent
),
},
// Workflows (formerly /release-orchestrator/workflows)
{
path: 'workflows',
title: 'Workflows',
data: { breadcrumb: 'Workflows' },
loadChildren: () =>
import('../features/release-orchestrator/workflows/workflows.routes').then(
(m) => m.WORKFLOW_ROUTES
),
},
// AI Preferences
{
path: 'ai-preferences',
title: 'AI Preferences',
data: { breadcrumb: 'AI Preferences' },
loadComponent: () =>
import('../features/settings/ai-preferences-workbench.component').then(
(m) => m.AiPreferencesWorkbenchComponent
),
},
];