-- Build Events: PostgreSQL-backed event persistence for SSE replay -- Stores build events for reconnection support beyond in-memory buffer CREATE TABLE IF NOT EXISTS build_events ( id TEXT PRIMARY KEY, -- Event ID (format: "{task_id}:{sequence}") task_id TEXT NOT NULL, -- Build task ID project_id TEXT NOT NULL, -- Project ID type TEXT NOT NULL, -- Event type (build.started, build.output, etc.) sequence BIGINT NOT NULL, -- Monotonic sequence within task timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- When event occurred data JSONB NOT NULL DEFAULT '{}', -- Event-specific payload created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() -- When stored (for cleanup) ); -- Index for efficient task-based queries (replay by task ID) CREATE INDEX IF NOT EXISTS idx_build_events_task_id ON build_events(task_id); -- Index for efficient sequence-based replay (Last-Event-ID support) CREATE INDEX IF NOT EXISTS idx_build_events_task_sequence ON build_events(task_id, sequence); -- Index for cleanup queries (delete old events) CREATE INDEX IF NOT EXISTS idx_build_events_created_at ON build_events(created_at); -- Comments COMMENT ON TABLE build_events IS 'Persisted build events for SSE replay support'; COMMENT ON COLUMN build_events.id IS 'Unique event ID (format: {task_id}:{sequence})'; COMMENT ON COLUMN build_events.task_id IS 'Build task this event belongs to'; COMMENT ON COLUMN build_events.project_id IS 'Project this event belongs to'; COMMENT ON COLUMN build_events.type IS 'Event type (build.started, build.output, build.completed, etc.)'; COMMENT ON COLUMN build_events.sequence IS 'Monotonically increasing sequence number within task'; COMMENT ON COLUMN build_events.timestamp IS 'When the event occurred'; COMMENT ON COLUMN build_events.data IS 'Event-specific payload as JSONB'; COMMENT ON COLUMN build_events.created_at IS 'When stored in database (used for cleanup)';