diff --git a/admin-compliance/app/sdk/document-generator/contextBridge-helpers.ts b/admin-compliance/app/sdk/document-generator/contextBridge-helpers.ts index ca5c858..eee2387 100644 --- a/admin-compliance/app/sdk/document-generator/contextBridge-helpers.ts +++ b/admin-compliance/app/sdk/document-generator/contextBridge-helpers.ts @@ -224,6 +224,46 @@ export function contextToPlaceholders(ctx: TemplateContext): Record = { NDA: ['{{PURPOSE}}', '{{DURATION_YEARS}}', '{{PENALTY_AMOUNT}}'], CONSENT: ['{{WEBSITE_NAME}}', '{{ANALYTICS_TOOLS}}', '{{MARKETING_PARTNERS}}', '{{ANALYTICS_TOOLS_LIST}}', '{{MARKETING_PARTNERS_LIST}}'], HOSTING: ['{{HOSTING_PROVIDER_NAME}}', '{{HOSTING_PROVIDER_COUNTRY}}', '{{HOSTING_PROVIDER_CONTRACT_TYPE}}'], - FEATURES: ['{{CONSENT_WITHDRAWAL_PATH}}', '{{SECURITY_MEASURES_SUMMARY}}', '{{DATA_SUBJECT_REQUEST_CHANNEL}}', '{{TRANSFER_GUARDS}}', '{{REGULATED_PROFESSION_TEXT}}', '{{EDITORIAL_RESPONSIBLE_NAME}}', '{{EDITORIAL_RESPONSIBLE_ADDRESS}}', '{{DISPUTE_RESOLUTION_TEXT}}', '{{NEWSLETTER_PROVIDER_DETAIL}}', '{{PAYMENT_PROVIDER_DETAIL}}', '{{SOCIAL_MEDIA_DETAIL}}', '{{ANALYTICS_TOOLS_DETAIL}}', '{{MARKETING_TOOLS_DETAIL}}', '{{CMP_NAME}}', '{{PRICES_TEXT}}', '{{PAYMENT_TERMS_TEXT}}', '{{CONTRACT_TERM_TEXT}}', '{{SLA_URL}}', '{{EXPORT_POLICY_TEXT}}', '{{LIMITATION_CAP_TEXT}}', '{{CONSUMER_WITHDRAWAL_TEXT}}', '{{SUPPORT_CHANNELS_TEXT}}'], + FEATURES: ['{{CONSENT_WITHDRAWAL_PATH}}', '{{SECURITY_MEASURES_SUMMARY}}', '{{DATA_SUBJECT_REQUEST_CHANNEL}}', '{{TRANSFER_GUARDS}}', '{{REGULATED_PROFESSION_TEXT}}', '{{EDITORIAL_RESPONSIBLE_NAME}}', '{{EDITORIAL_RESPONSIBLE_ADDRESS}}', '{{DISPUTE_RESOLUTION_TEXT}}', '{{NEWSLETTER_PROVIDER_DETAIL}}', '{{PAYMENT_PROVIDER_DETAIL}}', '{{SOCIAL_MEDIA_DETAIL}}', '{{ANALYTICS_TOOLS_DETAIL}}', '{{MARKETING_TOOLS_DETAIL}}', '{{CMP_NAME}}', '{{PRICES_TEXT}}', '{{PAYMENT_TERMS_TEXT}}', '{{CONTRACT_TERM_TEXT}}', '{{SLA_URL}}', '{{EXPORT_POLICY_TEXT}}', '{{LIMITATION_CAP_TEXT}}', '{{CONSUMER_WITHDRAWAL_TEXT}}', '{{SUPPORT_CHANNELS_TEXT}}', '{{WHISTLEBLOWER_CONTACT_NAME}}', '{{WHISTLEBLOWER_EMAIL}}', '{{WHISTLEBLOWER_URL}}', '{{VIDEO_PROVIDER_NAME}}', '{{APPROVED_AI_SYSTEMS}}', '{{SOCIAL_MEDIA_PLATFORMS_LIST}}', '{{DSI_TITLE}}', '{{SERVICE_SCOPE_DESCRIPTION}}', '{{GUIDELINES_URL}}', '{{PROCESSOR_LIST_URL}}', '{{RECIPIENT_NAME}}', '{{RECIPIENT_COUNTRY}}', '{{TRANSFER_PURPOSE}}', '{{TRANSFER_MECHANISM}}'], TOM: ['{{ISB_NAME}}', '{{GF_NAME}}', '{{DOCUMENT_VERSION}}', '{{NEXT_REVIEW_DATE}}'], DPA: ['{{AG_NAME}}', '{{AG_STRASSE}}', '{{AG_PLZ_ORT}}', '{{AN_NAME}}', '{{AN_STRASSE}}', '{{AN_PLZ_ORT}}', '{{VERARBEITUNGSGEGENSTAND}}', '{{VERARBEITUNGSZWECK}}', '{{VERARBEITUNGSARTEN}}', '{{DATENKATEGORIEN}}', '{{PERSONENKATEGORIEN}}', '{{BREACH_NOTIFICATION_HOURS}}', '{{INSTRUCTION_RETENTION_YEARS}}', '{{SUB_PROCESSOR_NOTICE_WEEKS}}', '{{SUB_PROCESSOR_OBJECTION_WEEKS}}', '{{DATA_EXPORT_FORMAT}}', '{{RETURN_CHOICE_WEEKS}}', '{{DELETION_DAYS}}', '{{REACTIVATION_MONTHS}}', '{{TERMINATION_WEEKS}}', '{{AN_DSB_NAME}}', '{{AN_DSB_EMAIL}}', '{{AG_ORT}}', '{{AN_ORT}}', '{{VERTRAGSDATUM}}', '{{AG_UNTERZEICHNER_NAME}}', '{{AG_UNTERZEICHNER_FUNKTION}}', '{{AN_UNTERZEICHNER_NAME}}', '{{AN_UNTERZEICHNER_FUNKTION}}', '{{GERICHTSSTAND}}'], } diff --git a/admin-compliance/app/sdk/document-generator/examples/ai_usage_policy_de.json b/admin-compliance/app/sdk/document-generator/examples/ai_usage_policy_de.json new file mode 100644 index 0000000..67c751a --- /dev/null +++ b/admin-compliance/app/sdk/document-generator/examples/ai_usage_policy_de.json @@ -0,0 +1,14 @@ +{ + "document_type": "ai_usage_policy", + "language": "de", + "context": { + "PROVIDER": { "LEGAL_NAME": "Muster GmbH" }, + "FEATURES": { + "APPROVED_AI_SYSTEMS": "ChatGPT (OpenAI), GitHub Copilot, DeepL Pro", + "HAS_APPROVED_AI_LIST": true, + "HAS_AI_LABELING_INTERNAL": true, + "HAS_TDM_OPTOUT": true + }, + "TOM": { "DOCUMENT_VERSION": "1.0.0", "NEXT_REVIEW_DATE": "2026-11-01" } + } +} diff --git a/admin-compliance/app/sdk/document-generator/examples/employee_dsi_de.json b/admin-compliance/app/sdk/document-generator/examples/employee_dsi_de.json new file mode 100644 index 0000000..d53c10d --- /dev/null +++ b/admin-compliance/app/sdk/document-generator/examples/employee_dsi_de.json @@ -0,0 +1,33 @@ +{ + "document_type": "employee_dsi", + "language": "de", + "context": { + "PROVIDER": { + "LEGAL_NAME": "Muster GmbH", + "LEGAL_FORM": "GmbH", + "ADDRESS_LINE": "Musterstrasse 1", + "POSTAL_CODE": "10115", + "CITY": "Berlin", + "COUNTRY": "DE", + "EMAIL": "info@muster.de", + "PHONE": "+49 30 123456" + }, + "PRIVACY": { + "DPO_NAME": "Dr. Datenschutz", + "DPO_EMAIL": "dsb@muster.de", + "SUPERVISORY_AUTHORITY_NAME": "Berliner Beauftragte fuer Datenschutz" + }, + "FEATURES": { + "HAS_IT_USAGE_MONITORING": true, + "HAS_COMPANY_VEHICLE": false, + "HAS_ACCESS_CONTROL": true, + "HAS_VIDEO_SURVEILLANCE": false, + "HAS_COMPANY_PENSION": true, + "HAS_EXTERNAL_HR_SOFTWARE": true, + "HAS_WORKS_COUNCIL": false, + "HAS_SPECIAL_CATEGORIES_EMPLOYEES": true, + "DATA_SUBJECT_REQUEST_CHANNEL": "per E-Mail an dsb@muster.de" + }, + "SECURITY": { "LOG_RETENTION_DAYS": 90 } + } +} diff --git a/admin-compliance/app/sdk/document-generator/examples/social_media_dsi_de.json b/admin-compliance/app/sdk/document-generator/examples/social_media_dsi_de.json new file mode 100644 index 0000000..a058a01 --- /dev/null +++ b/admin-compliance/app/sdk/document-generator/examples/social_media_dsi_de.json @@ -0,0 +1,27 @@ +{ + "document_type": "social_media_dsi", + "language": "de", + "context": { + "PROVIDER": { + "LEGAL_NAME": "Muster GmbH", + "WEBSITE_URL": "https://www.muster.de", + "EMAIL": "info@muster.de", + "PHONE": "+49 30 123456" + }, + "PRIVACY": { + "DPO_EMAIL": "dsb@muster.de", + "SUPERVISORY_AUTHORITY_NAME": "Berliner Beauftragte fuer Datenschutz", + "SUPERVISORY_AUTHORITY_ADDRESS": "Friedrichstr. 219, 10969 Berlin" + }, + "FEATURES": { + "HAS_FACEBOOK": true, + "HAS_YOUTUBE": true, + "HAS_LINKEDIN": true, + "HAS_TIKTOK": false, + "HAS_X_TWITTER": false, + "HAS_META_PIXEL": true, + "HAS_RECRUITING_VIA_SOCIAL": true, + "SOCIAL_MEDIA_PLATFORMS_LIST": "Facebook, Instagram, YouTube und LinkedIn" + } + } +} diff --git a/admin-compliance/app/sdk/document-generator/examples/tia_de.json b/admin-compliance/app/sdk/document-generator/examples/tia_de.json new file mode 100644 index 0000000..292774b --- /dev/null +++ b/admin-compliance/app/sdk/document-generator/examples/tia_de.json @@ -0,0 +1,19 @@ +{ + "document_type": "transfer_impact_assessment", + "language": "de", + "context": { + "PROVIDER": { "LEGAL_NAME": "Muster GmbH" }, + "PRIVACY": { "DPO_NAME": "Dr. Datenschutz", "DPO_EMAIL": "dsb@muster.de" }, + "FEATURES": { + "RECIPIENT_NAME": "Cloud Provider Inc.", + "RECIPIENT_COUNTRY": "US", + "RECIPIENT_ROLE": "Auftragsverarbeiter", + "TRANSFER_PURPOSE": "Hosting der Anwendungsdaten", + "TRANSFER_MECHANISM": "EU-Standardvertragsklauseln (SCC) + EU-US DPF", + "DATA_CATEGORIES_TRANSFERRED": "Stammdaten, Kontaktdaten, Nutzungsdaten", + "DATA_SUBJECTS": "Kunden, Nutzer der Plattform", + "TRANSFER_FREQUENCY": "Kontinuierlich (Echtzeit-Datenverarbeitung)" + }, + "TOM": { "GF_NAME": "Max Geschaeftsfuehrer", "DOCUMENT_VERSION": "1.0.0", "NEXT_REVIEW_DATE": "2027-05-01" } + } +} diff --git a/admin-compliance/app/sdk/document-generator/templateRecommendations.ts b/admin-compliance/app/sdk/document-generator/templateRecommendations.ts index 2cdeedb..6d5d41d 100644 --- a/admin-compliance/app/sdk/document-generator/templateRecommendations.ts +++ b/admin-compliance/app/sdk/document-generator/templateRecommendations.ts @@ -35,8 +35,11 @@ const TEMPLATE_RULES: TemplateRule[] = [ templateType: 'employee_dsi', label: 'Mitarbeiter-Datenschutzinformation', condition: (answers, level) => { + const hasEmployees = answers.get('org_has_employees') const empCount = answers.get('org_employee_count') - if (empCount && empCount !== 'none' && empCount !== '0') return level >= 'L2' ? 'required' : 'recommended' + if (hasEmployees === 'yes' || (empCount && empCount !== 'none' && empCount !== '0')) { + return level >= 'L2' ? 'required' : 'recommended' + } return null }, }, @@ -44,8 +47,11 @@ const TEMPLATE_RULES: TemplateRule[] = [ templateType: 'applicant_dsi', label: 'Bewerber-Datenschutzinformation', condition: (answers, level) => { + const hasEmployees = answers.get('org_has_employees') const empCount = answers.get('org_employee_count') - if (empCount && empCount !== 'none' && empCount !== '0') return level >= 'L2' ? 'recommended' : 'optional' + if (hasEmployees === 'yes' || (empCount && empCount !== 'none' && empCount !== '0')) { + return level >= 'L2' ? 'recommended' : 'optional' + } return null }, }, @@ -67,7 +73,7 @@ const TEMPLATE_RULES: TemplateRule[] = [ templateType: 'ai_usage_policy', label: 'KI-Nutzungsrichtlinie', condition: (answers) => { - const aiUsage = answers.get('proc_ai_usage') + const aiUsage = answers.get('proc_ai_usage') || answers.get('proc_uses_ai_tools') if (aiUsage && aiUsage !== 'none' && aiUsage !== 'no') return 'required' return null }, @@ -78,7 +84,8 @@ const TEMPLATE_RULES: TemplateRule[] = [ templateType: 'byod_policy', label: 'BYOD-Richtlinie', condition: (answers, level) => { - // BYOD relevant fuer Unternehmen mit Mitarbeitern + const byod = answers.get('proc_byod_allowed') + if (byod === 'yes') return 'required' if (level >= 'L3') return 'recommended' return 'optional' }, @@ -88,8 +95,9 @@ const TEMPLATE_RULES: TemplateRule[] = [ { templateType: 'social_media_dsi', label: 'Social-Media-Datenschutzinformation', - condition: (_answers, level) => { - // Fast jedes Unternehmen hat Social Media + condition: (answers, level) => { + const sm = answers.get('org_has_social_media') + if (sm === 'yes') return 'required' return level >= 'L2' ? 'recommended' : 'optional' }, }, @@ -98,7 +106,9 @@ const TEMPLATE_RULES: TemplateRule[] = [ { templateType: 'video_conference_dsi', label: 'Videokonferenz-Datenschutzinformation', - condition: (_answers, level) => { + condition: (answers, level) => { + const video = answers.get('org_has_video_conferencing') + if (video === 'yes') return 'recommended' if (level >= 'L3') return 'recommended' return 'optional' }, @@ -158,7 +168,8 @@ const TEMPLATE_RULES: TemplateRule[] = [ label: 'Gemeinschaftsrichtlinien', condition: (answers) => { const model = answers.get('org_business_model') - if (model === 'platform' || model === 'marketplace' || model === 'social') return 'required' + const ugc = answers.get('prod_ugc_platform') + if (ugc === 'yes' || model === 'platform' || model === 'marketplace' || model === 'social') return 'required' return null }, }, @@ -167,7 +178,8 @@ const TEMPLATE_RULES: TemplateRule[] = [ label: 'Nutzungsbedingungen', condition: (answers) => { const model = answers.get('org_business_model') - if (model === 'platform' || model === 'marketplace' || model === 'social' || model === 'saas') return 'required' + const ugc = answers.get('prod_ugc_platform') + if (ugc === 'yes' || model === 'platform' || model === 'marketplace' || model === 'social' || model === 'saas') return 'required' return null }, }, diff --git a/admin-compliance/lib/sdk/compliance-scope-data.ts b/admin-compliance/lib/sdk/compliance-scope-data.ts index 57b72b3..5a26b6e 100644 --- a/admin-compliance/lib/sdk/compliance-scope-data.ts +++ b/admin-compliance/lib/sdk/compliance-scope-data.ts @@ -52,6 +52,15 @@ export const QUESTION_SCORE_WEIGHTS: Record< comp_training: { risk: 5, complexity: 4, assurance: 7 }, comp_vendor_management: { risk: 6, complexity: 6, assurance: 7 }, comp_documentation_level: { risk: 6, complexity: 7, assurance: 8 }, + + // Zusaetzliche Fragen fuer Template-Empfehlungen (7 Fragen) + org_has_employees: { risk: 2, complexity: 3, assurance: 3 }, + org_has_social_media: { risk: 3, complexity: 2, assurance: 3 }, + org_has_video_conferencing: { risk: 2, complexity: 2, assurance: 2 }, + proc_uses_ai_tools: { risk: 7, complexity: 6, assurance: 7 }, + proc_byod_allowed: { risk: 5, complexity: 4, assurance: 5 }, + prod_ugc_platform: { risk: 6, complexity: 5, assurance: 6 }, + org_cert_iso27001: { risk: 2, complexity: 8, assurance: 9 }, } // ============================================================================