Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history

0061_pr_live_sessions.sql

Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.

0061_pr_live_sessions.sqlBlame52 lines · 1 contributor
3c03977Claude1-- Live co-editing on PRs — presence + cursor + content sync.
2--
3-- A `pr_live_sessions` row represents a single browser tab (or agent
4-- runtime) actively editing a PR's description, comments, or inline
5-- diff annotations. The SSE endpoint at /api/v2/pulls/:prId/live
6-- fans presence + cursor + content patches out to every subscriber
7-- on the same PR.
8--
9-- Either `user_id` OR `agent_session_id` is non-null (XOR-ish at the
10-- app layer; the DB just keeps both nullable so the same table can
11-- represent humans and AI agents in one stream). `color` is a stable
12-- per-user hue picked deterministically by the lib so concurrent tabs
13-- of the same user share a colour and the cursor ribbon stays steady.
14--
15-- `cursor_position` is JSON shaped like:
16-- { "field": "description" | "comment_<uuid>" | "line_<path>:<n>",
17-- "range": { "start": number, "end": number } }
18-- We keep this opaque at the DB layer so future field types (e.g. a
19-- new "review_summary" textarea) don't require a migration.
20--
21-- Lifecycle:
22-- joined_at — when the session was first registered.
23-- last_seen_at — touched by every heartbeat (15s cadence from the
24-- client) and every cursor/edit broadcast.
25-- status — 'active' | 'idle' (>60s no heartbeat) | 'left'
26-- (>5m no heartbeat or explicit leave).
27-- The autopilot pr-live-cleanup task transitions stale rows; the SSE
28-- subscriber also lazily updates status when it notices a stale peer.
29
30CREATE TABLE IF NOT EXISTS pr_live_sessions (
31 id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
32 pr_id uuid NOT NULL REFERENCES pull_requests(id) ON DELETE CASCADE,
33 user_id uuid REFERENCES users(id) ON DELETE CASCADE,
34 agent_session_id uuid REFERENCES agent_sessions(id) ON DELETE CASCADE,
35 cursor_position jsonb,
36 color text NOT NULL,
37 joined_at timestamptz NOT NULL DEFAULT now(),
38 last_seen_at timestamptz NOT NULL DEFAULT now(),
39 status text NOT NULL DEFAULT 'active'
40);
41
42-- Active-presence lookup: "who is here on PR X right now?" — answered
43-- in O(1) by this partial index. Status transitions to 'left' drop the
44-- row from the index automatically.
45CREATE INDEX IF NOT EXISTS pr_live_sessions_active_pr
46 ON pr_live_sessions (pr_id, last_seen_at)
47 WHERE status <> 'left';
48
49-- Stale-sweep lookup: the autopilot cleanup task scans rows whose
50-- last_seen_at is older than the idle/left thresholds.
51CREATE INDEX IF NOT EXISTS pr_live_sessions_status_seen
52 ON pr_live_sessions (status, last_seen_at);