Skip to content

feat(ui): add health score facet to compare page#2348

Closed
hamdibenjarrar wants to merge 7 commits intonpmx-dev:mainfrom
hamdibenjarrar:feat/health-score-facet
Closed

feat(ui): add health score facet to compare page#2348
hamdibenjarrar wants to merge 7 commits intonpmx-dev:mainfrom
hamdibenjarrar:feat/health-score-facet

Conversation

@hamdibenjarrar
Copy link
Copy Markdown
Contributor

@hamdibenjarrar hamdibenjarrar commented Mar 31, 2026

🔗 Linked issue

No linked issue.

🌐 Context

The compare page shows a lot of useful data per package but there's no single signal that summarizes the overall health. I added a Health Score facet to fill that gap.

📝 Description

Added healthScore as a new facet in the compare page. Score goes from 0 to 100, computed from data that npmx already fetches — no external API used.

How it breaks down:

  • Maintenance 35% — days since last publish
  • Quality 30% — types, module format, license, has description
  • Security 20% — vulnerability severity
  • Popularity 15% — weekly downloads

Deprecated packages automatically score 0. Displays as XX/100 with good/warning/bad status colors and a tooltip explaining the score.

Tested locally: react 90/100, vue 97/100, svelte 97/100.

Changes

  • shared/types/comparison.ts — added healthScore to the ComparisonFacet type and FACET_INFO
  • app/composables/usePackageComparison.ts — added exported computeHealthScore() function and wired it into the facet switch
  • app/composables/useFacetSelection.ts — label, description, chartable: true
  • i18n: en, ar-EG, fr-FR translations + schema regenerated
  • Tests for computeHealthScore() covering deprecated, critical vuln, perfect package, no data

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 31, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
npmx.dev Ready Ready Preview, Comment Mar 31, 2026 3:24pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview Mar 31, 2026 3:24pm
npmx-lunaria Ignored Ignored Mar 31, 2026 3:24pm

Request Review

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 31, 2026

Lunaria Status Overview

🌕 This pull request will trigger status changes.

Learn more

By default, every PR changing files present in the Lunaria configuration's files property will be considered and trigger status changes accordingly.

You can change this by adding one of the keywords present in the ignoreKeywords property in your Lunaria configuration file in the PR's title (ignoring all files) or by including a tracker directive in the merged commit's description.

Tracked Files

File Note
i18n/locales/ar-EG.json Localization changed, will be marked as complete.
i18n/locales/en.json Source changed, localizations will be marked as outdated.
i18n/locales/fr-FR.json Localization changed, will be marked as complete.
Warnings reference
Icon Description
🔄️ The source for this localization has been updated since the creation of this pull request, make sure all changes in the source have been applied.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 31, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f36f156c-613f-4462-b88d-2fe06577093f

📥 Commits

Reviewing files that changed from the base of the PR and between 0e24f19 and 4179da3.

📒 Files selected for processing (1)
  • test/nuxt/components/compare/FacetSelector.spec.ts

📝 Walkthrough

Walkthrough

Added a new comparison facet healthScore. Translation keys and JSON schema entries were added for the facet. The ComparisonFacet type and FACET_INFO now include healthScore. useFacetSelection exposes healthScore labels with chartable: true. usePackageComparison was extended with an optional healthScore field, an exported computeHealthScore(data) function (returns 0–100; deprecated packages yield 0), and computeFacetValue gained a healthScore case. Tests and component mocks were updated to include the new facet.

Possibly related PRs

Suggested reviewers

  • danielroe
  • serhalp
🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The pull request description comprehensively describes the changeset, detailing the new healthScore facet, its calculation methodology, implementation locations, and test coverage.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 and usage tips.

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 31, 2026

Codecov Report

❌ Patch coverage is 86.84211% with 5 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
app/composables/usePackageComparison.ts 86.84% 4 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/composables/usePackageComparison.ts (1)

161-166: ⚠️ Potential issue | 🟠 Major

