42e02fe72d
Phase 6 of the Document Templates Masterplan: - Categories: Consolidated AI governance into internal_policies, removed redundant category - scopeDefaults.ts: Added getRecommendedDocuments() function that maps L1-L4 compliance levels to required/recommended/optional document types (~60 types across 4 tiers) - Examples: Added dpa_de.json, tom_de.json, whistleblower_de.json example contexts for the document generator Document recommendation per level: - L1 (Startup): 5 required (DSI, Impressum, AGB, Cookie) - L2 (KMU): +6 recommended (AVV, TOM, VVT, Löschkonzept, etc.) - L3 (Extended): +16 recommended (Security concepts, policies, HR DSI) - L4 (Enterprise): +25 recommended (ISMS, BCM, all policies) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
321 lines
10 KiB
TypeScript
321 lines
10 KiB
TypeScript
/**
|
|
* 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<ComplianceDepthLevel, Partial<TOMCtx>> = {
|
|
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<ComplianceDepthLevel, Partial<DPACtx>> = {
|
|
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<TOMCtx>
|
|
dpa: Partial<DPACtx>
|
|
/** Which fields were set by the scope engine (for UI highlighting) */
|
|
scopeSet: Set<string>
|
|
}
|
|
|
|
/**
|
|
* 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<string>()
|
|
|
|
// 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<ComplianceDepthLevel, string> = {
|
|
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: [] }
|
|
}
|
|
}
|