content-sources-backend

Lightwell vulnerabilities — local development

Lightwell vulnerabilities live in the same backend as the rest of content-sources: database migrations, compose, and tests follow the normal app workflow. This doc covers the lightwell-specific seed data, sqlc store, schema reference, and read API.

Local setup

Use the standard dev environment (see README.md): copy configs/config.yaml.example to configs/config.yaml, then:

make compose-up

If you hit migration issues on an old local DB (e.g. from superseded lightwell migrations during development), reset and re-migrate:

make test-db-migrations

Apply dev seed data

The seed script loads mock vulnerabilities into two demo customers (demo-customer-1, demo-customer-2). Statuses include On Hold and Unremediated. Each Unremediated row stores one supported resolution_reason, and the list API returns the customer explanation for that selection. Two rows set duplicate_of to a canonical vulnerability_id (not present in the mock):

psql "sslmode=disable dbname=content user=content host=localhost port=5433 password=content" -f db/seeds/lightwell_vulnerabilities.sql

Or through the compose postgres container:

docker compose exec -T postgres-content psql "sslmode=disable dbname=content user=content host=localhost port=5432 password=content" -f - < db/seeds/lightwell_vulnerabilities.sql

Adjust connection parameters to match your configs/config.yaml if they differ from the compose defaults.

Advisories and the package mirror are loaded by scripts/create_lightwell_repo.sh after it creates the Pulp repositories and imports them. That script inserts one advisory (and a release row per published_versions entry) only for seed rows whose stage is Lightwell Network, using the vulnerability purl as package_name and component_version as package_version. Java advisories are attached to lightwell/java/remediated or lightwell/java/predisclosure, Python advisories to lightwell/python/remediated or lightwell/python/predisclosure, and JavaScript advisories to lightwell/javascript/remediated. See Lightwell packages:

./scripts/create_lightwell_repo.sh

Read API

With the API running, authenticated clients can call:

customer_id is required on the list and ltwlsupt-ticket-ids endpoints. Filters (severity, status, complexity, ltwlsupt_ticket_id, flag) accept comma-separated values. flag accepts embargo and duplicate (OR). search requires at least 2 characters when provided.

Beacon status mapping

Jira workflow status is stored as a Beacon status. A published fix promotes Validation to Lightwell Network. Once stored, Lightwell Network stays Lightwell Network if a later sync would only move it back to Validation.

Jira status Stored as
New Submitted
Backlog Classified
To Do Classified
In Progress Fix in Progress
Review Fix in Progress
On Hold On Hold
Verified Validation
Release Pending Validation
Released Validation
Closed Validation
Anything else Submitted

Jira resolution can override that, or drop the issue. Won’t Do and Not a Bug are stored as Unremediated with resolution_reason set to the explanation. The database keeps the Jira selection; the list API returns the explanation sentence. Those resolution names are not stored.

Jira resolution Result
Done Stored from the workflow status above. No explanation.
Won’t Do Stored as Unremediated. Explanation comes from Lightwell Closure Reasoning Context. Selection Not a Customer is ignored and the issue is deleted.
Not a Bug Stored as Unremediated. Explanation comes from VEX Justification.
Duplicate Ignored. Deleted if it was stored before.
Obsolete Ignored. Deleted if it was stored before.
Cannot Reproduce Ignored. Deleted if it was stored before.
Won’t Fix Ignored. Deleted if it was stored before.

Ignored resolutions are logged at warning level with the message beacon_ignored_resolution, plus issue, resolution, and detail when the selection is Not a Customer.

Run tests

Integration tests use the configured database and roll back per test:

CONFIG_PATH="$(pwd)/configs/" go test ./pkg/lightwell/db/store/... ./pkg/dao/... ./pkg/handler/...

Or via make (runs all pkg/ tests):

make test-unit

Regenerate sqlc store

After changing pkg/lightwell/db/queries/*.sql or the migration schema:

make sqlc-generate-lightwell

This runs the sqlc version pinned in mk/sqlc.mk (the same pin used by the sqlcdiff CI job). Generated code is written to pkg/lightwell/db/store/.

sqlc uses pkg/lightwell/db/schema.sql (final table snapshot plus lightwell_filtered_vulnerabilities) rather than parsing rename migrations directly. Update that file when the lightwell schema changes. List/count queries share filters through that function because sqlc has no query fragments.