// ============================================================================= // TOM Document — HTML Sections 1–6 // ============================================================================= import type { DerivedTOM, CompanyProfile, RiskProfile, ControlCategory } from '../tom-generator/types' import { getControlById, getAllCategories, getCategoryMetadata } from '../tom-generator/controls/loader' import type { TOMDocumentOrgHeader } from './types-defaults' import { CATEGORY_LABELS_DE, STATUS_LABELS_DE, STATUS_BADGE_CLASSES, APPLICABILITY_LABELS_DE, } from './types-defaults' import { escHtml, formatDateDE } from './helpers' export function buildSections1to6( orgName: string, orgHeader: TOMDocumentOrgHeader, companyProfile: CompanyProfile | null, riskProfile: RiskProfile | null, applicableTOMs: DerivedTOM[], tomsByCategory: Map, today: string ): string { let html = '' html += buildCoverAndTOC(orgName, orgHeader, applicableTOMs, tomsByCategory, today) html += buildSection1(orgName) html += buildSection2(orgName, orgHeader, companyProfile, applicableTOMs, tomsByCategory) html += buildSection3() html += buildSection4(riskProfile) html += buildSection5(tomsByCategory) html += buildSection6(tomsByCategory) return html } function buildCoverAndTOC( orgName: string, orgHeader: TOMDocumentOrgHeader, applicableTOMs: DerivedTOM[], tomsByCategory: Map, today: string ): string { const sections = [ 'Ziel und Zweck', 'Geltungsbereich', 'Grundprinzipien Art. 32', 'Schutzbedarf und Risikoanalyse', 'Massnahmen-Uebersicht', 'Detaillierte Massnahmen', 'SDM Gewaehrleistungsziele', 'Verantwortlichkeiten', 'Pruef- und Revisionszyklus', 'Compliance-Status', 'Aenderungshistorie', ] return `

TOM-Dokumentation

Technische und Organisatorische Massnahmen gemaess Art. 32 DSGVO
Organisation: ${escHtml(orgName)}
${orgHeader.industry ? `
Branche: ${escHtml(orgHeader.industry)}
` : ''} ${orgHeader.dpoName ? `
DSB: ${escHtml(orgHeader.dpoName)}
` : ''} ${orgHeader.dpoContact ? `
DSB-Kontakt: ${escHtml(orgHeader.dpoContact)}
` : ''} ${orgHeader.responsiblePerson ? `
Verantwortlicher: ${escHtml(orgHeader.responsiblePerson)}
` : ''} ${orgHeader.itSecurityContact ? `
IT-Sicherheit: ${escHtml(orgHeader.itSecurityContact)}
` : ''} ${orgHeader.employeeCount ? `
Mitarbeiter: ${escHtml(orgHeader.employeeCount)}
` : ''} ${orgHeader.locations.length > 0 ? `
Standorte: ${escHtml(orgHeader.locations.join(', '))}
` : ''}

Inhaltsverzeichnis

${sections.map((s, i) => `
${i + 1}. ${escHtml(s)}
`).join('\n ')}
` } function buildSection1(orgName: string): string { return `
1. Ziel und Zweck

Diese TOM-Dokumentation beschreibt die technischen und organisatorischen Massnahmen zum Schutz personenbezogener Daten bei ${escHtml(orgName)}. Sie dient der Umsetzung folgender DSGVO-Anforderungen:

RechtsgrundlageInhalt
Art. 32 Abs. 1 lit. a DSGVOPseudonymisierung und Verschluesselung personenbezogener Daten
Art. 32 Abs. 1 lit. b DSGVOFaehigkeit, die Vertraulichkeit, Integritaet, Verfuegbarkeit und Belastbarkeit der Systeme und Dienste im Zusammenhang mit der Verarbeitung auf Dauer sicherzustellen
Art. 32 Abs. 1 lit. c DSGVOFaehigkeit, die Verfuegbarkeit der personenbezogenen Daten und den Zugang zu ihnen bei einem physischen oder technischen Zwischenfall rasch wiederherzustellen
Art. 32 Abs. 1 lit. d DSGVOVerfahren zur regelmaessigen Ueberpruefung, Bewertung und Evaluierung der Wirksamkeit der technischen und organisatorischen Massnahmen

