// Wire contract for the code-security dependency-scan endpoints, shared by the // server handlers and the UI so the two can't drift. The taxonomy below is // mirrored by the PackageVulnerability DB entity (its columns import these). export type Ecosystem = 'npm'; export type VulnerabilitySource = 'osv'; export type AdvisoryKind = 'vulnerability' | 'malware'; // Qualitative bands, ascending, then `unknown` (no scorable CVSS vector and no // qualitative rating). Doubles as the runtime allowlist for untrusted severity input. export const SEVERITY_LEVELS = ['none', 'low', 'medium', 'high', 'critical', 'unknown'] as const; export type SeverityLevel = (typeof SEVERITY_LEVELS)[number]; // needs_review: version couldn't be pinned, so a "clear" verdict would be unearned. export type DependencyScanStatus = 'clear' | 'needs_review' | 'unresolved'; export const DEPENDENCY_SCAN_DATE_FILTERS = ['all', 'today', '-7d', '-30d', 'ytd'] as const; export type DependencyScanDateFilter = (typeof DEPENDENCY_SCAN_DATE_FILTERS)[number]; export type DependencyScanOrder = 'asc' | 'desc'; export const DEPENDENCY_SCAN_SORTS = ['severity', 'last_updated', 'last_published'] as const; export type DependencyScanSort = (typeof DEPENDENCY_SCAN_SORTS)[number]; export function parseDependencyScanDateFilter(value: string | null | undefined): DependencyScanDateFilter { for (const filter of DEPENDENCY_SCAN_DATE_FILTERS) { if (filter === value) return filter; } return 'all'; } export interface AdvisoryDetail { advisoryId: string; source: VulnerabilitySource; kind: AdvisoryKind; severity: SeverityLevel; summary: string | null; packageName: string; currentVersion: string; fixedVersion: string | null; lowConfidence: boolean; } export interface PerAppVuln { appId: string; lastPublished: string | null; lastUpdated: string; name: string; owner: string | null; published: boolean; visibility: 'private' | 'public'; status: DependencyScanStatus; totalCount: number; topSeverity: SeverityLevel | null; severityCounts: Partial>; advisories: AdvisoryDetail[]; lowConfidence: boolean; // Caller may undeploy this app (APPLICATIONS:DEPLOY). Set per-request on the // list handler — not part of the org scan cache. canDeploy: boolean; } export interface DependencyScanSummary { overallSeverityCounts: Partial>; publishedPublicWithVulns: number; publishedWithVulns: number; totalProjects: number; }