Skip to content

RHIDP-12121: Support "StatusGrouped" and "Average" types of aggregation - #2923

Merged
imykhno merged 19 commits into
redhat-developer:mainfrom
imykhno:scorecard-average-as-aggregation-type
Apr 28, 2026
Merged

RHIDP-12121: Support "StatusGrouped" and "Average" types of aggregation#2923
imykhno merged 19 commits into
redhat-developer:mainfrom
imykhno:scorecard-average-as-aggregation-type

Conversation

@imykhno

@imykhno imykhno commented Apr 26, 2026

Copy link
Copy Markdown
Contributor

Hey, I just made a Pull Request!

This change adds average as a first-class aggregation KPI type next to statusGrouped, so homepage scorecard cards can show a single portfolio score (donut / gauge) derived from weighted status counts across owned entities, instead of only a status-grouped pie.

Behavior

  • statusGrouped (unchanged): Aggregates counts per status key across the user’s owned-entity scope, suited to “how many entities are green vs red” style charts.

  • average (new): Uses the same underlying status counts, applies options.statusScores (per threshold rule key → weight), and returns averageScore in 0,1 (one decimal). The UI can treat averageScore × 100 as the headline percentage.

  • Donut coloring for average: Optional options.aggregationResultThresholds (same shape as metric thresholds) is evaluated against averageScore × 100. If omitted, the backend applies built-in defaults (documented in aggregation.md / thresholds.md and aggregationKPIs.ts).

  • Strategy-based backend: Aggregation is wired through a small registry (AverageAggregationStrategy, StatusGroupedAggregationStrategy, shared loader/service) so new types do not sprawl across the router.

  • Frontend: New aggregated metric card stack (AggregatedMetricCard, AverageCard, StatusGroupedCard, shared chart/tooltip pieces), homepage wiring, translations, mocks/fixtures, and removal of the old monolithic homepage card component in favor of the new layout.

  • Quality: Unit tests across backend strategies, router, validation, mappers, threshold merge/helpers; Playwright coverage and helpers for the average card on the legacy app.

Configuration

Customization stays under scorecard.aggregationKPIs in app-config.yaml. For average, you must supply type, metricId, and options.statusScores (non-empty). Optional options.aggregationResultThresholds controls the aggregated result color band.

scorecard:
  aggregationKPIs:
    portfolioHealth:
      title: 'Portfolio health'
      description: 'Weighted average of entity statuses for this metric.'
      type: average
      metricId: github.open_prs
      options:
        statusScores:
          success: 1
          warning: 0.5
          error: 0
        # thresholds: optional; defaults apply if omitted

Invalid KPI entries (unknown type, missing options for average, empty statusScores, bad thresholds, unknown metricId, etc.) fail backend startup so misconfiguration is caught early.

New logic implemented for:

✔️ Checklist

  • A changeset describing the change and affected packages. (more info)
  • Added or Updated documentation
  • Tests for new functionality and regression tests for bug fixes
  • Screenshots attached (for UI changes)

How to test

  1. Default / statusGrouped: Confirm existing homepage cards and aggregationId behavior unchanged (including legacy metricId mount patterns if you still support them).
  2. average KPI: Add an aggregationKPIs row with type: average, valid statusScores, and mount the homepage card with matching aggregationId, confirm donut, headline %, tooltips, and colors (default vs custom aggregationResultThresholds).
  3. Validation: Temporarily break app-config (e.g. empty statusScores, wrong type) and confirm the backend fails fast at startup with a clear error.
  4. RBAC / permissions: Without scorecard/catalog access, confirm the homepage shows the expected permission / error states and does not leak aggregation data.

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>
@rhdh-qodo-merge

rhdh-qodo-merge Bot commented Apr 26, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Average gauge out-of-range🐞 Bug ≡ Correctness
Description
AverageCardComponent feeds averageScore * 100 directly into the donut chart slice value without
bounding it, so averageScore < 0 or > 1 can produce negative or >100 slice values and render
incorrectly. The backend algorithm and docs explicitly allow ratios >1.0 when statusScores
includes weighted keys not aligned with threshold rules, so this can happen in real configs.
Code

workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/AverageCard/AverageCardComponent.tsx[R73-91]

+  const displayPercent = scorecard.result.averageScore * 100;
+
+  const arcResolvedColor = resolveStatusColor(
+    theme,
+    scorecard.result.aggregationChartDisplayColor,
+  );
+
+  const averagePieData: PieData[] = [
+    {
+      name: AVERAGE_SCORE_SLICE,
+      value: displayPercent,
+      color: arcResolvedColor,
+    },
+    {
+      name: AVERAGE_REMAINDER_SLICE,
+      value: Math.max(0, 100 - displayPercent),
+      color: theme.palette.grey[300],
+    },
+  ];
Relevance

⭐⭐⭐ High

UI correctness issue: pie slice should be bounded; team has fixed donut/tooltip chart bugs before.

PR-#2352
PR-#2378
PR-#2640

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The frontend computes displayPercent from the backend-provided averageScore and uses it as a pie
slice value with only the remainder clamped, not the main slice. On the backend, the numerator
(weighted sum) is computed over all statuses in stored counts using statusScores, while the
denominator max score is computed only from metric threshold-rule keys; this mismatch allows
weightedSum > maxPossibleScore (and thus averageScore > 1). The backend documentation also calls
out that the ratio can exceed 1.0 under misaligned configs, making this a real scenario rather than
theoretical.

workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/AverageCard/AverageCardComponent.tsx[73-90]
workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/strategies/AverageAggregationStrategy.ts[118-133]
workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/strategies/AverageAggregationStrategy.ts[152-169]
workspaces/scorecard/plugins/scorecard-backend/docs/aggregation.md[46-49]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`AverageCardComponent` uses `averageScore * 100` as a Recharts pie slice value without bounding it. Because the backend can legitimately return `averageScore > 1.0` (or `< 0` if weights are negative), the donut chart can receive negative or >100 slice values and render incorrectly.

### Issue Context
Backend `AverageAggregationStrategy` computes `weightedSum` over all statuses in stored counts, but computes `maxPossibleScore` from the max score of *threshold rule keys* only. The docs explicitly note the ratio can exceed 1.0 when `statusScores` and threshold rules are misaligned.

### Fix Focus Areas
- Clamp the percent used for chart slices and center label to a safe range (e.g., `0..100`). Consider whether the label should show the clamped value (e.g., `100%`) or a special string (e.g., `>100%`).
- Ensure both donut slice values are non-negative and sum to 100.

- workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/AverageCard/AverageCardComponent.tsx[73-91]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Advisory comments

