The "via …" line under an affected package was missing or wrong in three
constellations, so a finding's provenance could not be read off the detail
page:
- A package confirmed by two scanners kept only the one that wrote first —
record_affected_package never merged `source` on an existing row.
- Findings that only carry the parent summary (OS-level rows, pseudo-CVEs,
data written before per-package tracking) fell into a fallback block that
renders no source at all.
- Rows with a NULL source rendered nothing instead of falling back to the
finding's own sources.
Package sources are now cumulative ("app-scan,msrc", widened to VARCHAR(60)
in migration 039), the API synthesises a package entry from the parent
summary when no child rows exist, and the UI renders every source as a chip
— never blank.
Also makes HOST / PACKAGE / ASSIGNED TO sortable; the assignee sorts by
username, not by id.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>