Files
gw-svelte/docker/postgres/init/004-session-events.sql
T
2026-05-26 23:30:22 +12:00

49 lines
2.0 KiB
SQL

-- Visitor journey reconstruction. Two tables, two retention policies.
--
-- session_events: every analytics event the SvelteKit /api/track endpoint
-- receives, keyed by the anon_id cookie set in hooks.server.ts. This buffer
-- is the source for journey reconstruction when a visitor submits the
-- booking form. It is pruned aggressively (24h TTL) so we don't hoard
-- behavioural data for visitors who never enquire.
--
-- submission_journeys: when a visitor submits the booking/contact form,
-- /api/track/promote copies their recent session_events into this table
-- linked to the submission email. These rows are kept so the owner can
-- review the journey from the CP dashboard.
--
-- The promotion step is the only place where an anonymous browsing record
-- becomes linked to a named person, and it only happens because that
-- person chose to submit a form. The privacy policy covers this.
create table if not exists session_events (
id bigserial primary key,
anon_id text not null,
event_name text not null,
page_path text,
params jsonb not null default '{}'::jsonb,
created_at timestamptz not null default now()
);
create index if not exists session_events_anon_idx
on session_events (anon_id, created_at);
-- Used by the probabilistic prune in /api/track to find rows past TTL.
create index if not exists session_events_created_idx
on session_events (created_at);
create table if not exists submission_journeys (
id bigserial primary key,
email text not null,
anon_id text,
-- Snapshot of session_events rows at promotion time (server-captured).
events jsonb not null default '[]'::jsonb,
-- Client-side sessionStorage buffer sent with the promote request, as a
-- fallback for events that never reached /api/track (e.g. blocked at the
-- network layer alongside gtag).
client_events jsonb not null default '[]'::jsonb,
created_at timestamptz not null default now()
);
create index if not exists submission_journeys_email_idx
on submission_journeys (email, created_at desc);