Assessor_2.0/src/domain/severity-order.ts

69 lines
2.4 KiB
TypeScript

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<CanonicalSeverity, number> = {
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<CanonicalSeverity, string> = {
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));
}