Files
git.stella-ops.org/docs-archived/ui-analysis/rework/04-migration-map.md

30 KiB
Raw Blame History

Below is a migration map from your current route surface (~120+) to a canonical release-control-plane IA, plus a redirect/alias strategy designed to preserve existing deep links, keep bookmarks working, and avoid breaking external references (docs, emails, Slack links, ticket comments, etc.).

Im assuming the new canonical IA is:

  • Product flows (what customers do): / (Control Plane), /releases, /approvals, /environments, /deployments, /security/*, /evidence/*, /witness/*
  • Operations (running the platform): /operations/*
  • Settings (configuration + access control): /settings/*
  • Policy authoring (still first-class): /policy/* (instead of /policy-studio/*)

If you want to keep /ops/* and /console/* as canonical, you can—but then your route taxonomy stays inconsistent. The plan below keeps canonical clean without breaking anything, by keeping /ops/* and /console/* as legacy aliases indefinitely.


0) Canonical new route taxonomy (what were migrating to)

0.1 Control plane and release lifecycle

  • /Control Plane (pipeline, pending approvals, drift/risk deltas)
  • /releases → Releases list
  • /releases/:releaseId → Release detail (gates, diff, evidence, proof chain)
  • /approvals → Approvals inbox
  • /approvals/:approvalId → Approval detail (diff-first + decision + evidence)
  • /environments → Environments
  • /environments/:envId → Environment detail
  • /deployments → Deployments list
  • /deployments/:deployId → Deployment detail (workflow DAG + artifacts + evidence)

0.2 Security (scanner heritage becomes “gate inputs”)

  • /security/overview → Security overview dashboard (old Home dashboard preserved here)
  • /security/findings → Findings (impact-to-release, reachability chips)
  • /security/scans/:scanId → Scan run detail
  • /security/vulnerabilities → CVE explorer
  • /security/vulnerabilities/:cveId → CVE detail
  • /security/sbom/graph → SBOM graph explorer
  • /security/lineage → Lineage/compare (global)
  • /security/reachability → Reachability center
  • /security/vex → VEX hub (no longer under /admin)
  • /security/unknowns → Unknowns tracking
  • /security/patch-map → Patch map

0.3 Evidence and verification

  • /evidence → Evidence center (packets, bundles, export, replay, provenance)
  • /evidence/:evidenceId → Evidence packet viewer
  • /evidence/packs and /evidence/packs/:packId → Evidence packs
  • /evidence/proofs/:subjectDigest → Proof chain viewer
  • /witness/:witnessId → Witness viewer (reachability slice + replay/verify)

0.4 Policy (rename, but keep semantics)

  • /policy/packs (list)
  • /policy/packs/:packId/editor
  • /policy/packs/:packId/yaml
  • /policy/packs/:packId/simulate
  • /policy/packs/:packId/approvals
  • /policy/packs/:packId/rules
  • /policy/packs/:packId/explain/:runId
  • /policy/packs/:packId/dashboard
  • /policy/exceptions (exception queue + approvals)

0.5 Operations

  • /operations/orchestrator (+ jobs, quotas)
  • /operations/quotas/*
  • /operations/dead-letter/*
  • /operations/slo/*
  • /operations/health/*
  • /operations/feeds/*
  • /operations/offline-kit/*
  • /operations/aoc/*
  • /operations/scheduler/*
  • /operations/doctor

0.6 Settings

  • /settings/profile
  • /settings/integrations/* (hub + detail + activity)
  • /settings/admin/* (tenants/users/roles/clients/tokens/branding)
  • /settings/trust/* (keys/issuers/certs/score-config/audit)
  • /settings/registries (registry token service)
  • /settings/notifications/*
  • /settings/policy/governance
  • /settings/sbom-sources
  • /settings/trivy-db (or fold into feeds)

1) Migration principles (minimize breaking links)

Principle A — Keep old links working forever: Every old route either:

  • Redirects to the new canonical route, or
  • Remains as an alias that renders the same page/module.

Principle B — Preserve identifiers and semantics: If :scanId, :packId, :subjectDigest exist today, do not change their format. New routes simply “re-home” them.

Principle C — Use redirects only when mapping is 1:1: If old route needs query params (e.g., “filter type=audit”), use a guard-based redirect returning a UrlTree (so you can append query parameters safely).

Principle D — Track legacy usage: Add telemetry: whenever a legacy route is hit, record { oldPath, newPath }. This lets you quantify remaining legacy usage.


2) Old → new route migration map

Each entry includes: Old route → New canonical route + strategy.

Legend:

  • KEEP = route stays as-is (canonical already good)
  • REDIRECT = Angular router redirect (1:1 mapping)
  • SMART REDIRECT = redirect via guard/matcher to add query params/open specific view
  • ALIAS = old route still loads same module/component as new (no visible URL change)

2.1 Home & dashboard routes

Old Route New Route Strategy Notes
/ / KEEP (content changes) Home becomes Control Plane. Preserve old “security dashboard” as /security/overview.
/welcome /welcome KEEP Usually public. Keep stable.
/dashboard/sources /operations/feeds REDIRECT Old “sources dashboard” becomes operational view of feeds/mirrors.

Add a prominent navigation link: Security Overview/security/overview to avoid “we removed my dashboard” backlash.


2.2 Analyze routes → Security namespace

Old Route New Route Strategy Notes
/findings /security/findings REDIRECT Findings become security impact-to-release view.
/findings/:scanId /security/scans/:scanId REDIRECT Preserve deep links; scan detail page remains.
/vulnerabilities /security/vulnerabilities REDIRECT CVE explorer moved under security.
/vulnerabilities/:vulnId /security/vulnerabilities/:vulnId REDIRECT 1:1 mapping.
/graph /security/sbom/graph REDIRECT SBOM graph belongs under Security.
/lineage /security/lineage REDIRECT (Or /releases/lineage, choose one canonical; I recommend Security.)
/lineage/:artifact/compare /security/lineage/:artifact/compare ALIAS or REDIRECT Keep params same.
/lineage/compare /security/lineage/compare REDIRECT Stable.
/reachability /security/reachability REDIRECT Reachability center is security analysis.
/admin/vex-hub /security/vex REDIRECT VEX is not “admin-only”; move.
/admin/vex-hub/search /security/vex/search REDIRECT Keep identical subroutes.
/admin/vex-hub/search/detail/:id /security/vex/search/detail/:id REDIRECT 1:1.
/admin/vex-hub/stats /security/vex/stats REDIRECT 1:1.
/admin/vex-hub/consensus /security/vex/consensus REDIRECT 1:1.
/admin/vex-hub/explorer /security/vex/explorer REDIRECT 1:1.
/analyze/unknowns /security/unknowns REDIRECT 1:1.
/analyze/patch-map /security/patch-map REDIRECT 1:1.
/scans/:scanId /security/scans/:scanId REDIRECT Consolidate scan detail here.
/compare/:currentId /security/lineage/compare/:currentId REDIRECT Preserve compare deep links.
/cvss/receipts/:receiptId /evidence/receipts/cvss/:receiptId REDIRECT CVSS receipt is an evidence artifact.

2.3 Triage routes → split between Security (artifact triage) and Policy/Evidence

Old Route New Route Strategy Notes
/triage/artifacts /security/artifacts REDIRECT “Artifact workspace” becomes security artifact index (digest-first).
/triage/artifacts/:artifactId /security/artifacts/:artifactId REDIRECT Preserve the triage workspace; it becomes “Artifact Detail”.
/exceptions /policy/exceptions REDIRECT Exceptions are governance controls for gates.
/triage/audit-bundles /evidence?type=audit SMART REDIRECT Needs query param. Alternatively create /evidence/bundles/audit to allow simple redirect.
/triage/audit-bundles/new /evidence/bundles/new?type=audit SMART REDIRECT Needs query param.
/risk /security/risk REDIRECT Risk dashboard becomes security analytics.

Recommendation to reduce SMART redirects: create explicit canonical paths:

  • /evidence/bundles/audit
  • /evidence/bundles/release
  • /evidence/bundles/scan Then redirects are trivial and do not require query injection.

2.4 Policy routes (/policy-studio/*/policy/*)

Old Route New Route Strategy Notes
/policy-studio/packs /policy/packs REDIRECT Rename for brevity.
/policy-studio/packs/:packId/editor /policy/packs/:packId/editor REDIRECT 1:1.
/policy-studio/packs/:packId/yaml /policy/packs/:packId/yaml REDIRECT 1:1.
/policy-studio/packs/:packId/simulate /policy/packs/:packId/simulate REDIRECT 1:1.
/policy-studio/packs/:packId/approvals /policy/packs/:packId/approvals REDIRECT 1:1.
/policy-studio/packs/:packId/rules /policy/packs/:packId/rules REDIRECT 1:1.
/policy-studio/packs/:packId/explain/:runId /policy/packs/:packId/explain/:runId REDIRECT 1:1.
/policy-studio/packs/:packId/dashboard /policy/packs/:packId/dashboard REDIRECT 1:1.
/orchestrator /operations/orchestrator REDIRECT Orchestrator is ops.
/orchestrator/jobs /operations/orchestrator/jobs REDIRECT 1:1.
/orchestrator/jobs/:jobId /operations/orchestrator/jobs/:jobId REDIRECT 1:1.
/orchestrator/quotas /operations/orchestrator/quotas REDIRECT 1:1.

2.5 Ops routes (/ops/* + /scheduler/*/operations/*)

Old Route New Route Strategy Notes
/sbom-sources /settings/sbom-sources REDIRECT This is configuration, not ops.
/ops/quotas /operations/quotas REDIRECT 1:1.
/ops/quotas/tenants /operations/quotas/tenants REDIRECT 1:1.
/ops/quotas/tenants/:tenantId /operations/quotas/tenants/:tenantId REDIRECT 1:1.
/ops/quotas/throttle /operations/quotas/throttle REDIRECT 1:1.
/ops/quotas/alerts /operations/quotas/alerts REDIRECT 1:1.
/ops/quotas/forecast /operations/quotas/forecast REDIRECT 1:1.
/ops/quotas/reports /operations/quotas/reports REDIRECT 1:1.
/ops/orchestrator/dead-letter /operations/dead-letter REDIRECT Flatten path; keep subroute for queue.
/ops/orchestrator/dead-letter/queue /operations/dead-letter/queue REDIRECT 1:1.
/ops/orchestrator/slo /operations/slo REDIRECT 1:1.
/ops/orchestrator/slo/alerts /operations/slo/alerts REDIRECT 1:1.
/ops/orchestrator/slo/definitions /operations/slo/definitions REDIRECT 1:1.
/ops/health /operations/health REDIRECT 1:1.
/ops/feeds /operations/feeds REDIRECT 1:1.
/ops/feeds/mirror/:mirrorId /operations/feeds/mirror/:mirrorId REDIRECT 1:1.
/ops/feeds/airgap/import /operations/feeds/airgap/import REDIRECT 1:1.
/ops/feeds/airgap/export /operations/feeds/airgap/export REDIRECT 1:1.
/ops/feeds/version-locks /operations/feeds/version-locks REDIRECT 1:1.
/ops/offline-kit/* /operations/offline-kit/* ALIAS or REDIRECT Either keep the segment name to avoid churn, or canonicalize to /operations/offline/*.
/ops/aoc/* /operations/aoc/* REDIRECT Keep short; avoid nested /compliance/ unless you really need it.
/ops/doctor /operations/doctor REDIRECT 1:1.
/scheduler/* /operations/scheduler/* REDIRECT Fix inconsistent prefix.
/ops/scanner/* /operations/scanner/* REDIRECT Scanner ops is now “security gate engine ops”.

2.6 Notify

Old Route New Route Strategy Notes
/notify /operations/notifications REDIRECT If /notify is history/dispatch, it belongs to operations. If it is configuration, redirect to /settings/notifications.

2.7 Admin + Console routes → Settings namespace

Old Route New Route Strategy Notes
/console/profile /settings/profile REDIRECT Consolidate under settings.
/console/status /operations/status REDIRECT Status is ops.
/console/configuration /settings/integrations REDIRECT Configuration pane becomes integrations hub.
/console/admin/tenants /settings/admin/tenants REDIRECT 1:1.
/console/admin/users /settings/admin/users REDIRECT 1:1.
/console/admin/roles /settings/admin/roles REDIRECT 1:1.
/console/admin/clients /settings/admin/clients REDIRECT 1:1.
/console/admin/tokens /settings/admin/tokens REDIRECT 1:1.
/console/admin/audit /evidence/audit REDIRECT Audit is evidence.
/console/admin/branding /settings/admin/branding REDIRECT 1:1.
/admin/audit/* /evidence/audit/* REDIRECT Unified audit log belongs under evidence.
/admin/trust/* /settings/trust/* REDIRECT Keys/issuers/certs/score config consolidated.
/admin/registries /settings/registries REDIRECT Registry token service is configuration.
/admin/issuers /settings/trust/issuers REDIRECT Fold into trust.
/admin/notifications /settings/notifications/admin REDIRECT Admin notifications config.
/admin/policy/governance /settings/policy/governance REDIRECT Governance is configuration.
/admin/policy/simulation /policy/simulation REDIRECT Or keep /settings/policy/simulation if truly admin-only.
/concelier/trivy-db-settings /settings/trivy-db REDIRECT Or fold into /operations/feeds/trivy.

2.8 Release Orchestrator routes (/release-orchestrator/* → lifecycle roots)

Old Route New Route Strategy Notes
/release-orchestrator / REDIRECT Control plane becomes the orchestrator home.
/release-orchestrator/environments /environments REDIRECT 1:1.
/release-orchestrator/releases /releases REDIRECT 1:1.
/release-orchestrator/workflows /workflows (or /settings/workflows) REDIRECT Decide: if workflows are editable config → settings; if used daily → top-level.
/release-orchestrator/approvals /approvals REDIRECT 1:1.
/release-orchestrator/deployments /deployments REDIRECT 1:1.
/release-orchestrator/evidence /evidence?type=release SMART REDIRECT Better to create /evidence/bundles/release for simple redirect.

2.9 Evidence routes (mostly keep)

Old Route New Route Strategy Notes
/evidence /evidence KEEP Already good.
/evidence/bundles /evidence ALIAS or REDIRECT If you keep tabbed routes, you can keep it as alias.
/evidence/export /evidence/export KEEP Stable.
/evidence/replay /evidence/replay KEEP Stable.
/evidence/provenance /evidence/provenance KEEP Stable.
/evidence-packs /evidence/packs REDIRECT Normalize under evidence namespace.
/evidence-packs/:packId /evidence/packs/:packId REDIRECT 1:1.
/proofs/:subjectDigest /evidence/proofs/:subjectDigest ALIAS (recommended) Keep /proofs/* forever as a public-friendly shortlink.

2.10 Integrations routes → Settings

Old Route New Route Strategy Notes
/integrations /settings/integrations REDIRECT Canonicalize.
/integrations/registries /settings/integrations/registries REDIRECT 1:1.
/integrations/scm /settings/integrations/scm REDIRECT 1:1.
/integrations/ci /settings/integrations/ci REDIRECT 1:1.
/integrations/hosts /settings/integrations/hosts REDIRECT 1:1.
/integrations/feeds /settings/integrations/feeds REDIRECT 1:1.
/integrations/activity /settings/integrations/activity REDIRECT Or move to /operations/integrations/activity if you want.
/integrations/:integrationId /settings/integrations/:integrationId REDIRECT 1:1.

2.11 Other routes

Old Route New Route Strategy Notes
/ai-runs /operations/ai-runs REDIRECT AI runs are operational telemetry.
/ai-runs/:runId /operations/ai-runs/:runId REDIRECT 1:1.
/change-trace /evidence/change-trace REDIRECT Change trace is evidence lineage.
/setup /setup KEEP Installation wizard should remain stable.
/auth/callback /auth/callback KEEP Must remain stable for OIDC.

3) Redirect strategy (implementation plan that wont bite you)

3.1 Use a dedicated “Legacy Routes” layer (lowest priority in router)

Order matters. Put all legacy redirects after the new canonical route tree so you dont accidentally intercept new paths.

  • app.routes.ts

    1. New canonical routes
    2. Legacy redirect/alias routes
    3. ** fallback

3.2 Three redirect mechanisms (use the right one)

Mechanism 1 — Simple static redirect (redirectTo)

Use when mapping is clean and 1:1:

  • /findings/security/findings
  • /release-orchestrator/releases/releases

Mechanism 2 — Param redirect (redirectTo with :param)

Use when its still 1:1 but has params:

  • /vulnerabilities/:vulnId/security/vulnerabilities/:vulnId
  • /findings/:scanId/security/scans/:scanId

Mechanism 3 — SMART redirect (guard/matcher returning a UrlTree)

Use when you must:

  • Add query params (e.g., type=audit)
  • Switch tabs
  • Open a drawer based on route

Examples:

  • /triage/audit-bundles/evidence?type=audit
  • /release-orchestrator/evidence/evidence?type=release

Strong recommendation: Avoid SMART redirects by giving evidence bundle types real paths:

  • /evidence/bundles/audit
  • /evidence/bundles/release Then you can use simple redirects and remove complexity.

3.3 Preserve query params and fragments always

Legacy URLs in tickets often include query params. Your redirect logic must preserve:

  • ?tab=...
  • ?filters=...
  • #anchor

In Angular, guard-based UrlTree redirects are the most reliable way to preserve and augment query params intentionally.

Some paths are extremely convenient and should remain:

  • /proofs/:subjectDigest (keep forever, even if canonical is under /evidence/proofs/...)
  • Potentially /deploy/:id if you ever add it

This reduces friction when humans share links.

3.5 Add a “Legacy URL” banner (optional but useful)

On legacy-rendered aliases (not redirects), show a slim banner:

  • “This URL has moved. Update bookmarks.”
  • Button: “Go to new location”
  • Include one-click copy of canonical URL

This is very effective during the transition without forcing redirects.

3.6 Instrument legacy hits

Emit a telemetry event:

  • legacy_route_hit

    • oldPath
    • newPath
    • tenantId
    • userId (if available)
    • timestamp

This tells you when its safe to remove legacy routes (if you ever choose to).


4) Practical redirect coverage checklist (to prevent surprises)

Before shipping, test these as direct loads (not SPA navigation):

  1. /admin/vex-hub/search/detail/123 loads and lands on /security/vex/search/detail/123
  2. /findings/SCAN-123 lands on scan detail
  3. /proofs/sha256:... still works and lands on proof viewer
  4. /release-orchestrator/environments lands on /environments
  5. /triage/audit-bundles lands on the correct evidence bundle view (no empty state)