Skip to content

feat: add Delivery Insights (DORA metrics) UI at namespace, project, and component levels - #724

Draft
LakshanSS wants to merge 9 commits into
openchoreo:mainfrom
LakshanSS:laki-dora-1
Draft

feat: add Delivery Insights (DORA metrics) UI at namespace, project, and component levels#724
LakshanSS wants to merge 9 commits into
openchoreo:mainfrom
LakshanSS:laki-dora-1

Conversation

@LakshanSS

@LakshanSS LakshanSS commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds an Insights tab to the domain (Namespace), system (Project), and component entity pages, with two inner tabs:
    • Delivery Insights: the four DORA metrics (Deployment Frequency, Lead Time for Changes, Change Failure Rate, MTTR) as KPI tiles with classification, delta vs previous window, and sparklines; trend charts per range (7d/30d/90d/12mo) and granularity (daily/weekly/monthly); a one-level-down breakdown table (namespace → project → component) with drill-down; per-environment cards; environment filter.
    • Cost Insights: embeds the existing FinOps cost analysis at project level.
  • Backed by the observer's new DORA read API (POST /api/v1alpha1/insights/dora/query), tracked in openchoreo/openchoreo#4248 (not yet merged — see note below).
  • getDoraMetrics/getDoraDeployments added to the observability API client; namespace-level observer URL resolution (resolveForNamespace, resolves through the namespace's environments when no environmentName is given).
  • Merged current upstream/main into this branch to keep it up to date (no conflicts).

Status

Draft — this depends on openchoreo/openchoreo#4248, which is intentionally held open until the full Delivery Insights feature (events pipeline, WorkloadSource, MCP tool) lands. Opening this now for visibility/early review; not ready to merge until the backend PR does.

Test plan

  • Verified locally end-to-end against a k3d install running the laki-obs observer/controller branch: real (non-seeded) DORA data from an actual deployment success + a deliberate failure shows up correctly in the Insights tab's charts and KPI tiles.
  • Verified with the demo kit's seeded 120-day dataset (oc-delivery-insights/local-demo) across namespace/project/component levels and the environment filter/drill-down.

Summary by CodeRabbit

  • New Features

    • Added Delivery Insights with DORA metrics across namespace, project, component, system, and domain pages.
    • Added KPI tiles, trend charts, environment breakdowns, drill-downs, filtering, refresh controls, and deployment details.
    • Added project-level Cost Insights access where available.
    • Added namespace-level observability resolution without selecting an environment.
    • Added clear loading, empty, and error states throughout Insights views.
  • Documentation

    • Documented DORA observability integration and metric calculation details.

…and component levels

Adds an Insights tab to the domain (Namespace), system (Project), and
component entity pages, backed by the observer's new DORA read API
(openchoreo#3668). The tab hosts two inner views per the Insights design:

- Delivery Insights: four DORA KPI tiles (value, DORA classification,
  delta vs previous window, sparkline), trend charts with range
  (7d/30d/90d/12mo) and granularity (daily/weekly/monthly) controls, an
  environment filter, a one-level-down breakdown table (namespace: by
  project, project: by component, component: by environment) with row
  drill-down into the child's Insights tab (environment rows apply the
  env filter instead), per-environment metric cards, and a
  how-it-is-calculated footnote.
- Cost Insights: embeds the existing FinOps cost analysis at project
  level (drill-down preserved under /insights/cost); other levels point
  to the project pages until cost lands there.

Supporting changes: getDoraMetrics/getDoraDeployments on the
observability API client, and namespace-level observer URL resolution
(resolve-urls without environmentName resolves through the namespace's
environments) for the cross-environment scopes.

Signed-off-by: LakshanSS <lakshan230897@gmail.com>
The sparkline is absolutely positioned in the tile's bottom-right corner,
so long footer text (e.g. the lead-time coverage line) flowed underneath
it. Reserve the sparkline's width as footer padding and let the text wrap.

Signed-off-by: LakshanSS <lakshan230897@gmail.com>
@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: bca4f294-04e4-491a-90be-185b7d46bf46

📥 Commits

Reviewing files that changed from the base of the PR and between d8ad0c2 and 11da8a3.

📒 Files selected for processing (3)
  • plugins/openchoreo-observability/src/api/ObservabilityApi.ts
  • plugins/openchoreo-observability/src/index.ts
  • plugins/openchoreo-observability/src/types.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • plugins/openchoreo-observability/src/index.ts
  • plugins/openchoreo-observability/src/types.ts
  • plugins/openchoreo-observability/src/api/ObservabilityApi.ts

📝 Walkthrough

Walkthrough

Adds DORA Delivery Insights across catalog entity pages. The change includes typed observability APIs, namespace-level URL resolution, DORA data hooks, KPI and trend visualizations, breakdowns, environment metrics, filtering, drill-downs, and project-level Cost Insights.

Changes

DORA data and URL resolution

Layer / File(s) Summary
DORA contracts and API client
plugins/openchoreo-observability/src/types.ts, plugins/openchoreo-observability/src/api/ObservabilityApi.ts, plugins/openchoreo-observability/src/api/ObserverUrlCache.ts
Adds typed DORA metric and deployment responses. Adds API methods with scoped queries, defaults, response parsing, and error handling. Supports namespace-level URL requests.
Namespace observability URL resolution
packages/openchoreo-client-node/src/observability-url-resolver.ts, packages/openchoreo-client-node/src/observability-url-resolver.test.ts, plugins/openchoreo-observability-backend/src/router.ts, plugins/openchoreo-observability-backend/src/services/ObservabilityService.ts, plugins/openchoreo-observability-backend/src/router.test.ts
Allows requests without an environment name. Lists namespace environments and returns the first successfully resolved observer URL. Tests caching, token isolation, validation, and namespace-level resolution.
DORA data hooks and presentation utilities
plugins/openchoreo-observability/src/components/Insights/useDoraInsights.ts, plugins/openchoreo-observability/src/components/Insights/useDoraBreakdown.ts, plugins/openchoreo-observability/src/components/Insights/utils.ts
Fetches scoped metrics and child-entity summaries. Adds cancellation handling, sorting, formatting, classification colors, delta interpretation, and time-range options.

Insights page

Layer / File(s) Summary
Insights page and DORA visualizations
plugins/openchoreo-observability/src/components/Insights/ObservabilityInsightsPage.tsx, plugins/openchoreo-observability/src/components/Insights/InsightsContent.tsx, plugins/openchoreo-observability/src/components/Insights/Dora*.tsx
Adds Delivery and Cost tabs. Renders KPI tiles, trend charts, breakdown tables, environment cards, filters, metadata, loading states, and error states.
Entity routing and plugin exports
plugins/openchoreo-observability/src/components/Insights/index.ts, plugins/openchoreo-observability/src/plugin.ts, plugins/openchoreo-observability/src/index.ts, packages/portal-app/src/components/catalog/EntityPage.tsx, .changeset/delivery-insights-dora-ui.md
Exports a lazy Insights component and adds feature-gated /insights routes for service, component, system, and domain entities. Documents the release changes.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CatalogEntityPage
  participant ObservabilityInsightsPage
  participant InsightsContent
  participant useDoraInsights
  participant ObservabilityApi
  participant ObservabilityUrlResolver

  CatalogEntityPage->>ObservabilityInsightsPage: render /insights
  ObservabilityInsightsPage->>InsightsContent: provide DORA scope
  InsightsContent->>useDoraInsights: request metrics
  useDoraInsights->>ObservabilityApi: getDoraMetrics
  ObservabilityApi->>ObservabilityUrlResolver: resolve namespace/environment URLs
  ObservabilityUrlResolver-->>ObservabilityApi: observer URL
  ObservabilityApi-->>useDoraInsights: DoraMetricsResponse
  useDoraInsights-->>InsightsContent: metrics and loading state
  InsightsContent-->>CatalogEntityPage: render tiles and charts
Loading

Possibly related PRs

Suggested reviewers: stefinie123

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the feature, dependency, draft status, and test results, but it omits most required template sections and details. Complete the required sections, including purpose, goals, approach, user stories, release note, documentation, security checks, automation tests, and test environment.
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the primary change: adding Delivery Insights with DORA metrics UI across namespace, project, and component levels.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@LakshanSS

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
plugins/openchoreo-observability/src/components/Insights/useDoraBreakdown.ts (1)

144-166: 🚀 Performance & Scalability | 🔵 Trivial

Consider the scaling limits of per-child metric fan-out.

For each breakdown level, this hook issues one getDoraMetrics call per catalog child in parallel, with no limit on catalogApi.getEntities. In namespaces or projects with a large number of systems or components, this fans out into a large burst of concurrent observability requests on every render of the Insights page. Consider capping the number of children fetched per view, or requesting a batch/aggregate DORA endpoint from the observer API for the breakdown use case once available.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/openchoreo-observability/src/components/Insights/useDoraBreakdown.ts`
around lines 144 - 166, The useDoraBreakdown flow currently fans out one
getDoraMetrics request per child without a concurrency or result limit. Update
fetchSummary and the Promise.all processing for children and envChildren to
enforce an appropriate per-view cap or bounded concurrency, preserving the
existing row fallback behavior for failed requests; use a batch/aggregate
observability endpoint instead if one is available.
plugins/openchoreo-observability/src/components/Insights/DoraTrendChart.tsx (1)

110-128: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a Legend for multi-series charts.

The lead-time chart passes three series (p50Ms, p75Ms, p95Ms) with distinct colors, but no Legend is rendered. A user cannot map a line color to a percentile without hovering. Render Legend when series.length > 1.

♻️ Proposed change
-import {
-  Bar,
-  BarChart,
-  CartesianGrid,
-  Line,
-  LineChart,
-  ResponsiveContainer,
-  Tooltip,
-  XAxis,
-  YAxis,
-} from 'recharts';
+import {
+  Bar,
+  BarChart,
+  CartesianGrid,
+  Legend,
+  Line,
+  LineChart,
+  ResponsiveContainer,
+  Tooltip,
+  XAxis,
+  YAxis,
+} from 'recharts';
                 <Tooltip formatter={renderTooltipValue} />
+                {series.length > 1 && <Legend />}
                 {series.map(s => (
                   <Line
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/openchoreo-observability/src/components/Insights/DoraTrendChart.tsx`
around lines 110 - 128, Add a Recharts Legend to the LineChart rendering in
DoraTrendChart, rendering it only when series.length is greater than 1 so
multi-series lines expose their labels and colors while single-series charts
remain unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/openchoreo-client-node/src/observability-url-resolver.ts`:
- Around line 148-156: Update resolveForNamespace so namespace cache entries are
partitioned by the caller’s authorization identity rather than using only
`namespaceName` in `cacheKey`; derive the key from the authenticated principal
represented by token, or validate authorization before returning a cached
result. Preserve caching for the same principal and add coverage with two users
having different namespace access to ensure one user cannot receive the other’s
cached observability URL.

In
`@plugins/openchoreo-observability/src/components/Insights/InsightsContent.tsx`:
- Around line 67-86: Update useDoraBreakdown so every generated
project/component child scope preserves the parent scope’s environment value
when one is set, keeping the breakdown table consistent with effectiveScope and
the KPI/chart data. Retain existing namespace, project, and child-name scope
construction for unfiltered requests.
- Around line 173-185: Update the Deployment Frequency value formatting in the
DoraMetricTile usage to round frequency.perDay to two decimal places before
appending “/day”, while preserving the existing fallback when frequency is
unavailable.

In
`@plugins/openchoreo-observability/src/components/Insights/useDoraBreakdown.ts`:
- Around line 50-52: Update the child scope construction in useDoraBreakdown to
copy scope.environment for domain- and system-level breakdown rows, preserving
the inherited environment filter. Include scope.environment in scopeKey so the
breakdown effect recalculates when only the environment changes.

---

Nitpick comments:
In `@plugins/openchoreo-observability/src/components/Insights/DoraTrendChart.tsx`:
- Around line 110-128: Add a Recharts Legend to the LineChart rendering in
DoraTrendChart, rendering it only when series.length is greater than 1 so
multi-series lines expose their labels and colors while single-series charts
remain unchanged.

In
`@plugins/openchoreo-observability/src/components/Insights/useDoraBreakdown.ts`:
- Around line 144-166: The useDoraBreakdown flow currently fans out one
getDoraMetrics request per child without a concurrency or result limit. Update
fetchSummary and the Promise.all processing for children and envChildren to
enforce an appropriate per-view cap or bounded concurrency, preserving the
existing row fallback behavior for failed requests; use a batch/aggregate
observability endpoint instead if one is available.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1a373ae8-b42d-4553-99d1-b3a40e5e526c

📥 Commits

Reviewing files that changed from the base of the PR and between f39a20c and fe6b016.

📒 Files selected for processing (20)
  • .changeset/delivery-insights-dora-ui.md
  • packages/openchoreo-client-node/src/observability-url-resolver.ts
  • packages/portal-app/src/components/catalog/EntityPage.tsx
  • plugins/openchoreo-observability-backend/src/router.ts
  • plugins/openchoreo-observability-backend/src/services/ObservabilityService.ts
  • plugins/openchoreo-observability/src/api/ObservabilityApi.ts
  • plugins/openchoreo-observability/src/api/ObserverUrlCache.ts
  • plugins/openchoreo-observability/src/components/Insights/DoraBreakdownTable.tsx
  • plugins/openchoreo-observability/src/components/Insights/DoraEnvironmentCards.tsx
  • plugins/openchoreo-observability/src/components/Insights/DoraMetricTile.tsx
  • plugins/openchoreo-observability/src/components/Insights/DoraTrendChart.tsx
  • plugins/openchoreo-observability/src/components/Insights/InsightsContent.tsx
  • plugins/openchoreo-observability/src/components/Insights/ObservabilityInsightsPage.tsx
  • plugins/openchoreo-observability/src/components/Insights/index.ts
  • plugins/openchoreo-observability/src/components/Insights/useDoraBreakdown.ts
  • plugins/openchoreo-observability/src/components/Insights/useDoraInsights.ts
  • plugins/openchoreo-observability/src/components/Insights/utils.ts
  • plugins/openchoreo-observability/src/index.ts
  • plugins/openchoreo-observability/src/plugin.ts
  • plugins/openchoreo-observability/src/types.ts

Comment thread packages/openchoreo-client-node/src/observability-url-resolver.ts
Signed-off-by: LakshanSS <lakshan230897@gmail.com>
The test asserted the pre-namespace-resolution error message
('namespaceName and environmentName are required'), but environmentName
has been optional since resolve-urls gained namespace-level resolution.
Also adds coverage for the omitted-environmentName success path.

Signed-off-by: LakshanSS <lakshan230897@gmail.com>
resolveForNamespace cached results keyed only by namespaceName, so a
namespace result resolved for one user could be served to a different
user who cannot access that namespace or its environments. Scope the
cache key to the caller's token, matching per-request authorization.

Signed-off-by: LakshanSS <lakshan230897@gmail.com>
InsightsContent's environment filter narrowed the KPI tiles/charts but
not the project/component breakdown table: useDoraBreakdown rebuilt each
child scope without scope.environment, so the table always showed all
environments. Also include environment in scopeKey so the breakdown
effect refires when only the environment filter changes.

Signed-off-by: LakshanSS <lakshan230897@gmail.com>
An unrounded rate (e.g. 1.1428571428571428) printed the raw float in
the KPI tile instead of a formatted value like 1.14/day.

Signed-off-by: LakshanSS <lakshan230897@gmail.com>
@LakshanSS

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Resolves conflicts with the cost insights view (openchoreo#723): both PRs
independently added new types/methods to ObservabilityApi.ts and
types.ts, kept both sides.

Signed-off-by: LakshanSS <lakshan230897@gmail.com>
@LakshanSS

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant