feat(cmp): Phase 2 — script blocking + cookie tracking

Migration 108: scripts_blocked, scripts_released, cookies_set JSONB columns.
Backend models/schema/service/serializer/routes extended.
Admin detail modal shows released scripts and set cookies with categories.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-05-11 22:52:26 +02:00
parent 051890c370
commit 397de741c1
8 changed files with 73 additions and 0 deletions
@@ -87,6 +87,9 @@ async def record_consent(
screen_resolution=body.screen_resolution,
session_id=body.session_id,
consent_scope=body.consent_scope,
scripts_blocked=body.scripts_blocked,
scripts_released=body.scripts_released,
cookies_set=body.cookies_set,
)
@@ -50,6 +50,10 @@ class BannerConsentDB(Base):
os = Column(Text)
screen_resolution = Column(Text)
session_id = Column(Text)
# Script/Cookie-Tracking (Migration 108)
scripts_blocked = Column(JSON, default=list)
scripts_released = Column(JSON, default=list)
cookies_set = Column(JSON, default=list)
expires_at = Column(DateTime)
created_at = Column(DateTime, nullable=False, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
@@ -30,6 +30,10 @@ class ConsentCreate(BaseModel):
screen_resolution: Optional[str] = None
session_id: Optional[str] = None
consent_scope: Optional[str] = None
# Script/Cookie-Tracking (Migration 108)
scripts_blocked: List[dict[str, Any]] = []
scripts_released: List[dict[str, Any]] = []
cookies_set: List[dict[str, Any]] = []
class SiteConfigCreate(BaseModel):
@@ -41,6 +41,9 @@ def consent_to_dict(c: BannerConsentDB) -> dict[str, Any]:
"os": c.os,
"screen_resolution": c.screen_resolution,
"session_id": c.session_id,
"scripts_blocked": c.scripts_blocked or [],
"scripts_released": c.scripts_released or [],
"cookies_set": c.cookies_set or [],
"expires_at": c.expires_at.isoformat() if c.expires_at else None,
"created_at": c.created_at.isoformat() if c.created_at else None,
"updated_at": c.updated_at.isoformat() if c.updated_at else None,
@@ -181,6 +181,9 @@ class BannerConsentService:
screen_resolution: Optional[str] = None,
session_id: Optional[str] = None,
consent_scope: Optional[str] = None,
scripts_blocked: Optional[list[dict]] = None,
scripts_released: Optional[list[dict]] = None,
cookies_set: Optional[list[dict]] = None,
) -> dict[str, Any]:
"""Upsert a device consent row for (tenant, site, device_fingerprint).
@@ -213,6 +216,9 @@ class BannerConsentService:
"screen_resolution": screen_resolution,
"session_id": session_id,
"consent_scope": consent_scope or "domain",
"scripts_blocked": scripts_blocked or [],
"scripts_released": scripts_released or [],
"cookies_set": cookies_set or [],
}
existing = (
@@ -0,0 +1,18 @@
-- Migration 108: Script- und Cookie-Tracking fuer Banner-Consents
-- Erfasst welche Scripts blockiert/freigegeben und welche Cookies gesetzt wurden.
-- Alle Felder JSONB + nullable → backward-compatible.
-- Scripts die VOR Consent blockiert waren
ALTER TABLE compliance_banner_consents
ADD COLUMN IF NOT EXISTS scripts_blocked JSONB DEFAULT '[]'::jsonb;
-- [{"src": "https://www.googletagmanager.com/gtag/js", "category": "analytics"}]
-- Scripts die NACH Consent freigegeben wurden
ALTER TABLE compliance_banner_consents
ADD COLUMN IF NOT EXISTS scripts_released JSONB DEFAULT '[]'::jsonb;
-- [{"src": "https://www.googletagmanager.com/gtag/js", "category": "analytics"}]
-- Cookies die NACH Consent gesetzt wurden
ALTER TABLE compliance_banner_consents
ADD COLUMN IF NOT EXISTS cookies_set JSONB DEFAULT '[]'::jsonb;
-- [{"name": "_ga", "domain": ".breakpilot.ai", "expiry_days": 730, "category": "analytics"}]