Dashboard stats materialization

Dashboard stats materialization

Last Updated: 2026-08-12

Two scheduled processors keep the Resolve dashboard’s global catalog joins and org aggregation outside user requests.

flowchart LR F[Customer findings] --> C[cve-dashboard-facts-processor] V[Global vulnerability catalog] --> C C --> CF[CveDashboardFact] CF --> O[org-stats-processor] F --> O O --> OS[OrgStats] OS --> API[Site API]

CVE dashboard facts processor

Processor: cve-dashboard-facts-processor

Schedule: hourly at minute 5

Reads: customer-relevant identifiers from Finding, then CVEAffected, versions, references, aliases, KEV, exploits, CVSS, EPSS, and malicious-package metadata from the read pool

Writes: CveDashboardFact through the writer pool

Each run processes a bounded oldest-first batch. The default is 2,000 (identifier, packageName) pairs. The package is part of the key because fix availability can differ between packages named by one advisory. Rows remain usable for 24 hours and are refreshed earlier when the finding source watermark advances.

The processor uses indexed probes for the same fix and exploitation channels as the API. The API wraps each fact lookup in a live catalog fallback, so an incomplete initial backfill cannot remove a signal from a response.

Org stats processor

Processor: org-stats-processor

Schedule: every 15 minutes

Reads: latest findings, latest triage, suppression, reachability, EOL, detection rules, and CveDashboardFact from the read pool

Writes: OrgStats through the writer pool

The job produces the exact full and lite /v1/findings/metrics payloads for an org and each attributed repository in one grouped read. It skips an org until CVE fact coverage is complete. This preserves the current live-query result during rollout. Orgs are ordered by their oldest metric snapshot so repeated runs rotate across the tenant set.

Both jobs hold PostgreSQL session advisory locks for their full lifetime. Task termination releases the lock at the database connection boundary. Reads have task-specific statement timeouts and writes use bounded pgx batches.

Operations

Use just go-cve-dashboard-facts and just go-org-stats for local runs after loading the appropriate database environment. The ecr-build target registry includes both processor images, which must be published before applying the Terraform schedules. ECS schedules use the standard processor task role, read replica endpoint, writer proxy, CloudWatch logs, and scheduler dead-letter queue.

Apply the SaaS migration 20260812000001_dashboard_stats before enabling either schedule. The site API can still compute and persist a missing aggregate under a Valkey lease, which covers datasets not yet produced by the org stats processor.