bae59e2ce0
Complete overhaul of document generator templates based on paragraph-by-paragraph legal review of attorney-drafted templates (TOM, AVV, AGB, DSI, Community Guidelines, Nutzungsbedingungen, Widerrufsbelehrung, Cookie-Richtlinie). Templates (11 migrations 087-097): - 087: TOM-Dokumentation v2 (11 categories incl. Trennungskontrolle) - 088: AVV Art. 28 DSGVO (complete, §§ 1-11, 3 annexes) - 089: Cross-document updates (Löschkonzept DIN 66399, VVT recipients) - 090: AGB SaaS/Shop v2 (18 §§, B2B/B2C, IoT, physical goods, IP protection) - 091: Community Guidelines v2 (3 tones, 11 modular categories, DSA-compliant) - 092: Media & Content modules (MStV, AI Act Art. 50, UWG, Pressekodex) - 093: DSI/Privacy Policy v2 (Art. 13 complete, shop+corporate modules) - 094: Nutzungsbedingungen (Terms of Use, UGC, tipping, wallet, CC licenses) - 095: Widerrufsbelehrung (SaaS + physical + IoT bundle + combo) - 096: Social Media DSI (Facebook, YouTube, LinkedIn, TikTok, Meta Pixel) - 097: Cookie-Richtlinie v2 (TDDDG § 25, consent banner, browser links) Frontend (generator): - scopeDefaults.ts: L1-L4 scope-based defaults from Compliance Scope Engine - contextBridge.ts: TOMCtx + DPACtx interfaces (70+ new fields) - contextBridge-helpers.ts: 35+ placeholder mappings for TOM/DPA/AGB - _constants.ts: 120+ new generator fields (TOM, DPA, AGB, community, media, social, nutzungsbedingungen, widerruf, cookie, shop, IoT) - page.tsx: Auto-prefill TOM/DPA from scope engine decision Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
392 lines
13 KiB
TypeScript
392 lines
13 KiB
TypeScript
/**
|
||
* Template-Spec v1 — Context Bridge
|
||
*
|
||
* Maps a structured TemplateContext (canonical entities: PROVIDER, CUSTOMER, etc.)
|
||
* to the flat {{PLACEHOLDER}} map used by legacy templates.
|
||
*
|
||
* Flow: TemplateContext → contextToPlaceholders() → Record<string, string>
|
||
* → string.replace({{KEY}}, value) in renderer
|
||
*/
|
||
|
||
// =============================================================================
|
||
// Types
|
||
// =============================================================================
|
||
|
||
export interface ProviderCtx {
|
||
LEGAL_NAME: string
|
||
LEGAL_FORM?: string
|
||
ADDRESS_LINE: string
|
||
POSTAL_CODE: string
|
||
CITY: string
|
||
COUNTRY: string
|
||
EMAIL: string
|
||
PHONE?: string
|
||
WEBSITE_URL?: string
|
||
CEO_NAME?: string
|
||
REGISTER_COURT?: string
|
||
REGISTER_NUMBER?: string
|
||
VAT_ID?: string
|
||
}
|
||
|
||
export interface CustomerCtx {
|
||
LEGAL_NAME: string
|
||
ADDRESS_LINE?: string
|
||
POSTAL_CODE?: string
|
||
CITY?: string
|
||
COUNTRY?: string
|
||
CONTACT_NAME?: string
|
||
EMAIL: string
|
||
IS_CONSUMER: boolean
|
||
IS_BUSINESS: boolean
|
||
}
|
||
|
||
export interface ServiceCtx {
|
||
NAME: string
|
||
DESCRIPTION: string
|
||
MODEL: 'SaaS' | 'PaaS' | 'IaaS' | 'OnPrem' | 'Hybrid' | ''
|
||
TIER: string
|
||
DATA_LOCATION: string
|
||
EXPORT_FORMATS?: string[]
|
||
EXPORT_WINDOW_DAYS?: number
|
||
MIN_TERM_MONTHS?: number
|
||
TERMINATION_NOTICE_DAYS?: number
|
||
}
|
||
|
||
export interface LegalCtx {
|
||
GOVERNING_LAW: string
|
||
JURISDICTION_CITY: string
|
||
VERSION_DATE: string // YYYY-MM-DD
|
||
EFFECTIVE_DATE: string // YYYY-MM-DD
|
||
LANG: 'de' | 'en'
|
||
}
|
||
|
||
export interface PrivacyCtx {
|
||
CONTACT_EMAIL: string
|
||
DPO_NAME: string
|
||
DPO_EMAIL: string
|
||
SUPERVISORY_AUTHORITY_NAME?: string
|
||
SUPERVISORY_AUTHORITY_ADDRESS?: string
|
||
PRIVACY_POLICY_URL: string
|
||
COOKIE_POLICY_URL?: string
|
||
ANALYTICS_RETENTION_MONTHS?: number
|
||
DATA_TRANSFER_THIRD_COUNTRIES?: string
|
||
}
|
||
|
||
export interface SLACtx {
|
||
AVAILABILITY_PERCENT: number | ''
|
||
MAINTENANCE_NOTICE_HOURS: number | ''
|
||
SUPPORT_EMAIL: string
|
||
SUPPORT_PHONE?: string
|
||
SUPPORT_HOURS: string
|
||
RESPONSE_CRITICAL_H: number | ''
|
||
RESOLUTION_CRITICAL_H: number | ''
|
||
RESPONSE_HIGH_H: number | ''
|
||
RESOLUTION_HIGH_H: number | ''
|
||
RESPONSE_MEDIUM_H: number | ''
|
||
RESOLUTION_MEDIUM_H: number | ''
|
||
RESPONSE_LOW_H: number | ''
|
||
}
|
||
|
||
export interface PaymentsCtx {
|
||
MONTHLY_FEE_EUR: number | ''
|
||
PAYMENT_DUE_DAY: number | ''
|
||
PAYMENT_METHOD: string
|
||
PAYMENT_DAYS: number | ''
|
||
}
|
||
|
||
export interface SecurityCtx {
|
||
INCIDENT_NOTICE_HOURS: number | ''
|
||
LOG_RETENTION_DAYS: number | ''
|
||
SECURITY_LOG_RETENTION_DAYS: number | ''
|
||
}
|
||
|
||
export interface NDACtx {
|
||
PURPOSE: string
|
||
DURATION_YEARS: number | ''
|
||
PENALTY_AMOUNT_EUR: number | null | ''
|
||
}
|
||
|
||
export interface ConsentCtx {
|
||
WEBSITE_NAME: string
|
||
ANALYTICS_TOOLS: string | null
|
||
MARKETING_PARTNERS: string | null
|
||
}
|
||
|
||
export interface HostingCtx {
|
||
PROVIDER_NAME: string
|
||
COUNTRY: string
|
||
CONTRACT_TYPE: string // e.g. "AVV nach Art. 28 DSGVO"
|
||
}
|
||
|
||
export interface FeaturesCtx {
|
||
// ── Impressum ──────────────────────────────────────────────────────────────
|
||
HAS_REGULATED_PROFESSION: boolean
|
||
REGULATED_PROFESSION_TEXT: string
|
||
HAS_EDITORIAL_RESPONSIBLE: boolean
|
||
EDITORIAL_RESPONSIBLE_NAME: string
|
||
EDITORIAL_RESPONSIBLE_ADDRESS: string
|
||
HAS_DISPUTE_RESOLUTION: boolean
|
||
DISPUTE_RESOLUTION_TEXT: string
|
||
|
||
// ── DSI / Datenschutzerklärung ─────────────────────────────────────────────
|
||
HAS_THIRD_COUNTRY: boolean
|
||
TRANSFER_GUARDS: string // e.g. "EU-Standardvertragsklauseln (SCC)"
|
||
SECURITY_MEASURES_SUMMARY: string // e.g. "TLS, RBAC, Backups, Logging"
|
||
DATA_SUBJECT_REQUEST_CHANNEL: string // e.g. "per E-Mail an {{CONTACT_EMAIL}}"
|
||
CONSENT_WITHDRAWAL_PATH: string // e.g. "Footer-Link ›Cookie-Einstellungen‹"
|
||
|
||
// ── Service-Features (DSI/AGB) ─────────────────────────────────────────────
|
||
HAS_NEWSLETTER: boolean
|
||
NEWSLETTER_PROVIDER_DETAIL: string
|
||
HAS_ACCOUNT: boolean
|
||
HAS_PAYMENTS: boolean
|
||
PAYMENT_PROVIDER_DETAIL: string
|
||
HAS_SUPPORT: boolean
|
||
HAS_SOCIAL_MEDIA: boolean
|
||
SOCIAL_MEDIA_DETAIL: string
|
||
|
||
// ── Tool-Details (DSI + Cookie Banner) ────────────────────────────────────
|
||
ANALYTICS_TOOLS_DETAIL: string
|
||
MARKETING_TOOLS_DETAIL: string
|
||
CMP_NAME: string
|
||
CMP_LOGS_CONSENTS: boolean
|
||
HAS_FUNCTIONAL_COOKIES: boolean
|
||
|
||
// ── AGB (SaaS) ────────────────────────────────────────────────────────────
|
||
HAS_PAID_PLANS: boolean
|
||
PRICES_TEXT: string
|
||
PAYMENT_TERMS_TEXT: string
|
||
CONTRACT_TERM_TEXT: string
|
||
HAS_SLA: boolean
|
||
SLA_URL: string
|
||
HAS_EXPORT_POLICY: boolean
|
||
EXPORT_POLICY_TEXT: string
|
||
LIMITATION_CAP_TEXT: string
|
||
HAS_WITHDRAWAL: boolean
|
||
CONSUMER_WITHDRAWAL_TEXT: string
|
||
SUPPORT_CHANNELS_TEXT: string
|
||
}
|
||
|
||
export interface TOMCtx {
|
||
ISB_NAME: string
|
||
GF_NAME: string
|
||
DOCUMENT_VERSION: string
|
||
NEXT_REVIEW_DATE: string
|
||
// Conditional blocks
|
||
HAS_PHYSICAL_TRANSPORT: boolean
|
||
HAS_THIRD_COUNTRY_TRANSFER: boolean
|
||
HAS_CLOUD_SERVICES: boolean
|
||
HAS_MFA: boolean
|
||
HAS_USB_LOCKED: boolean
|
||
HAS_MOBILE_MEDIA: boolean
|
||
HAS_FOUR_EYES_DELETE: boolean
|
||
HAS_EXTERNAL_DESTRUCTION: boolean
|
||
HAS_REDUNDANCY: boolean
|
||
HAS_GEO_REDUNDANCY: boolean
|
||
HAS_USV: boolean
|
||
HAS_OWN_SERVER_ROOM: boolean
|
||
HAS_MULTI_TENANT: boolean
|
||
HAS_TEST_DATA_ANONYMIZED: boolean
|
||
// Selects
|
||
LOG_RETENTION_MONTHS: number | ''
|
||
DIN_66399_LEVEL: string
|
||
AVAILABILITY_TARGET: string
|
||
SEPARATION_TYPE: string
|
||
}
|
||
|
||
export interface DPACtx {
|
||
// Parties
|
||
AG_NAME: string
|
||
AG_STRASSE: string
|
||
AG_PLZ_ORT: string
|
||
AN_NAME: string
|
||
AN_STRASSE: string
|
||
AN_PLZ_ORT: string
|
||
// Processing details
|
||
VERARBEITUNGSGEGENSTAND: string
|
||
VERARBEITUNGSZWECK: string
|
||
VERARBEITUNGSARTEN: string
|
||
DATENKATEGORIEN: string
|
||
PERSONENKATEGORIEN: string
|
||
// Timings
|
||
BREACH_NOTIFICATION_HOURS: number | ''
|
||
INSTRUCTION_RETENTION_YEARS: number | ''
|
||
SUB_PROCESSOR_NOTICE_WEEKS: number | ''
|
||
SUB_PROCESSOR_OBJECTION_WEEKS: number | ''
|
||
RETURN_CHOICE_WEEKS: number | ''
|
||
DELETION_DAYS: number | ''
|
||
REACTIVATION_MONTHS: number | ''
|
||
TERMINATION_WEEKS: number | ''
|
||
CHANGE_NOTICE_WEEKS: number | ''
|
||
THIRD_COUNTRY_OBJECTION_WEEKS: number | ''
|
||
// Data return
|
||
DATA_EXPORT_FORMAT: string
|
||
// DSB
|
||
AN_DSB_NAME: string
|
||
AN_DSB_EMAIL: string
|
||
// Signatures
|
||
AG_ORT: string
|
||
AN_ORT: string
|
||
VERTRAGSDATUM: string
|
||
AG_UNTERZEICHNER_NAME: string
|
||
AG_UNTERZEICHNER_FUNKTION: string
|
||
AN_UNTERZEICHNER_NAME: string
|
||
AN_UNTERZEICHNER_FUNKTION: string
|
||
GERICHTSSTAND: string
|
||
// Optional clauses
|
||
HAS_LIABILITY_PROTECTION: boolean
|
||
HAS_SUPPORT_COST_CLAUSE: boolean
|
||
HAS_SUB_PROCESSOR_SILENCE_APPROVAL: boolean
|
||
HAS_SUB_PROCESSOR_TERMINATION_RIGHT: boolean
|
||
HAS_REACTIVATION_PERIOD: boolean
|
||
HAS_RETURN_COST_CLAUSE: boolean
|
||
HAS_GERICHTSSTAND_CLAUSE: boolean
|
||
HAS_UNILATERAL_CHANGE_RIGHT: boolean
|
||
HAS_THIRD_COUNTRY_OBJECTION: boolean
|
||
}
|
||
|
||
export interface TemplateContext {
|
||
PROVIDER: ProviderCtx
|
||
CUSTOMER: CustomerCtx
|
||
SERVICE: ServiceCtx
|
||
LEGAL: LegalCtx
|
||
PRIVACY: PrivacyCtx
|
||
SLA: SLACtx
|
||
PAYMENTS: PaymentsCtx
|
||
SECURITY: SecurityCtx
|
||
NDA: NDACtx
|
||
CONSENT: ConsentCtx
|
||
HOSTING: HostingCtx
|
||
FEATURES: FeaturesCtx
|
||
TOM: TOMCtx
|
||
DPA: DPACtx
|
||
}
|
||
|
||
export interface ComputedFlags {
|
||
IS_B2C: boolean
|
||
IS_B2B: boolean
|
||
SERVICE_IS_SAAS: boolean
|
||
SERVICE_IS_HYBRID: boolean
|
||
HAS_PENALTY: boolean
|
||
HAS_ANALYTICS: boolean
|
||
HAS_MARKETING: boolean
|
||
}
|
||
|
||
// =============================================================================
|
||
// Empty default context
|
||
// =============================================================================
|
||
|
||
export const EMPTY_CONTEXT: TemplateContext = {
|
||
PROVIDER: {
|
||
LEGAL_NAME: '', LEGAL_FORM: '', ADDRESS_LINE: '', POSTAL_CODE: '', CITY: '',
|
||
COUNTRY: 'DE', EMAIL: '', PHONE: '', WEBSITE_URL: '',
|
||
CEO_NAME: '', REGISTER_COURT: '', REGISTER_NUMBER: '', VAT_ID: '',
|
||
},
|
||
CUSTOMER: {
|
||
LEGAL_NAME: '', ADDRESS_LINE: '', POSTAL_CODE: '', CITY: '', COUNTRY: 'DE',
|
||
CONTACT_NAME: '', EMAIL: '', IS_CONSUMER: false, IS_BUSINESS: true,
|
||
},
|
||
SERVICE: {
|
||
NAME: '', DESCRIPTION: '', MODEL: 'SaaS', TIER: '', DATA_LOCATION: 'Deutschland',
|
||
EXPORT_FORMATS: [], EXPORT_WINDOW_DAYS: 30, MIN_TERM_MONTHS: 12,
|
||
TERMINATION_NOTICE_DAYS: 30,
|
||
},
|
||
LEGAL: {
|
||
GOVERNING_LAW: 'Deutschland', JURISDICTION_CITY: '', VERSION_DATE: '', EFFECTIVE_DATE: '',
|
||
LANG: 'de',
|
||
},
|
||
PRIVACY: {
|
||
CONTACT_EMAIL: '', DPO_NAME: '', DPO_EMAIL: '',
|
||
SUPERVISORY_AUTHORITY_NAME: '', SUPERVISORY_AUTHORITY_ADDRESS: '',
|
||
PRIVACY_POLICY_URL: '', COOKIE_POLICY_URL: '',
|
||
ANALYTICS_RETENTION_MONTHS: 13, DATA_TRANSFER_THIRD_COUNTRIES: 'nicht statt',
|
||
},
|
||
SLA: {
|
||
AVAILABILITY_PERCENT: 99.5, MAINTENANCE_NOTICE_HOURS: 72,
|
||
SUPPORT_EMAIL: '', SUPPORT_PHONE: '', SUPPORT_HOURS: 'Mo–Fr 09:00–18:00 CET',
|
||
RESPONSE_CRITICAL_H: 2, RESOLUTION_CRITICAL_H: 8,
|
||
RESPONSE_HIGH_H: 4, RESOLUTION_HIGH_H: 24,
|
||
RESPONSE_MEDIUM_H: 24, RESOLUTION_MEDIUM_H: 120,
|
||
RESPONSE_LOW_H: 72,
|
||
},
|
||
PAYMENTS: {
|
||
MONTHLY_FEE_EUR: '', PAYMENT_DUE_DAY: 1, PAYMENT_METHOD: 'Rechnung', PAYMENT_DAYS: 14,
|
||
},
|
||
SECURITY: {
|
||
INCIDENT_NOTICE_HOURS: 24, LOG_RETENTION_DAYS: 7, SECURITY_LOG_RETENTION_DAYS: 30,
|
||
},
|
||
NDA: { PURPOSE: '', DURATION_YEARS: 5, PENALTY_AMOUNT_EUR: null },
|
||
CONSENT: { WEBSITE_NAME: '', ANALYTICS_TOOLS: null, MARKETING_PARTNERS: null },
|
||
HOSTING: {
|
||
PROVIDER_NAME: '', COUNTRY: 'Deutschland', CONTRACT_TYPE: 'AVV nach Art. 28 DSGVO',
|
||
},
|
||
FEATURES: {
|
||
// Impressum
|
||
HAS_REGULATED_PROFESSION: false, REGULATED_PROFESSION_TEXT: '',
|
||
HAS_EDITORIAL_RESPONSIBLE: false, EDITORIAL_RESPONSIBLE_NAME: '', EDITORIAL_RESPONSIBLE_ADDRESS: '',
|
||
HAS_DISPUTE_RESOLUTION: false, DISPUTE_RESOLUTION_TEXT: '',
|
||
// DSI
|
||
HAS_THIRD_COUNTRY: false, TRANSFER_GUARDS: 'EU-Standardvertragsklauseln (SCC)',
|
||
SECURITY_MEASURES_SUMMARY: 'TLS 1.3, RBAC, Verschlüsselung at rest, regelmäßige Backups, Logging',
|
||
DATA_SUBJECT_REQUEST_CHANNEL: 'per E-Mail', CONSENT_WITHDRAWAL_PATH: 'Footer-Link „Cookie-Einstellungen"',
|
||
// Service features
|
||
HAS_NEWSLETTER: false, NEWSLETTER_PROVIDER_DETAIL: '',
|
||
HAS_ACCOUNT: false, HAS_PAYMENTS: false, PAYMENT_PROVIDER_DETAIL: '',
|
||
HAS_SUPPORT: false, HAS_SOCIAL_MEDIA: false, SOCIAL_MEDIA_DETAIL: '',
|
||
// Tools
|
||
ANALYTICS_TOOLS_DETAIL: '', MARKETING_TOOLS_DETAIL: '',
|
||
CMP_NAME: '', CMP_LOGS_CONSENTS: false, HAS_FUNCTIONAL_COOKIES: false,
|
||
// AGB
|
||
HAS_PAID_PLANS: false, PRICES_TEXT: '', PAYMENT_TERMS_TEXT: '',
|
||
CONTRACT_TERM_TEXT: '', HAS_SLA: false, SLA_URL: '',
|
||
HAS_EXPORT_POLICY: false, EXPORT_POLICY_TEXT: '',
|
||
LIMITATION_CAP_TEXT: '', HAS_WITHDRAWAL: false, CONSUMER_WITHDRAWAL_TEXT: '',
|
||
SUPPORT_CHANNELS_TEXT: '',
|
||
},
|
||
TOM: {
|
||
ISB_NAME: '', GF_NAME: '', DOCUMENT_VERSION: '1.0.0', NEXT_REVIEW_DATE: '',
|
||
HAS_PHYSICAL_TRANSPORT: false, HAS_THIRD_COUNTRY_TRANSFER: false,
|
||
HAS_CLOUD_SERVICES: false, HAS_MFA: true, HAS_USB_LOCKED: false,
|
||
HAS_MOBILE_MEDIA: false, HAS_FOUR_EYES_DELETE: false,
|
||
HAS_EXTERNAL_DESTRUCTION: false, HAS_REDUNDANCY: false,
|
||
HAS_GEO_REDUNDANCY: false, HAS_USV: true, 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',
|
||
},
|
||
DPA: {
|
||
AG_NAME: '', AG_STRASSE: '', AG_PLZ_ORT: '',
|
||
AN_NAME: '', AN_STRASSE: '', AN_PLZ_ORT: '',
|
||
VERARBEITUNGSGEGENSTAND: '', VERARBEITUNGSZWECK: '', VERARBEITUNGSARTEN: '',
|
||
DATENKATEGORIEN: '', PERSONENKATEGORIEN: '',
|
||
BREACH_NOTIFICATION_HOURS: 24, INSTRUCTION_RETENTION_YEARS: 3,
|
||
SUB_PROCESSOR_NOTICE_WEEKS: 2, SUB_PROCESSOR_OBJECTION_WEEKS: 2,
|
||
RETURN_CHOICE_WEEKS: 4, DELETION_DAYS: 90, REACTIVATION_MONTHS: 3,
|
||
TERMINATION_WEEKS: 4, CHANGE_NOTICE_WEEKS: 4, THIRD_COUNTRY_OBJECTION_WEEKS: 3,
|
||
DATA_EXPORT_FORMAT: 'CSV/JSON', AN_DSB_NAME: '', AN_DSB_EMAIL: '',
|
||
AG_ORT: '', AN_ORT: '', VERTRAGSDATUM: '',
|
||
AG_UNTERZEICHNER_NAME: '', AG_UNTERZEICHNER_FUNKTION: 'Geschaeftsfuehrer',
|
||
AN_UNTERZEICHNER_NAME: '', AN_UNTERZEICHNER_FUNKTION: 'Geschaeftsfuehrer',
|
||
GERICHTSSTAND: '',
|
||
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, HAS_RETURN_COST_CLAUSE: false,
|
||
HAS_GERICHTSSTAND_CLAUSE: true, HAS_UNILATERAL_CHANGE_RIGHT: false,
|
||
HAS_THIRD_COUNTRY_OBJECTION: false,
|
||
},
|
||
}
|
||
|
||
// =============================================================================
|
||
// Re-exports from helpers (barrel — no consumer imports need updating)
|
||
// =============================================================================
|
||
|
||
export {
|
||
contextToPlaceholders,
|
||
computeFlags,
|
||
getRelevantSections,
|
||
getUncoveredPlaceholders,
|
||
getMissingRequired,
|
||
setContextPath,
|
||
getContextPath,
|
||
} from './contextBridge-helpers'
|