3ddeb5c1cd
Roadmap item #11. Ships the non-modal bottom-of-page cookie consent banner, the default /privacy and /cookies policy pages, the `cookie_consent` table + two §17 endpoints for server-side persistence, the localStorage fallback for anonymous viewers, the /settings "Privacy & cookies" tab for revisiting the choice, and the `frontend/src/lib/consent.js` helper that roadmap item #13's analytics SDK (v0.15.0) will gate against. No analytics SDK ships in this release — the consent infrastructure goes in first so the gate is already in place. Adds SPEC §14.5 / §14.6, lists two new endpoints in §17, names the new table in §5, and surfaces four §19.2 candidates (content-repo file vs env-var policy, GPC / DNT headers, i18n, item-#13 dependency). Two new optional env vars (`VITE_PRIVACY_POLICY_URL`, `VITE_COOKIES_POLICY_URL`) — defaults render the framework's stub pages. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
36 lines
1.8 KiB
SQL
36 lines
1.8 KiB
SQL
-- v0.13.0 / roadmap item #11 — cookie consent.
|
|
--
|
|
-- The framework now ships a non-modal cookie consent banner per the
|
|
-- privacy-and-cookies UX (SPEC §14.5 / §14.6). Authenticated viewers
|
|
-- get their choice persisted server-side so it survives sign-out /
|
|
-- sign-in across devices; anonymous viewers persist their choice in
|
|
-- localStorage only.
|
|
--
|
|
-- Shape: a single row per user, three flags, plus a recorded-at stamp.
|
|
-- The flags are:
|
|
-- - essential: the framework's strictly-necessary cookies (session,
|
|
-- itsdangerous-signed payloads, CSRF if any). Permanently
|
|
-- true at the API surface — included in the row for
|
|
-- symmetry with the analytics / other flags rather than
|
|
-- because the user can switch it off.
|
|
-- - analytics: reserved for the §13 analytics SDK gating that lands
|
|
-- in v0.15.0. Off by default; opt-in via the banner.
|
|
-- - other: everything else (third-party embeds, social widgets).
|
|
-- Off by default; opt-in via the banner.
|
|
--
|
|
-- A NULL recorded_at means "no choice yet" — the banner should re-prompt
|
|
-- the next time the user signs in on a fresh device. Once recorded_at is
|
|
-- set, the banner is hidden until the user re-opens it from the
|
|
-- /settings/notifications "Privacy & cookies" tab.
|
|
--
|
|
-- The row is created lazily on first PUT. Absence of a row is equivalent
|
|
-- to NULL recorded_at — the banner shows.
|
|
|
|
CREATE TABLE cookie_consent (
|
|
user_id INTEGER PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
|
|
essential INTEGER NOT NULL DEFAULT 1 CHECK (essential IN (0, 1)),
|
|
analytics INTEGER NOT NULL DEFAULT 0 CHECK (analytics IN (0, 1)),
|
|
other_cookies INTEGER NOT NULL DEFAULT 0 CHECK (other_cookies IN (0, 1)),
|
|
recorded_at TEXT
|
|
);
|