description is never populated, so the +10 quality bonus in computeHealthScore is unreachable.

Line 372 awards +10 quality points when data.package.description is truthy, but here description is explicitly set to undefined. The packument typically contains a description field at the root level, so this should be wired up.

🐛 Proposed fix
             return {
               package: {
                 name: pkgData.name,
                 version: latestVersion,
-                description: undefined,
+                description: pkgData.description,
               },
🧹 Nitpick comments (2)
test/nuxt/composables/use-package-comparison.spec.ts (2)

145-168: "Perfect package" test omits description, leaving the +10 quality bonus untested.

The computeHealthScore function awards +10 quality points when data.package.description is truthy (line 372 in usePackageComparison.ts). This test intends to verify a "perfect" package but the makeData() override doesn't include a description field, so that scoring path is never exercised.

Consider adding description to the package object to truly test the perfect-score scenario:

🔧 Suggested fix
       const score = computeHealthScore(
         makeData({
+          package: { name: 'test', version: '1.0.0', description: 'A test package' },
           metadata: {
             lastUpdated: new Date().toISOString(),
             license: 'MIT',
           },

132-138: Consider hoisting makeData outside the describe block.

The static analysis correctly flags that makeData doesn't capture any variables from its parent scope. Moving it to module level (or at least outside the inner describe) would satisfy the linter and make it reusable for additional test cases.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b6ba5fff-6609-4994-a829-462c5c89a1a3

📥 Commits

Reviewing files that changed from the base of the PR and between a54def4 and e95160e.

📒 Files selected for processing (9)
  • app/composables/useFacetSelection.ts
  • app/composables/usePackageComparison.ts
  • i18n/locales/ar-EG.json
  • i18n/locales/en.json
  • i18n/locales/fr-FR.json
  • i18n/schema.json
  • shared/types/comparison.ts
  • test/nuxt/components/compare/FacetSelector.spec.ts
  • test/nuxt/composables/use-package-comparison.spec.ts

@hamdibenjarrar hamdibenjarrar changed the title feat(compare): add health score facet feat(ui): add health score facet to compare page Mar 31, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
test/nuxt/composables/use-package-comparison.spec.ts (1)

131-137: Consider moving makeData to module level.

The helper doesn't capture any variables from its enclosing scope, so it could be hoisted to module level for clearer organisation and to resolve the linter warning.

♻️ Proposed refactor

Move the helper above the describe('usePackageComparison') block:

+function makeData(overrides: Partial<PackageComparisonData> = {}): PackageComparisonData {
+  return {
+    package: { name: 'test', version: '1.0.0' },
+    directDeps: 2,
+    ...overrides,
+  }
+}
+
 describe('usePackageComparison', () => {
   afterEach(() => {
     vi.unstubAllGlobals()
   })
   // ...
-  function makeData(overrides: Partial<PackageComparisonData> = {}): PackageComparisonData {
-    return {
-      package: { name: 'test', version: '1.0.0' },
-      directDeps: 2,
-      ...overrides,
-    }
-  }

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0524525e-682f-4b29-9d4b-4fa85c8af851

📥 Commits

Reviewing files that changed from the base of the PR and between e95160e and daf3b28.

📒 Files selected for processing (2)
  • app/composables/usePackageComparison.ts
  • test/nuxt/composables/use-package-comparison.spec.ts

Copy link
Copy Markdown
Contributor Author

@hamdibenjarrar hamdibenjarrar left a comment

Choose a reason for hiding this comment

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

fixed

@MatteoGabriele
Copy link
Copy Markdown
Member

This is your second PR related to the health score, and the second time you've submitted an automated PR.
Please review the existing discussion on this issue here #1099, engage with other contributors, and once everything is settled, create a PR with your own code and description.

AI assistance is permitted, but automation is not allowed in this project.

@MatteoGabriele MatteoGabriele added the automation This PR might have been created by an AI, which goes against our code of conduct. label Mar 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automation This PR might have been created by an AI, which goes against our code of conduct.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants