// ============================================================================= // TOM Document — HTML Sections 7–11 // ============================================================================= import type { DerivedTOM, ControlCategory } from '../tom-generator/types' import { SDM_CATEGORY_MAPPING } from '../tom-generator/types' import type { TOMComplianceCheckResult, TOMComplianceIssueSeverity } from '../tom-compliance' import type { TOMDocumentOrgHeader, TOMDocumentRevision } from './types-defaults' import { SEVERITY_LABELS_DE, SEVERITY_COLORS } from './types-defaults' import { escHtml, formatDateDE } from './helpers' export function buildSections7to11( orgName: string, orgHeader: TOMDocumentOrgHeader, tomsByCategory: Map, roleMap: Map, complianceResult: TOMComplianceCheckResult | null, revisions: TOMDocumentRevision[], today: string ): string { let html = '' html += buildSection7(tomsByCategory) html += buildSection8(roleMap) html += buildSection9(orgHeader) html += buildSection10(complianceResult) html += buildSection11(revisions, orgHeader, today) return html } function buildSection7(tomsByCategory: Map): string { const allSDMGoals = [ 'Verfuegbarkeit', 'Integritaet', 'Vertraulichkeit', 'Nichtverkettung', 'Intervenierbarkeit', 'Transparenz', 'Datenminimierung', ] as const const sdmGoals: Array<{ goal: string; categories: ControlCategory[] }> = [] for (const goal of allSDMGoals) { const cats: ControlCategory[] = [] for (const [cat, goals] of Object.entries(SDM_CATEGORY_MAPPING)) { if (goals.includes(goal)) { cats.push(cat as ControlCategory) } } sdmGoals.push({ goal, categories: cats }) } let html = `
7. SDM Gewaehrleistungsziele

Die folgende Tabelle zeigt die Abdeckung der sieben Gewaehrleistungsziele des Standard-Datenschutzmodells (SDM) durch die implementierten Massnahmen:

` for (const { goal, categories } of sdmGoals) { let totalInGoal = 0 let implementedInGoal = 0 for (const cat of categories) { const tomsInCat = tomsByCategory.get(cat) || [] totalInGoal += tomsInCat.length implementedInGoal += tomsInCat.filter(t => t.implementationStatus === 'IMPLEMENTED').length } const percentage = totalInGoal > 0 ? Math.round((implementedInGoal / totalInGoal) * 100) : 0 html += ` ` } html += `
Gewaehrleistungsziel Abgedeckt Gesamt Abdeckung (%)
${escHtml(goal)} ${implementedInGoal} ${totalInGoal} ${percentage}%
` return html } function buildSection8(roleMap: Map): string { let html = `
8. Verantwortlichkeiten

Die folgende Rollenmatrix zeigt, welche Personen oder Abteilungen fuer welche Massnahmen die Umsetzungsverantwortung tragen:

` for (const [role, controls] of roleMap.entries()) { html += ` ` } html += `
Rolle / VerantwortlichMassnahmenAnzahl
${escHtml(role)} ${controls.map(c => escHtml(c)).join(', ')} ${controls.length}
` return html } function buildSection9(orgHeader: TOMDocumentOrgHeader): string { return `
9. Pruef- und Revisionszyklus
EigenschaftWert
Aktuelles Pruefintervall${escHtml(orgHeader.reviewInterval)}
Letzte Pruefung${formatDateDE(orgHeader.lastReviewDate)}
Naechste Pruefung${formatDateDE(orgHeader.nextReviewDate)}
Aktuelle Version${escHtml(orgHeader.documentVersion)}

Bei jeder Pruefung wird die TOM-Dokumentation auf folgende Punkte ueberprueft:

  • Vollstaendigkeit aller Massnahmen (neue Systeme oder Verarbeitungen erfasst?)
  • Aktualitaet des Umsetzungsstatus (Aenderungen seit letzter Pruefung?)
  • Wirksamkeit der technischen Massnahmen (Penetration-Tests, Audit-Ergebnisse)
  • Angemessenheit der organisatorischen Massnahmen (Schulungen, Richtlinien aktuell?)
  • Abdeckung aller SDM-Gewaehrleistungsziele
  • Zuordnung von Verantwortlichkeiten zu allen Massnahmen
` } function buildSection10(complianceResult: TOMComplianceCheckResult | null): string { let html = `
10. Compliance-Status
` if (complianceResult) { const scoreClass = complianceResult.score >= 90 ? 'score-excellent' : complianceResult.score >= 75 ? 'score-good' : complianceResult.score >= 50 ? 'score-needs-work' : 'score-poor' const scoreLabel = complianceResult.score >= 90 ? 'Ausgezeichnet' : complianceResult.score >= 75 ? 'Gut' : complianceResult.score >= 50 ? 'Verbesserungswuerdig' : 'Mangelhaft' html += `

${complianceResult.score}/100 ${escHtml(scoreLabel)}

KennzahlWert
Gepruefte Massnahmen${complianceResult.stats.total}
Bestanden${complianceResult.stats.passed}
Beanstandungen${complianceResult.stats.failed}
` if (complianceResult.issues.length > 0) { html += `

Befunde nach Schweregrad:

` const severityOrder: TOMComplianceIssueSeverity[] = ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW'] for (const sev of severityOrder) { const count = complianceResult.stats.bySeverity[sev] if (count === 0) continue const issuesForSev = complianceResult.issues.filter(i => i.severity === sev) html += ` ` } html += `
SchweregradAnzahlBefunde
${SEVERITY_LABELS_DE[sev]} ${count} ${issuesForSev.map(i => escHtml(i.title)).join('; ')}
` } else { html += `

Keine Beanstandungen. Alle Massnahmen sind konform.

` } } else { html += `

Compliance-Check wurde noch nicht ausgefuehrt. Fuehren Sie den Check im Export-Tab durch, um den Status in das Dokument aufzunehmen.

` } html += `
` return html } function buildSection11( revisions: TOMDocumentRevision[], orgHeader: TOMDocumentOrgHeader, today: string ): string { let html = `
11. Aenderungshistorie
` if (revisions.length > 0) { for (const rev of revisions) { html += ` ` } } else { html += ` ` } html += `
VersionDatumAutorAenderungen
${escHtml(rev.version)} ${formatDateDE(rev.date)} ${escHtml(rev.author)} ${escHtml(rev.changes)}
${escHtml(orgHeader.documentVersion)} ${today} ${escHtml(orgHeader.dpoName || orgHeader.responsiblePerson || '-')} Erstversion der TOM-Dokumentation
` return html }