Files
breakpilot-compliance/admin-compliance/app/sdk/document-generator/scopeDefaults.ts
T
Benjamin Admin a28db8f8f0 fix(admin): resolve all 266 TypeScript errors, enable strict build
Eliminate the pre-existing TS errors that were masked by
next.config.js `typescript.ignoreBuildErrors: true`, then turn the flag
OFF so the compiler is a real safety net for future changes. `next build`
and `tsc --noEmit` now pass with 0 errors.

The errors were not cosmetic — several exposed real latent bugs hidden by
the flag, e.g. the drafting-engine ConstraintEnforcer read non-existent
fields (`t.rule.dsfaRequired`, `d.required`, `r.title`), so its DSFA hard
gate and risk-flag checks were silently no-ops; scopeDefaults read
snake_case CompanyProfile fields that never matched the camelCase type
(generator defaults never populated). Both fixed by aligning code to the
current types.

Highlights:
- Vitest globals: add vitest-globals.d.ts (config already had globals:true)
  so the test files type-check; exclude Playwright specs from vitest.
- Add a minimal ambient `pg` module declaration (no @types/pg installed).
- Fix Next 15 route handlers to await Promise params.
- Reconcile drifted types across loeschfristen, compliance-scope, document-
  generator, drafting-engine, vendor-compliance, agent and more.

Pre-existing (NOT caused here, proven by stashing the diff): 3 vitest
logic tests still fail — getNextStep (2) and buildDocumentScope priority (1).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 00:42:44 +02:00

317 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.companyName) {
dpaBase.AN_NAME = profile.companyName
scopeSet.add('DPA.AN_NAME')
}
if (profile.headquartersStreet) {
dpaBase.AN_STRASSE = profile.headquartersStreet
scopeSet.add('DPA.AN_STRASSE')
}
if (profile.headquartersCity && profile.headquartersZip) {
dpaBase.AN_PLZ_ORT = `${profile.headquartersZip} ${profile.headquartersCity}`
scopeSet.add('DPA.AN_PLZ_ORT')
}
if (profile.dpoName) {
tomBase.ISB_NAME = tomBase.ISB_NAME || ''
dpaBase.AN_DSB_NAME = profile.dpoName
scopeSet.add('DPA.AN_DSB_NAME')
}
if (profile.dpoEmail) {
dpaBase.AN_DSB_EMAIL = profile.dpoEmail
scopeSet.add('DPA.AN_DSB_EMAIL')
}
// Unterzeichner/GF werden NICHT aus dem CompanyProfile befuellt — es enthaelt
// keine Person; diese Felder kommen aus dem TOM/DPA-Generator selbst.
}
// 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: [] }
}
}