Why this matters
Granular, auditable consent enables purpose limitation and proof of consent/revocation.
Consent must be stored per user and per purpose with lawful_basis, version, granted_at, source, and optional revoked_at. Do not overwrite or store a single boolean flag. (GDPR Art. 7, purpose limitation)
Granular, auditable consent enables purpose limitation and proof of consent/revocation.
Side-by-side examples engineers can pattern-match during review.
CREATE TABLE users (
id UUID PRIMARY KEY,
email TEXT,
consent BOOLEAN -- single flag, no purpose/version
);CREATE TABLE consents (
id UUID PRIMARY KEY,
user_id UUID NOT NULL,
purpose TEXT NOT NULL, -- e.g., analytics, marketing
lawful_basis TEXT NOT NULL, -- consent, contract, legitimate_interest
version TEXT NOT NULL, -- policy version
granted_at TIMESTAMPTZ NOT NULL,
source TEXT NOT NULL, -- ui, api, import
revoked_at TIMESTAMPTZ
);
CREATE UNIQUE INDEX consents_latest ON consents(user_id, purpose, version, granted_at DESC);INSERT INTO consents(user_id,purpose,lawful_basis,version,granted_at,source)
VALUES($1,'analytics','consent','v3',NOW(),'ui');UPDATE users SET consent=true WHERE id=$1;From the same buckets as this rule.