Files
multica/server/pkg/db/generated/autopilot.sql.go
Naiyuan Qing d94ffd7a7a feat(autopilots): derive trigger kinds, next run, last run status in list
The list endpoint only selected the autopilot table, so the list UI
could not answer "is this automation working" without N+1 detail
calls. Each list row now carries trigger_kinds + next_run_at (enabled
triggers only — the columns describe how it fires today) and
last_run_status (most recent run). Fields are omitempty and absent
from detail/create/update responses; clients must treat them as
optional per the API compatibility rules.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 15:44:34 +08:00

1424 lines
43 KiB
Go

// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.31.1
// source: autopilot.sql
package db
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const advanceTriggerNextRun = `-- name: AdvanceTriggerNextRun :exec
UPDATE autopilot_trigger
SET next_run_at = $2,
last_fired_at = now(),
updated_at = now()
WHERE id = $1
`
type AdvanceTriggerNextRunParams struct {
ID pgtype.UUID `json:"id"`
NextRunAt pgtype.Timestamptz `json:"next_run_at"`
}
func (q *Queries) AdvanceTriggerNextRun(ctx context.Context, arg AdvanceTriggerNextRunParams) error {
_, err := q.db.Exec(ctx, advanceTriggerNextRun, arg.ID, arg.NextRunAt)
return err
}
const claimDueScheduleTriggers = `-- name: ClaimDueScheduleTriggers :many
UPDATE autopilot_trigger t
SET next_run_at = NULL
FROM autopilot a
WHERE t.autopilot_id = a.id
AND t.kind = 'schedule'
AND t.enabled = true
AND t.next_run_at IS NOT NULL
AND t.next_run_at <= now()
AND a.status = 'active'
RETURNING t.id, t.autopilot_id, t.kind, t.enabled, t.cron_expression, t.timezone, t.next_run_at, t.webhook_token, t.label, t.last_fired_at, t.created_at, t.updated_at, t.provider, t.signing_secret, t.event_filters, a.workspace_id AS autopilot_workspace_id
`
type ClaimDueScheduleTriggersRow struct {
ID pgtype.UUID `json:"id"`
AutopilotID pgtype.UUID `json:"autopilot_id"`
Kind string `json:"kind"`
Enabled bool `json:"enabled"`
CronExpression pgtype.Text `json:"cron_expression"`
Timezone pgtype.Text `json:"timezone"`
NextRunAt pgtype.Timestamptz `json:"next_run_at"`
WebhookToken pgtype.Text `json:"webhook_token"`
Label pgtype.Text `json:"label"`
LastFiredAt pgtype.Timestamptz `json:"last_fired_at"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
Provider string `json:"provider"`
SigningSecret pgtype.Text `json:"signing_secret"`
EventFilters []byte `json:"event_filters"`
AutopilotWorkspaceID pgtype.UUID `json:"autopilot_workspace_id"`
}
// =====================
// Scheduler Queries
// =====================
// Atomically claim all due schedule triggers to prevent concurrent execution.
// Joins the autopilot table to ensure only active autopilots are fired.
func (q *Queries) ClaimDueScheduleTriggers(ctx context.Context) ([]ClaimDueScheduleTriggersRow, error) {
rows, err := q.db.Query(ctx, claimDueScheduleTriggers)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ClaimDueScheduleTriggersRow{}
for rows.Next() {
var i ClaimDueScheduleTriggersRow
if err := rows.Scan(
&i.ID,
&i.AutopilotID,
&i.Kind,
&i.Enabled,
&i.CronExpression,
&i.Timezone,
&i.NextRunAt,
&i.WebhookToken,
&i.Label,
&i.LastFiredAt,
&i.CreatedAt,
&i.UpdatedAt,
&i.Provider,
&i.SigningSecret,
&i.EventFilters,
&i.AutopilotWorkspaceID,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const createAutopilot = `-- name: CreateAutopilot :one
INSERT INTO autopilot (
workspace_id, title, description, assignee_type, assignee_id,
status, execution_mode, issue_title_template, project_id,
created_by_type, created_by_id
) VALUES (
$1, $2, $9, $3, $4,
$5, $6, $10, $11,
$7, $8
) RETURNING id, workspace_id, title, description, assignee_id, status, execution_mode, issue_title_template, created_by_type, created_by_id, last_run_at, created_at, updated_at, assignee_type, project_id
`
type CreateAutopilotParams struct {
WorkspaceID pgtype.UUID `json:"workspace_id"`
Title string `json:"title"`
AssigneeType string `json:"assignee_type"`
AssigneeID pgtype.UUID `json:"assignee_id"`
Status string `json:"status"`
ExecutionMode string `json:"execution_mode"`
CreatedByType string `json:"created_by_type"`
CreatedByID pgtype.UUID `json:"created_by_id"`
Description pgtype.Text `json:"description"`
IssueTitleTemplate pgtype.Text `json:"issue_title_template"`
ProjectID pgtype.UUID `json:"project_id"`
}
func (q *Queries) CreateAutopilot(ctx context.Context, arg CreateAutopilotParams) (Autopilot, error) {
row := q.db.QueryRow(ctx, createAutopilot,
arg.WorkspaceID,
arg.Title,
arg.AssigneeType,
arg.AssigneeID,
arg.Status,
arg.ExecutionMode,
arg.CreatedByType,
arg.CreatedByID,
arg.Description,
arg.IssueTitleTemplate,
arg.ProjectID,
)
var i Autopilot
err := row.Scan(
&i.ID,
&i.WorkspaceID,
&i.Title,
&i.Description,
&i.AssigneeID,
&i.Status,
&i.ExecutionMode,
&i.IssueTitleTemplate,
&i.CreatedByType,
&i.CreatedByID,
&i.LastRunAt,
&i.CreatedAt,
&i.UpdatedAt,
&i.AssigneeType,
&i.ProjectID,
)
return i, err
}
const createAutopilotRun = `-- name: CreateAutopilotRun :one
INSERT INTO autopilot_run (
autopilot_id, trigger_id, source, status, trigger_payload, squad_id
) VALUES (
$1, $4, $2, $3, $5,
$6
) RETURNING id, autopilot_id, trigger_id, source, status, issue_id, task_id, triggered_at, completed_at, failure_reason, trigger_payload, result, created_at, squad_id
`
type CreateAutopilotRunParams struct {
AutopilotID pgtype.UUID `json:"autopilot_id"`
Source string `json:"source"`
Status string `json:"status"`
TriggerID pgtype.UUID `json:"trigger_id"`
TriggerPayload []byte `json:"trigger_payload"`
SquadID pgtype.UUID `json:"squad_id"`
}
// =====================
// Autopilot Run Management
// =====================
// squad_id is an attribution hook: set to the assignee squad when the
// parent autopilot has assignee_type='squad', NULL otherwise. The executing
// agent_id on agent_task_queue still records who actually ran the work
// (the squad leader); squad_id lets reports group by squad without a join.
func (q *Queries) CreateAutopilotRun(ctx context.Context, arg CreateAutopilotRunParams) (AutopilotRun, error) {
row := q.db.QueryRow(ctx, createAutopilotRun,
arg.AutopilotID,
arg.Source,
arg.Status,
arg.TriggerID,
arg.TriggerPayload,
arg.SquadID,
)
var i AutopilotRun
err := row.Scan(
&i.ID,
&i.AutopilotID,
&i.TriggerID,
&i.Source,
&i.Status,
&i.IssueID,
&i.TaskID,
&i.TriggeredAt,
&i.CompletedAt,
&i.FailureReason,
&i.TriggerPayload,
&i.Result,
&i.CreatedAt,
&i.SquadID,
)
return i, err
}
const createAutopilotTask = `-- name: CreateAutopilotTask :one
INSERT INTO agent_task_queue (agent_id, runtime_id, issue_id, status, priority, autopilot_run_id, trigger_summary)
VALUES ($1, $2, NULL, 'queued', $3, $4, $5)
RETURNING id, agent_id, issue_id, status, priority, dispatched_at, started_at, completed_at, result, error, created_at, context, runtime_id, session_id, work_dir, trigger_comment_id, chat_session_id, autopilot_run_id, attempt, max_attempts, parent_task_id, failure_reason, trigger_summary, force_fresh_session, is_leader_task, wait_reason, initiator_user_id
`
type CreateAutopilotTaskParams struct {
AgentID pgtype.UUID `json:"agent_id"`
RuntimeID pgtype.UUID `json:"runtime_id"`
Priority int32 `json:"priority"`
AutopilotRunID pgtype.UUID `json:"autopilot_run_id"`
TriggerSummary pgtype.Text `json:"trigger_summary"`
}
// =====================
// Task Queue (run_only mode)
// =====================
func (q *Queries) CreateAutopilotTask(ctx context.Context, arg CreateAutopilotTaskParams) (AgentTaskQueue, error) {
row := q.db.QueryRow(ctx, createAutopilotTask,
arg.AgentID,
arg.RuntimeID,
arg.Priority,
arg.AutopilotRunID,
arg.TriggerSummary,
)
var i AgentTaskQueue
err := row.Scan(
&i.ID,
&i.AgentID,
&i.IssueID,
&i.Status,
&i.Priority,
&i.DispatchedAt,
&i.StartedAt,
&i.CompletedAt,
&i.Result,
&i.Error,
&i.CreatedAt,
&i.Context,
&i.RuntimeID,
&i.SessionID,
&i.WorkDir,
&i.TriggerCommentID,
&i.ChatSessionID,
&i.AutopilotRunID,
&i.Attempt,
&i.MaxAttempts,
&i.ParentTaskID,
&i.FailureReason,
&i.TriggerSummary,
&i.ForceFreshSession,
&i.IsLeaderTask,
&i.WaitReason,
&i.InitiatorUserID,
)
return i, err
}
const createAutopilotTrigger = `-- name: CreateAutopilotTrigger :one
INSERT INTO autopilot_trigger (
autopilot_id, kind, enabled, cron_expression, timezone,
next_run_at, webhook_token, label, provider, event_filters
) VALUES (
$1, $2, $3, $4, $5,
$6, $7, $8,
COALESCE($9::text, 'generic'),
$10
) RETURNING id, autopilot_id, kind, enabled, cron_expression, timezone, next_run_at, webhook_token, label, last_fired_at, created_at, updated_at, provider, signing_secret, event_filters
`
type CreateAutopilotTriggerParams struct {
AutopilotID pgtype.UUID `json:"autopilot_id"`
Kind string `json:"kind"`
Enabled bool `json:"enabled"`
CronExpression pgtype.Text `json:"cron_expression"`
Timezone pgtype.Text `json:"timezone"`
NextRunAt pgtype.Timestamptz `json:"next_run_at"`
WebhookToken pgtype.Text `json:"webhook_token"`
Label pgtype.Text `json:"label"`
Provider pgtype.Text `json:"provider"`
EventFilters []byte `json:"event_filters"`
}
func (q *Queries) CreateAutopilotTrigger(ctx context.Context, arg CreateAutopilotTriggerParams) (AutopilotTrigger, error) {
row := q.db.QueryRow(ctx, createAutopilotTrigger,
arg.AutopilotID,
arg.Kind,
arg.Enabled,
arg.CronExpression,
arg.Timezone,
arg.NextRunAt,
arg.WebhookToken,
arg.Label,
arg.Provider,
arg.EventFilters,
)
var i AutopilotTrigger
err := row.Scan(
&i.ID,
&i.AutopilotID,
&i.Kind,
&i.Enabled,
&i.CronExpression,
&i.Timezone,
&i.NextRunAt,
&i.WebhookToken,
&i.Label,
&i.LastFiredAt,
&i.CreatedAt,
&i.UpdatedAt,
&i.Provider,
&i.SigningSecret,
&i.EventFilters,
)
return i, err
}
const deleteAutopilot = `-- name: DeleteAutopilot :exec
DELETE FROM autopilot WHERE id = $1
`
func (q *Queries) DeleteAutopilot(ctx context.Context, id pgtype.UUID) error {
_, err := q.db.Exec(ctx, deleteAutopilot, id)
return err
}
const deleteAutopilotTrigger = `-- name: DeleteAutopilotTrigger :exec
DELETE FROM autopilot_trigger WHERE id = $1
`
func (q *Queries) DeleteAutopilotTrigger(ctx context.Context, id pgtype.UUID) error {
_, err := q.db.Exec(ctx, deleteAutopilotTrigger, id)
return err
}
const failAutopilotRunsByIssue = `-- name: FailAutopilotRunsByIssue :exec
UPDATE autopilot_run
SET status = 'failed', completed_at = now(), failure_reason = 'linked issue was deleted'
WHERE issue_id = $1
AND status IN ('issue_created', 'running')
`
// Fails active autopilot runs linked to a given issue.
// Must be called BEFORE issue deletion (ON DELETE SET NULL clears issue_id).
func (q *Queries) FailAutopilotRunsByIssue(ctx context.Context, issueID pgtype.UUID) error {
_, err := q.db.Exec(ctx, failAutopilotRunsByIssue, issueID)
return err
}
const getAutopilot = `-- name: GetAutopilot :one
SELECT id, workspace_id, title, description, assignee_id, status, execution_mode, issue_title_template, created_by_type, created_by_id, last_run_at, created_at, updated_at, assignee_type, project_id FROM autopilot
WHERE id = $1
`
func (q *Queries) GetAutopilot(ctx context.Context, id pgtype.UUID) (Autopilot, error) {
row := q.db.QueryRow(ctx, getAutopilot, id)
var i Autopilot
err := row.Scan(
&i.ID,
&i.WorkspaceID,
&i.Title,
&i.Description,
&i.AssigneeID,
&i.Status,
&i.ExecutionMode,
&i.IssueTitleTemplate,
&i.CreatedByType,
&i.CreatedByID,
&i.LastRunAt,
&i.CreatedAt,
&i.UpdatedAt,
&i.AssigneeType,
&i.ProjectID,
)
return i, err
}
const getAutopilotInWorkspace = `-- name: GetAutopilotInWorkspace :one
SELECT id, workspace_id, title, description, assignee_id, status, execution_mode, issue_title_template, created_by_type, created_by_id, last_run_at, created_at, updated_at, assignee_type, project_id FROM autopilot
WHERE id = $1 AND workspace_id = $2
`
type GetAutopilotInWorkspaceParams struct {
ID pgtype.UUID `json:"id"`
WorkspaceID pgtype.UUID `json:"workspace_id"`
}
func (q *Queries) GetAutopilotInWorkspace(ctx context.Context, arg GetAutopilotInWorkspaceParams) (Autopilot, error) {
row := q.db.QueryRow(ctx, getAutopilotInWorkspace, arg.ID, arg.WorkspaceID)
var i Autopilot
err := row.Scan(
&i.ID,
&i.WorkspaceID,
&i.Title,
&i.Description,
&i.AssigneeID,
&i.Status,
&i.ExecutionMode,
&i.IssueTitleTemplate,
&i.CreatedByType,
&i.CreatedByID,
&i.LastRunAt,
&i.CreatedAt,
&i.UpdatedAt,
&i.AssigneeType,
&i.ProjectID,
)
return i, err
}
const getAutopilotRun = `-- name: GetAutopilotRun :one
SELECT id, autopilot_id, trigger_id, source, status, issue_id, task_id, triggered_at, completed_at, failure_reason, trigger_payload, result, created_at, squad_id FROM autopilot_run
WHERE id = $1
`
func (q *Queries) GetAutopilotRun(ctx context.Context, id pgtype.UUID) (AutopilotRun, error) {
row := q.db.QueryRow(ctx, getAutopilotRun, id)
var i AutopilotRun
err := row.Scan(
&i.ID,
&i.AutopilotID,
&i.TriggerID,
&i.Source,
&i.Status,
&i.IssueID,
&i.TaskID,
&i.TriggeredAt,
&i.CompletedAt,
&i.FailureReason,
&i.TriggerPayload,
&i.Result,
&i.CreatedAt,
&i.SquadID,
)
return i, err
}
const getAutopilotRunByIssue = `-- name: GetAutopilotRunByIssue :one
SELECT id, autopilot_id, trigger_id, source, status, issue_id, task_id, triggered_at, completed_at, failure_reason, trigger_payload, result, created_at, squad_id FROM autopilot_run
WHERE issue_id = $1 AND status IN ('issue_created', 'running')
LIMIT 1
`
// =====================
// Run lookup by linked entities
// =====================
func (q *Queries) GetAutopilotRunByIssue(ctx context.Context, issueID pgtype.UUID) (AutopilotRun, error) {
row := q.db.QueryRow(ctx, getAutopilotRunByIssue, issueID)
var i AutopilotRun
err := row.Scan(
&i.ID,
&i.AutopilotID,
&i.TriggerID,
&i.Source,
&i.Status,
&i.IssueID,
&i.TaskID,
&i.TriggeredAt,
&i.CompletedAt,
&i.FailureReason,
&i.TriggerPayload,
&i.Result,
&i.CreatedAt,
&i.SquadID,
)
return i, err
}
const getAutopilotTrigger = `-- name: GetAutopilotTrigger :one
SELECT id, autopilot_id, kind, enabled, cron_expression, timezone, next_run_at, webhook_token, label, last_fired_at, created_at, updated_at, provider, signing_secret, event_filters FROM autopilot_trigger
WHERE id = $1
`
func (q *Queries) GetAutopilotTrigger(ctx context.Context, id pgtype.UUID) (AutopilotTrigger, error) {
row := q.db.QueryRow(ctx, getAutopilotTrigger, id)
var i AutopilotTrigger
err := row.Scan(
&i.ID,
&i.AutopilotID,
&i.Kind,
&i.Enabled,
&i.CronExpression,
&i.Timezone,
&i.NextRunAt,
&i.WebhookToken,
&i.Label,
&i.LastFiredAt,
&i.CreatedAt,
&i.UpdatedAt,
&i.Provider,
&i.SigningSecret,
&i.EventFilters,
)
return i, err
}
const getWebhookTriggerByToken = `-- name: GetWebhookTriggerByToken :one
SELECT t.id, t.autopilot_id, t.kind, t.enabled, t.cron_expression, t.timezone, t.next_run_at, t.webhook_token, t.label, t.last_fired_at, t.created_at, t.updated_at, t.provider, t.signing_secret, t.event_filters, a.workspace_id AS autopilot_workspace_id
FROM autopilot_trigger t
JOIN autopilot a ON a.id = t.autopilot_id
WHERE t.kind = 'webhook'
AND t.webhook_token = $1
`
type GetWebhookTriggerByTokenRow struct {
ID pgtype.UUID `json:"id"`
AutopilotID pgtype.UUID `json:"autopilot_id"`
Kind string `json:"kind"`
Enabled bool `json:"enabled"`
CronExpression pgtype.Text `json:"cron_expression"`
Timezone pgtype.Text `json:"timezone"`
NextRunAt pgtype.Timestamptz `json:"next_run_at"`
WebhookToken pgtype.Text `json:"webhook_token"`
Label pgtype.Text `json:"label"`
LastFiredAt pgtype.Timestamptz `json:"last_fired_at"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
Provider string `json:"provider"`
SigningSecret pgtype.Text `json:"signing_secret"`
EventFilters []byte `json:"event_filters"`
AutopilotWorkspaceID pgtype.UUID `json:"autopilot_workspace_id"`
}
// Look up a webhook trigger by its public bearer token. Joined to autopilot
// so the webhook handler can derive the workspace from the trigger's parent
// without trusting any request header. The handler still re-loads the
// Autopilot via GetAutopilot and cross-checks WorkspaceID matches the row's
// autopilot_workspace_id.
func (q *Queries) GetWebhookTriggerByToken(ctx context.Context, webhookToken pgtype.Text) (GetWebhookTriggerByTokenRow, error) {
row := q.db.QueryRow(ctx, getWebhookTriggerByToken, webhookToken)
var i GetWebhookTriggerByTokenRow
err := row.Scan(
&i.ID,
&i.AutopilotID,
&i.Kind,
&i.Enabled,
&i.CronExpression,
&i.Timezone,
&i.NextRunAt,
&i.WebhookToken,
&i.Label,
&i.LastFiredAt,
&i.CreatedAt,
&i.UpdatedAt,
&i.Provider,
&i.SigningSecret,
&i.EventFilters,
&i.AutopilotWorkspaceID,
)
return i, err
}
const listAutopilotRuns = `-- name: ListAutopilotRuns :many
SELECT id, autopilot_id, trigger_id, source, status, issue_id, task_id, triggered_at, completed_at, failure_reason, trigger_payload, result, created_at, squad_id FROM autopilot_run
WHERE autopilot_id = $1
ORDER BY created_at DESC
LIMIT $2 OFFSET $3
`
type ListAutopilotRunsParams struct {
AutopilotID pgtype.UUID `json:"autopilot_id"`
Limit int32 `json:"limit"`
Offset int32 `json:"offset"`
}
func (q *Queries) ListAutopilotRuns(ctx context.Context, arg ListAutopilotRunsParams) ([]AutopilotRun, error) {
rows, err := q.db.Query(ctx, listAutopilotRuns, arg.AutopilotID, arg.Limit, arg.Offset)
if err != nil {
return nil, err
}
defer rows.Close()
items := []AutopilotRun{}
for rows.Next() {
var i AutopilotRun
if err := rows.Scan(
&i.ID,
&i.AutopilotID,
&i.TriggerID,
&i.Source,
&i.Status,
&i.IssueID,
&i.TaskID,
&i.TriggeredAt,
&i.CompletedAt,
&i.FailureReason,
&i.TriggerPayload,
&i.Result,
&i.CreatedAt,
&i.SquadID,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listAutopilotTriggers = `-- name: ListAutopilotTriggers :many
SELECT id, autopilot_id, kind, enabled, cron_expression, timezone, next_run_at, webhook_token, label, last_fired_at, created_at, updated_at, provider, signing_secret, event_filters FROM autopilot_trigger
WHERE autopilot_id = $1
ORDER BY created_at ASC
`
// =====================
// Autopilot Trigger CRUD
// =====================
func (q *Queries) ListAutopilotTriggers(ctx context.Context, autopilotID pgtype.UUID) ([]AutopilotTrigger, error) {
rows, err := q.db.Query(ctx, listAutopilotTriggers, autopilotID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []AutopilotTrigger{}
for rows.Next() {
var i AutopilotTrigger
if err := rows.Scan(
&i.ID,
&i.AutopilotID,
&i.Kind,
&i.Enabled,
&i.CronExpression,
&i.Timezone,
&i.NextRunAt,
&i.WebhookToken,
&i.Label,
&i.LastFiredAt,
&i.CreatedAt,
&i.UpdatedAt,
&i.Provider,
&i.SigningSecret,
&i.EventFilters,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listAutopilots = `-- name: ListAutopilots :many
SELECT
a.id, a.workspace_id, a.title, a.description, a.assignee_id, a.status, a.execution_mode, a.issue_title_template, a.created_by_type, a.created_by_id, a.last_run_at, a.created_at, a.updated_at, a.assignee_type, a.project_id,
(
SELECT array_agg(DISTINCT t.kind ORDER BY t.kind)
FROM autopilot_trigger t
WHERE t.autopilot_id = a.id AND t.enabled
)::text[] AS trigger_kinds,
(
SELECT min(t.next_run_at)
FROM autopilot_trigger t
WHERE t.autopilot_id = a.id AND t.enabled AND t.kind = 'schedule'
)::timestamptz AS next_run_at,
COALESCE((
SELECT r.status
FROM autopilot_run r
WHERE r.autopilot_id = a.id
ORDER BY r.triggered_at DESC
LIMIT 1
), '')::text AS last_run_status
FROM autopilot a
WHERE a.workspace_id = $1
AND ($2::text IS NULL OR a.status = $2)
ORDER BY a.created_at DESC
`
type ListAutopilotsParams struct {
WorkspaceID pgtype.UUID `json:"workspace_id"`
Status pgtype.Text `json:"status"`
}
type ListAutopilotsRow struct {
Autopilot Autopilot `json:"autopilot"`
TriggerKinds []string `json:"trigger_kinds"`
NextRunAt pgtype.Timestamptz `json:"next_run_at"`
LastRunStatus string `json:"last_run_status"`
}
// =====================
// Autopilot CRUD
// =====================
// List rows carry three derived columns the list UI needs (trigger badges,
// next run, last-run outcome) so the page never has to N+1 into the detail
// endpoint. trigger_kinds/next_run_at only consider ENABLED triggers — the
// columns answer "how does this fire today", not "what is configured".
// last_run_status is COALESCEd to ” (never ran) because sqlc cannot infer
// nullability through a scalar subquery; the handler maps ” back to omitted.
func (q *Queries) ListAutopilots(ctx context.Context, arg ListAutopilotsParams) ([]ListAutopilotsRow, error) {
rows, err := q.db.Query(ctx, listAutopilots, arg.WorkspaceID, arg.Status)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ListAutopilotsRow{}
for rows.Next() {
var i ListAutopilotsRow
if err := rows.Scan(
&i.Autopilot.ID,
&i.Autopilot.WorkspaceID,
&i.Autopilot.Title,
&i.Autopilot.Description,
&i.Autopilot.AssigneeID,
&i.Autopilot.Status,
&i.Autopilot.ExecutionMode,
&i.Autopilot.IssueTitleTemplate,
&i.Autopilot.CreatedByType,
&i.Autopilot.CreatedByID,
&i.Autopilot.LastRunAt,
&i.Autopilot.CreatedAt,
&i.Autopilot.UpdatedAt,
&i.Autopilot.AssigneeType,
&i.Autopilot.ProjectID,
&i.TriggerKinds,
&i.NextRunAt,
&i.LastRunStatus,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const recoverLostTriggers = `-- name: RecoverLostTriggers :many
SELECT t.id, t.autopilot_id, t.kind, t.enabled, t.cron_expression, t.timezone, t.next_run_at, t.webhook_token, t.label, t.last_fired_at, t.created_at, t.updated_at, t.provider, t.signing_secret, t.event_filters, a.workspace_id AS autopilot_workspace_id
FROM autopilot_trigger t
JOIN autopilot a ON t.autopilot_id = a.id
WHERE t.kind = 'schedule'
AND t.enabled = true
AND t.next_run_at IS NULL
AND t.cron_expression IS NOT NULL
AND a.status = 'active'
`
type RecoverLostTriggersRow struct {
ID pgtype.UUID `json:"id"`
AutopilotID pgtype.UUID `json:"autopilot_id"`
Kind string `json:"kind"`
Enabled bool `json:"enabled"`
CronExpression pgtype.Text `json:"cron_expression"`
Timezone pgtype.Text `json:"timezone"`
NextRunAt pgtype.Timestamptz `json:"next_run_at"`
WebhookToken pgtype.Text `json:"webhook_token"`
Label pgtype.Text `json:"label"`
LastFiredAt pgtype.Timestamptz `json:"last_fired_at"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
Provider string `json:"provider"`
SigningSecret pgtype.Text `json:"signing_secret"`
EventFilters []byte `json:"event_filters"`
AutopilotWorkspaceID pgtype.UUID `json:"autopilot_workspace_id"`
}
// =====================
// Scheduler Recovery
// =====================
// Finds schedule triggers that were claimed (next_run_at = NULL) but never
// advanced — typically due to a scheduler crash. Returns them so the scheduler
// can recompute next_run_at.
func (q *Queries) RecoverLostTriggers(ctx context.Context) ([]RecoverLostTriggersRow, error) {
rows, err := q.db.Query(ctx, recoverLostTriggers)
if err != nil {
return nil, err
}
defer rows.Close()
items := []RecoverLostTriggersRow{}
for rows.Next() {
var i RecoverLostTriggersRow
if err := rows.Scan(
&i.ID,
&i.AutopilotID,
&i.Kind,
&i.Enabled,
&i.CronExpression,
&i.Timezone,
&i.NextRunAt,
&i.WebhookToken,
&i.Label,
&i.LastFiredAt,
&i.CreatedAt,
&i.UpdatedAt,
&i.Provider,
&i.SigningSecret,
&i.EventFilters,
&i.AutopilotWorkspaceID,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const rotateAutopilotTriggerWebhookToken = `-- name: RotateAutopilotTriggerWebhookToken :one
UPDATE autopilot_trigger
SET webhook_token = $2,
updated_at = now()
WHERE id = $1
AND kind = 'webhook'
RETURNING id, autopilot_id, kind, enabled, cron_expression, timezone, next_run_at, webhook_token, label, last_fired_at, created_at, updated_at, provider, signing_secret, event_filters
`
type RotateAutopilotTriggerWebhookTokenParams struct {
ID pgtype.UUID `json:"id"`
WebhookToken pgtype.Text `json:"webhook_token"`
}
// Rotates the bearer token for a webhook trigger. Restricted to kind='webhook'
// so an accidental call against a schedule/api trigger is a no-op (returns no
// rows) rather than corrupting unrelated state.
func (q *Queries) RotateAutopilotTriggerWebhookToken(ctx context.Context, arg RotateAutopilotTriggerWebhookTokenParams) (AutopilotTrigger, error) {
row := q.db.QueryRow(ctx, rotateAutopilotTriggerWebhookToken, arg.ID, arg.WebhookToken)
var i AutopilotTrigger
err := row.Scan(
&i.ID,
&i.AutopilotID,
&i.Kind,
&i.Enabled,
&i.CronExpression,
&i.Timezone,
&i.NextRunAt,
&i.WebhookToken,
&i.Label,
&i.LastFiredAt,
&i.CreatedAt,
&i.UpdatedAt,
&i.Provider,
&i.SigningSecret,
&i.EventFilters,
)
return i, err
}
const selectAutopilotsExceedingFailureThreshold = `-- name: SelectAutopilotsExceedingFailureThreshold :many
WITH stats AS (
SELECT autopilot_id,
count(*) FILTER (WHERE status IN ('completed', 'failed')) AS total,
count(*) FILTER (WHERE status = 'failed') AS failed
FROM autopilot_run
WHERE created_at >= $3::timestamptz
GROUP BY autopilot_id
)
SELECT a.id, a.workspace_id, a.title, a.assignee_id,
a.created_by_type, a.created_by_id,
s.total::bigint AS total_runs,
s.failed::bigint AS failed_runs
FROM autopilot a
JOIN stats s ON s.autopilot_id = a.id
WHERE a.status = 'active'
AND s.total >= $1::bigint
AND s.failed::float8 / NULLIF(s.total, 0)::float8 >= $2::float8
ORDER BY s.failed DESC, a.id ASC
`
type SelectAutopilotsExceedingFailureThresholdParams struct {
MinRuns int64 `json:"min_runs"`
FailRatioThreshold float64 `json:"fail_ratio_threshold"`
Since pgtype.Timestamptz `json:"since"`
}
type SelectAutopilotsExceedingFailureThresholdRow struct {
ID pgtype.UUID `json:"id"`
WorkspaceID pgtype.UUID `json:"workspace_id"`
Title string `json:"title"`
AssigneeID pgtype.UUID `json:"assignee_id"`
CreatedByType string `json:"created_by_type"`
CreatedByID pgtype.UUID `json:"created_by_id"`
TotalRuns int64 `json:"total_runs"`
FailedRuns int64 `json:"failed_runs"`
}
// =====================
// Failure-rate auto-pause
// =====================
// Find active autopilots whose recent run failure rate exceeds the threshold.
// Counts only "real" terminal runs (completed | failed). 'skipped' is
// excluded from BOTH numerator and denominator: an admission-skipped run
// (e.g. assignee runtime offline at dispatch time, MUL-1899) is neither a
// success nor a failure, so it must not dilute the failure ratio (which
// would let a 100%-failing autopilot mask itself behind a wall of skips)
// nor inflate it. issue_created/running are still excluded so in-flight
// work isn't penalised.
// Used by the failure monitor to auto-pause sustained-failure autopilots
// (the canonical example from MUL-1336 was an autopilot scheduled every 5 min
// that 100% failed for days, burning ~1.5k useless tasks per week).
func (q *Queries) SelectAutopilotsExceedingFailureThreshold(ctx context.Context, arg SelectAutopilotsExceedingFailureThresholdParams) ([]SelectAutopilotsExceedingFailureThresholdRow, error) {
rows, err := q.db.Query(ctx, selectAutopilotsExceedingFailureThreshold, arg.MinRuns, arg.FailRatioThreshold, arg.Since)
if err != nil {
return nil, err
}
defer rows.Close()
items := []SelectAutopilotsExceedingFailureThresholdRow{}
for rows.Next() {
var i SelectAutopilotsExceedingFailureThresholdRow
if err := rows.Scan(
&i.ID,
&i.WorkspaceID,
&i.Title,
&i.AssigneeID,
&i.CreatedByType,
&i.CreatedByID,
&i.TotalRuns,
&i.FailedRuns,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const setAutopilotTriggerSigningSecret = `-- name: SetAutopilotTriggerSigningSecret :one
UPDATE autopilot_trigger
SET signing_secret = $2,
updated_at = now()
WHERE id = $1
AND kind = 'webhook'
RETURNING id, autopilot_id, kind, enabled, cron_expression, timezone, next_run_at, webhook_token, label, last_fired_at, created_at, updated_at, provider, signing_secret, event_filters
`
type SetAutopilotTriggerSigningSecretParams struct {
ID pgtype.UUID `json:"id"`
SigningSecret pgtype.Text `json:"signing_secret"`
}
// Writes the signing secret for a webhook trigger. Kept as a dedicated query
// (not a field on UpdateAutopilotTrigger) so the request body for the
// write-only endpoint only ever carries the secret value, with no risk of an
// accidental log line leaking it alongside other fields. Restricted to
// webhook triggers to avoid corrupting unrelated state.
func (q *Queries) SetAutopilotTriggerSigningSecret(ctx context.Context, arg SetAutopilotTriggerSigningSecretParams) (AutopilotTrigger, error) {
row := q.db.QueryRow(ctx, setAutopilotTriggerSigningSecret, arg.ID, arg.SigningSecret)
var i AutopilotTrigger
err := row.Scan(
&i.ID,
&i.AutopilotID,
&i.Kind,
&i.Enabled,
&i.CronExpression,
&i.Timezone,
&i.NextRunAt,
&i.WebhookToken,
&i.Label,
&i.LastFiredAt,
&i.CreatedAt,
&i.UpdatedAt,
&i.Provider,
&i.SigningSecret,
&i.EventFilters,
)
return i, err
}
const setAutopilotTriggerWebhookToken = `-- name: SetAutopilotTriggerWebhookToken :one
UPDATE autopilot_trigger
SET webhook_token = $2,
updated_at = now()
WHERE id = $1
RETURNING id, autopilot_id, kind, enabled, cron_expression, timezone, next_run_at, webhook_token, label, last_fired_at, created_at, updated_at, provider, signing_secret, event_filters
`
type SetAutopilotTriggerWebhookTokenParams struct {
ID pgtype.UUID `json:"id"`
WebhookToken pgtype.Text `json:"webhook_token"`
}
// Sets the webhook token at creation time. CreateAutopilotTrigger inserts the
// row first (using its full 8-arg signature), then this query attaches the
// token. Splitting the create + token-set keeps the existing CreateAutopilotTrigger
// query usable by the schedule path without forcing every caller to think
// about webhook_token.
func (q *Queries) SetAutopilotTriggerWebhookToken(ctx context.Context, arg SetAutopilotTriggerWebhookTokenParams) (AutopilotTrigger, error) {
row := q.db.QueryRow(ctx, setAutopilotTriggerWebhookToken, arg.ID, arg.WebhookToken)
var i AutopilotTrigger
err := row.Scan(
&i.ID,
&i.AutopilotID,
&i.Kind,
&i.Enabled,
&i.CronExpression,
&i.Timezone,
&i.NextRunAt,
&i.WebhookToken,
&i.Label,
&i.LastFiredAt,
&i.CreatedAt,
&i.UpdatedAt,
&i.Provider,
&i.SigningSecret,
&i.EventFilters,
)
return i, err
}
const systemPauseAutopilot = `-- name: SystemPauseAutopilot :one
UPDATE autopilot
SET status = 'paused', updated_at = now()
WHERE id = $1 AND status = 'active'
RETURNING id, workspace_id, title, description, assignee_id, status, execution_mode, issue_title_template, created_by_type, created_by_id, last_run_at, created_at, updated_at, assignee_type, project_id
`
// Atomically pauses an autopilot only if it is currently active. Returns no
// rows when the autopilot was already paused/archived (or another worker
// raced first), letting the caller treat that as a benign no-op rather than
// an error.
func (q *Queries) SystemPauseAutopilot(ctx context.Context, id pgtype.UUID) (Autopilot, error) {
row := q.db.QueryRow(ctx, systemPauseAutopilot, id)
var i Autopilot
err := row.Scan(
&i.ID,
&i.WorkspaceID,
&i.Title,
&i.Description,
&i.AssigneeID,
&i.Status,
&i.ExecutionMode,
&i.IssueTitleTemplate,
&i.CreatedByType,
&i.CreatedByID,
&i.LastRunAt,
&i.CreatedAt,
&i.UpdatedAt,
&i.AssigneeType,
&i.ProjectID,
)
return i, err
}
const touchAutopilotTriggerFiredAt = `-- name: TouchAutopilotTriggerFiredAt :exec
UPDATE autopilot_trigger
SET last_fired_at = now(),
updated_at = now()
WHERE id = $1
`
// Bumps last_fired_at after a webhook fires, regardless of whether the
// dispatch succeeded, was admission-skipped, or even if Autopilot status
// transitioned to paused/disabled at exactly the wrong moment. Disabled /
// paused early-return paths in the handler never call this.
func (q *Queries) TouchAutopilotTriggerFiredAt(ctx context.Context, id pgtype.UUID) error {
_, err := q.db.Exec(ctx, touchAutopilotTriggerFiredAt, id)
return err
}
const updateAutopilot = `-- name: UpdateAutopilot :one
UPDATE autopilot SET
title = COALESCE($2, title),
description = COALESCE($3, description),
assignee_type = COALESCE($4, assignee_type),
assignee_id = COALESCE($5::uuid, assignee_id),
status = COALESCE($6, status),
execution_mode = COALESCE($7, execution_mode),
issue_title_template = $8,
project_id = $9,
updated_at = now()
WHERE id = $1
RETURNING id, workspace_id, title, description, assignee_id, status, execution_mode, issue_title_template, created_by_type, created_by_id, last_run_at, created_at, updated_at, assignee_type, project_id
`
type UpdateAutopilotParams struct {
ID pgtype.UUID `json:"id"`
Title pgtype.Text `json:"title"`
Description pgtype.Text `json:"description"`
AssigneeType pgtype.Text `json:"assignee_type"`
AssigneeID pgtype.UUID `json:"assignee_id"`
Status pgtype.Text `json:"status"`
ExecutionMode pgtype.Text `json:"execution_mode"`
IssueTitleTemplate pgtype.Text `json:"issue_title_template"`
ProjectID pgtype.UUID `json:"project_id"`
}
func (q *Queries) UpdateAutopilot(ctx context.Context, arg UpdateAutopilotParams) (Autopilot, error) {
row := q.db.QueryRow(ctx, updateAutopilot,
arg.ID,
arg.Title,
arg.Description,
arg.AssigneeType,
arg.AssigneeID,
arg.Status,
arg.ExecutionMode,
arg.IssueTitleTemplate,
arg.ProjectID,
)
var i Autopilot
err := row.Scan(
&i.ID,
&i.WorkspaceID,
&i.Title,
&i.Description,
&i.AssigneeID,
&i.Status,
&i.ExecutionMode,
&i.IssueTitleTemplate,
&i.CreatedByType,
&i.CreatedByID,
&i.LastRunAt,
&i.CreatedAt,
&i.UpdatedAt,
&i.AssigneeType,
&i.ProjectID,
)
return i, err
}
const updateAutopilotLastRunAt = `-- name: UpdateAutopilotLastRunAt :exec
UPDATE autopilot SET last_run_at = now(), updated_at = now()
WHERE id = $1
`
func (q *Queries) UpdateAutopilotLastRunAt(ctx context.Context, id pgtype.UUID) error {
_, err := q.db.Exec(ctx, updateAutopilotLastRunAt, id)
return err
}
const updateAutopilotRunCompleted = `-- name: UpdateAutopilotRunCompleted :one
UPDATE autopilot_run
SET status = 'completed', completed_at = now(), result = $2
WHERE id = $1
RETURNING id, autopilot_id, trigger_id, source, status, issue_id, task_id, triggered_at, completed_at, failure_reason, trigger_payload, result, created_at, squad_id
`
type UpdateAutopilotRunCompletedParams struct {
ID pgtype.UUID `json:"id"`
Result []byte `json:"result"`
}
func (q *Queries) UpdateAutopilotRunCompleted(ctx context.Context, arg UpdateAutopilotRunCompletedParams) (AutopilotRun, error) {
row := q.db.QueryRow(ctx, updateAutopilotRunCompleted, arg.ID, arg.Result)
var i AutopilotRun
err := row.Scan(
&i.ID,
&i.AutopilotID,
&i.TriggerID,
&i.Source,
&i.Status,
&i.IssueID,
&i.TaskID,
&i.TriggeredAt,
&i.CompletedAt,
&i.FailureReason,
&i.TriggerPayload,
&i.Result,
&i.CreatedAt,
&i.SquadID,
)
return i, err
}
const updateAutopilotRunFailed = `-- name: UpdateAutopilotRunFailed :one
UPDATE autopilot_run
SET status = 'failed', completed_at = now(), failure_reason = $2
WHERE id = $1
RETURNING id, autopilot_id, trigger_id, source, status, issue_id, task_id, triggered_at, completed_at, failure_reason, trigger_payload, result, created_at, squad_id
`
type UpdateAutopilotRunFailedParams struct {
ID pgtype.UUID `json:"id"`
FailureReason pgtype.Text `json:"failure_reason"`
}
func (q *Queries) UpdateAutopilotRunFailed(ctx context.Context, arg UpdateAutopilotRunFailedParams) (AutopilotRun, error) {
row := q.db.QueryRow(ctx, updateAutopilotRunFailed, arg.ID, arg.FailureReason)
var i AutopilotRun
err := row.Scan(
&i.ID,
&i.AutopilotID,
&i.TriggerID,
&i.Source,
&i.Status,
&i.IssueID,
&i.TaskID,
&i.TriggeredAt,
&i.CompletedAt,
&i.FailureReason,
&i.TriggerPayload,
&i.Result,
&i.CreatedAt,
&i.SquadID,
)
return i, err
}
const updateAutopilotRunIssueCreated = `-- name: UpdateAutopilotRunIssueCreated :one
UPDATE autopilot_run
SET status = 'issue_created', issue_id = $2
WHERE id = $1
RETURNING id, autopilot_id, trigger_id, source, status, issue_id, task_id, triggered_at, completed_at, failure_reason, trigger_payload, result, created_at, squad_id
`
type UpdateAutopilotRunIssueCreatedParams struct {
ID pgtype.UUID `json:"id"`
IssueID pgtype.UUID `json:"issue_id"`
}
func (q *Queries) UpdateAutopilotRunIssueCreated(ctx context.Context, arg UpdateAutopilotRunIssueCreatedParams) (AutopilotRun, error) {
row := q.db.QueryRow(ctx, updateAutopilotRunIssueCreated, arg.ID, arg.IssueID)
var i AutopilotRun
err := row.Scan(
&i.ID,
&i.AutopilotID,
&i.TriggerID,
&i.Source,
&i.Status,
&i.IssueID,
&i.TaskID,
&i.TriggeredAt,
&i.CompletedAt,
&i.FailureReason,
&i.TriggerPayload,
&i.Result,
&i.CreatedAt,
&i.SquadID,
)
return i, err
}
const updateAutopilotRunRunning = `-- name: UpdateAutopilotRunRunning :one
UPDATE autopilot_run
SET status = 'running', task_id = $2
WHERE id = $1
RETURNING id, autopilot_id, trigger_id, source, status, issue_id, task_id, triggered_at, completed_at, failure_reason, trigger_payload, result, created_at, squad_id
`
type UpdateAutopilotRunRunningParams struct {
ID pgtype.UUID `json:"id"`
TaskID pgtype.UUID `json:"task_id"`
}
func (q *Queries) UpdateAutopilotRunRunning(ctx context.Context, arg UpdateAutopilotRunRunningParams) (AutopilotRun, error) {
row := q.db.QueryRow(ctx, updateAutopilotRunRunning, arg.ID, arg.TaskID)
var i AutopilotRun
err := row.Scan(
&i.ID,
&i.AutopilotID,
&i.TriggerID,
&i.Source,
&i.Status,
&i.IssueID,
&i.TaskID,
&i.TriggeredAt,
&i.CompletedAt,
&i.FailureReason,
&i.TriggerPayload,
&i.Result,
&i.CreatedAt,
&i.SquadID,
)
return i, err
}
const updateAutopilotRunSkipped = `-- name: UpdateAutopilotRunSkipped :one
UPDATE autopilot_run
SET status = 'skipped', completed_at = now(), failure_reason = $2
WHERE id = $1
RETURNING id, autopilot_id, trigger_id, source, status, issue_id, task_id, triggered_at, completed_at, failure_reason, trigger_payload, result, created_at, squad_id
`
type UpdateAutopilotRunSkippedParams struct {
ID pgtype.UUID `json:"id"`
FailureReason pgtype.Text `json:"failure_reason"`
}
// Marks an autopilot_run as skipped without enqueueing any task. Used by the
// pre-flight admission check when the assignee agent's runtime is offline:
// creating an issue / task in that state would just pile a doomed job onto
// agent_task_queue (the canonical "持续给离线 local agent 入队" symptom from
// MUL-1899). Recording the skip + reason gives the UI / failure monitor / ops
// a paper trail without polluting the failure ratio.
func (q *Queries) UpdateAutopilotRunSkipped(ctx context.Context, arg UpdateAutopilotRunSkippedParams) (AutopilotRun, error) {
row := q.db.QueryRow(ctx, updateAutopilotRunSkipped, arg.ID, arg.FailureReason)
var i AutopilotRun
err := row.Scan(
&i.ID,
&i.AutopilotID,
&i.TriggerID,
&i.Source,
&i.Status,
&i.IssueID,
&i.TaskID,
&i.TriggeredAt,
&i.CompletedAt,
&i.FailureReason,
&i.TriggerPayload,
&i.Result,
&i.CreatedAt,
&i.SquadID,
)
return i, err
}
const updateAutopilotRunSkippedWithResult = `-- name: UpdateAutopilotRunSkippedWithResult :one
UPDATE autopilot_run
SET status = 'skipped',
completed_at = now(),
failure_reason = $2,
result = $3
WHERE id = $1
RETURNING id, autopilot_id, trigger_id, source, status, issue_id, task_id, triggered_at, completed_at, failure_reason, trigger_payload, result, created_at, squad_id
`
type UpdateAutopilotRunSkippedWithResultParams struct {
ID pgtype.UUID `json:"id"`
FailureReason pgtype.Text `json:"failure_reason"`
Result []byte `json:"result"`
}
func (q *Queries) UpdateAutopilotRunSkippedWithResult(ctx context.Context, arg UpdateAutopilotRunSkippedWithResultParams) (AutopilotRun, error) {
row := q.db.QueryRow(ctx, updateAutopilotRunSkippedWithResult, arg.ID, arg.FailureReason, arg.Result)
var i AutopilotRun
err := row.Scan(
&i.ID,
&i.AutopilotID,
&i.TriggerID,
&i.Source,
&i.Status,
&i.IssueID,
&i.TaskID,
&i.TriggeredAt,
&i.CompletedAt,
&i.FailureReason,
&i.TriggerPayload,
&i.Result,
&i.CreatedAt,
&i.SquadID,
)
return i, err
}
const updateAutopilotTrigger = `-- name: UpdateAutopilotTrigger :one
UPDATE autopilot_trigger SET
enabled = COALESCE($2::boolean, enabled),
cron_expression = COALESCE($3, cron_expression),
timezone = COALESCE($4, timezone),
next_run_at = $5,
label = COALESCE($6, label),
event_filters = COALESCE($7, event_filters),
updated_at = now()
WHERE id = $1
RETURNING id, autopilot_id, kind, enabled, cron_expression, timezone, next_run_at, webhook_token, label, last_fired_at, created_at, updated_at, provider, signing_secret, event_filters
`
type UpdateAutopilotTriggerParams struct {
ID pgtype.UUID `json:"id"`
Enabled pgtype.Bool `json:"enabled"`
CronExpression pgtype.Text `json:"cron_expression"`
Timezone pgtype.Text `json:"timezone"`
NextRunAt pgtype.Timestamptz `json:"next_run_at"`
Label pgtype.Text `json:"label"`
EventFilters []byte `json:"event_filters"`
}
func (q *Queries) UpdateAutopilotTrigger(ctx context.Context, arg UpdateAutopilotTriggerParams) (AutopilotTrigger, error) {
row := q.db.QueryRow(ctx, updateAutopilotTrigger,
arg.ID,
arg.Enabled,
arg.CronExpression,
arg.Timezone,
arg.NextRunAt,
arg.Label,
arg.EventFilters,
)
var i AutopilotTrigger
err := row.Scan(
&i.ID,
&i.AutopilotID,
&i.Kind,
&i.Enabled,
&i.CronExpression,
&i.Timezone,
&i.NextRunAt,
&i.WebhookToken,
&i.Label,
&i.LastFiredAt,
&i.CreatedAt,
&i.UpdatedAt,
&i.Provider,
&i.SigningSecret,
&i.EventFilters,
)
return i, err
}