import type { CanonicalSeverity } from './canonical-model'; import { clean } from '../shared/text'; /** * Rangfolge der kanonischen Severity-Skala: kritischste Funde zuerst. * Werkzeugunabhaengig, weil alle Quellen auf dieselbe Skala abgebildet werden - * dadurch ersetzt sie das Sortieren nach werkzeugeigenen Punktespalten * (Purple Knight: Weight, PingCastle: Points), die untereinander nicht * vergleichbar sind. */ const SEVERITY_RANK: Record = { critical: 0, high: 1, medium: 2, low: 3, info: 4, unknown: 5 }; export function severityRank(severity: CanonicalSeverity): number { return SEVERITY_RANK[severity] ?? SEVERITY_RANK.unknown; } /** * Anzeigenamen der kanonischen Stufen. Werkzeuge schreiben dieselbe Stufe * unterschiedlich ("High", "hoch", "Informational", "info"); in der Oberflaeche * traegt jede Stufe genau einen Namen, sonst stuenden zwei Eintraege fuer * denselben Schweregrad nebeneinander. */ export const SEVERITY_LABEL: Record = { critical: 'Critical', high: 'High', medium: 'Medium', low: 'Low', info: 'Info', unknown: 'Unknown' }; /** * Bildet einen rohen Severity-Text auf die kanonische Skala ab. Bewusst * tolerant, weil die Werkzeuge unterschiedliche Schreibweisen liefern * ("Critical", "HIGH", "Mittel", "Informational"). */ export function normalizeSeverityValue(value: string): CanonicalSeverity { const normalized = clean(value).toLocaleLowerCase('de-DE'); if (/critical|kritisch/.test(normalized)) return 'critical'; if (/\bhigh\b|\bhoch\b/.test(normalized)) return 'high'; if (/medium|mittel|moderate/.test(normalized)) return 'medium'; if (/\blow\b|niedrig/.test(normalized)) return 'low'; if (/info/.test(normalized)) return 'info'; return 'unknown'; } /** * Kopfzeilen, hinter denen die Einstufung eines Funds steht. Wird gebraucht, * weil das aus der Datenbank rekonstruierte Arbeits-Dataset keine * Spaltenerkennung mehr mitfuehrt und die Severity dort nur ueber den * Spaltennamen auffindbar ist. */ const SEVERITY_HEADER = /^(?:severity|schweregrad|criticality|kritikalit(?:ae|ä)t|risk|risiko|priority|priorit(?:ae|ä)t)$/i; export function isSeverityHeader(header: string): boolean { return SEVERITY_HEADER.test(clean(header)); } export function findSeverityHeaderIndex(headers: string[]): number { return headers.findIndex(header => isSeverityHeader(header)); }