Skip to content

feat: add covered-category-count and capped max-score fields for partial health scores (IN-1262) - #4548

Merged
gaspergrom merged 10 commits into
mainfrom
feat/IN-1262-partial-health-score
Sep 2, 2026
Merged

feat: add covered-category-count and capped max-score fields for partial health scores (IN-1262)#4548
gaspergrom merged 10 commits into
mainfrom
feat/IN-1262-partial-health-score

Conversation

@gaspergrom

@gaspergrom gaspergrom commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds coveredCategoryCount (0-3) and healthMaxScore (60/65/75/100) to the Tinybird pipe chain — project_insights_copy_ds.datasourceproject_insights_copy.pipeproject_insights.pipe, plus the two sink pipes — so a project missing exactly one Health Score v2 category (Maintainer 40 / Security & Supply Chain 35 / Development Activity 25) carries a single source-of-truth capped denominator and coverage count, instead of Insights, LFX One, and the Health Score Badge each recomputing the "- Partial" logic independently.
  • healthMaxScore is null when fewer than 2 categories are covered (mirrors the existing healthScoreV2 null guard), 100 when all 3 are covered, otherwise 100 minus the weight of the one missing category.
  • The korg project override in project_insights_copy.pipe explicitly nulls both new fields, matching how it already nulls other v2 fields for that slug.
  • Repo-level records in project_insights_copy.pipe get both fields hardcoded to NULL — coverage/partial scoring is a project-level concept only.
  • Also un-comments and activates the previously-inert EXPORT_SCHEDULE cron on health_score_v2_sink.pipe (was @on-demand-only pending stakeholder sign-off, now runs daily at 03:35 UTC — after project_insights_copy_ds's 03:00 refresh — and threads the two new fields through both health_score_sink.pipe and health_score_v2_sink.pipe.
  • healthLabel in project_insights_copy.pipe and avgHealthScore in collection_insights_aggregate_projects_copy_pipe.pipe both bucket/average the score normalized to healthScoreV2 * 100.0 / healthMaxScore rather than the raw capped score, so a partial score (e.g. 45/60) benchmarks consistently as its full-scale equivalent (75/100) at both the project and collection level.
  • Does not change how healthScoreV2 itself is computed, and does not touch the Insights/LFX One/Health Score Badge consumers — those are separate companion PRs.

Changes

File What changed
services/libs/tinybird/datasources/project_insights_copy_ds.datasource Adds coveredCategoryCount and healthMaxScore Nullable(UInt8) columns + doc comments
services/libs/tinybird/pipes/project_insights_copy.pipe Computes both fields from the same category-presence checks the healthScoreV2 guard uses; nulls them for korg and for repo records
services/libs/tinybird/pipes/project_insights.pipe Exposes both fields on the public project_insights endpoint, with doc comment
services/libs/tinybird/pipes/health_score_sink.pipe Adds covered_category_count_v2 / health_max_score_v2 to the sink output
services/libs/tinybird/pipes/health_score_v2_sink.pipe Activates the daily EXPORT_SCHEDULE at 03:35 UTC (was on-demand only) and adds coveredCategoryCount / healthMaxScore to the sink output
services/libs/tinybird/pipes/collection_insights_aggregate_projects_copy_pipe.pipe Normalizes avgHealthScore to healthScoreV2 * 100.0 / healthMaxScore before averaging, to stay consistent with the project-level healthLabel normalization

JIRA

IN-1262 — Implement Partial Health Score labels and capped totals for projects with 1 missing category

This is crowd.dev's slice of a cross-repo ticket. Companion PRs exist in insights, lfx-self-serve, and lf-dbt to consume these fields for the "- Partial" label and capped total display.

Deploy order

  1. This PR (crowd.dev Tinybird pipes) deploys first — already done and QA'd against live production Tinybird.
  2. insights, lfx-self-serve, and lf-dbt companion PRs deploy after, since their features read coveredCategoryCount/healthMaxScore from these pipes and are not testable end-to-end until this is live.

Test plan

  • Deployed to production Tinybird and validated against live data (coverage counts and capped denominators match expected values for projects missing one category)
  • Confirm korg project still returns null for both new fields after deploy
  • Confirm repo-type records in project_insights_copy.pipe return null for both fields
  • Confirm the health_score_v2_sink.pipe daily export runs at 03:35 UTC without error on its first scheduled fire

Checklist

  • git commit --signoff -S on every commit
  • MIT license header on every new source file (no new files — existing pipes/datasource modified)
  • PR diff < 1000 lines (48 lines)
  • No unrelated changes bundled
  • Cross-repo impact documented above (insights, lfx-self-serve, lf-dbt)

…ial health scores (IN-1262)

Signed-off-by: Gašper Grom <gasper.grom@gmail.com>
…262)

