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.

This scaffold is validated against the release compliance 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. Honours navigator.globalPrivacyControl. Mirrors choice to a httpOnly server cookie.
Browser privacy signalssrc/proxy.ts + src/lib/compliance/consent.tsMiddleware honours Sec-GPC: 1 and DNT: 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 endpointsDELETE /api/users/me (Settings UI) and POST /api/account/delete (API/runbook)Soft-delete + 30-day grace window + scheduled hard-delete via pnpm db:cleanup. Revokes active credentials immediately; PII is retained only during the restore window, then removed by the cleanup job. 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 and the Stripe Billing Portal only - no raw card data ever touches this database. Designed for a SAQ-A posture, subject to buyer validation and deployment choices.

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 you choose (database, hosting, payments, email, analytics, support, and other vendors).
  • 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 compliance steps if your service is directed at users under 13 or you knowingly collect data from children under 13, including notice and verifiable parental consent where required.
  • 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 flow sends best-effort account.deletion_requested and account.deletion_completed notifications with { userId, deletedAt } context so processors can purge their copy. Delivery failures are logged but never block the user's erasure.
  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 → Danger Zone → Delete account (calls DELETE /api/users/me with email confirmation and, for password accounts, current-password reauth). For manual/API workflows, call POST /api/account/delete with { "confirm": "DELETE", "password": "<current password>" } for password accounts; passwordless accounts must use a fresh OAuth or magic-link session. The hard-delete completes 30 days later via the cleanup cron. You have 30 days under UK/EU GDPR.
  • Deletion restore during grace window: account deletion is pending during the configured grace period. If support needs to reverse a mistaken request before the hard-delete sweep, run pnpm account:restore <userId>.
  • 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;

Reference coverage: scaffold reviewed against UK GDPR; UK Data (Use and Access) Act 2025; UK Companies Act 2006 §82; UK ePrivacy Regulations (PECR); UK Digital Markets, Competition and Consumers Act 2024 subscription-contract provisions; UK Modern Slavery Act 2015 §54; EU GDPR; EU AI Act 2024/1689; EU Accessibility Act 2025; CCPA/CPRA; US state privacy-law patterns that may apply by jurisdiction; US ADA accessibility guidance; DMCA §512; CalOPPA. Buyers must validate final obligations for their product, sector, and deployment.


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