Dependency list export N+1s on vulnerability_reads when rendering the malware field

Summary

Sbom::Exporters::DependencyListService renders the malware field but does not preload vulnerability_reads, so evaluating it costs one query per vulnerability across an entire export.

Problem

The exporter preloads:

def preloads
  [
    :component,
    :component_version,
    :vulnerabilities
  ]
end

DependencyEntity exposes malware as occurrence.malware_status, which is ::Vulnerability.malware_status_for(vulnerabilities) and resolves to has_glam_identifier? per vulnerability. That reads vulnerability_read.identifier_names, and :vulnerability_read is not in the preload list, so each vulnerability triggers its own query.

The exporter builds its EntityRequest with project: only, so subject resolves to the project and malware_field_enabled? is satisfied whenever dependency_malware_detection is on for that project. The field is therefore rendered on exports today.

Unlike the dependency list, an export is not bounded to a page. The N+1 scales with the number of vulnerabilities in the whole project.

Scope

Pre-existing since !233323 (merged) added the field. Not introduced by the group-level work, and not fixed there either: !251901 (merged) adds Sbom::MalwareStatusPreloader for the dependency list surfaces and deliberately leaves the exporter alone, because it is a different surface and a correct fix needs its own export-path regression spec rather than a one-line preload tweak.

Proposal

Either add the missing association to the preload list:

{ vulnerabilities: :vulnerability_read }

or route the exporter through Sbom::MalwareStatusPreloader.per_occurrence, which already expresses this and is covered by specs.

The second is preferable if the intent is that every caller of malware_status goes through one place, which is the direction !252166 (merged) takes further by removing the vulnerability dependency altogether.

Acceptance criteria

  • Exporting a project dependency list with the malware field enabled issues a bounded number of queries for vulnerability_reads.
  • A regression spec on the export path asserts the query count, not just the rendered output.