2. Dead avg-thresholds info log🐞 Bug ⚙ Maintainability
Description
AverageAggregationStrategy logs an info message when options.aggregationResultThresholds is
missing, but buildAggregationConfig always populates aggregationResultThresholds with a default
for average KPIs, making that log branch effectively unreachable in the normal router/config path.
This also contradicts the docs that claim an info log occurs when the field is omitted.
Code

workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/strategies/AverageAggregationStrategy.ts[R53-62]

+    const aggregationResultThresholds =
+      options.aggregationResultThresholds ??
+      DEFAULT_AVERAGE_KPI_RESULT_THRESHOLDS;
+
+    if (!options.aggregationResultThresholds) {
+      this.logger.info(
+        `The "scorecard.aggregationKPIs.${aggregationConfig.id}.options.aggregationResultThresholds" is not configured for average aggregation; ` +
+          'using the default 0–100% health scale (higher is better).',
+      );
+    }
Relevance

⭐⭐⭐ High

Team often aligns logs/docs; unreachable info branch likely unwanted/noisy. Similar logging cleanup
accepted previously.

PR-#2393
PR-#2020
PR-#2844

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The aggregation config builder sets options.aggregationResultThresholds to
buildAggregationThresholdsConfig(...) ?? DEFAULT_AVERAGE_KPI_RESULT_THRESHOLDS, so the strategy’s
if (!options.aggregationResultThresholds) { logger.info(...) } condition won’t be true when
configs come from AggregationsService.getAggregationConfig(). However, the documentation states
that omitting the field will produce an info log, which won’t happen with the current defaulting
location.

workspaces/scorecard/plugins/scorecard-backend/src/utils/buildAggregationConfig.ts[87-94]
workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/strategies/AverageAggregationStrategy.ts[53-62]
workspaces/scorecard/plugins/scorecard-backend/docs/aggregation.md[50-50]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`AverageAggregationStrategy` contains an info-log branch intended to fire when `options.aggregationResultThresholds` is omitted, but `buildAggregationConfig` always fills it with a default for `type: average`, so the log is effectively dead and docs describing the log are inaccurate.

### Issue Context
Average KPI result thresholds are currently defaulted in the config builder, while the strategy also contains fallback + logging logic.

### Fix Focus Areas
Choose one consistent approach:
- **Option A (preferred):** Keep `aggregationResultThresholds` truly optional in `buildAggregationConfig` (only set when configured), and let `AverageAggregationStrategy` apply the default + emit the info log when absent.
- **Option B:** Keep defaulting in `buildAggregationConfig`, but remove the unreachable log branch from the strategy and update docs to match.

- workspaces/scorecard/plugins/scorecard-backend/src/utils/buildAggregationConfig.ts[87-94]
- workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/strategies/AverageAggregationStrategy.ts[53-62]
- workspaces/scorecard/plugins/scorecard-backend/docs/aggregation.md[50-50]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

@rhdh-gh-app

rhdh-gh-app Bot commented Apr 26, 2026

Copy link
Copy Markdown

Important

This PR includes changes that affect public-facing API. Please ensure you are adding/updating documentation for new features or behavior.

Changed Packages

Package Name Package Path Changeset Bump Current Version
app-legacy workspaces/scorecard/packages/app-legacy none v0.0.0
@red-hat-developer-hub/backstage-plugin-scorecard-backend workspaces/scorecard/plugins/scorecard-backend minor v2.6.0
@red-hat-developer-hub/backstage-plugin-scorecard-common workspaces/scorecard/plugins/scorecard-common minor v2.6.0
@red-hat-developer-hub/backstage-plugin-scorecard-node workspaces/scorecard/plugins/scorecard-node minor v2.6.0
@red-hat-developer-hub/backstage-plugin-scorecard workspaces/scorecard/plugins/scorecard minor v2.6.0

@rhdh-qodo-merge

Copy link
Copy Markdown

Review Summary by Qodo

Support "Sum" and "Average" types of aggregation with weighted scoring and strategy-based architecture

✨ Enhancement 🧪 Tests

Grey Divider

Walkthroughs

Description
• Added support for average aggregation type alongside existing statusGrouped type, enabling
  weighted scoring of KPIs based on configurable status scores
• Implemented strategy-based aggregation architecture with AggregationsService,
  AverageAggregationStrategy, and StatusGroupedAggregationStrategy for extensible aggregation
  handling
• Created new UI components for average aggregation display: AverageCardComponent with donut
  chart, center percentage, and weighted score tooltips
• Refactored threshold validation into separate validateThresholdsForMetric and
  validateThresholdsForAggregation functions with different requirements (icon required for metrics,
  optional for aggregations)
• Added comprehensive test coverage for new aggregation strategies, service layer, validation, and
  e2e scenarios including average KPI rendering and error handling
• Extended configuration schema with options field for average KPI containing statusScores map
  and optional aggregationResultThresholds
• Added default threshold configuration for average KPI result thresholds (error <30%, warning
  30-79%, success ≥80%)
• Updated public API types to include AggregatedMetricAverageResult,
  StatusGroupedAggregationResult, and discriminated union AggregationResultByType
• Added internationalization support with translations for average aggregation UI labels and
  tooltips in 5 languages (Japanese, German, Italian, French, Spanish)
• Enhanced accessibility with aria-labels for loading progress indicators
• Comprehensive documentation covering aggregation types, configuration, validation, thresholds, and
  drill-down behavior
Diagram
flowchart LR
  Config["KPI Config<br/>statusScores<br/>thresholds"]
  AggService["AggregationsService"]
  Registry["Strategy Registry"]
  AvgStrategy["AverageAggregationStrategy"]
  StatusStrategy["StatusGroupedAggregationStrategy"]
  Loader["AggregatedMetricLoader"]
  Result["AggregatedMetricResult"]
  UI["UI Components<br/>AverageCard<br/>StatusGroupedCard"]
  
  Config -- "loads" --> AggService
  AggService -- "delegates to" --> Registry
  Registry -- "routes to" --> AvgStrategy
  Registry -- "routes to" --> StatusStrategy
  AvgStrategy -- "uses" --> Loader
  StatusStrategy -- "uses" --> Loader
  AvgStrategy -- "returns" --> Result
  StatusStrategy -- "returns" --> Result
  Result -- "renders" --> UI
Loading

Grey Divider

File Changes

1. workspaces/scorecard/plugins/scorecard-backend/src/service/router.test.ts ✨ Enhancement +218/-84

Refactor aggregation service integration and add average KPI tests

• Refactored router test to use new AggregationsService instead of calling
 catalogMetricService.getAggregatedMetricByEntityRefs directly
• Updated test setup to create AggregationsService instances and pass them via service object to
 createRouter
• Changed database mock spies from getAggregatedMetricByEntityRefs to
 readAggregatedMetricByEntityRefs to reflect new data layer