Die TOM-Dokumentation ist fester Bestandteil des Datenschutz-Managementsystems und wird regelmaessig ueberprueft und aktualisiert.

` } function buildSection2( orgName: string, orgHeader: TOMDocumentOrgHeader, companyProfile: CompanyProfile | null, applicableTOMs: DerivedTOM[], tomsByCategory: Map ): string { const industryInfo = companyProfile?.industry || orgHeader.industry || '' const hostingInfo = companyProfile ? `Unternehmen: ${escHtml(companyProfile.name || orgName)}, Groesse: ${escHtml(companyProfile.size || '-')}` : '' return `
2. Geltungsbereich

Diese TOM-Dokumentation gilt fuer alle IT-Systeme, Anwendungen und Verarbeitungsprozesse von ${escHtml(orgName)}${industryInfo ? ` (Branche: ${escHtml(industryInfo)})` : ''}.

${hostingInfo ? `

${hostingInfo}

` : ''} ${orgHeader.locations.length > 0 ? `

Standorte: ${escHtml(orgHeader.locations.join(', '))}

` : ''}

Die dokumentierten Massnahmen stammen aus zwei Quellen:

  • Embedded Library (TOM-xxx): Integrierte Kontrollbibliothek mit spezifischen Massnahmen fuer Art. 32 DSGVO
  • Canonical Control Library (CP-CLIB): Uebergreifende Kontrollbibliothek mit framework-uebergreifenden Massnahmen

Insgesamt umfasst dieses Dokument ${applicableTOMs.length} anwendbare Massnahmen in ${tomsByCategory.size} Kategorien.

` } function buildSection3(): string { return `
3. Grundprinzipien Art. 32
Vertraulichkeit: Schutz personenbezogener Daten vor unbefugter Kenntnisnahme durch Zutrittskontrolle, Zugangskontrolle, Zugriffskontrolle und Verschluesselung (Art. 32 Abs. 1 lit. b DSGVO).
Integritaet: Sicherstellung, dass personenbezogene Daten nicht unbefugt oder unbeabsichtigt veraendert werden koennen, durch Eingabekontrolle, Weitergabekontrolle und Protokollierung (Art. 32 Abs. 1 lit. b DSGVO).
Verfuegbarkeit und Belastbarkeit: Gewaehrleistung, dass Systeme und Dienste bei Lastspitzen und Stoerungen zuverlaessig funktionieren, durch Backup, Redundanz und Disaster Recovery (Art. 32 Abs. 1 lit. b DSGVO).
Rasche Wiederherstellbarkeit: Faehigkeit, nach einem physischen oder technischen Zwischenfall Daten und Systeme schnell wiederherzustellen, durch getestete Recovery-Prozesse (Art. 32 Abs. 1 lit. c DSGVO).
Regelmaessige Wirksamkeitspruefung: Verfahren zur regelmaessigen Ueberpruefung, Bewertung und Evaluierung der Wirksamkeit aller technischen und organisatorischen Massnahmen (Art. 32 Abs. 1 lit. d DSGVO).
` } function buildSection4(riskProfile: RiskProfile | null): string { let html = `
4. Schutzbedarf und Risikoanalyse
` if (riskProfile) { html += `

Die folgende Schutzbedarfsanalyse bildet die Grundlage fuer die Auswahl und Priorisierung der technischen und organisatorischen Massnahmen:

${riskProfile.specialRisks.length > 0 ? `` : ''} ${riskProfile.regulatoryRequirements.length > 0 ? `` : ''}
KriteriumBewertung
Vertraulichkeit${riskProfile.ciaAssessment.confidentiality}/5
Integritaet${riskProfile.ciaAssessment.integrity}/5
Verfuegbarkeit${riskProfile.ciaAssessment.availability}/5
Schutzniveau${escHtml(riskProfile.protectionLevel)}
DSFA-Pflicht${riskProfile.dsfaRequired ? 'Ja' : 'Nein'}
Spezialrisiken${escHtml(riskProfile.specialRisks.join(', '))}
Regulatorische Anforderungen${escHtml(riskProfile.regulatoryRequirements.join(', '))}
` } else { html += `

