/** * Scope-basierte Generator-Defaults * * Nimmt ScopeDecision.determinedLevel + CompanyProfile und liefert * vorausgefuellte TOM/DPA-Context-Werte. Alle Felder bleiben vom * Kunden aenderbar — die Defaults sind Empfehlungen. * * Mapping: * L1 = Lean Startup (≤10 MA, Cloud-only, Home Office) * L2 = KMU Standard (11-249 MA) * L3 = Erweitert (risikoreich oder >100 MA) * L4 = Zertifizierungsbereit (≥250 MA oder regulierte Branche) */ import type { ComplianceDepthLevel } from '../../lib/sdk/compliance-scope-types/core-levels' import type { CompanyProfile } from '../../lib/sdk/types' import type { TOMCtx, DPACtx } from './contextBridge' // ============================================================================ // TOM Defaults per Level // ============================================================================ const TOM_DEFAULTS: Record> = { L1: { // Lean Startup: Cloud-only, kein eigener Serverraum, Home Office HAS_MFA: true, HAS_USB_LOCKED: false, HAS_MOBILE_MEDIA: false, HAS_FOUR_EYES_DELETE: false, HAS_EXTERNAL_DESTRUCTION: false, HAS_PHYSICAL_TRANSPORT: false, HAS_THIRD_COUNTRY_TRANSFER: false, HAS_CLOUD_SERVICES: true, HAS_REDUNDANCY: false, HAS_GEO_REDUNDANCY: false, HAS_USV: false, HAS_OWN_SERVER_ROOM: false, HAS_MULTI_TENANT: false, HAS_TEST_DATA_ANONYMIZED: true, LOG_RETENTION_MONTHS: 3, DIN_66399_LEVEL: '3', AVAILABILITY_TARGET: '99.0', SEPARATION_TYPE: 'logisch', }, L2: { // KMU Standard HAS_MFA: true, HAS_USB_LOCKED: false, HAS_MOBILE_MEDIA: false, HAS_FOUR_EYES_DELETE: false, HAS_EXTERNAL_DESTRUCTION: false, HAS_PHYSICAL_TRANSPORT: false, HAS_THIRD_COUNTRY_TRANSFER: false, HAS_CLOUD_SERVICES: true, HAS_REDUNDANCY: false, HAS_GEO_REDUNDANCY: false, HAS_USV: false, HAS_OWN_SERVER_ROOM: false, HAS_MULTI_TENANT: false, HAS_TEST_DATA_ANONYMIZED: true, LOG_RETENTION_MONTHS: 6, DIN_66399_LEVEL: '3', AVAILABILITY_TARGET: '99.5', SEPARATION_TYPE: 'logisch', }, L3: { // Erweitert HAS_MFA: true, HAS_USB_LOCKED: false, HAS_MOBILE_MEDIA: false, HAS_FOUR_EYES_DELETE: true, HAS_EXTERNAL_DESTRUCTION: true, HAS_PHYSICAL_TRANSPORT: false, HAS_THIRD_COUNTRY_TRANSFER: false, HAS_CLOUD_SERVICES: true, HAS_REDUNDANCY: true, HAS_GEO_REDUNDANCY: false, HAS_USV: true, HAS_OWN_SERVER_ROOM: true, HAS_MULTI_TENANT: true, HAS_TEST_DATA_ANONYMIZED: true, LOG_RETENTION_MONTHS: 12, DIN_66399_LEVEL: '4', AVAILABILITY_TARGET: '99.9', SEPARATION_TYPE: 'logisch', }, L4: { // Zertifizierungsbereit / Enterprise HAS_MFA: true, HAS_USB_LOCKED: true, HAS_MOBILE_MEDIA: false, HAS_FOUR_EYES_DELETE: true, HAS_EXTERNAL_DESTRUCTION: true, HAS_PHYSICAL_TRANSPORT: false, HAS_THIRD_COUNTRY_TRANSFER: false, HAS_CLOUD_SERVICES: true, HAS_REDUNDANCY: true, HAS_GEO_REDUNDANCY: true, HAS_USV: true, HAS_OWN_SERVER_ROOM: true, HAS_MULTI_TENANT: true, HAS_TEST_DATA_ANONYMIZED: true, LOG_RETENTION_MONTHS: 24, DIN_66399_LEVEL: '5', AVAILABILITY_TARGET: '99.99', SEPARATION_TYPE: 'logisch', }, } // ============================================================================ // DPA Defaults per Level // ============================================================================ const DPA_DEFAULTS: Record> = { L1: { BREACH_NOTIFICATION_HOURS: 48, INSTRUCTION_RETENTION_YEARS: 3, SUB_PROCESSOR_NOTICE_WEEKS: 2, SUB_PROCESSOR_OBJECTION_WEEKS: 2, DATA_EXPORT_FORMAT: 'CSV/JSON', RETURN_CHOICE_WEEKS: 4, DELETION_DAYS: 90, HAS_LIABILITY_PROTECTION: false, HAS_SUPPORT_COST_CLAUSE: false, HAS_SUB_PROCESSOR_SILENCE_APPROVAL: true, HAS_SUB_PROCESSOR_TERMINATION_RIGHT: false, HAS_REACTIVATION_PERIOD: true, REACTIVATION_MONTHS: 3, HAS_RETURN_COST_CLAUSE: false, HAS_GERICHTSSTAND_CLAUSE: false, HAS_UNILATERAL_CHANGE_RIGHT: false, HAS_THIRD_COUNTRY_OBJECTION: false, }, L2: { BREACH_NOTIFICATION_HOURS: 24, INSTRUCTION_RETENTION_YEARS: 3, SUB_PROCESSOR_NOTICE_WEEKS: 4, SUB_PROCESSOR_OBJECTION_WEEKS: 2, DATA_EXPORT_FORMAT: 'CSV/JSON', RETURN_CHOICE_WEEKS: 4, DELETION_DAYS: 90, HAS_LIABILITY_PROTECTION: false, HAS_SUPPORT_COST_CLAUSE: false, HAS_SUB_PROCESSOR_SILENCE_APPROVAL: true, HAS_SUB_PROCESSOR_TERMINATION_RIGHT: false, HAS_REACTIVATION_PERIOD: true, REACTIVATION_MONTHS: 3, HAS_RETURN_COST_CLAUSE: false, HAS_GERICHTSSTAND_CLAUSE: true, HAS_UNILATERAL_CHANGE_RIGHT: false, HAS_THIRD_COUNTRY_OBJECTION: false, }, L3: { BREACH_NOTIFICATION_HOURS: 24, INSTRUCTION_RETENTION_YEARS: 5, SUB_PROCESSOR_NOTICE_WEEKS: 4, SUB_PROCESSOR_OBJECTION_WEEKS: 4, DATA_EXPORT_FORMAT: 'CSV/JSON', RETURN_CHOICE_WEEKS: 4, DELETION_DAYS: 60, HAS_LIABILITY_PROTECTION: true, HAS_SUPPORT_COST_CLAUSE: true, HAS_SUB_PROCESSOR_SILENCE_APPROVAL: true, HAS_SUB_PROCESSOR_TERMINATION_RIGHT: true, HAS_REACTIVATION_PERIOD: true, REACTIVATION_MONTHS: 3, HAS_RETURN_COST_CLAUSE: true, HAS_GERICHTSSTAND_CLAUSE: true, HAS_UNILATERAL_CHANGE_RIGHT: false, HAS_THIRD_COUNTRY_OBJECTION: false, }, L4: { BREACH_NOTIFICATION_HOURS: 12, INSTRUCTION_RETENTION_YEARS: 5, SUB_PROCESSOR_NOTICE_WEEKS: 6, SUB_PROCESSOR_OBJECTION_WEEKS: 4, DATA_EXPORT_FORMAT: 'CSV/JSON', RETURN_CHOICE_WEEKS: 8, DELETION_DAYS: 30, HAS_LIABILITY_PROTECTION: true, HAS_SUPPORT_COST_CLAUSE: true, HAS_SUB_PROCESSOR_SILENCE_APPROVAL: false, HAS_SUB_PROCESSOR_TERMINATION_RIGHT: true, HAS_REACTIVATION_PERIOD: false, REACTIVATION_MONTHS: 3, HAS_RETURN_COST_CLAUSE: true, HAS_GERICHTSSTAND_CLAUSE: true, HAS_UNILATERAL_CHANGE_RIGHT: false, HAS_THIRD_COUNTRY_OBJECTION: false, }, } // ============================================================================ // Public API // ============================================================================ export interface GeneratorDefaults { tom: Partial dpa: Partial /** Which fields were set by the scope engine (for UI highlighting) */ scopeSet: Set } /** * Berechnet Generator-Defaults basierend auf dem Compliance-Level * und dem CompanyProfile. Alle Werte sind Vorschlaege — der Kunde * kann sie aendern. */ export function getGeneratorDefaults( level: ComplianceDepthLevel, profile?: CompanyProfile | null, ): GeneratorDefaults { const tomBase = { ...TOM_DEFAULTS[level] } const dpaBase = { ...DPA_DEFAULTS[level] } const scopeSet = new Set() // CompanyProfile-Felder in TOM/DPA uebernehmen if (profile) { if (profile.company_name) { dpaBase.AN_NAME = profile.company_name scopeSet.add('DPA.AN_NAME') } if (profile.address) { dpaBase.AN_STRASSE = profile.address scopeSet.add('DPA.AN_STRASSE') } if (profile.city && profile.postal_code) { dpaBase.AN_PLZ_ORT = `${profile.postal_code} ${profile.city}` scopeSet.add('DPA.AN_PLZ_ORT') } if (profile.dpo_name) { tomBase.ISB_NAME = tomBase.ISB_NAME || '' dpaBase.AN_DSB_NAME = profile.dpo_name scopeSet.add('DPA.AN_DSB_NAME') } if (profile.dpo_email) { dpaBase.AN_DSB_EMAIL = profile.dpo_email scopeSet.add('DPA.AN_DSB_EMAIL') } if (profile.ceo_name) { dpaBase.AN_UNTERZEICHNER_NAME = profile.ceo_name tomBase.GF_NAME = profile.ceo_name scopeSet.add('DPA.AN_UNTERZEICHNER_NAME') scopeSet.add('TOM.GF_NAME') } } // Alle gesetzten TOM/DPA Felder als scope-set markieren for (const key of Object.keys(tomBase)) { scopeSet.add(`TOM.${key}`) } for (const key of Object.keys(dpaBase)) { scopeSet.add(`DPA.${key}`) } return { tom: tomBase, dpa: dpaBase, scopeSet } } /** * Gibt das empfohlene Profil-Label zurueck (fuer UI-Anzeige). */ export function getProfileLabel(level: ComplianceDepthLevel): string { const labels: Record = { L1: 'Startup / Kleinstunternehmen', L2: 'KMU Standard', L3: 'Erweiterte Compliance', L4: 'Zertifizierungsbereit / Enterprise', } return labels[level] } /** * Empfiehlt relevante Dokumenttypen basierend auf dem Compliance-Level. * Hilft dem Kunden zu verstehen, welche Dokumente er braucht. */ export function getRecommendedDocuments(level: ComplianceDepthLevel): { required: string[] recommended: string[] optional: string[] } { const always = [ 'privacy_policy', 'impressum', 'agb', 'cookie_banner', 'cookie_policy', ] const l2plus = [ 'dpa', 'tom_documentation', 'vvt_register', 'loeschkonzept', 'community_guidelines', 'terms_of_use', ] const l3plus = [ 'it_security_concept', 'data_protection_concept', 'incident_response_plan', 'access_control_concept', 'backup_recovery_concept', 'logging_concept', 'risk_management_concept', 'pflichtenregister', 'password_policy', 'encryption_policy', 'information_security_policy', 'access_control_policy', 'whistleblower_policy', 'employee_dsi', 'applicant_dsi', 'ai_usage_policy', ] const l4only = [ 'isms_manual', 'cybersecurity_policy', 'byod_policy', 'dsfa', 'social_media_dsi', 'media_content_policy', 'video_conference_dsi', 'consent_texts', 'data_protection_policy', 'data_classification_policy', 'data_retention_policy', 'data_transfer_policy', 'privacy_incident_policy', 'employee_security_policy', 'security_awareness_policy', 'remote_work_policy', 'offboarding_policy', 'vendor_risk_management_policy', 'third_party_security_policy', 'supplier_security_policy', 'business_continuity_policy', 'disaster_recovery_policy', 'crisis_management_policy', ] switch (level) { case 'L1': return { required: always, recommended: [], optional: l2plus } case 'L2': return { required: always, recommended: l2plus, optional: l3plus } case 'L3': return { required: [...always, ...l2plus], recommended: l3plus, optional: l4only } case 'L4': return { required: [...always, ...l2plus, ...l3plus], recommended: l4only, optional: [] } } }