Skip to content

Fixes: latestKpiResult returns most recent bucket, not the partial leading one#30166

Open
ulixius9 wants to merge 1 commit into
mainfrom
georgetown
Open

Fixes: latestKpiResult returns most recent bucket, not the partial leading one#30166
ulixius9 wants to merge 1 commit into
mainfrom
georgetown

Conversation

@ulixius9

@ulixius9 ulixius9 commented Jul 17, 2026

Copy link
Copy Markdown
Member

Describe your changes:

Fixes #

I fixed /api/v1/kpi/{fqn}/latestKpiResult returning 0.0 while the day-aligned /kpiResult time series correctly showed the real value (e.g. 0.68). KpiRepository.getKpiResult() (and the bulk fetchAndSetKpiResults() path) aggregated a trailing 24h window and took results.get(0) — but that window straddles two day buckets and the first/oldest one is a partial fragment that aggregates to 0.0. I introduced a shared getMostRecentResult() helper that selects the most recent bucket via getLast() and routed both call sites through it.

Type of change:

  • Bug fix

High-level design:

N/A — small change.

Tests:

Use cases covered

  • latestKpiResult for a KPI now returns the most recent day's value instead of the partial leading bucket's 0.0.

Unit tests

  • Added openmetadata-service/src/test/java/org/openmetadata/service/jdbi3/KpiRepositoryTest.java
    • latestResultUsesMostRecentBucketNotFirst — asserts the newest bucket (0.68) is chosen over the leading 0.0 bucket (fails against the old get(0) logic).
    • latestResultReturnsNullWhenNoBuckets — null/empty guard.

Backend integration tests

  • Not applicable (no API contract change; existing KpiResourceIT still covers the endpoint).

Manual testing performed

Reproduced via curl against a live instance: latestKpiResult returned 0.0 and equalled kpiResult(now-24h, now).results[0], while results[-1] held the correct 0.68; polling confirmed it was structural, not a transient reindex.

UI screen recording / screenshots:

Not applicable.

Checklist:

  • I have read the CONTRIBUTING document.
  • I have added a test that covers the exact scenario we are fixing.

Greptile Summary

This PR changes KPI lookup to select the final result bucket. The main changes are:

  • Adds a shared helper for selecting the final chart result.
  • Uses the helper in single and bulk KPI result paths.
  • Adds tests for ascending buckets and empty results.

Confidence Score: 4/5

The changed result-selection path can return an unrelated term bucket or an incomplete current-day bucket.

  • The helper works for the ascending two-bucket fixture.
  • Non-timestamp charts do not give list position a recency meaning.
  • A trailing partial day can still replace the latest completed value with zero or null.

openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/KpiRepository.java

Important Files Changed

Filename Overview
openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/KpiRepository.java Centralizes final-bucket selection, but applies positional ordering to non-temporal and incomplete temporal results.
openmetadata-service/src/test/java/org/openmetadata/service/jdbi3/KpiRepositoryTest.java Covers ascending temporal buckets and empty inputs, but not non-temporal charts or an incomplete trailing bucket.

Reviews (1): Last reviewed commit: "fix(kpi): latestKpiResult returns most r..." | Re-trigger Greptile

Greptile also left 2 inline comments on this PR.

Context used:

  • Context used - CLAUDE.md (source)
  • Context used - AGENTS.md (source)

… leading one

getKpiResult() and fetchAndSetKpiResults() computed the "latest" KPI value by
aggregating a trailing 24h window and taking results.get(0). That window straddles
two day buckets and the first (oldest) bucket is a partial fragment that aggregates
to 0.0, so /latestKpiResult reported 0.0 while the day-aligned /kpiResult series
correctly showed the real value. Select the most recent bucket (getLast()) via a
shared getMostRecentResult() helper instead.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 17, 2026 07:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions

Copy link
Copy Markdown
Contributor

❌ PR checklist incomplete