• Updated aggregation type references from aggregationTypes to aggregationKinds
• Added tests for average aggregation KPI type with weighted scoring

workspaces/scorecard/plugins/scorecard-backend/src/service/router.test.ts


2. workspaces/scorecard/plugins/scorecard-backend/src/service/mappers.test.ts 🧪 Tests +49/-178

Simplify mapper tests and add average aggregation support

• Simplified toAggregatedMetricResult test cases to focus on wrapping aggregation data rather than
 internal mapping logic
• Added test for average aggregation type with weighted scores and average-specific fields
• Removed redundant tests for threshold key ordering and custom threshold handling
• Updated test expectations to use aggregationKinds constant

workspaces/scorecard/plugins/scorecard-backend/src/service/mappers.test.ts


3. workspaces/scorecard/plugins/scorecard-node/src/utils/thresholds/validateThresholds.test.ts ✨ Enhancement +104/-26

Split threshold validation for metrics and aggregations

• Split validation into two functions: validateThresholdsForMetric (requires color and icon) and
 validateThresholdsForAggregation (requires only color)
• Added new test suite for aggregation-specific threshold validation
• Updated all existing tests to call the appropriate validation function
• Added tests for average aggregation threshold validation with MUI palette colors

workspaces/scorecard/plugins/scorecard-node/src/utils/thresholds/validateThresholds.test.ts


View more (91)
4. workspaces/scorecard/plugins/scorecard-backend/src/service/CatalogMetricService.test.ts 🧪 Tests +13/-135

Migrate aggregation loading to dedicated loader class

• Removed config parameter from CatalogMetricService constructor in tests
• Renamed test suite from getAggregatedMetricByEntityRefs to
 AggregatedMetricLoader.loadStatusGroupedMetricByEntityRefs
• Updated tests to use new AggregatedMetricLoader class instead of service method
• Removed test for unsupported aggregation type (now handled by AggregationsService)

workspaces/scorecard/plugins/scorecard-backend/src/service/CatalogMetricService.test.ts


5. workspaces/scorecard/packages/app-legacy/e2e-tests/scorecard.test.ts 🧪 Tests +180/-0

Add e2e tests for average aggregation KPI type

• Added e2e tests for average aggregation KPI (openPrsWeightedKpi) including title, description,
 and weighted score display
• Added tests for average card center percent, donut tooltip, and legend tooltips
• Added accessibility tests for weighted average card
• Added test for unsupported aggregation type error handling
• Imported new assertion utilities for average card verification

workspaces/scorecard/packages/app-legacy/e2e-tests/scorecard.test.ts


6. workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/AggregationsService.test.ts 🧪 Tests +206/-0

Add comprehensive tests for AggregationsService

• New test file for AggregationsService covering statusGrouped and average aggregation strategies
• Tests for configuration loading with and without KPI config
• Tests for error handling when aggregation type is unsupported
• Tests for default fallback behavior when KPI config is absent

workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/AggregationsService.test.ts


7. workspaces/scorecard/plugins/scorecard-backend/src/validation/validateAggregationConfig.test.ts 🧪 Tests +152/-4

Add validation tests for average aggregation KPI config

• Added tests for average KPI configuration validation with statusScores and optional
 aggregationResultThresholds
• Added tests for validation errors when average KPI is missing required options block
• Added tests for invalid threshold expressions in aggregation result thresholds
• Updated existing tests to use aggregationKinds constant

workspaces/scorecard/plugins/scorecard-backend/src/validation/validateAggregationConfig.test.ts


8. workspaces/scorecard/plugins/scorecard-backend/src/service/CatalogMetricService.ts Refactoring +1/-102

Remove aggregation-related code from CatalogMetricService

• Removed config parameter from service (moved to AggregationsService)
• Removed AggregatedMetric and aggregationTypes imports (no longer used)
• Changed Entity import to type-only import

workspaces/scorecard/plugins/scorecard-backend/src/service/CatalogMetricService.ts


9. workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/strategies/AverageAggregationStrategy.ts ✨ Enhancement +171/-0

Implement average aggregation strategy with weighted scoring

• New strategy class implementing weighted average aggregation with configurable status scores
• Calculates weighted sum, average score, and max possible score from entity status counts
• Determines aggregation chart display color based on result thresholds
• Handles missing status scores with warnings and defaults to zero

workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/strategies/AverageAggregationStrategy.ts


10. workspaces/scorecard/plugins/scorecard-node/src/utils/thresholds/validateThresholds.ts Refactoring +104/-36

Refactor threshold validation into metric and aggregation variants

• Extracted validateThresholds into two separate functions: validateThresholdsForMetric and
 validateThresholdsForAggregation
• Created helper functions for validation logic: validateConfigType, validateThresholdRule,
 validateColorAndIconExists, validateColorExists, validateDuplicateKey
• Aggregation validation requires only color (not icon) for custom threshold keys
• Improved code organization and reusability

workspaces/scorecard/plugins/scorecard-node/src/utils/thresholds/validateThresholds.ts


11. workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/strategies/averageAggregationStrategy.test.ts 🧪 Tests +150/-0

Add tests for average aggregation strategy

• New test file for AverageAggregationStrategy covering weighted average calculations
• Tests for weighted sum, average score, and max possible score computation
• Tests for error handling when statusScores is missing
• Tests for warning when loader returns unknown status not in threshold rules

workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/strategies/averageAggregationStrategy.test.ts


12. workspaces/scorecard/plugins/scorecard-backend/src/service/router.ts ✨ Enhancement +26/-33

Integrate AggregationsService into router endpoints

• Updated ScorecardRouterOptions to accept service object containing aggregationsService and
 catalogMetricService
• Refactored aggregation endpoints to use AggregationsService.getAggregatedMetricByEntityRefs
 instead of CatalogMetricService
• Removed direct calls to catalogMetricService.getAggregationConfigs; now uses
 aggregationsService.getAggregationConfig
• Removed aggregationTypes import (no longer needed)

workspaces/scorecard/plugins/scorecard-backend/src/service/router.ts


13. workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/strategies/statusGroupedAggregationStrategy.test.ts 🧪 Tests +133/-0

Add tests for status-grouped aggregation strategy

• New test file for StatusGroupedAggregationStrategy covering status-grouped aggregation
• Tests for loading aggregates and mapping to API result format
• Tests for handling empty entity refs without database calls

workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/strategies/statusGroupedAggregationStrategy.test.ts


14. workspaces/scorecard/packages/app-legacy/e2e-tests/utils/scorecardResponseUtils.ts 🧪 Tests +71/-0

Add mock response data for average aggregation KPI

• Added mock response data for average KPI aggregation (openPrsWeightedKpiMetadataResponse,
 openPrsWeightedAggregatedResponse)
• Added empty response variant for average KPI with zero entities
• Added unsupported aggregation type response for error handling tests
• Imported aggregationKinds constant

workspaces/scorecard/packages/app-legacy/e2e-tests/utils/scorecardResponseUtils.ts


15. workspaces/scorecard/plugins/scorecard-backend/src/utils/buildAggregationConfig.test.ts 🧪 Tests +61/-3

Add tests for average KPI configuration building

• Added tests for building average KPI configuration with statusScores
• Added tests for optional aggregationResultThresholds in average KPI config
• Updated existing tests to use aggregationKinds constant

workspaces/scorecard/plugins/scorecard-backend/src/utils/buildAggregationConfig.test.ts


16. workspaces/scorecard/plugins/scorecard-node/src/utils/thresholds/getThresholdsFromConfig.test.ts 🧪 Tests +41/-16

Update threshold config tests for metric-specific validation

• Updated mock to use validateThresholdsForMetric instead of generic validateThresholds
• Updated test data paths from scorecard.rules to scorecard.defaultMetricThresholds
• Updated error message expectations to include config path in error

workspaces/scorecard/plugins/scorecard-node/src/utils/thresholds/getThresholdsFromConfig.test.ts


17. workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/AggregationService.ts ✨ Enhancement +109/-0

Implement AggregationsService for strategy-based aggregation

• New service class managing aggregation strategies and configuration loading
• Provides getAggregationConfig method to load KPI config or return defaults
• Provides getAggregatedMetricByEntityRefs method to delegate to appropriate strategy
• Maintains registry of aggregation strategies (statusGrouped, average)
• Handles missing KPI config with warnings and sensible defaults

workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/AggregationService.ts


18. workspaces/scorecard/packages/app-legacy/e2e-tests/utils/averageCardAssertions.ts 🧪 Tests +93/-0

Add assertion utilities for average card e2e tests

• New utility file with assertion helpers for average aggregation card UI tests
• Functions to verify center percent display, donut tooltip content, and legend tooltips
• Helper functions for translation interpolation and metric copy lookup

workspaces/scorecard/packages/app-legacy/e2e-tests/utils/averageCardAssertions.ts


19. workspaces/scorecard/plugins/scorecard-backend/src/validation/validateAggregationConfig.ts Refactoring +18/-12

Refactor aggregation config validation with schema

• Refactored to use new aggregationConfigSchema from schemas module
• Added validation for aggregationResultThresholds when aggregation type is average
• Imported validateThresholdsForAggregation for threshold validation
• Updated to use aggregationKinds constant

workspaces/scorecard/plugins/scorecard-backend/src/validation/validateAggregationConfig.ts


20. workspaces/scorecard/plugins/scorecard-backend/src/utils/buildAggregationConfig.ts ✨ Enhancement +56/-2

Extend aggregation config building for average KPI options

• Added AverageOptions type with statusScores and optional aggregationResultThresholds
• Updated AggregationConfig type to include optional options field
• Added helper functions buildStatusScores and buildAggregationThresholdsConfig
• For average aggregation type, populates options with statusScores and default/configured
 thresholds

workspaces/scorecard/plugins/scorecard-backend/src/utils/buildAggregationConfig.ts


21. workspaces/scorecard/packages/app-legacy/e2e-tests/pages/HomePage.ts ✨ Enhancement +19/-1

Add weighted KPI card support and improve drill-down link selection

• Added card pattern matching for weighted KPI card (withOpenPrsWeightedKpi)
• Improved clickDrillDownLink to use regex filter for more precise link selection
• Handles ambiguity when card description contains "entities" keyword

workspaces/scorecard/packages/app-legacy/e2e-tests/pages/HomePage.ts


22. workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/AggregatedMetricLoader.test.ts 🧪 Tests +64/-0

Add tests for AggregatedMetricLoader

• New test file for AggregatedMetricLoader covering database read operations
• Tests for empty entity refs returning empty aggregation without DB call
• Tests for reading and mapping database rows to aggregated metric format

workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/AggregatedMetricLoader.test.ts


23. workspaces/scorecard/plugins/scorecard-common/src/types/aggregation.ts ✨ Enhancement +24/-6

Add average aggregation result types and update aggregation types

• Updated AggregationType to use aggregationKinds instead of aggregationTypes
• Added optional score field to AggregatedMetricValue for weighted aggregations
• Added new types: StatusGroupedAggregationResult, AggregatedMetricAverageResult,
 AggregationResultByType
• Updated AggregatedMetricResult.result to use discriminated union type

workspaces/scorecard/plugins/scorecard-common/src/types/aggregation.ts


24. workspaces/scorecard/packages/app-legacy/e2e-tests/utils/mockHomepageAggregations.ts 🧪 Tests +12/-2

Add mock for weighted KPI aggregation endpoint

• Added mock response for weighted KPI aggregation endpoint
• Updated mockAllDefaultHomepageAggregationsSuccess to include weighted KPI mock
• Updated comment to reflect all default homepage aggregation endpoints

workspaces/scorecard/packages/app-legacy/e2e-tests/utils/mockHomepageAggregations.ts


25. workspaces/scorecard/plugins/scorecard-backend/src/validation/schemas/aggregationConfigSchemas.ts ✨ Enhancement +58/-0

Add Zod schemas for aggregation configuration validation

• New schema file with Zod validation schemas for aggregation configurations
• Separate schemas for statusGrouped and average aggregation types
• Average schema includes required options.statusScores and optional aggregationResultThresholds
• Discriminated union schema for type-safe aggregation config validation

workspaces/scorecard/plugins/scorecard-backend/src/validation/schemas/aggregationConfigSchemas.ts


26. workspaces/scorecard/plugins/scorecard/__fixtures__/scorecardData.ts 🧪 Tests +27/-3

Add mock data for average aggregation type

• Added mock data for average aggregation type with weighted scores
• Updated existing mock to use aggregationKinds constant
• Added averageScore, averageWeightedSum, and averageMaxPossible fields to average mock

workspaces/scorecard/plugins/scorecard/fixtures/scorecardData.ts


27. workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/strategies/StatusGroupedAggregationStrategy.ts ✨ Enhancement +56/-0

Implement status-grouped aggregation strategy

• New strategy class implementing status-grouped aggregation (default behavior)
• Loads aggregated metric via AggregatedMetricLoader
• Maps database results to status-grouped API result format with threshold rules
• Delegates to AggregatedMetricMapper for final result wrapping

workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/strategies/StatusGroupedAggregationStrategy.ts


28. workspaces/scorecard/plugins/scorecard-common/src/constants/aggregations.ts ✨ Enhancement +7/-1

Add average aggregation type constant

• Renamed aggregationTypes constant to aggregationKinds for clarity
• Added average aggregation type alongside existing statusGrouped
• Updated JSDoc to mark aggregationKinds as public API

workspaces/scorecard/plugins/scorecard-common/src/constants/aggregations.ts


29. workspaces/scorecard/plugins/scorecard-backend/src/service/mappers.ts ✨ Enhancement +5/-16

Refactor metric mapper for aggregation result types

• Updated imports to use aggregationKinds instead of aggregationTypes
• Refactored toAggregatedMetricResult method to accept AggregationResultByType instead of
 separate thresholds and aggregatedMetric parameters
• Simplified result object construction by directly using the result parameter

workspaces/scorecard/plugins/scorecard-backend/src/service/mappers.ts


30. workspaces/scorecard/plugins/scorecard-backend/src/constants/aggregationKPIs.ts ✨ Enhancement +29/-0

Add default average KPI result thresholds

• Added default threshold configuration for average KPI result thresholds
• Defined DEFAULT_AVERAGE_KPI_RESULT_THRESHOLDS with three rules: error (<30%), warning (30-79%),
 success (≥80%)
• Imported ThresholdConfig and ScorecardThresholdRuleColors types

workspaces/scorecard/plugins/scorecard-backend/src/constants/aggregationKPIs.ts


31. workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/AggregatedMetricLoader.ts ✨ Enhancement +40/-0

Create aggregated metric loader service

• New class to load aggregated metrics from database
• Provides loadStatusGroupedMetricByEntityRefs method for loading status-grouped metrics
• Handles empty entity refs by returning empty aggregated metric

workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/AggregatedMetricLoader.ts


32. workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/types.ts ✨ Enhancement +28/-0

Define aggregation options type

• Defined AggregationOptions type containing metric, entity refs, thresholds, and aggregation
 config
• Used by aggregation strategies to process aggregation requests

workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/types.ts


33. workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/strategies/types.ts ✨ Enhancement +22/-0

Define aggregation strategy interface

• Defined AggregationStrategy interface with aggregate method
• Method accepts AggregationOptions and returns AggregatedMetricResult promise

workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/strategies/types.ts


34. workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/strategies/registerStrategies.ts ✨ Enhancement +38/-0

Create aggregation strategy registry factory

• New factory function to create aggregation strategy registry
• Registers StatusGroupedAggregationStrategy and AverageAggregationStrategy
• Returns Map<AggregationType, AggregationStrategy> for strategy lookup

workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/strategies/registerStrategies.ts


35. workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/strategies/registerStrategies.test.ts 🧪 Tests +39/-0

Test aggregation strategy registry

• Tests that registry correctly registers both aggregation strategies
• Verifies correct strategy instances are returned for each aggregation kind
• Confirms registry contains exactly 2 strategies

workspaces/scorecard/plugins/scorecard-backend/src/service/aggregations/strategies/registerStrategies.test.ts


36. workspaces/scorecard/plugins/scorecard-backend/src/plugin.ts ✨ Enhancement +12/-1

Integrate aggregations service into plugin

• Added AggregationsService instantiation with config, database, and logger
• Updated router creation to pass service object containing both aggregationsService and
 catalogMetricService
• Refactored service dependencies for aggregation handling

workspaces/scorecard/plugins/scorecard-backend/src/plugin.ts


37. workspaces/scorecard/plugins/scorecard-backend/config.d.ts ⚙️ Configuration changes +19/-0

Add aggregation KPI options configuration schema

• Added options field to aggregation KPI configuration
• Defined statusScores map for weighting threshold rule keys (required for average type)
• Added optional aggregationResultThresholds for coloring average KPI headline values

workspaces/scorecard/plugins/scorecard-backend/config.d.ts


38. workspaces/scorecard/plugins/scorecard-backend/src/utils/mergeEntityAndProviderThresholds.ts ✨ Enhancement +3/-3

Update threshold validation function call

• Updated import to use validateThresholdsForMetric instead of validateThresholds
• Reorganized imports for better clarity
• Updated function call to use renamed validation function

workspaces/scorecard/plugins/scorecard-backend/src/utils/mergeEntityAndProviderThresholds.ts


39. workspaces/scorecard/plugins/scorecard-backend/src/utils/mergeEntityAndProviderThresholds.test.ts 🧪 Tests +14/-0

Add test for invalid boolean threshold override

• Added test case for invalid boolean metric threshold override expression
• Verifies ThresholdConfigFormatError is thrown with correct annotation path message

workspaces/scorecard/plugins/scorecard-backend/src/utils/mergeEntityAndProviderThresholds.test.ts


40. workspaces/scorecard/plugins/scorecard-node/src/utils/index.ts ✨ Enhancement +4/-1

Export metric and aggregation threshold validators

• Renamed validateThresholds export to validateThresholdsForMetric
• Added new validateThresholdsForAggregation export for aggregation-specific validation

workspaces/scorecard/plugins/scorecard-node/src/utils/index.ts


41. workspaces/scorecard/plugins/scorecard-node/src/utils/thresholds/getThresholdsFromConfig.ts ✨ Enhancement +2/-2

Update metric threshold validation call

• Updated to call validateThresholdsForMetric instead of validateThresholds
• Maintains same validation logic for metric threshold configuration

workspaces/scorecard/plugins/scorecard-node/src/utils/thresholds/getThresholdsFromConfig.ts


42. workspaces/scorecard/plugins/scorecard-common/src/constants/aggregations.ts ✨ Enhancement +7/-1

Export aggregation kinds constant

• Exported aggregationKinds constant with statusGrouped and average values
• Updated type definition for AggregationType to reference aggregationKinds

workspaces/scorecard/plugins/scorecard-common/src/constants/aggregations.ts


43. workspaces/scorecard/plugins/scorecard-common/report.api.md ✨ Enhancement +30/-9

Update aggregation result types in public API

• Added AggregatedMetricAverageResult type with average score, weighted sum, and max possible
 fields
• Added StatusGroupedAggregationResult type for status-grouped aggregations
• Renamed aggregationTypes to aggregationKinds in public API
• Updated AggregatedMetricResult.result to use AggregationResultByType union
• Added optional score field to AggregatedMetricValue

workspaces/scorecard/plugins/scorecard-common/report.api.md


44. workspaces/scorecard/plugins/scorecard/src/translations/ref.ts ✨ Enhancement +6/-3

Add average aggregation translation keys

• Added unsupportedAggregationType error message for unsupported aggregation types
• Removed noMetricsFound and multipleMetricsFound error messages
• Added four new metric translation keys for average aggregation tooltips and labels

workspaces/scorecard/plugins/scorecard/src/translations/ref.ts


