Package manager detection: Extract ecosystem from PURL (pkg:npm/... → npm, pkg:cargo/... → cargo) instead of using CycloneDX type field which was returning "library"/"file" for everything
Lock file generation: Auto-generate Cargo.lock, package-lock.json, and requirements.txt before Syft scan for repos that gitignore their lock files
License resolution: Enable Syft remote license lookups for Go/JS/Python/Java, enrich Cargo via cargo metadata, and parse SPDX license expressions
Dynamic filter dropdowns: Manager and license dropdowns now populate from actual DB data via new /api/v1/sbom/filters endpoint
Stale entry cleanup: Delete old SBOM entries on rescan instead of only upserting, so removed dependencies don't linger
Docker image: Added cargo, npm, go, php, ruby, composer, bundler for lockfile generation in production
Test plan
Rescan a Rust repo — should see cargo packages with licenses
Rescan an npm repo — manager should show "npm" not "library"
Add Python/Go/Java/PHP/Ruby repos and scan — verify correct managers and licenses
Verify manager and license dropdowns populate dynamically
Filter by manager and license — should return correct results
## Summary
- **Package manager detection**: Extract ecosystem from PURL (`pkg:npm/...` → npm, `pkg:cargo/...` → cargo) instead of using CycloneDX `type` field which was returning "library"/"file" for everything
- **Lock file generation**: Auto-generate `Cargo.lock`, `package-lock.json`, and `requirements.txt` before Syft scan for repos that gitignore their lock files
- **License resolution**: Enable Syft remote license lookups for Go/JS/Python/Java, enrich Cargo via `cargo metadata`, and parse SPDX license expressions
- **Dynamic filter dropdowns**: Manager and license dropdowns now populate from actual DB data via new `/api/v1/sbom/filters` endpoint
- **Stale entry cleanup**: Delete old SBOM entries on rescan instead of only upserting, so removed dependencies don't linger
- **Docker image**: Added cargo, npm, go, php, ruby, composer, bundler for lockfile generation in production
## Test plan
- [x] Rescan a Rust repo — should see cargo packages with licenses
- [x] Rescan an npm repo — manager should show "npm" not "library"
- [x] Add Python/Go/Java/PHP/Ruby repos and scan — verify correct managers and licenses
- [x] Verify manager and license dropdowns populate dynamically
- [x] Filter by manager and license — should return correct results
🤖 Generated with [Claude Code](https://claude.com/claude-code)
- Extract package manager from PURL instead of CycloneDX component type
(was showing "library"/"file" instead of "npm"/"cargo"/"pip" etc.)
- Generate missing lock files (Cargo.lock, package-lock.json) before Syft
scan so repos that gitignore them still get full dependency trees
- Enable Syft remote license lookups for Go, JS, Python, and Java
- Enrich Cargo entries with license data from cargo metadata
- Parse CycloneDX license expressions (e.g. "MIT OR Apache-2.0")
- Delete stale SBOM entries on rescan instead of only upserting
- Add /api/v1/sbom/filters endpoint for dynamic filter options
- Make manager and license dropdowns dynamic from actual DB data
- Add cargo, npm, go, php, ruby, composer, bundler to Docker image
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
pkg:npm/...→ npm,pkg:cargo/...→ cargo) instead of using CycloneDXtypefield which was returning "library"/"file" for everythingCargo.lock,package-lock.json, andrequirements.txtbefore Syft scan for repos that gitignore their lock filescargo metadata, and parse SPDX license expressions/api/v1/sbom/filtersendpointTest plan
🤖 Generated with Claude Code