Mirrors the existing healthScoreV2/healthLabel korg override (IN-1244) so a
project with no displayable overall score never gets a populated partial-score
denominator either.

Signed-off-by: Gašper Grom <gasper.grom@gmail.com>
…N-1262)

Sum of three IS NOT NULL boolean checks infers as Nullable(UInt32) in
ClickHouse, which Tinybird rejects against the Nullable(UInt8) schema
column. Already validated and live in production; committing the fix
to keep the branch in sync with the deployed pipe.

Signed-off-by: Gašper Grom <gasper.grom@gmail.com>
…endpoint (IN-1262)

Insights frontend reads project detail data through this pipe, not
project_insights_copy_ds directly, so the two new partial-health-score
columns need to be forwarded here before the frontend can consume them.

Signed-off-by: Gašper Grom <gasper.grom@gmail.com>
Copilot AI balanced review requested due to automatic review settings September 1, 2026 16:08
@cursor

cursor Bot commented Sep 1, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Changes published health labels and collection averages for partial scores and enables a daily v2 Kafka export; downstream apps must deploy after this to consume the new fields safely.

Overview
Adds coveredCategoryCount and healthMaxScore to the Tinybird project-insights pipeline so partial Health Score v2 (one missing category) has a single capped denominator (60/65/75) and coverage count at the data layer, for downstream “Partial” UI without duplicating logic.

project_insights_copy.pipe computes both from the same category-presence rules as healthScoreV2, nulls them for korg and repo rows, and re-buckets healthLabel using healthScoreV2 * 100 / healthMaxScore instead of the raw capped points. Collection avgHealthScore uses the same normalization before averaging.

The fields flow through project_insights_copy_ds, project_insights.pipe, project_repo_insights.pipe, and Kafka sinks health_score_sink / health_score_v2_sink. health_score_v2_sink is scheduled daily at 03:35 UTC (after the 03:00 insights copy) instead of the prior on-demand-only setup; healthScoreV2 computation is unchanged.

Reviewed by Cursor Bugbot for commit e7c2e7c. Bugbot is set up for automated code reviews on this repo. Configure here.

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.

Pull request overview

Adds project-level Health Score v2 coverage counts and capped maximum scores for downstream consumers.

Changes:

  • Computes and stores category coverage and maximum score.
  • Exposes fields through project insights and Kafka sink output.
  • Documents the scheduled Health Score v2 export.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
project_insights.pipe Exposes the new fields.
project_insights_copy.pipe Computes project values and nulls unsupported records.
health_score_v2_sink.pipe Updates export schedule documentation.
health_score_sink.pipe Adds fields to Kafka output.
project_insights_copy_ds.datasource Adds nullable storage columns.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread services/libs/tinybird/pipes/health_score_v2_sink.pipe Outdated

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 7140994. Configure here.

Comment thread services/libs/tinybird/pipes/project_insights.pipe
project_repo_insights.pipe (serving the Collections page) was missing
the two fields project_insights.pipe already exposes for the partial
Health Score v2 treatment, so Collections never received the data
needed to render the capped denominator or partial label suffix.

Signed-off-by: Gašper Grom <gasper.grom@gmail.com>
Copilot AI review requested due to automatic review settings September 1, 2026 18:15

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.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Suppressed comments (1)

