Aggregate result of a security scan: every layer's LayerResult
plus run metadata. The report is the single object handed to
formatters (terminal, JSON, markdown) and the value returned
from MobDev.SecurityScan.run/1.
Severity rollup helpers (severity_counts/1, worst_severity/1)
are colocated here so formatters and the --strict exit-code
logic agree on the math.
Summary
Functions
Flatten findings across all layers.
Total wall-clock duration of the scan in milliseconds, or nil if not yet finished.
Count findings by severity across the report.
Returns a map keyed by :critical, :high, :medium, :low,
:unknown — every key is present (zero if no findings at that level).
Worst severity present in the report. Returns :none when the
report has zero findings.
Types
@type t() :: %MobDev.SecurityScan.Report{ finished_at: DateTime.t() | nil, layers: [MobDev.SecurityScan.LayerResult.t()], project_root: String.t(), started_at: DateTime.t() }
Functions
@spec all_findings(t()) :: [MobDev.SecurityScan.Finding.t()]
Flatten findings across all layers.
@spec duration_ms(t()) :: non_neg_integer() | nil
Total wall-clock duration of the scan in milliseconds, or nil if not yet finished.
@spec severity_counts(t()) :: %{ required(MobDev.SecurityScan.Finding.severity()) => non_neg_integer() }
Count findings by severity across the report.
Returns a map keyed by :critical, :high, :medium, :low,
:unknown — every key is present (zero if no findings at that level).
@spec worst_severity(t()) :: MobDev.SecurityScan.Finding.severity() | :none
Worst severity present in the report. Returns :none when the
report has zero findings.