/** * Finding Types and Templates * * Pre-defined finding templates for contract reviews. * Barrel re-export — FINDING_TEMPLATES lives in findings-templates.ts. */ import { FindingType, FindingCategory, FindingSeverity, LocalizedText, } from '../types' // ========================================== // FINDING SEVERITY DEFINITIONS // ========================================== export const SEVERITY_DEFINITIONS: Record = { LOW: { label: { de: 'Niedrig', en: 'Low' }, description: { de: 'Geringfügige Abweichung ohne wesentliche Auswirkungen', en: 'Minor deviation without significant impact', }, responseTime: { de: 'Bei nächster Vertragserneuerung', en: 'At next contract renewal', }, color: 'blue', }, MEDIUM: { label: { de: 'Mittel', en: 'Medium' }, description: { de: 'Abweichung mit potenziellen Auswirkungen auf Compliance', en: 'Deviation with potential impact on compliance', }, responseTime: { de: 'Innerhalb von 90 Tagen', en: 'Within 90 days', }, color: 'yellow', }, HIGH: { label: { de: 'Hoch', en: 'High' }, description: { de: 'Erhebliche Abweichung mit Auswirkungen auf Datenschutz-Compliance', en: 'Significant deviation with impact on data protection compliance', }, responseTime: { de: 'Innerhalb von 30 Tagen', en: 'Within 30 days', }, color: 'orange', }, CRITICAL: { label: { de: 'Kritisch', en: 'Critical' }, description: { de: 'Schwerwiegende Abweichung - unmittelbarer Handlungsbedarf', en: 'Serious deviation - immediate action required', }, responseTime: { de: 'Sofort / vor Vertragsabschluss', en: 'Immediately / before contract signing', }, color: 'red', }, } // ========================================== // FINDING TYPE DEFINITIONS // ========================================== export const FINDING_TYPE_DEFINITIONS: Record = { OK: { label: { de: 'Erfüllt', en: 'Fulfilled' }, description: { de: 'Anforderung ist vollständig erfüllt', en: 'Requirement is fully met', }, icon: 'check-circle', }, GAP: { label: { de: 'Lücke', en: 'Gap' }, description: { de: 'Anforderung fehlt oder ist unvollständig', en: 'Requirement is missing or incomplete', }, icon: 'alert-circle', }, RISK: { label: { de: 'Risiko', en: 'Risk' }, description: { de: 'Potenzielles Risiko identifiziert', en: 'Potential risk identified', }, icon: 'alert-triangle', }, UNKNOWN: { label: { de: 'Unklar', en: 'Unknown' }, description: { de: 'Nicht eindeutig bestimmbar', en: 'Cannot be clearly determined', }, icon: 'help-circle', }, } import { FINDING_TEMPLATES } from './findings-templates' import type { FindingTemplate } from './findings-templates' export type { FindingTemplate } export { FINDING_TEMPLATES } // ========================================== // HELPER FUNCTIONS // ========================================== /** * Get finding template by ID */ export function getFindingTemplateById(id: string): FindingTemplate | undefined { return FINDING_TEMPLATES.find((t) => t.id === id) } /** * Get finding templates by category */ export function getFindingTemplatesByCategory(category: FindingCategory): FindingTemplate[] { return FINDING_TEMPLATES.filter((t) => t.category === category) } /** * Get finding templates by type */ export function getFindingTemplatesByType(type: FindingType): FindingTemplate[] { return FINDING_TEMPLATES.filter((t) => t.type === type) } /** * Get finding templates by severity */ export function getFindingTemplatesBySeverity(severity: FindingSeverity): FindingTemplate[] { return FINDING_TEMPLATES.filter((t) => t.severity === severity) } /** * Get severity color class */ export function getSeverityColorClass(severity: FindingSeverity): string { return SEVERITY_DEFINITIONS[severity].color } /** * Sort findings by severity (critical first) */ export function sortFindingsBySeverity( findings: T[] ): T[] { const order: Record = { CRITICAL: 0, HIGH: 1, MEDIUM: 2, LOW: 3, } return [...findings].sort((a, b) => order[a.severity] - order[b.severity]) } /** * Count findings by severity */ export function countFindingsBySeverity( findings: T[] ): Record { return findings.reduce( (acc, f) => { acc[f.severity] = (acc[f.severity] || 0) + 1 return acc }, { LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0 } as Record ) } /** * Get overall severity from list of findings */ export function getOverallSeverity(findings: { severity: FindingSeverity }[]): FindingSeverity { if (findings.some((f) => f.severity === 'CRITICAL')) return 'CRITICAL' if (findings.some((f) => f.severity === 'HIGH')) return 'HIGH' if (findings.some((f) => f.severity === 'MEDIUM')) return 'MEDIUM' return 'LOW' }