Barrel-split pattern: each original becomes a thin re-export barrel; logic moved to sibling files so no consumer imports need updating. Files split: - loeschfristen-profiling.ts → profiling-data.ts + profiling-generator.ts - vendor-compliance/catalog/vendor-templates.ts → vendor-country-profiles.ts - vendor-compliance/catalog/legal-basis.ts → legal-basis-retention.ts - dsfa/eu-legal-frameworks.ts → eu-legal-frameworks-national.ts - compliance-scope-types/document-scope-matrix-core.ts → core-part2.ts - compliance-scope-types/document-scope-matrix-extended.ts → extended-part2.ts - app/sdk/document-generator/contextBridge.ts → contextBridge-helpers.ts - app/api/sdk/drafting-engine/draft/route.ts → draft-helpers.ts + draft-helpers-v2.ts All files ≤ 500 LOC. Zero behavior changes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
281 lines
9.2 KiB
TypeScript
281 lines
9.2 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 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
|
||
}
|
||
|
||
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: '',
|
||
},
|
||
}
|
||
|
||
// =============================================================================
|
||
// Re-exports from helpers (barrel — no consumer imports need updating)
|
||
// =============================================================================
|
||
|
||
export {
|
||
contextToPlaceholders,
|
||
computeFlags,
|
||
getRelevantSections,
|
||
getUncoveredPlaceholders,
|
||
getMissingRequired,
|
||
setContextPath,
|
||
getContextPath,
|
||
} from './contextBridge-helpers'
|