Skip to main content
Skip to content

Last updated on 4 June 2026

Compliance Scaffold — UK / EU / US

This template ships a compliance scaffold — the wiring buyers need to operate under UK GDPR, EU GDPR, US state privacy laws, and adjacent regulations. The scaffold is not legal advice, and shipping the scaffold does not make a buyer compliant on its own. The buyer is the compliant party.

This document is the contract: what the kit does for the buyer, and what the buyer must still do for themselves.

Template Empire validates this scaffold against its internal compliance standard and Gate 17 release checklist before packaging.

What ships in the scaffold

AreaWhere it livesWhat you get
Legal pages/privacy, /terms, /cookie-policy, /accessibility, /dmca, /do-not-sellSkeleton copy with structurally-correct headings, region-conditional rendering for US-only pages, GDPR-rights enumeration on the privacy page.
Footersrc/components/landing/footer.tsxRenders registered legal entity (company number, registered office, jurisdiction) and region-conditional legal links. Reads everything from SITE_CONFIG.legalEntity.
Cookie bannersrc/components/ui/cookie-consent.tsxAccept all and Reject all at visual parity (Gate 17 #8 P0). Honours navigator.globalPrivacyControl. Mirrors choice to a httpOnly server cookie.
GPC serversrc/proxy.ts + src/lib/compliance/consent.tsMiddleware honours Sec-GPC: 1 even on the very first request (auto-records deny). getConsent(request) and getAnalytics(request) helpers for route handlers.
DSAR endpointPOST /api/account/exportAuthenticated user gets a JSON download of every row holding their personal data. Audit-logged. Rate-limited 5/hr.
Erasure endpointPOST /api/account/deleteSoft-delete + 30-day grace window + scheduled hard-delete via pnpm db:cleanup. Anonymises PII columns immediately, revokes all sessions, fires optional outbound webhook for third-party tools.
Audit logaudit_log table in initial migrationAuto-written for login, logout, signup, password_reset, email_change, consent.updated, account.deletion_requested, data_export.requested, etc. Pruned after auditLogRetentionDays.
PCI DSS posturesrc/services/billing.service.ts (when present)Stripe Checkout / Elements only — no raw card data ever touches this database. Buyer stays in PCI DSS SAQ-A.

What stays with you (the buyer)

  • Real privacy policy wording for your specific data flows, sub-processors, and retention windows.
  • DPA signing with each sub-processor (Supabase, Stripe, Vercel, Resend, etc.).
  • DPIA (Data Protection Impact Assessment) for any high-risk processing.
  • DPO appointment if you're an EU public body or large-scale special-category processor.
  • ICO registration if you're in the UK and process personal data (£52/year for most controllers).
  • Sales tax / nexus calculation — Stripe Tax is the easiest route; the kit links it but doesn't configure it.
  • UGC content moderation — the UK Online Safety Act 2023 + DMCA require active moderation tooling if you allow user-generated content.
  • COPPA registration if your service is directed at users under 13.
  • Trust mark registration (ISO 27001, SOC 2) if you market enterprise — the kit makes this easier but doesn't grant it.

Pre-launch checklist

Before going live, complete every item below:

  1. SITE_CONFIG.legalEntity — fill in companyName, companyNumber, placeOfRegistration, registeredAddress, jurisdiction, and vatNumber (if applicable).
  2. SITE_CONFIG.regions — set every region you actually sell to (NOT just where you're registered).
  3. SITE_CONFIG.compliance.dmca.* — fill in your DMCA agent details if regions.us is true.
  4. SITE_CONFIG.compliance.modernSlaveryStatementUrl — set if your turnover is ≥ £36m.
  5. SITE_CONFIG.contact.privacy — replace the placeholder with a monitored mailbox.
  6. SITE_CONFIG.legalEffectiveDate — bump to your launch date.
  7. Privacy / Terms / Cookie / Accessibility / DMCA / Do-Not-Sell pages — review the scaffold copy, replace placeholder paragraphs, run past your lawyer.
  8. Sign DPAs with every sub-processor.
  9. Set up the daily cron for pnpm db:cleanup so the hard-delete sweep, audit-log pruning, and token cleanup all run. The script writes an account.deletion_completed audit-log row for every user it hard-deletes so the chain of custody is provable.
  10. DELETION_WEBHOOK_URL in .env — set if you use third-party tools (Mailchimp, Intercom, Mixpanel, etc.) that hold their own copy of user data; the deletion route POSTs { userId, deletedAt } so they can purge their copy.
  11. Audit-log retention and deletion-grace windows are configured in SITE_CONFIG.compliance.{auditLogRetentionDays, deletionGraceDays} (NOT env vars). Defaults: 365-day retention, 30-day grace. Set auditLogRetentionDays: 0 to disable retention pruning entirely.

Subject-rights request runbook

When a user (or a regulator) sends a DSAR or erasure request to your privacy mailbox:

  • DSAR / right of access: point them at Settings → Privacy → Download my data (calls /api/account/export). If they need a manual export, run pnpm dsar <userId> or run the route via curl with the user's session token. You have 30 days under UK/EU GDPR (extendable to 90 for complex requests, with notice).
  • Right to erasure: point them at Settings → Delete account (calls /api/account/delete). The hard-delete completes 30 days later via the cleanup cron. You have 30 days under UK/EU GDPR.
  • Right to rectification: most fields are user-editable in the profile UI. For fields that aren't, fix in DB and write an audit_log entry.
  • Right to portability: the DSAR JSON export IS the portable format. No additional work.
  • Right to object / restrict: flip the relevant notification_preferences row, or set the user's account to paused if you implement that.

Auditor-friendly queries

sql
-- Outstanding deletion requests (still in grace window)
SELECT id, deleted_at, deleted_at + INTERVAL '30 days' AS hard_delete_at
FROM users WHERE deleted_at IS NOT NULL ORDER BY deleted_at;

-- Recent consent changes
SELECT user_id, action, details, created_at
FROM audit_log WHERE action = 'consent.updated' ORDER BY created_at DESC LIMIT 50;

-- DSAR requests in the last 90 days
SELECT user_id, created_at
FROM audit_log WHERE action = 'data_export.requested'
  AND created_at > NOW() - INTERVAL '90 days' ORDER BY created_at DESC;

Last reviewed against: UK GDPR; UK Data (Use and Access) Act 2025; UK Companies Act 2006 §82; UK ePrivacy Regulations (PECR); UK DMCC 2025 §29; UK Modern Slavery Act 2015 §54; EU GDPR; EU AI Act 2024/1689; EU Accessibility Act 2025; CCPA/CPRA + 19 US state privacy laws; ADA Title III + DOJ April 2026 rule; DMCA §512; CalOPPA.


See Template Empire's compliance standards for how every kit is held to — and audited against — these requirements.