-- name: InsertDiagnosticEvent :one -- Records one client-reported diagnostic event. The writer validates the -- `kind` category against its whitelist before this runs; the CHECK -- constraint is the belt-and-braces guard. payload carries the finer -- event discriminator + all event-specific fields. Returns received_at -- so the caller can confirm ingest. INSERT INTO diagnostic_events ( user_id, client_id, app_version, os_version, kind, payload, occurred_at ) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING id, received_at; -- name: ListAdminDiagnostics :many -- Admin timeline query. All filters are optional (NULL = no filter): -- account (user_id), device (client_id), category (kind), and the -- occurred_at window (from_ts/to_ts). Newest-first; the SPA reverses for -- a chronological timeline / export. Joined with users for the username -- so the view renders without a second round-trip. SELECT de.id AS id, de.user_id AS user_id, u.username AS username, de.client_id AS client_id, de.app_version AS app_version, de.os_version AS os_version, de.kind AS kind, de.payload AS payload, de.occurred_at AS occurred_at, de.received_at AS received_at FROM diagnostic_events de JOIN users u ON u.id = de.user_id WHERE (sqlc.narg(user_id)::uuid IS NULL OR de.user_id = sqlc.narg(user_id)::uuid) AND (sqlc.narg(client_id)::text IS NULL OR de.client_id = sqlc.narg(client_id)::text) AND (sqlc.narg(kind)::text IS NULL OR de.kind = sqlc.narg(kind)::text) AND (sqlc.narg(from_ts)::timestamptz IS NULL OR de.occurred_at >= sqlc.narg(from_ts)::timestamptz) AND (sqlc.narg(to_ts)::timestamptz IS NULL OR de.occurred_at <= sqlc.narg(to_ts)::timestamptz) ORDER BY de.occurred_at DESC LIMIT sqlc.arg(lim)::int OFFSET sqlc.arg(off)::int; -- name: ListDiagnosticDevices :many -- Distinct devices that have reported, for the admin device filter + -- "who is currently reporting" overview. Optionally scoped to one account. SELECT de.client_id AS client_id, de.user_id AS user_id, u.username AS username, max(de.app_version)::text AS app_version, max(de.os_version)::text AS os_version, max(de.occurred_at)::timestamptz AS last_seen, count(*) AS event_count FROM diagnostic_events de JOIN users u ON u.id = de.user_id WHERE (sqlc.narg(user_id)::uuid IS NULL OR de.user_id = sqlc.narg(user_id)::uuid) GROUP BY de.client_id, de.user_id, u.username ORDER BY last_seen DESC; -- name: GcPruneDiagnostics :execrows -- Retention sweep for the gc worker. Deletes diagnostic_events older -- than 30 days by server clock (received_at) so a skewed client clock -- can't keep rows alive. Matches the other gc lifecycle sweeps' -- hardcoded-threshold style; diagnostics are debug telemetry, not user -- data, and 30 days is ample to investigate a live incident after the -- fact. Returns the affected row count for the sweep log line. DELETE FROM diagnostic_events WHERE received_at < now() - INTERVAL '30 days';