feat(cmp): restore vendor-agnostic fields + module wiring
Build + Deploy / build-admin-compliance (push) Successful in 2m0s
Build + Deploy / build-backend-compliance (push) Successful in 14s
Build + Deploy / build-ai-sdk (push) Successful in 10s
Build + Deploy / build-developer-portal (push) Successful in 14s
Build + Deploy / build-tts (push) Successful in 11s
Build + Deploy / build-document-crawler (push) Successful in 11s
Build + Deploy / build-dsms-gateway (push) Successful in 10s
Build + Deploy / build-dsms-node (push) Successful in 13s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / loc-budget (push) Failing after 18s
CI / secret-scan (push) Has been skipped
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Successful in 2m55s
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / test-go (push) Successful in 45s
CI / test-python-backend (push) Successful in 41s
CI / test-python-document-crawler (push) Successful in 30s
CI / test-python-dsms-gateway (push) Successful in 26s
CI / validate-canonical-controls (push) Successful in 15s
Build + Deploy / trigger-orca (push) Successful in 2m17s

Re-add 13 vendor-agnostic columns to banner models/serializers/service
(consent_method, banner_version, device_type, browser, os, etc.) that
were lost when another session overwrote the code. Keep vendor_consents
dict from the other session.

Add list_consents method back to BannerConsentService.

Wire CookieBanner, Loeschfristen and UseCases into Document Generator
contextBridge (CMP_NAME, analytics tools, retention months, feature flags).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-05-11 21:57:54 +02:00
parent 90da26745b
commit 051890c370
4 changed files with 155 additions and 0 deletions
@@ -101,6 +101,78 @@ function DocumentGeneratorPageInner() {
}
}, [state?.complianceScope?.determinedLevel, state?.companyProfile])
// ── MODULE WIRING: CookieBanner → CONSENT + FEATURES ─────────────────────
useEffect(() => {
const banner = state?.cookieBanner
if (!banner) return
const cats = banner.categories || []
const analyticsTools = cats
.filter((c) => c.id === 'analytics' || c.id === 'statistics')
.flatMap((c) => c.cookies?.map((ck) => ck.name) ?? [])
const marketingTools = cats
.filter((c) => c.id === 'marketing')
.flatMap((c) => c.cookies?.map((ck) => ck.name) ?? [])
const hasFunctional = cats.some((c) => c.id === 'functional')
setContext((prev) => ({
...prev,
CONSENT: {
...prev.CONSENT,
ANALYTICS_TOOLS: analyticsTools.length > 0 ? analyticsTools.join(', ') : prev.CONSENT.ANALYTICS_TOOLS,
MARKETING_PARTNERS: marketingTools.length > 0 ? marketingTools.join(', ') : prev.CONSENT.MARKETING_PARTNERS,
},
FEATURES: {
...prev.FEATURES,
CMP_NAME: 'BreakPilot CMP',
CMP_LOGS_CONSENTS: true,
HAS_FUNCTIONAL_COOKIES: hasFunctional || prev.FEATURES.HAS_FUNCTIONAL_COOKIES,
CONSENT_WITHDRAWAL_PATH: 'Footer-Link "Cookie-Einstellungen"',
},
}))
}, [state?.cookieBanner])
// ── MODULE WIRING: Loeschfristen → PRIVACY retention ──────────────────────
useEffect(() => {
const policies = state?.retentionPolicies
if (!policies || policies.length === 0) return
const maxMonths = policies.reduce((max, p) => {
const match = p.retentionPeriod?.match(/(\d+)\s*(Monat|Jahr|Tag)/i)
if (!match) return max
const val = parseInt(match[1], 10)
const unit = match[2].toLowerCase()
const months = unit.startsWith('jahr') ? val * 12 : unit.startsWith('tag') ? Math.ceil(val / 30) : val
return Math.max(max, months)
}, 0)
if (maxMonths > 0) {
setContext((prev) => ({
...prev,
PRIVACY: { ...prev.PRIVACY, ANALYTICS_RETENTION_MONTHS: maxMonths },
}))
}
}, [state?.retentionPolicies])
// ── MODULE WIRING: UseCases → FEATURES flags ─────────────────────────────
useEffect(() => {
const useCases = state?.useCases
if (!useCases || useCases.length === 0) return
const allText = useCases.map((uc) => `${uc.name} ${uc.description}`).join(' ').toLowerCase()
const hasAccount = allText.includes('account') || allText.includes('konto') || allText.includes('registrier')
const hasPayments = allText.includes('zahlung') || allText.includes('payment') || allText.includes('stripe') || allText.includes('paypal')
const hasNewsletter = allText.includes('newsletter') || allText.includes('mailchimp') || allText.includes('e-mail-marketing')
const hasSocial = allText.includes('social') || allText.includes('linkedin') || allText.includes('facebook') || allText.includes('instagram')
setContext((prev) => ({
...prev,
FEATURES: {
...prev.FEATURES,
HAS_ACCOUNT: hasAccount || prev.FEATURES.HAS_ACCOUNT,
HAS_PAYMENTS: hasPayments || prev.FEATURES.HAS_PAYMENTS,
HAS_NEWSLETTER: hasNewsletter || prev.FEATURES.HAS_NEWSLETTER,
HAS_SOCIAL_MEDIA: hasSocial || prev.FEATURES.HAS_SOCIAL_MEDIA,
},
}))
}, [state?.useCases])
// Pre-fill extra placeholders from Einwilligungen data points
useEffect(() => {
if (selectedDataPointsData && selectedDataPointsData.length > 0) {