services/libs/tinybird/pipes/health_score_v2_sink.pipe:3

  • The 00:35 export runs before both inputs it publishes: project_insights_impact_breakdown_copy.pipe refreshes at 02:40 and project_insights_copy.pipe refreshes at 03:00. This can emit the previous day's health and impact snapshot; the existing dependency documentation explicitly identifies 03:30 as the intended sink time. Please schedule this after 03:00 (for example, EXPORT_SCHEDULE 35 3 * * *). Also, because the cron directive itself is unchanged in this diff, this edit only updates the comment rather than activating the export as the PR description claims.
    -- Live and scheduled: EXPORT_SCHEDULE below runs this daily at 00:35 UTC.

Comment thread services/libs/tinybird/datasources/project_insights_copy_ds.datasource Outdated
Comment thread services/libs/tinybird/pipes/project_repo_insights.pipe Outdated
… (IN-1262)

healthLabel now buckets healthScoreV2 * 100.0 / healthMaxScore against the
85/70/50/30 thresholds instead of the raw capped score, so partial scores
benchmark on the same scale as full ones. Also reschedules the Kafka sink
export to 03:35 UTC so it runs after project_insights_copy_ds's refresh and
picks up the corrected labels.

Signed-off-by: Gašper Grom <gasper.grom@gmail.com>
Copilot AI review requested due to automatic review settings September 2, 2026 09:28

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.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Comment thread services/libs/tinybird/pipes/project_insights_copy.pipe
Comment thread services/libs/tinybird/pipes/health_score_v2_sink.pipe
Comment thread services/libs/tinybird/pipes/health_score_v2_sink.pipe
… avgHealthScore (IN-1262)

avgHealthScore now averages each project's healthScoreV2 * 100.0 /
healthMaxScore instead of the raw capped score, so a partial score
contributes its full-scale equivalent to the collection average rather
than a disadvantaged raw value. Confirmed with product (Joana Maia) that
partial scores should be treated as if they weren't partial.

Signed-off-by: Gašper Grom <gasper.grom@gmail.com>
Copilot AI review requested due to automatic review settings September 2, 2026 09:36

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.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Suppressed comments (3)

services/libs/tinybird/pipes/health_score_v2_sink.pipe:42

  • The diff reschedules an already-active export from 00:35 to 03:35; it does not activate an inert @on-demand sink as the PR description states, and the test plan still expects 00:35. Align the documented rollout/test expectation with the intended cron before merge.
EXPORT_SCHEDULE 35 3 * * *

services/libs/tinybird/pipes/project_repo_insights.pipe:16

  • This combined endpoint also returns repository records, but both new fields are hardcoded to NULL for repositories. State that these semantics apply only to project records so API consumers do not expect repository coverage values.
    - `coveredCategoryCount` (0-3) and `healthMaxScore` (60/65/75/100, IN-1262) describe a partial Health Score v2: `healthMaxScore` is the capped denominator when exactly one category is missing (2 of 3 covered), 100 when all 3 are covered, and null when fewer than 2 are covered (same guard as `healthScoreV2`).

services/libs/tinybird/pipes/project_insights_copy.pipe:245

  • This changes project healthLabel semantics for every two-category project (for example, 45/60 moves from fair to healthy), but the PR description says consumer behavior is unchanged and neither lists nor tests this relabeling. Please either remove this scope or document and validate the behavior before merge.
            (hv2.healthScoreV2 * 100.0 / hv2.healthMaxScore) >= 85,

Adds coveredCategoryCount and healthMaxScore to health_score_v2_sink.pipe's
SELECT, matching health_score_sink.pipe and the PR description. Fixes the
healthMaxScore doc comment's denominator wording on project_insights_copy_ds
and scopes the coveredCategoryCount/healthMaxScore doc on
project_repo_insights.pipe to project records only.

Signed-off-by: Gašper Grom <gasper.grom@gmail.com>
Copilot AI review requested due to automatic review settings September 2, 2026 11:25

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.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Suppressed comments (1)

services/libs/tinybird/pipes/health_score_v2_sink.pipe:26

  • EXPORT_FORMAT csv emits headerless positional rows, so inserting these fields here immediately shifts every existing impact/date column for the current Kafka consumer. This conflicts with the documented producer-first rollout: append the new fields after the existing date column (and coordinate the rollout if the consumer rejects extra fields) so existing positions retain their meaning.
        p.coveredCategoryCount AS coveredCategoryCount,
        p.healthMaxScore AS healthMaxScore,

Comment on lines 13 to 16
p.healthScoreV2 as overall_score_v2,
p.coveredCategoryCount as covered_category_count_v2,
p.healthMaxScore as health_max_score_v2,
toStartOfDay(now()) as date
Comment on lines +3 to +5
-- Live and scheduled: EXPORT_SCHEDULE below runs this daily at 03:35 UTC,
-- after project_insights_copy_ds's 03:00 refresh and the impact breakdown's
-- 02:40 refresh (see project_insights_impact_breakdown_copy.pipe).
Comment on lines +234 to +239
-- healthLabel buckets the score NORMALIZED to /100 (healthScoreV2 * 100 / healthMaxScore),
-- not the raw capped healthScoreV2 - so a partial score like 45/60 benchmarks as its
-- full-scale equivalent 75/100 ('healthy'), not the raw 45 ('fair') (IN-1262, per product
-- decision - see collection_insights_aggregate_projects_copy_pipe.pipe for the same rule
-- applied to the Collections average). healthMaxScore is 100 when all 3 categories are
-- covered, so this is a no-op for non-partial scores.
Copilot AI review requested due to automatic review settings September 2, 2026 14:41
@gaspergrom
gaspergrom merged commit 6cfef46 into main Sep 2, 2026
15 checks passed
@gaspergrom
gaspergrom deleted the feat/IN-1262-partial-health-score branch September 2, 2026 14:42

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.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Suppressed comments (2)

services/libs/tinybird/pipes/project_insights_copy.pipe:239

  • This six-line block narrates the expression immediately below it. Repository guidance prohibits comments that merely explain what code does and limits allowed comments to two lines; the healthMaxScore name and pipe DESCRIPTION already capture this behavior, so remove this block.
        -- healthLabel buckets the score NORMALIZED to /100 (healthScoreV2 * 100 / healthMaxScore),
        -- not the raw capped healthScoreV2 - so a partial score like 45/60 benchmarks as its
        -- full-scale equivalent 75/100 ('healthy'), not the raw 45 ('fair') (IN-1262, per product
        -- decision - see collection_insights_aggregate_projects_copy_pipe.pipe for the same rule
        -- applied to the Collections average). healthMaxScore is 100 when all 3 categories are
        -- covered, so this is a no-op for non-partial scores.

services/libs/tinybird/pipes/health_score_v2_sink.pipe:5

  • The scheduling-order invariant is a valid comment, but repository guidance limits allowed comments to two lines. Condense this three-line note while retaining the reason for the ordering.
    -- Live and scheduled: EXPORT_SCHEDULE below runs this daily at 03:35 UTC,
    -- after project_insights_copy_ds's 03:00 refresh and the impact breakdown's
    -- 02:40 refresh (see project_insights_impact_breakdown_copy.pipe).

Comment on lines +43 to +44
- `coveredCategoryCount` column (0-3) is the count of the three health-v2 categories (maintainer, security, development) with a non-null score. Project records only; null for repo records.
- `healthMaxScore` column is the capped denominator for a partial `healthScoreV2` (e.g. 65, not 100, when Security & Supply Chain is the one missing category — `healthScoreV2` is then out of 65). Null when `coveredCategoryCount` < 2, 100 when all 3 categories are covered. Project records only; null for repo records.
EXPORT_SERVICE kafka
EXPORT_CONNECTION_NAME lfx-oracle-kafka-streaming
EXPORT_SCHEDULE 35 0 * * *
EXPORT_SCHEDULE 35 3 * * *
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.

3 participants