This PR cannot be merged until the following are addressed on its linked issue:

  • No GitHub issue is linked. Link an issue in the Development section of the PR (or add Fixes #12345 to the description). For a same-org cross-repo issue, add Fixes open-metadata/<repo>#123 to the description.

The fields live on the linked issue in the Shipping project (open the issue → right sidebar → Projects). After you set them, re-run this check (or push a commit) — issue/project changes do not re-trigger it automatically.

Maintainers can bypass this check by adding the skip-pr-checks label.

@github-actions github-actions Bot added Ingestion safe to test Add this label to run secure Github workflows on PRs labels Jul 17, 2026
@gitar-bot

gitar-bot Bot commented Jul 17, 2026

Copy link
Copy Markdown
Code Review ✅ Approved

Updates latestKpiResult logic to select the most recent bucket via a shared helper, ensuring accurate value retrieval instead of returning partial leading fragments. Unit tests confirm the fix for the reported aggregation issue.

Options

Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@sonarqubecloud

Copy link
Copy Markdown

@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

🟡 Playwright Results — all passed (27 flaky)

✅ 4542 passed · ❌ 0 failed · 🟡 27 flaky · ⏭️ 95 skipped

Shard Passed Failed Flaky Skipped
🟡 Shard 1 436 0 4 16
✅ Shard 2 11 0 0 0
🟡 Shard 3 822 0 10 8
🟡 Shard 4 819 0 3 18
🟡 Shard 5 839 0 1 5
🟡 Shard 6 787 0 1 46
🟡 Shard 7 828 0 8 2
🟡 27 flaky test(s) (passed on retry)
  • Features/CustomizeDetailPage.spec.ts › Database Schema - customization should work (shard 1, 1 retry)
  • Flow/Metric.spec.ts › Metric creation flow should work (shard 1, 1 retry)
  • Pages/Lineage/LineageRightPanel.spec.ts › Verify custom properties tab IS visible for supported type: metric (shard 1, 1 retry)
  • Flow/SearchRBAC.spec.ts › the browse tree only shows the asset-type categories a user can access (shard 1, 1 retry)
  • Features/BulkEditEntity.spec.ts › Table (shard 3, 1 retry)
  • Features/BulkEditOperationBadges.spec.ts › Database service bulk edit search filters rows and clear restores them (shard 3, 1 retry)
  • Features/BulkImportWithDotInName.spec.ts › Bulk edit existing entity with dot in service name (shard 3, 1 retry)
  • Features/ContextCenterArchive.spec.ts › archive page lazy-loads more rows on scroll within its own scroll container (shard 3, 1 retry)
  • Features/ContextCenterArticles.spec.ts › Article listing search filters, clears, and shows empty state (shard 3, 1 retry)
  • Features/ContextCenterArticles.spec.ts › Quick link created from API can be opened and deleted from hierarchy (shard 3, 1 retry)
  • Features/ContextCenterArticles.spec.ts › Article list cards, recently viewed widget, and pagination work (shard 3, 1 retry)
  • Features/ContextCenterArticles.spec.ts › description: switching articles does not bleed unsaved content into next article (shard 3, 1 retry)
  • Features/ContextCenterMemories.spec.ts › Shared memory shows the shared-with-specific-people description (shard 3, 1 retry)
  • Features/ExploreUrlState.spec.ts › reloading the page preserves composed filters (shard 3, 1 retry)
  • Features/Glossary/GlossaryTermRelationsGraphNested.spec.ts › viewing a child term: parent appears as a 1-hop neighbour via parentOf edge (shard 4, 2 retries)
  • Features/Glossary/GlossaryTermRelationsGraphNested.spec.ts › viewing a child term: parentOf edge is rendered between parent and child (shard 4, 1 retry)
  • Features/IncidentManager.spec.ts › Complete Incident lifecycle with table owner (shard 4, 1 retry)
  • Flow/PersonaFlow.spec.ts › Set default persona for team should work properly (shard 5, 1 retry)
  • Pages/ExplorePageRightPanel_KnowledgeCenter.spec.ts › Should remove user owner for knowledgeCenter (shard 6, 1 retry)
  • Pages/GlossaryImportExport.spec.ts › Glossary Bulk Import Export (shard 7, 1 retry)
  • Pages/GlossaryImportExport.spec.ts › Import partial success - some terms pass, some fail (shard 7, 1 retry)
  • Pages/InputOutputPorts.spec.ts › Output ports section collapse/expand (shard 7, 1 retry)
  • Pages/Lineage/LineageFilters.spec.ts › Verify Impact Analysis service filter selection (shard 7, 1 retry)
  • Pages/Lineage/LineageRightPanel.spec.ts › Verify custom properties tab is NOT visible for pipelineService in platform lineage (shard 7, 1 retry)
  • Pages/Lineage/LineageRightPanel.spec.ts › Verify custom properties tab is NOT visible for apiService in platform lineage (shard 7, 1 retry)
  • Pages/ServiceListing.spec.ts › should render the service listing page (shard 7, 1 retry)
  • Pages/TestSuite.spec.ts › Logical TestSuite (shard 7, 1 retry)

📦 Download artifacts

How to debug locally
# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip    # view trace

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

Labels

Ingestion safe to test Add this label to run secure Github workflows on PRs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants