Skip to content

feat: stewardship api unmock (CM-1218)#4195

Open
ulemons wants to merge 2 commits into
feat/backfill-stewardship-scriptfrom
feat/stewardship-api-unmock
Open

feat: stewardship api unmock (CM-1218)#4195
ulemons wants to merge 2 commits into
feat/backfill-stewardship-scriptfrom
feat/stewardship-api-unmock

Conversation

@ulemons

@ulemons ulemons commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Removes all mock implementations from the 4 packages public API endpoints and replaces them with real queries against the packages DB. Also lands the stewardship schema migration and a backfill script to seed one unassigned stewardship row per critical package.

Changes

  • Stewardship schema — migration V1781094067__stewardship-tables.sql creates stewardships, stewardship_stewards, stewardship_activity, stewardship_assessments, stewardship_findings, stewardship_remediation_actions; in v1 only stewardships is populated
  • Backfill script — packages_worker/src/bin/stewardship-backfill.ts + runStewardshipBackfill — cursor-based idempotent batch job that inserts one unassigned row per critical package; re-checks is_critical at insert time, safe to re-run
  • DAL — new data-access-layer/src/osspckgs/api.ts with 5 query functions (getPackageMetrics, getPackagesByStewardshipPurls, listPackagesForApi, getPackageDetailByPurl, getAdvisoriesByPackageId); includes LATERAL join on package_repos+repos for scorecard/security/repo fields and subquery on downloads_last_30d
  • Backend config — CROWD_PACKAGES_DB_* env vars mapped in custom-environment-variables.json; lazy promise based singleton in backend/src/db/packagesDb.ts (race-safe: caches the in-flight Promise, not the resolved value)
  • API endpoints — all 4 endpoints (GET /packages/metrics, GET /packages, POST /packages:batch-stewardship, GET /packages/detail) now read from the real packages DB; v2 fields (healthScore, lifecycle, maintainerBusFactor, openVulns, stewards) remain null by design until future enrichers populate them
  • Field notes — packages.impact is the renamed criticality_score (migration V1780589607); packages.dependent_count is the renamed dependent_packages_count (migration V1780394591)

Type of change

  • Bug fix
  • New feature
  • Refactor / cleanup
  • Performance improvement
  • Chore / dependency update
  • Documentation

JIRA ticket

ticket


Note

Medium Risk
New required DB dependency and changed list/filter semantics for lifecycle and bus-factor; security/advisory data now comes from live queries.

Overview
Wires the public packages/stewardship API to the packages database instead of in-memory mocks, via CROWD_PACKAGES_DB_* config and a lazy getPackagesQx() connection helper.

Adds osspckgs/api DAL queries for metrics, paginated critical-package listing (with stewardships join, stale/unstewarded filters, impact/name sort), batch stewardship by PURL, package detail (repo lateral join, downloads subquery), and advisories. Handlers map DB fields (e.g. impact → impact score, stewardship status defaulting to unassigned) and leave v2 response fields null (health, lifecycle, openVulns, stewards, etc.) where the DB does not yet supply them.

List endpoint behavior change: lifecycle and busFactor1Only are still accepted in query params but are no longer applied in the new DB path (only ecosystem, stale, unstewarded, sort). getPackage moves PURL validation into Zod instead of a manual BadRequestError.

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

ulemons added 2 commits June 10, 2026 20:24
Signed-off-by: Umberto Sgueglia <usgueglia@contractor.linuxfoundation.org>
Signed-off-by: Umberto Sgueglia <usgueglia@contractor.linuxfoundation.org>
Copilot AI review requested due to automatic review settings June 10, 2026 18:37
@ulemons ulemons self-assigned this Jun 10, 2026

@github-actions github-actions Bot 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.

Conventional Commits FTW!

@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 2 potential issues.

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 2d2aa85. Configure here.

if (unstewardedOnly && p.stewardship !== 'unassigned') return false
if (staleOnly) {
const lastRelease = MOCK_DETAILS[p.purl]?.general.riskSignals.lastRelease
if (!lastRelease || new Date(lastRelease) >= staleThreshold) return false

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Ignored list query filters

Medium Severity

GET /packages still validates and echoes lifecycle and busFactor1Only, but those values are no longer passed into listPackagesForApi, so results stay unfiltered while the response filters object implies they were applied.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 2d2aa85. Configure here.


// health, openVulns are v2 fields — fall back to name sort
const sortExpr = opts.sortBy === 'impact' ? 'p.impact' : 'LOWER(p.name)'
const sortDir = opts.sortDir === 'desc' ? 'DESC' : 'ASC'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sort metadata does not match

Medium Severity

When sortBy is health or openVulns, the query orders by package name, yet listPackages still returns the requested sortBy in the response sort field.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 2d2aa85. Configure here.

@ulemons ulemons changed the title Feat/stewardship api unmock feat: stewardship api unmock (CM-1218) Jun 10, 2026

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

This PR wires the public v1 Packages/Stewardship API endpoints to the real packages-db (instead of in-memory mocks) by introducing a packages DB connection helper in the backend and a new DAL module (osspckgs/api) that queries package metrics, listings, detail, advisories, and batch stewardship rows.

Changes:

  • Add packagesDb config/env wiring (CROWD_PACKAGES_DB_*) and a lazy getPackagesQx() connection helper.
  • Add new DAL query module services/libs/data-access-layer/src/osspckgs/api.ts and export it through DAL entrypoints.
  • Update public API handlers (/packages, /packages/metrics, /packages/detail, /packages:batch-stewardship) to fetch from the packages DB and return v1 responses (with several v2 fields intentionally null).

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
services/libs/data-access-layer/src/osspckgs/index.ts Re-export new OSS packages DAL API module.
services/libs/data-access-layer/src/osspckgs/api.ts Introduce SQL queries backing metrics, list, detail, advisories, and batch stewardship lookup.
services/libs/data-access-layer/src/index.ts Export new DAL API module from the package root.
backend/src/db/packagesDb.ts Add lazy, singleton-style packages DB QueryExecutor initializer.
backend/src/conf/index.ts Add PACKAGES_DB_CONFIG configuration entry.
backend/src/api/public/v1/packages/listPackages.ts Replace mock listing logic with DAL-backed pagination and mapping.
backend/src/api/public/v1/packages/getPackagesMetrics.ts Replace mock metrics with DAL-backed metrics query.
backend/src/api/public/v1/packages/getPackage.ts Replace mock detail response with DB-backed package + advisories fetch and response mapping.
backend/src/api/public/v1/packages/batchGetStewardship.ts Replace mock batch stewardship with DB-backed lookup keyed by PURL.
backend/config/custom-environment-variables.json Map packagesDb config to CROWD_PACKAGES_DB_* environment variables.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +44 to 53
const qx = await getPackagesQx()
const { rows, total } = await listPackagesForApi(qx, {
page,
pageSize,
ecosystem,
staleOnly,
unstewardedOnly,
sortBy,
sortDir,
})
openVulns: null,
stewardship: (r.stewardshipStatus ?? 'unassigned') as StewardshipStatus,
stewards: null,
}))
Comment on lines +117 to +118
ORDER BY ${sortExpr} ${sortDir} NULLS LAST
LIMIT $(limit) OFFSET $(offset)
Comment on lines +8 to +18
export function getPackagesQx(): Promise<QueryExecutor> {
if (!_init) {
if (!PACKAGES_DB_CONFIG) {
throw new Error(
'Packages DB is not configured — set CROWD_PACKAGES_DB_* environment variables',
)
}
_init = getDbConnection(PACKAGES_DB_CONFIG).then(pgpQx)
}
return _init
}
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.

2 participants