Skip to content

Commit 4ad17ce

Browse files
authored
feat: add enriched fields (CM-1285) (#4257)
Signed-off-by: Umberto Sgueglia <usgueglia@contractor.linuxfoundation.org>
1 parent 1a3f3bc commit 4ad17ce

3 files changed

Lines changed: 62 additions & 10 deletions

File tree

backend/src/api/public/v1/packages/getPackage.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,23 @@ export async function getPackage(req: Request, res: Response): Promise<void> {
4040
const scorecardScore = pkg.scorecardScore != null ? Number(pkg.scorecardScore) : null
4141
const mappingConfidence =
4242
pkg.repoMappingConfidence != null ? Number(pkg.repoMappingConfidence) : null
43+
const healthBandScore = pkg.healthScore !== null ? pkg.healthScore / 10 : scorecardScore
4344

4445
ok(res, {
4546
purl: pkg.purl,
4647
name: pkg.name,
4748
ecosystem: pkg.ecosystem,
4849
latestVersion: pkg.latestVersion ?? null,
4950
general: {
50-
healthScore: scorecardScore !== null ? Math.round(scorecardScore * 10) : null,
51-
healthBand: computeHealthBand(scorecardScore),
51+
healthScore: pkg.healthScore,
52+
healthScoreDetails: {
53+
total: pkg.healthScore,
54+
label: pkg.healthLabel,
55+
maintainerHealth: pkg.maintainerHealthScore,
56+
securitySupplyChain: pkg.securitySupplyChainScore,
57+
developmentActivity: pkg.developmentActivityScore,
58+
},
59+
healthBand: computeHealthBand(healthBandScore),
5260
impact: {
5361
impactScore:
5462
pkg.criticalityScore != null ? Math.round(Number(pkg.criticalityScore) * 100) : null,
@@ -58,7 +66,7 @@ export async function getPackage(req: Request, res: Response): Promise<void> {
5866
transitiveReach: pkg.transitiveReach,
5967
},
6068
riskSignals: {
61-
lifecycle: null,
69+
lifecycle: pkg.lifecycleLabel,
6270
maintainerBusFactor: pkg.maintainerCount,
6371
lastRelease: pkg.latestReleaseAt ? pkg.latestReleaseAt.toISOString() : null,
6472
hasSecurityFile: pkg.hasSecurityFile,
@@ -67,6 +75,7 @@ export async function getPackage(req: Request, res: Response): Promise<void> {
6775
openSSFScorecard: scorecardScore,
6876
},
6977
},
78+
signalCoverageHealth: pkg.signalCoverageHealth,
7079
assessment: null,
7180
security: {
7281
securityContacts: null,

backend/src/api/public/v1/packages/openapi.yaml

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -267,10 +267,27 @@ components:
267267
type: object
268268
properties:
269269
healthScore:
270+
type:
271+
- integer
272+
- 'null'
273+
description: Composite health score (0–100). Tinybird-enriched when available, null otherwise.
274+
example: 18
275+
healthScoreDetails:
270276
type:
271277
- object
272278
- 'null'
279+
description: Breakdown of the composite health score. Null until Tinybird enrichment runs.
273280
properties:
281+
total:
282+
type:
283+
- integer
284+
- 'null'
285+
example: 18
286+
label:
287+
type:
288+
- string
289+
- 'null'
290+
example: Good
274291
maintainerHealth:
275292
type:
276293
- integer
@@ -286,11 +303,13 @@ components:
286303
- integer
287304
- 'null'
288305
example: 6
289-
total:
290-
type:
291-
- integer
292-
- 'null'
293-
example: 18
306+
healthBand:
307+
type:
308+
- string
309+
- 'null'
310+
enum: [healthy, fair, concerning, critical, null]
311+
description: Derived from Tinybird health score when available, OpenSSF Scorecard otherwise.
312+
example: concerning
294313
impact:
295314
type:
296315
- object
@@ -466,6 +485,12 @@ components:
466485
history:
467486
type: object
468487
description: Package history data. Empty in v1.
488+
signalCoverageHealth:
489+
type:
490+
- object
491+
- 'null'
492+
description: Signal coverage health data enriched by Tinybird. Null until enriched.
493+
additionalProperties: true
469494

470495
# ── Metrics ──────────────────────────────────────────────────────────────────
471496

@@ -672,11 +697,14 @@ paths:
672697
name: lodash
673698
ecosystem: npm
674699
general:
675-
healthScore:
700+
healthScore: 18
701+
healthScoreDetails:
702+
total: 18
703+
label: critical
676704
maintainerHealth: 4
677705
securitySupplyChain: 8
678706
developmentActivity: 6
679-
total: 18
707+
healthBand: critical
680708
impact:
681709
impactScore: 71
682710
downloadsLastMonth: 52142891

services/libs/data-access-layer/src/osspckgs/api.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,14 @@ export interface PackageDetailRow {
618618
downloadsLast30d: string | null
619619
maintainerCount: number
620620
transitiveReach: number | null
621+
// Tinybird-enriched health fields
622+
healthScore: number | null
623+
healthLabel: string | null
624+
maintainerHealthScore: number | null
625+
securitySupplyChainScore: number | null
626+
developmentActivityScore: number | null
627+
lifecycleLabel: string | null
628+
signalCoverageHealth: Record<string, unknown> | null
621629
}
622630

623631
export interface AdvisoryRow {
@@ -672,6 +680,13 @@ export async function getPackageDetailByPurl(
672680
LIMIT 1
673681
) AS "downloadsLast30d",
674682
(SELECT COUNT(*)::int FROM package_maintainers pm WHERE pm.package_id = p.id) AS "maintainerCount",
683+
p.health_score AS "healthScore",
684+
p.health_label AS "healthLabel",
685+
p.maintainer_health_score AS "maintainerHealthScore",
686+
p.security_supply_chain_score AS "securitySupplyChainScore",
687+
p.development_activity_score AS "developmentActivityScore",
688+
p.lifecycle_label AS "lifecycleLabel",
689+
p.signal_coverage_health AS "signalCoverageHealth",
675690
-- TODO: precompute and store in packages.transitive_reach_prank; full window scan is too slow at npm scale (~24s for npm)
676691
-- (
677692
-- SELECT r.prank

0 commit comments

Comments
 (0)