Implementation of Automatic Legal Document Updates on Law Changes
Legal documents — privacy policy, terms of service, Cookie Policy — must be updated when applicable legislation changes. Auto-update system minimizes legal risks.
Problem of Static Documents
Most sites create legal documents once and forget about them. Changes to GDPR, ePrivacy Directive, CCPA, and emergence of new laws (DSA in EU, PIPL in China) require document updates.
Consequences of outdated documents: regulatory fines, user claims, inability to use in court as proof of consent.
Auto-Update System Architecture
Option 1: Managed SaaS (Recommended)
iubenda, Termly, CookieBot — support automatic template updates when legislation changes. Documents are embedded via widget and updated on the service side.
Option 2: Document Versioning
# models.py
class LegalDocument(BaseModel):
type: str # 'privacy_policy', 'terms', 'cookie_policy'
version: str # 'v2024-03-01'
content: str # Markdown/HTML content
language: str # 'en', 'de', 'fr'
effective_from: datetime
requires_reacceptance: bool # Does user re-acceptance needed
change_summary: str # What changed (for notification)
class UserConsent(BaseModel):
user_id: int
document_type: str
document_version: str
accepted_at: datetime
ip_address: str
user_agent: str
Option 3: Git-based Versioning
/legal/
├── privacy_policy/
│ ├── v2022-01-01.en.md
│ ├── v2023-07-15.en.md # Update on GDPR change
│ └── v2024-03-01.en.md # Current
├── terms/
│ ├── v2022-01-01.en.md
│ └── v2024-01-10.en.md
└── changelog.yml
Notification System on Version Change
class LegalDocumentUpdater:
def publish_new_version(self, doc_type: str, new_content: str,
change_summary: str, requires_reacceptance: bool):
version = datetime.now().strftime('v%Y-%m-%d')
# Save new version
doc = LegalDocument(
type=doc_type,
version=version,
content=new_content,
effective_from=datetime.now() + timedelta(days=30), # notify 30 days before
requires_reacceptance=requires_reacceptance,
change_summary=change_summary
)
db.save(doc)
if requires_reacceptance:
self._notify_users(doc)
def _notify_users(self, doc: LegalDocument):
# Find users who accepted previous version
affected_users = db.query("""
SELECT DISTINCT u.id, u.email
FROM users u
JOIN user_consents uc ON u.id = uc.user_id
WHERE uc.document_type = %s
AND uc.document_version != %s
""", (doc.type, doc.version))
for user in affected_users:
send_email(
to=user['email'],
subject="Legal Documents Update",
template="legal_update_notification",
vars={
'doc_type': doc.type,
'change_summary': doc.change_summary,
'effective_date': doc.effective_from.strftime('%m/%d/%Y'),
'review_url': f"https://site.com/legal/{doc_type}",
'accept_url': f"https://site.com/legal/accept?doc={doc_type}&v={doc.version}"
}
)
Forcing Re-Acceptance
With material changes, user must explicitly accept the new version:
class LegalAcceptanceMiddleware:
def __call__(self, request):
if not request.user.is_authenticated:
return self.app(request)
current_versions = get_current_document_versions()
for doc_type, current_version in current_versions.items():
user_consent = db.get_latest_consent(request.user.id, doc_type)
if not user_consent or user_consent.version != current_version:
# Check if version requires re-acceptance
doc = db.get_document(doc_type, current_version)
if doc.requires_reacceptance:
# Redirect to acceptance page
return redirect(f'/legal/accept?doc={doc_type}')
return self.app(request)
Monitoring Legislative Changes
# Subscribe to updates via RSS/email from regulators
REGULATORY_SOURCES = [
'https://edpb.europa.eu/news/news_en.rss', # EDPB (GDPR)
'https://ico.org.uk/news-events/news/rss', # UK ICO
]
def check_regulatory_updates():
import feedparser
for source in REGULATORY_SOURCES:
feed = feedparser.parse(source)
for entry in feed.entries[:5]: # last 5 news
if any(kw in entry.title.lower() for kw in
['gdpr', 'personal data', 'privacy']):
notify_legal_team(entry.title, entry.link)
Consent Audit Log
-- Complete consent history for compliance proof
CREATE TABLE consent_audit_log (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL,
document_type VARCHAR(50) NOT NULL,
document_version VARCHAR(20) NOT NULL,
action VARCHAR(20) NOT NULL, -- 'accepted', 'rejected', 'withdrawn'
accepted_at TIMESTAMPTZ DEFAULT NOW(),
ip_address INET,
user_agent TEXT,
consent_method VARCHAR(50), -- 'checkbox', 'banner', 'api'
-- Immutable record
CONSTRAINT no_update CHECK (TRUE)
);
CREATE INDEX idx_consent_log_user ON consent_audit_log(user_id, document_type);
Implementation Timeline
Implementation of document versioning system with notifications and forced acceptance — 3–5 business days.







