/** * Controls Library * * Standard controls for vendor and processing activity compliance. * Data is split by domain into sibling files — each <500 LOC. * This file re-assembles them and provides all helper functions. */ import { Control, ControlDomain, ReviewFrequency, LocalizedText } from '../types' import { TRANSFER_CONTROLS, AUDIT_CONTROLS } from './transfer-audit' import { DELETION_CONTROLS, INCIDENT_CONTROLS } from './deletion-incident' import { SUBPROCESSOR_CONTROLS, TOM_CONTROLS } from './subprocessor-tom' import { CONTRACT_CONTROLS, DATA_SUBJECT_CONTROLS } from './contract-data-subject' import { SECURITY_CONTROLS, GOVERNANCE_CONTROLS } from './security-governance' // ========================================== // ASSEMBLED CONTROLS LIBRARY // ========================================== export const CONTROLS_LIBRARY: Control[] = [ ...TRANSFER_CONTROLS, ...AUDIT_CONTROLS, ...DELETION_CONTROLS, ...INCIDENT_CONTROLS, ...SUBPROCESSOR_CONTROLS, ...TOM_CONTROLS, ...CONTRACT_CONTROLS, ...DATA_SUBJECT_CONTROLS, ...SECURITY_CONTROLS, ...GOVERNANCE_CONTROLS, ] // ========================================== // HELPER FUNCTIONS // ========================================== /** * Get all controls */ export function getAllControls(): Control[] { return CONTROLS_LIBRARY } /** * Get controls by domain */ export function getControlsByDomain(domain: ControlDomain): Control[] { return CONTROLS_LIBRARY.filter((c) => c.domain === domain) } /** * Get control by ID */ export function getControlById(id: string): Control | undefined { return CONTROLS_LIBRARY.find((c) => c.id === id) } /** * Get required controls */ export function getRequiredControls(): Control[] { return CONTROLS_LIBRARY.filter((c) => c.isRequired) } /** * Get controls by frequency */ export function getControlsByFrequency(frequency: ReviewFrequency): Control[] { return CONTROLS_LIBRARY.filter((c) => c.defaultFrequency === frequency) } /** * Get controls applicable to vendors */ export function getVendorControls(): Control[] { return CONTROLS_LIBRARY.filter((c) => ['TRANSFER', 'AUDIT', 'DELETION', 'INCIDENT', 'SUBPROCESSOR', 'TOM', 'CONTRACT', 'DATA_SUBJECT', 'SECURITY', 'GOVERNANCE'].includes(c.domain) ) } /** * Get controls applicable to processing activities */ export function getProcessingActivityControls(): Control[] { return CONTROLS_LIBRARY.filter((c) => ['TOM', 'DATA_SUBJECT', 'GOVERNANCE', 'SECURITY'].includes(c.domain) ) } /** * Group controls by domain */ export function getControlsGroupedByDomain(): Map { const grouped = new Map() for (const control of CONTROLS_LIBRARY) { const existing = grouped.get(control.domain) || [] grouped.set(control.domain, [...existing, control]) } return grouped } /** * Get domain metadata */ export function getControlDomainMeta(domain: ControlDomain): LocalizedText { const meta: Record = { TRANSFER: { de: 'Drittlandtransfer', en: 'Third Country Transfer' }, AUDIT: { de: 'Audit & Prüfung', en: 'Audit & Review' }, DELETION: { de: 'Löschung', en: 'Deletion' }, INCIDENT: { de: 'Incident Response', en: 'Incident Response' }, SUBPROCESSOR: { de: 'Unterauftragnehmer', en: 'Sub-Processors' }, TOM: { de: 'Technische/Org. Maßnahmen', en: 'Technical/Org. Measures' }, CONTRACT: { de: 'Vertragliche Grundlagen', en: 'Contractual Basics' }, DATA_SUBJECT: { de: 'Betroffenenrechte', en: 'Data Subject Rights' }, SECURITY: { de: 'Sicherheit', en: 'Security' }, GOVERNANCE: { de: 'Governance', en: 'Governance' }, } return meta[domain] } /** * Calculate control coverage */ export function calculateControlCoverage( controlIds: string[], domain?: ControlDomain ): { covered: number; total: number; percentage: number } { const targetControls = domain ? getControlsByDomain(domain) : getRequiredControls() const covered = targetControls.filter((c) => controlIds.includes(c.id)).length return { covered, total: targetControls.length, percentage: targetControls.length > 0 ? Math.round((covered / targetControls.length) * 100) : 0, } }