45. workspaces/scorecard/plugins/scorecard/src/translations/ja.ts 📝 Documentation +7/-4

Add Japanese translations for average aggregation

• Added Japanese translation for unsupportedAggregationType error
• Removed translations for noMetricsFound and multipleMetricsFound
• Added four Japanese translations for average aggregation UI labels and tooltips

workspaces/scorecard/plugins/scorecard/src/translations/ja.ts


46. workspaces/scorecard/plugins/scorecard/src/translations/de.ts 📝 Documentation +7/-4

Add German translations for average aggregation

• Added German translation for unsupportedAggregationType error
• Removed translations for noMetricsFound and multipleMetricsFound
• Added four German translations for average aggregation UI labels and tooltips

workspaces/scorecard/plugins/scorecard/src/translations/de.ts


47. workspaces/scorecard/plugins/scorecard/src/translations/it.ts 📝 Documentation +7/-4

Add Italian translations for average aggregation

• Added Italian translation for unsupportedAggregationType error
• Removed translations for noMetricsFound and multipleMetricsFound
• Added four Italian translations for average aggregation UI labels and tooltips

workspaces/scorecard/plugins/scorecard/src/translations/it.ts


48. workspaces/scorecard/plugins/scorecard/src/translations/fr.ts 📝 Documentation +7/-4

Add French translations for average aggregation

• Added French translation for unsupportedAggregationType error
• Removed translations for noMetricsFound and multipleMetricsFound
• Added four French translations for average aggregation UI labels and tooltips

workspaces/scorecard/plugins/scorecard/src/translations/fr.ts


49. workspaces/scorecard/plugins/scorecard/src/translations/es.ts 📝 Documentation +7/-4

Add Spanish translations for average aggregation

• Added Spanish translation for unsupportedAggregationType error
• Removed translations for noMetricsFound and multipleMetricsFound
• Added four Spanish translations for average aggregation UI labels and tooltips

workspaces/scorecard/plugins/scorecard/src/translations/es.ts


50. workspaces/scorecard/plugins/scorecard/src/utils/constants.ts ✨ Enhancement +6/-0

Add loading progress aria-label constant

• Added SCORECARD_LOADING_ARIA_LABEL constant for accessibility
• Provides WCAG-compliant aria-label for CircularProgress components

workspaces/scorecard/plugins/scorecard/src/utils/constants.ts


51. workspaces/scorecard/plugins/scorecard/src/utils/index.ts ✨ Enhancement +1/-0

Export loading aria-label constant

• Exported new SCORECARD_LOADING_ARIA_LABEL constant for accessibility

workspaces/scorecard/plugins/scorecard/src/utils/index.ts


52. workspaces/scorecard/plugins/scorecard/src/components/types.ts ✨ Enhancement +1/-0

Add score field to pie data type

• Added optional score field to PieData type for average aggregation display

workspaces/scorecard/plugins/scorecard/src/components/types.ts


53. workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/AverageCard/types.ts ✨ Enhancement +32/-0

Define average card component props type

• Defined AverageCardComponentProps type for average aggregation card component
• Specifies props for rendering average-type aggregation results with donut chart

workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/AverageCard/types.ts


54. workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/StatusGroupedCard/types.ts ✨ Enhancement +32/-0

Define status-grouped card component props type

• Defined StatusGroupedCardComponentProps type for status-grouped card component
• Specifies props for rendering status-grouped aggregation results with pie chart

workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/StatusGroupedCard/types.ts


55. workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/AverageCard/AverageCardComponent.tsx ✨ Enhancement +231/-0

Create average aggregation card component

• New component to render average aggregation KPI as donut chart with center percentage
• Displays weighted health score with legend and tooltips for status breakdown
• Includes center tooltip showing weighted sum and max possible score

workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/AverageCard/AverageCardComponent.tsx


56. workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/StatusGroupedCard/StatusGroupedCardComponent.tsx ✨ Enhancement +120/-0

Create status-grouped card component

• New component to render status-grouped aggregation as multi-slice pie chart
• Displays entity counts per threshold status with legend and tooltips

workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/StatusGroupedCard/StatusGroupedCardComponent.tsx


57. workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/AggregatedMetricCard.tsx ✨ Enhancement +48/-0

Create aggregated metric card router component

• New router component that dispatches to appropriate card component based on aggregation type
• Handles statusGrouped and average types, with error fallback for unsupported types

workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/AggregatedMetricCard.tsx


58. workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/UnsupportedAggregationType.tsx ✨ Enhancement +47/-0

Create unsupported aggregation type error component

• New component to display error when aggregation type is not supported
• Shows error panel with aggregation type name for debugging

workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/UnsupportedAggregationType.tsx


59. workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/components/CardInfoButton.tsx ✨ Enhancement +67/-0

Create card info button component

• New component for info button showing last updated timestamp
• Extracted from card implementations for reuse across card types

workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/components/CardInfoButton.tsx


60. workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/components/CardSubheader.tsx ✨ Enhancement +50/-0

Create card subheader component

• New component for card subheader with entity count and drill-down link
• Extracted from card implementations for reuse across card types

workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/components/CardSubheader.tsx


61. workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/components/CardChartContainer.tsx ✨ Enhancement +45/-0

Create card chart container component

• New component for consistent chart container styling and layout
• Extracted from card implementations for reuse across card types

workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/components/CardChartContainer.tsx


62. workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/components/CardTooltip.tsx ✨ Enhancement +58/-0

Create card tooltip component

• New component for positioned tooltip display using Portal
• Supports custom content rendering for different aggregation types

workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/components/CardTooltip.tsx


63. workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/AverageCard/DonutChartTooltipContent.tsx ✨ Enhancement +42/-0

Create donut chart tooltip content component

• New component for donut chart center tooltip showing weighted sum and max possible
• Used when hovering over center percentage in average aggregation card

workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/AverageCard/DonutChartTooltipContent.tsx


64. workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/AverageCard/LegendTooltipContent.tsx ✨ Enhancement +54/-0

Create legend tooltip content component

• New component for legend tooltip showing entity count and weighted score per status
• Displays percentage contribution to overall average score

workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/AverageCard/LegendTooltipContent.tsx


65. workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/AverageCard/TooltipContent.tsx ✨ Enhancement +62/-0

Create tooltip content utility component

• New utility component for consistent tooltip content formatting
• Provides formatAggregationScoreDetail helper for number formatting

workspaces/scorecard/plugins/scorecard/src/components/AggregatedMetricCards/AverageCard/TooltipContent.tsx


66. workspaces/scorecard/plugins/scorecard/src/components/ScorecardHomepageSection/ScorecardHomepageCard.tsx ✨ Enhancement +2/-2

Update homepage card to use aggregation router

