// Code generated by sqlc. DO NOT EDIT. // versions: // sqlc v1.31.1 // source: issue_workflow.sql package db import ( "context" "github.com/jackc/pgx/v5/pgtype" ) const countProjectIssuesByStatus = `-- name: CountProjectIssuesByStatus :many SELECT status, COUNT(*)::bigint AS issue_count FROM issue WHERE workspace_id = $1::uuid AND project_id = ANY($2::uuid[]) GROUP BY status ORDER BY status ` type CountProjectIssuesByStatusParams struct { WorkspaceID pgtype.UUID `json:"workspace_id"` ProjectIds []pgtype.UUID `json:"project_ids"` } type CountProjectIssuesByStatusRow struct { Status string `json:"status"` IssueCount int64 `json:"issue_count"` } // Status census for a workflow switch or step removal, including terminal // issues: every issue of the project must end on a status its workflow lists. func (q *Queries) CountProjectIssuesByStatus(ctx context.Context, arg CountProjectIssuesByStatusParams) ([]CountProjectIssuesByStatusRow, error) { rows, err := q.db.Query(ctx, countProjectIssuesByStatus, arg.WorkspaceID, arg.ProjectIds) if err != nil { return nil, err } defer rows.Close() items := []CountProjectIssuesByStatusRow{} for rows.Next() { var i CountProjectIssuesByStatusRow if err := rows.Scan(&i.Status, &i.IssueCount); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const createDefaultIssueWorkflow = `-- name: CreateDefaultIssueWorkflow :many INSERT INTO issue_workflow (workspace_id, name, description, initial_status_key, steps, is_default) VALUES ( $1::uuid, 'Default', '', 'todo', $2::jsonb, true ) ON CONFLICT (workspace_id) WHERE is_default DO NOTHING RETURNING id, workspace_id, name, description, initial_status_key, steps, created_at, updated_at, is_default, owner_id ` type CreateDefaultIssueWorkflowParams struct { WorkspaceID pgtype.UUID `json:"workspace_id"` Steps []byte `json:"steps"` } // Returns no row when another request created the Default first. func (q *Queries) CreateDefaultIssueWorkflow(ctx context.Context, arg CreateDefaultIssueWorkflowParams) ([]IssueWorkflow, error) { rows, err := q.db.Query(ctx, createDefaultIssueWorkflow, arg.WorkspaceID, arg.Steps) if err != nil { return nil, err } defer rows.Close() items := []IssueWorkflow{} for rows.Next() { var i IssueWorkflow if err := rows.Scan( &i.ID, &i.WorkspaceID, &i.Name, &i.Description, &i.InitialStatusKey, &i.Steps, &i.CreatedAt, &i.UpdatedAt, &i.IsDefault, &i.OwnerID, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const createIssueWorkflow = `-- name: CreateIssueWorkflow :one INSERT INTO issue_workflow (workspace_id, name, description, initial_status_key, steps, owner_id) VALUES ( $1::uuid, $2::text, $3::text, $4::text, $5::jsonb, $6::uuid ) RETURNING id, workspace_id, name, description, initial_status_key, steps, created_at, updated_at, is_default, owner_id ` type CreateIssueWorkflowParams struct { WorkspaceID pgtype.UUID `json:"workspace_id"` Name string `json:"name"` Description string `json:"description"` InitialStatusKey string `json:"initial_status_key"` Steps []byte `json:"steps"` OwnerID pgtype.UUID `json:"owner_id"` } func (q *Queries) CreateIssueWorkflow(ctx context.Context, arg CreateIssueWorkflowParams) (IssueWorkflow, error) { row := q.db.QueryRow(ctx, createIssueWorkflow, arg.WorkspaceID, arg.Name, arg.Description, arg.InitialStatusKey, arg.Steps, arg.OwnerID, ) var i IssueWorkflow err := row.Scan( &i.ID, &i.WorkspaceID, &i.Name, &i.Description, &i.InitialStatusKey, &i.Steps, &i.CreatedAt, &i.UpdatedAt, &i.IsDefault, &i.OwnerID, ) return i, err } const deleteIssueWorkflow = `-- name: DeleteIssueWorkflow :execrows DELETE FROM issue_workflow WHERE id = $1::uuid AND workspace_id = $2::uuid AND NOT is_default ` type DeleteIssueWorkflowParams struct { ID pgtype.UUID `json:"id"` WorkspaceID pgtype.UUID `json:"workspace_id"` } func (q *Queries) DeleteIssueWorkflow(ctx context.Context, arg DeleteIssueWorkflowParams) (int64, error) { result, err := q.db.Exec(ctx, deleteIssueWorkflow, arg.ID, arg.WorkspaceID) if err != nil { return 0, err } return result.RowsAffected(), nil } const deleteIssueWorkflowsForWorkspace = `-- name: DeleteIssueWorkflowsForWorkspace :exec DELETE FROM issue_workflow WHERE workspace_id = $1::uuid ` // No foreign keys by project rule, so workspace teardown cleans up here. func (q *Queries) DeleteIssueWorkflowsForWorkspace(ctx context.Context, workspaceID pgtype.UUID) error { _, err := q.db.Exec(ctx, deleteIssueWorkflowsForWorkspace, workspaceID) return err } const getDefaultIssueWorkflow = `-- name: GetDefaultIssueWorkflow :one SELECT id, workspace_id, name, description, initial_status_key, steps, created_at, updated_at, is_default, owner_id FROM issue_workflow WHERE workspace_id = $1::uuid AND is_default ` func (q *Queries) GetDefaultIssueWorkflow(ctx context.Context, workspaceID pgtype.UUID) (IssueWorkflow, error) { row := q.db.QueryRow(ctx, getDefaultIssueWorkflow, workspaceID) var i IssueWorkflow err := row.Scan( &i.ID, &i.WorkspaceID, &i.Name, &i.Description, &i.InitialStatusKey, &i.Steps, &i.CreatedAt, &i.UpdatedAt, &i.IsDefault, &i.OwnerID, ) return i, err } const getIssueWorkflow = `-- name: GetIssueWorkflow :one SELECT id, workspace_id, name, description, initial_status_key, steps, created_at, updated_at, is_default, owner_id FROM issue_workflow WHERE id = $1::uuid AND workspace_id = $2::uuid ` type GetIssueWorkflowParams struct { ID pgtype.UUID `json:"id"` WorkspaceID pgtype.UUID `json:"workspace_id"` } func (q *Queries) GetIssueWorkflow(ctx context.Context, arg GetIssueWorkflowParams) (IssueWorkflow, error) { row := q.db.QueryRow(ctx, getIssueWorkflow, arg.ID, arg.WorkspaceID) var i IssueWorkflow err := row.Scan( &i.ID, &i.WorkspaceID, &i.Name, &i.Description, &i.InitialStatusKey, &i.Steps, &i.CreatedAt, &i.UpdatedAt, &i.IsDefault, &i.OwnerID, ) return i, err } const listIssueWorkflowNamesUsingStatusKey = `-- name: ListIssueWorkflowNamesUsingStatusKey :many SELECT name FROM issue_workflow WHERE workspace_id = $1::uuid AND NOT is_default AND steps @> jsonb_build_array(jsonb_build_object('status_key', $2::text)) ORDER BY lower(name) ` type ListIssueWorkflowNamesUsingStatusKeyParams struct { WorkspaceID pgtype.UUID `json:"workspace_id"` StatusKey string `json:"status_key"` } // Archive guard for the status catalog: a status a workflow still lists cannot // be retired, or that workflow's projects would lose a column. func (q *Queries) ListIssueWorkflowNamesUsingStatusKey(ctx context.Context, arg ListIssueWorkflowNamesUsingStatusKeyParams) ([]string, error) { rows, err := q.db.Query(ctx, listIssueWorkflowNamesUsingStatusKey, arg.WorkspaceID, arg.StatusKey) if err != nil { return nil, err } defer rows.Close() items := []string{} for rows.Next() { var name string if err := rows.Scan(&name); err != nil { return nil, err } items = append(items, name) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listIssueWorkflows = `-- name: ListIssueWorkflows :many SELECT id, workspace_id, name, description, initial_status_key, steps, created_at, updated_at, is_default, owner_id FROM issue_workflow WHERE workspace_id = $1::uuid ORDER BY is_default DESC, lower(name), created_at, id ` // Project workflows (MUL-7420). A workflow selects and orders statuses from // the workspace's issue_status catalog. Projects opt in through // project.workflow_id; a project without one uses the workspace's Default // workflow row. Each step also stores who an issue entering it is handed to. func (q *Queries) ListIssueWorkflows(ctx context.Context, workspaceID pgtype.UUID) ([]IssueWorkflow, error) { rows, err := q.db.Query(ctx, listIssueWorkflows, workspaceID) if err != nil { return nil, err } defer rows.Close() items := []IssueWorkflow{} for rows.Next() { var i IssueWorkflow if err := rows.Scan( &i.ID, &i.WorkspaceID, &i.Name, &i.Description, &i.InitialStatusKey, &i.Steps, &i.CreatedAt, &i.UpdatedAt, &i.IsDefault, &i.OwnerID, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listNamedIssueWorkflowSteps = `-- name: ListNamedIssueWorkflowSteps :many SELECT steps FROM issue_workflow WHERE workspace_id = $1::uuid AND NOT is_default ` // The steps of every workflow except Default, for the Default snapshot. func (q *Queries) ListNamedIssueWorkflowSteps(ctx context.Context, workspaceID pgtype.UUID) ([][]byte, error) { rows, err := q.db.Query(ctx, listNamedIssueWorkflowSteps, workspaceID) if err != nil { return nil, err } defer rows.Close() items := [][]byte{} for rows.Next() { var steps []byte if err := rows.Scan(&steps); err != nil { return nil, err } items = append(items, steps) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listProjectsUsingDefaultIssueWorkflow = `-- name: ListProjectsUsingDefaultIssueWorkflow :many SELECT id, workspace_id, title, description, icon, status, lead_type, lead_id, created_at, updated_at, priority, start_date, due_date, workflow_id FROM project WHERE workspace_id = $1::uuid AND workflow_id IS NULL ORDER BY created_at, id ` func (q *Queries) ListProjectsUsingDefaultIssueWorkflow(ctx context.Context, workspaceID pgtype.UUID) ([]Project, error) { rows, err := q.db.Query(ctx, listProjectsUsingDefaultIssueWorkflow, workspaceID) if err != nil { return nil, err } defer rows.Close() items := []Project{} for rows.Next() { var i Project if err := rows.Scan( &i.ID, &i.WorkspaceID, &i.Title, &i.Description, &i.Icon, &i.Status, &i.LeadType, &i.LeadID, &i.CreatedAt, &i.UpdatedAt, &i.Priority, &i.StartDate, &i.DueDate, &i.WorkflowID, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listProjectsUsingIssueWorkflow = `-- name: ListProjectsUsingIssueWorkflow :many SELECT id, workspace_id, title, description, icon, status, lead_type, lead_id, created_at, updated_at, priority, start_date, due_date, workflow_id FROM project WHERE workspace_id = $1::uuid AND workflow_id = $2::uuid ORDER BY created_at, id ` type ListProjectsUsingIssueWorkflowParams struct { WorkspaceID pgtype.UUID `json:"workspace_id"` WorkflowID pgtype.UUID `json:"workflow_id"` } func (q *Queries) ListProjectsUsingIssueWorkflow(ctx context.Context, arg ListProjectsUsingIssueWorkflowParams) ([]Project, error) { rows, err := q.db.Query(ctx, listProjectsUsingIssueWorkflow, arg.WorkspaceID, arg.WorkflowID) if err != nil { return nil, err } defer rows.Close() items := []Project{} for rows.Next() { var i Project if err := rows.Scan( &i.ID, &i.WorkspaceID, &i.Title, &i.Description, &i.Icon, &i.Status, &i.LeadType, &i.LeadID, &i.CreatedAt, &i.UpdatedAt, &i.Priority, &i.StartDate, &i.DueDate, &i.WorkflowID, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const lockProjectForWorkflowChange = `-- name: LockProjectForWorkflowChange :one SELECT id, workspace_id, title, description, icon, status, lead_type, lead_id, created_at, updated_at, priority, start_date, due_date, workflow_id FROM project WHERE id = $1::uuid AND workspace_id = $2::uuid FOR UPDATE ` type LockProjectForWorkflowChangeParams struct { ID pgtype.UUID `json:"id"` WorkspaceID pgtype.UUID `json:"workspace_id"` } // Serializes concurrent workflow switches of one project. func (q *Queries) LockProjectForWorkflowChange(ctx context.Context, arg LockProjectForWorkflowChangeParams) (Project, error) { row := q.db.QueryRow(ctx, lockProjectForWorkflowChange, arg.ID, arg.WorkspaceID) var i Project err := row.Scan( &i.ID, &i.WorkspaceID, &i.Title, &i.Description, &i.Icon, &i.Status, &i.LeadType, &i.LeadID, &i.CreatedAt, &i.UpdatedAt, &i.Priority, &i.StartDate, &i.DueDate, &i.WorkflowID, ) return i, err } const remapProjectIssueStatus = `-- name: RemapProjectIssueStatus :many UPDATE issue AS i SET status = $1::text, duplicate_of_issue_id = NULL, position = ( SELECT COALESCE(MIN(target.position), 0) - 1 FROM issue AS target WHERE target.workspace_id = i.workspace_id AND target.status = $1::text ), revision = i.revision + 1, last_activity_at = GREATEST(COALESCE(i.last_activity_at, i.updated_at), now()), updated_at = now() WHERE i.workspace_id = $2::uuid AND i.project_id = ANY($3::uuid[]) AND i.status = $4::text AND i.status <> $1::text RETURNING i.id, i.workspace_id, i.title, i.description, i.status, i.priority, i.assignee_type, i.assignee_id, i.creator_type, i.creator_id, i.parent_issue_id, i.acceptance_criteria, i.context_refs, i.position, i.due_date, i.created_at, i.updated_at, i.number, i.project_id, i.origin_type, i.origin_id, i.first_executed_at, i.start_date, i.metadata, i.stage, i.properties, i.revision, i.last_activity_at, i.triage_state, i.duplicate_of_issue_id ` type RemapProjectIssueStatusParams struct { ToStatus string `json:"to_status"` WorkspaceID pgtype.UUID `json:"workspace_id"` ProjectIds []pgtype.UUID `json:"project_ids"` FromStatus string `json:"from_status"` } // Moves every issue of the given projects from one status to another as part // of an administrative workflow change. Mirrors UpdateIssueStatus: the issue // is re-ranked to the top of its new column, the revision advances, and a // duplicate mark only survives cancelled -> cancelled (never the case here, // because from and to differ). It deliberately touches nothing else, so it // never hands an issue off or starts a run. func (q *Queries) RemapProjectIssueStatus(ctx context.Context, arg RemapProjectIssueStatusParams) ([]Issue, error) { rows, err := q.db.Query(ctx, remapProjectIssueStatus, arg.ToStatus, arg.WorkspaceID, arg.ProjectIds, arg.FromStatus, ) if err != nil { return nil, err } defer rows.Close() items := []Issue{} for rows.Next() { var i Issue if err := rows.Scan( &i.ID, &i.WorkspaceID, &i.Title, &i.Description, &i.Status, &i.Priority, &i.AssigneeType, &i.AssigneeID, &i.CreatorType, &i.CreatorID, &i.ParentIssueID, &i.AcceptanceCriteria, &i.ContextRefs, &i.Position, &i.DueDate, &i.CreatedAt, &i.UpdatedAt, &i.Number, &i.ProjectID, &i.OriginType, &i.OriginID, &i.FirstExecutedAt, &i.StartDate, &i.Metadata, &i.Stage, &i.Properties, &i.Revision, &i.LastActivityAt, &i.TriageState, &i.DuplicateOfIssueID, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const removeStatusFromDefaultIssueWorkflow = `-- name: RemoveStatusFromDefaultIssueWorkflow :exec UPDATE issue_workflow SET steps = COALESCE(( SELECT jsonb_agg(step ORDER BY ord) FROM jsonb_array_elements(steps) WITH ORDINALITY AS s(step, ord) WHERE step->>'status_key' <> $1::text ), '[]'::jsonb), updated_at = now() WHERE workspace_id = $2::uuid AND is_default AND steps @> jsonb_build_array(jsonb_build_object('status_key', $1::text)) ` type RemoveStatusFromDefaultIssueWorkflowParams struct { StatusKey string `json:"status_key"` WorkspaceID pgtype.UUID `json:"workspace_id"` } // An archived status leaves Default with it; Default never blocks an archive. func (q *Queries) RemoveStatusFromDefaultIssueWorkflow(ctx context.Context, arg RemoveStatusFromDefaultIssueWorkflowParams) error { _, err := q.db.Exec(ctx, removeStatusFromDefaultIssueWorkflow, arg.StatusKey, arg.WorkspaceID) return err } const setProjectWorkflow = `-- name: SetProjectWorkflow :one UPDATE project SET workflow_id = $1::uuid, updated_at = now() WHERE id = $2::uuid AND workspace_id = $3::uuid RETURNING id, workspace_id, title, description, icon, status, lead_type, lead_id, created_at, updated_at, priority, start_date, due_date, workflow_id ` type SetProjectWorkflowParams struct { WorkflowID pgtype.UUID `json:"workflow_id"` ID pgtype.UUID `json:"id"` WorkspaceID pgtype.UUID `json:"workspace_id"` } func (q *Queries) SetProjectWorkflow(ctx context.Context, arg SetProjectWorkflowParams) (Project, error) { row := q.db.QueryRow(ctx, setProjectWorkflow, arg.WorkflowID, arg.ID, arg.WorkspaceID) var i Project err := row.Scan( &i.ID, &i.WorkspaceID, &i.Title, &i.Description, &i.Icon, &i.Status, &i.LeadType, &i.LeadID, &i.CreatedAt, &i.UpdatedAt, &i.Priority, &i.StartDate, &i.DueDate, &i.WorkflowID, ) return i, err } const updateIssueWorkflow = `-- name: UpdateIssueWorkflow :one UPDATE issue_workflow SET name = $1::text, description = $2::text, initial_status_key = $3::text, steps = $4::jsonb, updated_at = now() WHERE id = $5::uuid AND workspace_id = $6::uuid RETURNING id, workspace_id, name, description, initial_status_key, steps, created_at, updated_at, is_default, owner_id ` type UpdateIssueWorkflowParams struct { Name string `json:"name"` Description string `json:"description"` InitialStatusKey string `json:"initial_status_key"` Steps []byte `json:"steps"` ID pgtype.UUID `json:"id"` WorkspaceID pgtype.UUID `json:"workspace_id"` } func (q *Queries) UpdateIssueWorkflow(ctx context.Context, arg UpdateIssueWorkflowParams) (IssueWorkflow, error) { row := q.db.QueryRow(ctx, updateIssueWorkflow, arg.Name, arg.Description, arg.InitialStatusKey, arg.Steps, arg.ID, arg.WorkspaceID, ) var i IssueWorkflow err := row.Scan( &i.ID, &i.WorkspaceID, &i.Name, &i.Description, &i.InitialStatusKey, &i.Steps, &i.CreatedAt, &i.UpdatedAt, &i.IsDefault, &i.OwnerID, ) return i, err }