Die Schutzbedarfsanalyse wurde noch nicht durchgefuehrt. Fuehren Sie den Risiko-Wizard im TOM-Generator durch, um den Schutzbedarf zu ermitteln.

` } html += `
` return html } function buildSection5(tomsByCategory: Map): string { const allCategories = getAllCategories() let html = `
5. Massnahmen-Uebersicht

Die folgende Tabelle zeigt eine Uebersicht aller anwendbaren Massnahmen nach Kategorie:

` for (const cat of allCategories) { const tomsInCat = tomsByCategory.get(cat) if (!tomsInCat || tomsInCat.length === 0) continue const implemented = tomsInCat.filter(t => t.implementationStatus === 'IMPLEMENTED').length const partial = tomsInCat.filter(t => t.implementationStatus === 'PARTIAL').length const notImpl = tomsInCat.filter(t => t.implementationStatus === 'NOT_IMPLEMENTED').length const catLabel = CATEGORY_LABELS_DE[cat] || cat html += ` ` } html += `
Kategorie Gesamt Umgesetzt Teilweise Offen
${escHtml(catLabel)} ${tomsInCat.length} ${implemented} ${partial} ${notImpl}
` return html } function buildSection6(tomsByCategory: Map): string { const allCategories = getAllCategories() let html = `
6. Detaillierte Massnahmen
` for (const cat of allCategories) { const tomsInCat = tomsByCategory.get(cat) if (!tomsInCat || tomsInCat.length === 0) continue const catLabel = CATEGORY_LABELS_DE[cat] || cat const catMeta = getCategoryMetadata(cat) const gdprRef = catMeta?.gdprReference || '' html += `

${escHtml(catLabel)}${gdprRef ? ` (${escHtml(gdprRef)})` : ''}

` const sortedTOMs = [...tomsInCat].sort((a, b) => { const codeA = getControlById(a.controlId)?.code || a.controlId const codeB = getControlById(b.controlId)?.code || b.controlId return codeA.localeCompare(codeB) }) for (const tom of sortedTOMs) { const control = getControlById(tom.controlId) const code = control?.code || tom.controlId const nameDE = control?.name?.de || tom.name const descDE = control?.description?.de || tom.description const typeLabel = control?.type === 'TECHNICAL' ? 'Technisch' : control?.type === 'ORGANIZATIONAL' ? 'Organisatorisch' : '-' const statusLabel = STATUS_LABELS_DE[tom.implementationStatus] || tom.implementationStatus const statusBadge = STATUS_BADGE_CLASSES[tom.implementationStatus] || 'badge-draft' const applicabilityLabel = APPLICABILITY_LABELS_DE[tom.applicability] || tom.applicability const responsible = [tom.responsiblePerson, tom.responsibleDepartment].filter(s => s && s.trim()).join(' / ') || '-' const implDate = tom.implementationDate ? formatDateDE(typeof tom.implementationDate === 'string' ? tom.implementationDate : tom.implementationDate.toISOString()) : '-' const reviewDate = tom.reviewDate ? formatDateDE(typeof tom.reviewDate === 'string' ? tom.reviewDate : tom.reviewDate.toISOString()) : '-' const evidenceInfo = tom.linkedEvidence.length > 0 ? tom.linkedEvidence.join(', ') : tom.evidenceGaps.length > 0 ? `Fehlend: ${escHtml(tom.evidenceGaps.join(', '))}` : '-' let mappingsHtml = '-' if (control?.mappings && control.mappings.length > 0) { mappingsHtml = control.mappings.map(m => `${escHtml(m.framework)}: ${escHtml(m.reference)}`).join('
') } html += `
${escHtml(code)} — ${escHtml(nameDE)} ${escHtml(statusLabel)}
Beschreibung${escHtml(descDE)}
Massnahmentyp${escHtml(typeLabel)}
Anwendbarkeit${escHtml(applicabilityLabel)}${tom.applicabilityReason ? ` — ${escHtml(tom.applicabilityReason)}` : ''}
Umsetzungsstatus${escHtml(statusLabel)}
Verantwortlich${escHtml(responsible)}
Umsetzungsdatum${implDate}
Naechste Pruefung${reviewDate}
Evidence${evidenceInfo}
Framework-Mappings${mappingsHtml}
` } } html += `
` return html }