• Updated to use new AggregatedMetricCard router component instead of
 ScorecardHomepageCardComponent
• Maintains same data loading and error handling logic

workspaces/scorecard/plugins/scorecard/src/components/ScorecardHomepageSection/ScorecardHomepageCard.tsx


67. workspaces/scorecard/plugins/scorecard/src/components/ScorecardHomepageSection/CustomLegend.tsx ✨ Enhancement +15/-23

Update custom legend positioning and translation

• Updated tooltip position type from { x, y } to { left, top } for consistency
• Simplified tooltip positioning logic by using viewport coordinates directly
• Improved label translation fallback logic for better handling of untranslated keys

workspaces/scorecard/plugins/scorecard/src/components/ScorecardHomepageSection/CustomLegend.tsx


68. workspaces/scorecard/plugins/scorecard/src/components/ScorecardHomepageSection/CustomTooltip.tsx ✨ Enhancement +18/-8

Update custom tooltip to support React node content

• Updated customContent prop type to accept React nodes in addition to strings
• Added conditional rendering for string vs node content types

workspaces/scorecard/plugins/scorecard/src/components/ScorecardHomepageSection/CustomTooltip.tsx


69. workspaces/scorecard/plugins/scorecard/src/components/ScorecardHomepageSection/ResponsivePieChart.tsx ✨ Enhancement +5/-3

Make pie chart tooltip optional

• Made tooltipContent prop optional for components that don't need tooltips
• Updated cursor and tooltip rendering to only show when tooltip is enabled

workspaces/scorecard/plugins/scorecard/src/components/ScorecardHomepageSection/ResponsivePieChart.tsx


70. workspaces/scorecard/plugins/scorecard/src/components/ScorecardPage/EntitiesTable/EntitiesTable.tsx ✨ Enhancement +5/-2

Add accessibility label to loading progress

• Added aria-label to CircularProgress for WCAG accessibility compliance
• Uses new SCORECARD_LOADING_ARIA_LABEL constant

workspaces/scorecard/plugins/scorecard/src/components/ScorecardPage/EntitiesTable/EntitiesTable.tsx


71. workspaces/scorecard/plugins/scorecard/src/components/Common/CardLoading.tsx ✨ Enhancement +3/-1

Add accessibility label to loading progress

• Added aria-label to CircularProgress for WCAG accessibility compliance
• Uses new SCORECARD_LOADING_ARIA_LABEL constant

workspaces/scorecard/plugins/scorecard/src/components/Common/CardLoading.tsx


72. workspaces/scorecard/plugins/scorecard/src/components/Common/__tests__/CardLoading.test.tsx 🧪 Tests +4/-1

Test loading progress accessibility label

• Updated test to verify CircularProgress has correct aria-label
• Uses SCORECARD_LOADING_ARIA_LABEL constant in test assertion

workspaces/scorecard/plugins/scorecard/src/components/Common/tests/CardLoading.test.tsx


73. workspaces/scorecard/plugins/scorecard/src/components/ScorecardHomepageSection/__tests__/ScorecardHomepageCard.test.tsx 🧪 Tests +100/-13

Test aggregation card router and average type

• Updated to test new AggregatedMetricCard router component
• Added tests for average aggregation rendering with donut chart
• Added test for unsupported aggregation type error handling
• Added mock for ResponseErrorPanel component

workspaces/scorecard/plugins/scorecard/src/components/ScorecardHomepageSection/tests/ScorecardHomepageCard.test.tsx


74. workspaces/scorecard/plugins/scorecard/src/components/ScorecardHomepageSection/__tests__/CustomLegend.test.tsx 🧪 Tests +26/-2

Test custom legend positioning and average segments

• Updated test assertions for new tooltip position type { left, top }
• Added test for average donut segment legend rendering with translation fallback

workspaces/scorecard/plugins/scorecard/src/components/ScorecardHomepageSection/tests/CustomLegend.test.tsx


75. workspaces/scorecard/plugins/scorecard/src/components/ScorecardHomepageSection/__tests__/ScorecardHomepageSection.test.tsx 🧪 Tests +2/-2

Update homepage section test mocks

• Updated mock to use new AggregatedMetricCard component path
• Maintains same test structure for section rendering

workspaces/scorecard/plugins/scorecard/src/components/ScorecardHomepageSection/tests/ScorecardHomepageSection.test.tsx


76. workspaces/scorecard/plugins/scorecard/dev/mocks.ts ✨ Enhancement +3/-3

Update mock data to use aggregation kinds

• Updated to use aggregationKinds instead of aggregationTypes
• Maintains same mock data structure for testing

workspaces/scorecard/plugins/scorecard/dev/mocks.ts


77. workspaces/scorecard/plugins/scorecard/src/alpha/extensions/homePageCards.tsx ✨ Enhancement +27/-0

Add weighted average KPI homepage widget

• Added new AggregatedCardWithGithubOpenPrsWeightedContent component for average KPI
• Exported aggregatedCardWithGithubOpenPrsWeightedWidget NFS widget blueprint

workspaces/scorecard/plugins/scorecard/src/alpha/extensions/homePageCards.tsx


78. workspaces/scorecard/plugins/scorecard/src/alpha/index.tsx ✨ Enhancement +2/-0

Export weighted KPI widget in alpha module

• Imported and exported new aggregatedCardWithGithubOpenPrsWeightedWidget in module

workspaces/scorecard/plugins/scorecard/src/alpha/index.tsx


79. workspaces/scorecard/plugins/scorecard/report.api.md 📝 Documentation +5/-2

Update public API documentation

• Updated public API to include new average aggregation translation keys
• Removed deprecated metric-not-found translation keys

workspaces/scorecard/plugins/scorecard/report.api.md


80. workspaces/scorecard/plugins/scorecard/report-alpha.api.md 📝 Documentation +5/-2

Update alpha API documentation

• Updated alpha API to include new average aggregation translation keys
• Removed deprecated metric-not-found translation keys

workspaces/scorecard/plugins/scorecard/report-alpha.api.md


81. workspaces/scorecard/plugins/scorecard-node/report.api.md 📝 Documentation +7/-1

Update threshold validation public API

• Updated public API to export validateThresholdsForMetric and validateThresholdsForAggregation
• Removed deprecated validateThresholds export

workspaces/scorecard/plugins/scorecard-node/report.api.md


82. workspaces/scorecard/plugins/scorecard-backend/README.md 📝 Documentation +31/-8

Document average aggregation KPI configuration

• Added comprehensive documentation for average aggregation type with weighted scoring
• Updated agg...

