diff --git a/admin-compliance/app/sdk/company-profile/page.tsx b/admin-compliance/app/sdk/company-profile/page.tsx index 02d824b..2b5e77a 100644 --- a/admin-compliance/app/sdk/company-profile/page.tsx +++ b/admin-compliance/app/sdk/company-profile/page.tsx @@ -281,6 +281,18 @@ function StepBusinessModel({ ))} + + {/* Hint when both webshop and SaaS are selected */} + {(data.offerings || []).includes('webshop') && (data.offerings || []).includes('software_saas') && ( +
+ + + +

+ Hinweis: Wenn Sie reine Software verkaufen, genuegt SaaS/CloudOnline-Shop ist nur fuer physische Produkte oder Hardware mit Abo-Modell gedacht. +

+
+ )} {/* URL fields for selected offerings */} @@ -638,35 +650,30 @@ function StepDataProtection({ // DSGVO-Standard Datenkategorien const ALL_DATA_CATEGORIES = [ - { id: 'stammdaten', label: 'Stammdaten', desc: 'Name, Geburtsdatum, Geschlecht' }, - { id: 'kontaktdaten', label: 'Kontaktdaten', desc: 'E-Mail, Telefon, Adresse' }, - { id: 'vertragsdaten', label: 'Vertragsdaten', desc: 'Vertragsnummer, Laufzeit, Konditionen' }, - { id: 'zahlungsdaten', label: 'Zahlungs-/Bankdaten', desc: 'IBAN, Kreditkarte, Rechnungen' }, - { id: 'beschaeftigtendaten', label: 'Beschäftigtendaten', desc: 'Gehalt, Arbeitszeiten, Urlaub' }, - { id: 'kommunikation', label: 'Kommunikationsdaten', desc: 'E-Mail-Inhalte, Chat-Verläufe' }, - { id: 'nutzungsdaten', label: 'Nutzungs-/Logdaten', desc: 'IP-Adressen, Login-Zeiten, Klicks' }, - { id: 'standortdaten', label: 'Standortdaten', desc: 'GPS, Check-in, Lieferadressen' }, - { id: 'bilddaten', label: 'Bild-/Videodaten', desc: 'Fotos, Videoaufnahmen, Profilbilder' }, - { id: 'bewerberdaten', label: 'Bewerberdaten', desc: 'Lebenslauf, Zeugnisse, Anschreiben' }, + { id: 'stammdaten', label: 'Stammdaten', desc: 'Name, Geburtsdatum, Geschlecht', info: 'Vor- und Nachname, Geburtsdatum, Geschlecht, Anrede, Titel, Familienstand, Staatsangehörigkeit, Personalnummer, Kundennummer' }, + { id: 'kontaktdaten', label: 'Kontaktdaten', desc: 'E-Mail, Telefon, Adresse', info: 'E-Mail-Adresse, Telefonnummer, Mobilnummer, Postanschrift, Faxnummer, Messenger-IDs, Ansprechpartner-Namen bei Kunden/Lieferanten (z.B. SAP-Kontaktpersonen)' }, + { id: 'vertragsdaten', label: 'Vertragsdaten', desc: 'Vertragsnummer, Laufzeit, Konditionen', info: 'Vertragsnummer, Vertragsbeginn/-ende, Laufzeit, Konditionen, Kündigungsfristen, Vertragsgegenstand, Bestellhistorie' }, + { id: 'zahlungsdaten', label: 'Zahlungs-/Bankdaten', desc: 'IBAN, Kreditkarte, Rechnungen', info: 'IBAN, BIC, Kontoinhaber, Kreditkartennummer, Rechnungsbeträge, Zahlungshistorie, Steuer-ID, USt-IdNr.' }, + { id: 'beschaeftigtendaten', label: 'Beschäftigtendaten', desc: 'Gehalt, Arbeitszeiten, Urlaub', info: 'Gehalt/Lohn, Steuerklasse, SV-Nummer, Krankenkasse (z.B. AOK, TK), Arbeitszeiten, Urlaubstage, Abwesenheiten, Beurteilungen, Eintrittsdatum' }, + { id: 'kommunikation', label: 'Kommunikationsdaten', desc: 'E-Mail-Inhalte, Chat-Verläufe', info: 'E-Mail-Inhalte und -Metadaten, Chat-Nachrichten, Gesprächsprotokolle, Support-Tickets, Briefkorrespondenz' }, + { id: 'nutzungsdaten', label: 'Nutzungs-/Logdaten', desc: 'IP-Adressen, Login-Zeiten, Klicks', info: 'IP-Adressen, Login-Zeitpunkte, Seitenaufrufe, Klickverhalten, Geräteinformationen, Browser-Typ, Session-Dauer' }, + { id: 'standortdaten', label: 'Standortdaten', desc: 'GPS, Check-in, Lieferadressen', info: 'GPS-Koordinaten, Check-in/Check-out-Zeiten, Lieferadressen, Reiserouten, WLAN-Standortbestimmung' }, + { id: 'bilddaten', label: 'Bild-/Videodaten', desc: 'Fotos, Videoaufnahmen, Profilbilder', info: 'Profilfotos, Ausweiskopien, Videoaufnahmen (Überwachung), Bewerbungsfotos, Schulungsvideos' }, + { id: 'bewerberdaten', label: 'Bewerberdaten', desc: 'Lebenslauf, Zeugnisse, Anschreiben', info: 'Lebenslauf, Anschreiben, Zeugnisse, Referenzen, Gehaltsvorstellungen, Verfügbarkeit, Bewerbungsquelle' }, + { id: 'qualifikationsdaten', label: 'Qualifikations-/Schulungsdaten', desc: 'Fortbildungen, Zertifikate, Abschlüsse', info: 'Besuchte Seminare und Schulungen, Zertifikate, Abschlüsse, Qualifikationsnachweise, Schulungsdaten und -ergebnisse, Weiterbildungshistorie' }, ] as const const ALL_SPECIAL_CATEGORIES = [ - { id: 'gesundheit', label: 'Gesundheitsdaten', desc: 'Krankheitstage, Atteste, Diagnosen' }, - { id: 'biometrie', label: 'Biometrische Daten', desc: 'Fingerabdruck, Gesichtserkennung' }, - { id: 'religion', label: 'Religiöse Überzeugungen', desc: 'Konfession, Feiertage' }, - { id: 'gewerkschaft', label: 'Gewerkschaftszugehörigkeit', desc: 'Mitgliedschaft' }, - { id: 'genetik', label: 'Genetische Daten', desc: 'DNA, Erbkrankheiten' }, -] as const - -// Rechtsgrundlagen nach DSGVO Art. 6 -const LEGAL_BASES = [ - { id: 'consent', label: 'Einwilligung (Art. 6 Abs. 1a)' }, - { id: 'contract', label: 'Vertragserfüllung (Art. 6 Abs. 1b)' }, - { id: 'legal', label: 'Rechtliche Verpflichtung (Art. 6 Abs. 1c)' }, - { id: 'interest', label: 'Berechtigtes Interesse (Art. 6 Abs. 1f)' }, + { id: 'gesundheit', label: 'Gesundheitsdaten', desc: 'Krankheitstage, Atteste, Diagnosen', info: 'Krankheitstage, AU-Bescheinigungen, Diagnosen, Behinderungsgrad (GdB), BEM-Daten, arbeitsmedizinische Untersuchungen, Impfstatus, Allergien. NICHT: Krankenkassenname (z.B. AOK, TK) — das sind normale Beschäftigtendaten.' }, + { id: 'biometrie', label: 'Biometrische Daten', desc: 'Fingerabdruck, Gesichtserkennung', info: 'Fingerabdruck, Gesichtserkennung, Iris-Scan, Stimmerkennung, Handvenenscan (zur eindeutigen Identifizierung)' }, + { id: 'religion', label: 'Religiöse Überzeugungen', desc: 'Konfession, Feiertage', info: 'Konfession (relevant für Kirchensteuer), religiöse Feiertage, Ernährungsvorschriften' }, + { id: 'gewerkschaft', label: 'Gewerkschaftszugehörigkeit', desc: 'Mitgliedschaft', info: 'Gewerkschaftsmitgliedschaft, Betriebsratszugehörigkeit, Tarifzugehörigkeit' }, + { id: 'genetik', label: 'Genetische Daten', desc: 'DNA, Erbkrankheiten', info: 'DNA-Analysen, genetische Prädispositionen, Erbkrankheitsrisiken (nur in Spezialfällen relevant)' }, ] as const // Verarbeitungstätigkeiten mit aktivitätsspezifischen Datenkategorien +// Hinweis: Rechtsgrundlage (legal_basis) wird hier im Profil nicht angezeigt — +// die juristische Zuordnung erfolgt im VVT-Schritt (Art. 30 DSGVO). interface ActivityTemplate { id: string name: string @@ -674,6 +681,8 @@ interface ActivityTemplate { primary_categories: string[] // Sichtbar + vorausgewählt art9_relevant: string[] // Art. 9 Kategorien die plausibel relevant sind default_legal_basis: string + legalHint?: string // Gesetzlicher Hinweis (z.B. ArbZG-Pflicht) + hasServiceProvider?: boolean // Kann ein externer Dienstleister eingesetzt werden? } interface ActivityDepartment { @@ -690,17 +699,17 @@ const UNIVERSAL_DEPARTMENTS: ActivityDepartment[] = [ id: 'personal', name: 'Personal / HR', icon: '👥', activities: [ { id: 'personalverwaltung', name: 'Personalverwaltung', purpose: 'Verwaltung von Beschäftigtendaten für das Arbeitsverhältnis', primary_categories: ['stammdaten', 'kontaktdaten', 'beschaeftigtendaten', 'zahlungsdaten'], art9_relevant: ['gesundheit', 'religion', 'gewerkschaft'], default_legal_basis: 'contract' }, - { id: 'lohnbuchhaltung', name: 'Lohn- und Gehaltsabrechnung', purpose: 'Berechnung und Auszahlung von Löhnen und Gehältern', primary_categories: ['beschaeftigtendaten', 'zahlungsdaten', 'stammdaten'], art9_relevant: ['gesundheit', 'religion'], default_legal_basis: 'legal' }, - { id: 'bewerbermanagement', name: 'Bewerbermanagement', purpose: 'Entgegennahme, Prüfung und Bearbeitung von Bewerbungen', primary_categories: ['bewerberdaten', 'stammdaten', 'kontaktdaten', 'kommunikation'], art9_relevant: ['gesundheit'], default_legal_basis: 'consent' }, - { id: 'arbeitszeiterfassung', name: 'Arbeitszeiterfassung', purpose: 'Erfassung und Dokumentation der Arbeitszeiten', primary_categories: ['beschaeftigtendaten'], art9_relevant: [], default_legal_basis: 'legal' }, - { id: 'weiterbildung', name: 'Fort- und Weiterbildung', purpose: 'Verwaltung von Schulungen und Weiterbildungsmaßnahmen', primary_categories: ['beschaeftigtendaten', 'stammdaten'], art9_relevant: [], default_legal_basis: 'contract' }, + { id: 'lohnbuchhaltung', name: 'Lohn- und Gehaltsabrechnung', purpose: 'Berechnung und Auszahlung von Löhnen und Gehältern', primary_categories: ['beschaeftigtendaten', 'zahlungsdaten', 'stammdaten'], art9_relevant: ['gesundheit', 'religion'], default_legal_basis: 'legal', hasServiceProvider: true }, + { id: 'bewerbermanagement', name: 'Bewerbermanagement', purpose: 'Entgegennahme, Prüfung und Bearbeitung von Bewerbungen', primary_categories: ['bewerberdaten', 'stammdaten', 'kontaktdaten', 'kommunikation', 'qualifikationsdaten'], art9_relevant: ['gesundheit', 'religion'], default_legal_basis: 'consent' }, + { id: 'arbeitszeiterfassung', name: 'Arbeitszeiterfassung', purpose: 'Erfassung und Dokumentation der Arbeitszeiten', primary_categories: ['beschaeftigtendaten'], art9_relevant: [], default_legal_basis: 'legal', legalHint: 'Gesetzlich vorgeschrieben (§ 3 ArbZG). Fehlende Arbeitszeiterfassung ist ein Compliance-Risiko.' }, + { id: 'weiterbildung', name: 'Fort- und Weiterbildung', purpose: 'Verwaltung von Schulungen und Weiterbildungsmaßnahmen', primary_categories: ['qualifikationsdaten', 'beschaeftigtendaten', 'stammdaten'], art9_relevant: [], default_legal_basis: 'contract' }, ], }, { id: 'finanzen', name: 'Finanzen / Buchhaltung', icon: '💰', activities: [ { id: 'finanzbuchhaltung', name: 'Finanzbuchhaltung', purpose: 'Buchführung, Rechnungsstellung, steuerliche Dokumentation', primary_categories: ['stammdaten', 'zahlungsdaten', 'vertragsdaten', 'kontaktdaten'], art9_relevant: [], default_legal_basis: 'legal' }, - { id: 'zahlungsverkehr', name: 'Zahlungsverkehr', purpose: 'Abwicklung von ein- und ausgehenden Zahlungen', primary_categories: ['zahlungsdaten', 'stammdaten', 'kontaktdaten'], art9_relevant: [], default_legal_basis: 'contract' }, + { id: 'zahlungsverkehr', name: 'Zahlungsverkehr', purpose: 'Abwicklung von ein- und ausgehenden Zahlungen', primary_categories: ['zahlungsdaten', 'stammdaten', 'kontaktdaten', 'vertragsdaten'], art9_relevant: [], default_legal_basis: 'contract' }, { id: 'mahnwesen', name: 'Mahnwesen / Inkasso', purpose: 'Überwachung offener Forderungen und Mahnverfahren', primary_categories: ['stammdaten', 'kontaktdaten', 'zahlungsdaten', 'vertragsdaten'], art9_relevant: [], default_legal_basis: 'interest' }, { id: 'reisekostenabrechnung', name: 'Reisekostenabrechnung', purpose: 'Abrechnung und Erstattung von Dienstreisekosten', primary_categories: ['beschaeftigtendaten', 'zahlungsdaten', 'standortdaten'], art9_relevant: [], default_legal_basis: 'contract' }, ], @@ -728,7 +737,7 @@ const UNIVERSAL_DEPARTMENTS: ActivityDepartment[] = [ { id: 'zugangsverwaltung', name: 'Zugangsverwaltung (IAM)', purpose: 'Verwaltung von Benutzerkonten, Passwörtern und Zugriffsrechten', primary_categories: ['beschaeftigtendaten', 'stammdaten', 'nutzungsdaten'], art9_relevant: ['biometrie'], default_legal_basis: 'contract' }, { id: 'email_kommunikation', name: 'E-Mail-Kommunikation', purpose: 'Geschäftliche E-Mail-Korrespondenz', primary_categories: ['kontaktdaten', 'kommunikation', 'stammdaten'], art9_relevant: [], default_legal_basis: 'interest' }, { id: 'datensicherung', name: 'Datensicherung / Backup', purpose: 'Sicherung von Unternehmensdaten zum Schutz vor Datenverlust', primary_categories: ['nutzungsdaten', 'beschaeftigtendaten'], art9_relevant: [], default_legal_basis: 'interest' }, - { id: 'website_betrieb', name: 'Website-Betrieb', purpose: 'Bereitstellung der Unternehmenswebsite und Kontaktformulare', primary_categories: ['nutzungsdaten', 'kontaktdaten'], art9_relevant: [], default_legal_basis: 'interest' }, + { id: 'website_betrieb', name: 'Website-Betrieb', purpose: 'Bereitstellung der Unternehmenswebsite und Kontaktformulare', primary_categories: ['nutzungsdaten', 'kontaktdaten', 'stammdaten'], art9_relevant: [], default_legal_basis: 'interest', hasServiceProvider: true, legalHint: 'Bei externem Website-Management: AVV nach Art. 28 DSGVO mit dem Dienstleister erforderlich. Cookies, Analytics und Kontaktformulare verarbeiten personenbezogene Daten — auch wenn der Dienstleister sie technisch betreibt, bleibt Ihr Unternehmen verantwortlich.' }, { id: 'it_sicherheit', name: 'IT-Sicherheit / Logging', purpose: 'Überwachung der IT-Sicherheit, Log-Analyse, Vorfallbehandlung', primary_categories: ['nutzungsdaten', 'beschaeftigtendaten'], art9_relevant: [], default_legal_basis: 'interest' }, ], }, @@ -858,6 +867,8 @@ interface ProcessingActivity { legal_basis: string department?: string custom?: boolean + usesServiceProvider?: boolean + serviceProviderName?: string } interface AISystem { @@ -889,6 +900,7 @@ function StepProcessingAndAI({ const [expandedActivity, setExpandedActivity] = useState(null) const [collapsedDepts, setCollapsedDepts] = useState>(new Set()) const [showExtraCategories, setShowExtraCategories] = useState>(new Set()) + const [expandedInfoCat, setExpandedInfoCat] = useState(null) const departments = getRelevantDepartments(industry, data.businessModel, data.companySize) const activeIds = new Set(activities.map(a => a.id)) @@ -978,6 +990,36 @@ function StepProcessingAndAI({ onChange({ aiSystems: updated }) } + // Render a data category checkbox with info tooltip + const renderCategoryCheckbox = (cat: { id: string; label: string; desc: string; info: string }, activity: ProcessingActivity, variant: 'normal' | 'extra' | 'art9' | 'art9-extra') => { + const isInfoExpanded = expandedInfoCat === `${activity.id}-${cat.id}` + const colorClasses = variant.startsWith('art9') + ? { check: 'text-red-600 focus:ring-red-500', hover: 'hover:bg-red-100', text: variant === 'art9-extra' ? 'text-gray-500' : 'text-gray-700' } + : { check: 'text-purple-600 focus:ring-purple-500', hover: 'hover:bg-gray-100', text: variant === 'extra' ? 'text-gray-500' : 'text-gray-700' } + + return ( +
+ + {isInfoExpanded && ( +
+ {cat.info} +
+ )} +
+ ) + } + // Render activity detail panel (shared between template and custom) const renderActivityDetail = (activity: ProcessingActivity, template: ActivityTemplate | null) => { const primaryIds = new Set(template?.primary_categories || []) @@ -992,6 +1034,14 @@ function StepProcessingAndAI({ return (
+ {/* Legal hint (e.g. ArbZG for Arbeitszeiterfassung) */} + {template?.legalHint && ( +
+ + {template.legalHint} +
+ )} + {/* Custom: name + purpose fields */} {isCustom && (
@@ -1000,16 +1050,43 @@ function StepProcessingAndAI({
)} + {/* Service Provider option (e.g. for Lohn- und Gehaltsabrechnung) */} + {template?.hasServiceProvider && ( +
+ + {activity.usesServiceProvider && ( +
+ updateActivity(activity.id, { serviceProviderName: e.target.value })} + placeholder="Name des Dienstleisters (optional)" + className="w-full px-3 py-1.5 border border-blue-200 rounded text-xs focus:ring-2 focus:ring-blue-400 focus:border-transparent bg-white" + /> +

Wird als Auftragsverarbeiter (AVV) im VVT erfasst.

+
+ )} +
+ )} + {/* Primary Data Categories */}
- {(isCustom ? ALL_DATA_CATEGORIES : primaryCats).map(cat => ( - - ))} + {(isCustom ? ALL_DATA_CATEGORIES : primaryCats).map(cat => + renderCategoryCheckbox(cat, activity, isCustom ? 'normal' : 'normal') + )}
@@ -1021,12 +1098,7 @@ function StepProcessingAndAI({ {showingExtra && (
- {extraCats.map(cat => ( - - ))} + {extraCats.map(cat => renderCategoryCheckbox(cat, activity, 'extra'))}
)}
@@ -1037,40 +1109,21 @@ function StepProcessingAndAI({
- {(isCustom ? ALL_SPECIAL_CATEGORIES : relevantArt9).map(cat => ( - - ))} + {(isCustom ? ALL_SPECIAL_CATEGORIES : relevantArt9).map(cat => + renderCategoryCheckbox(cat, activity, 'art9') + )}
{/* Show remaining Art. 9 categories if expanded */} {!isCustom && otherArt9.length > 0 && showingExtra && (
- {otherArt9.map(cat => ( - - ))} + {otherArt9.map(cat => renderCategoryCheckbox(cat, activity, 'art9-extra'))}
)}
)} - {/* Legal Basis */} -
- - -
- @@ -1142,7 +1195,15 @@ function StepProcessingAndAI({ className="w-4 h-4 text-purple-600 rounded focus:ring-purple-500 flex-shrink-0" />
- {template.name} +
+ {template.name} + {template.legalHint && ( + Pflicht + )} + {template.hasServiceProvider && ( + AVV-relevant + )} +

{template.purpose}

{isActive && ( diff --git a/admin-compliance/lib/sdk/types.ts b/admin-compliance/lib/sdk/types.ts index dda9da4..41fa1de 100644 --- a/admin-compliance/lib/sdk/types.ts +++ b/admin-compliance/lib/sdk/types.ts @@ -232,9 +232,9 @@ export const OFFERING_TYPE_LABELS: Record