@rhdh-qodo-merge rhdh-qodo-merge Bot added enhancement New feature or request Tests labels Apr 26, 2026
@imykhno imykhno changed the title RHIDP-12121: Support "Sum" and "Average" types of aggregation RHIDP-12121: Support "StatusGrouped" and "Average" types of aggregation Apr 26, 2026
imykhno added 4 commits April 27, 2026 09:29
Signed-off-by: Ihor Mykhno <imykhno@redhat.com>
Signed-off-by: Ihor Mykhno <imykhno@redhat.com>
Signed-off-by: Ihor Mykhno <imykhno@redhat.com>
…nagement

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>

@Eswaraiahsapram Eswaraiahsapram left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks @imykhno, tested locally, everything looks good to me 🎉 . Added a few nit comments, PTAL.

Comment thread workspaces/scorecard/plugins/scorecard/src/translations/ref.ts Outdated

@dzemanov dzemanov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you for the PR!
I confirmed test cases:

  1. default / status grouped / deprecated work correctly
Image
  1. average KPI:
Screen.Recording.2026-04-27.at.12.34.54.mov

We should take threshold configuration for aggregation cards from aggregationResultThresholds instead of thresholds in the metric, so the legend colors make sense.

  1. validation of kpis in config fails fast
  2. basic permissions work and conditional permissions work correctly
Image

It would be nice if in config.d.ts if there are different keys for each aggregation configuration (especially when for that configuration they are mandatory), then we don't specify each as optional in the big aggregation config, but have something like:

type AggregationKPIConfig =
  | AverageAggregationKPIConfig
  | StatusGroupedAggregationKPIConfig;

In future users will use UI to define scorecards, for which they define title, description, metricId, thresholds, entity filter, what location.... It looks similar to what we currently have in yaml for aggregationKPIs. Maybe we should have gone with name scorecards.
Right now, thresholds are only supported for aggregation scorecards, we might in future need to support those also for other scorecards defined via yaml. We might in future save scorecard results (aggregation results) in database, right now it is alright to do in runtime.

Comment thread workspaces/scorecard/plugins/scorecard-backend/src/constants/aggregationKPIs.ts Outdated
Comment thread workspaces/scorecard/plugins/scorecard-backend/config.d.ts Outdated
imykhno added 7 commits April 27, 2026 15:42
…tion

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>
…lds` in configuration

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>
…vice files

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>
Signed-off-by: Ihor Mykhno <imykhno@redhat.com>
Signed-off-by: Ihor Mykhno <imykhno@redhat.com>

@christoph-jerolimov christoph-jerolimov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hi @imykhno. Nice work.

I didn't tested it myself but there was already other people that has done that.

I just gone over the diff and here are some comments:

Comment thread workspaces/scorecard/README.md Outdated
Comment thread workspaces/scorecard/.changeset/twenty-trains-fetch.md Outdated
AGGREGATED_CARDS_WIDGET_TITLES.withOpenPrsWeightedKpi,
);
await homePage.saveChanges();
await page.reload();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why is this page.reload needed? Can you please create a bug so that we follow-up. Users should see the right cards and latest data after they save the homepage.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I will create a bug to follow and resolve all your comments related to e2e tests

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The bug was created - link

);

await homePage.navigateToHome();
await page.reload();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why is this needed?

homePage,
AGGREGATED_CARDS_WIDGET_TITLES.withOpenPrsWeightedKpi,
);
await page.reload();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The other comments: why? Can we follow up ok this with a bug please?

Comment on lines +45 to +47
key: z.string(),
expression: z.string(),
color: z.string(),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could probably have stricter types here in the future:

Key min max as the metric id?

Expression validation?

Color validation?

But not now.

Comment thread workspaces/scorecard/plugins/scorecard/__fixtures__/scorecardData.ts Outdated
Comment on lines +209 to +211
componentProps: {
Renderer: BorderlessHomeWidgetRenderer,
},

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why does the card needs a rendered prop. How will this work with mount points or NFS? Can we get rid of this?

If not today please create a bug as well so that we can follow up.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I will create a bug for this comment. Thank you

Comment thread workspaces/scorecard/plugins/scorecard/src/utils/constants.ts Outdated
…average KPI support

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>
imykhno added 5 commits April 28, 2026 10:45
…oded labels

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>
Signed-off-by: Ihor Mykhno <imykhno@redhat.com>
…nfiguration

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>
Signed-off-by: Ihor Mykhno <imykhno@redhat.com>
Signed-off-by: Ihor Mykhno <imykhno@redhat.com>

@Eswaraiahsapram Eswaraiahsapram left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks @imykhno, tested locally, looks good to me 🎉

expectation that Christoph's comments will be resolved via the follow-up bug.

Screen.Recording.2026-04-28.at.4.43.22.PM.mov

Missing Permission

image

Missing permission for github

image

Average

image

Tooltip

image

@dzemanov dzemanov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you.
I will create a follow up bug for:

We should take threshold configuration for aggregation cards from aggregationResultThresholds instead of thresholds in the metric, so the legend colors make sense.

…egationThresholdRule`

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>
@sonarqubecloud

Copy link
Copy Markdown

@imykhno
imykhno merged commit bf72ffc into redhat-developer:main Apr 28, 2026
12 checks passed
@imykhno
imykhno deleted the scorecard-average-as-aggregation-type branch April 28, 2026 12:34
lokanandaprabhu pushed a commit to lokanandaprabhu/rhdh-plugins that referenced this pull request May 14, 2026
…on (redhat-developer#2923)

* feat(scorecard): add `average` aggregation type

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>

* fix(scorecard): average gauge out-of-range

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>

* fix(scorecard): default aggregation threshold value usage

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>

* fix(scorecard): sonarqube issues

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>

* refactor(scorecard): update type definitions for tooltip and state management

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>

* fix(scorecard): update tooltip translations and aggregation configuration

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>

* refactor(scorecard): rename `aggregationResultThresholds` to `thresholds` in configuration

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>

* refactor(scorecard): consolidate AggregationConfig imports across service files

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>

* fix(scorecard): issues after merging main

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>

* feat(scorecard): enhance aggregation KPI configuration with new types

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>

* Revert "feat(scorecard): enhance aggregation KPI configuration with new types"

This reverts commit b264e55.

* refactor(scorecard): update README and aggregation configuration for average KPI support

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>

* feat(scorecard): use the i18n for loading indicators and remove hardcoded labels

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>

* refactor(scorecard): rename `aggregationKinds` to `aggregationTypes`

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>

* feat(scorecard): add detailed documentation for threshold rules in configuration

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>

* feat(scorecard): enhance threshold configuration with aggregation rules

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>

* fix(scorecard): average aggregation card percentage value

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>

* refactor(scorecard): rename `ThresholdRuleAggregationConfig` to `AggregationThresholdRule`

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>

---------

Signed-off-by: Ihor Mykhno <imykhno@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants