Skip to main content

Workflow Templates

A workflow template defines an ordered list of stages (e.g. backlog → in_progress → review → done) that crews attach to their issue trackers. The frontend renders these as column headers on board views; the issue handler enforces the stage transitions when an issue moves between columns. Implementation: internal/api/workflow_templates_handler.go. Backed by the workflow_templates table (schema introduced in migration v19, see internal/database/migrate_consts_v16_v25.go).
All endpoints require an authenticated session and workspace context. Mutating verbs additionally require OWNER, ADMIN, or MANAGER role (requireRole("create")).

Endpoints

Template shape

Stage shape

Stages live inside template_json as a JSON array. Each stage: Validation rules enforced by validateTemplateJSON:
  • At least one stage.
  • Exactly one stage with type: open.
  • At least one stage with type: completed.
  • All name values unique; all position values unique.
Violations return 400 with a single-sentence message describing the failing constraint.

Endpoint reference

CRUD over templates. Built-in rows are server-controlled and surface first on List.

GET /api/v1/workflow-templates

List every template visible to the current workspace. Built-in rows surface first (is_builtin DESC), then user-created rows by created_at ASC. Request: No request body or query parameters. Auth: authenticated session + workspace context. Response: 200 OK — JSON array (never null).

POST /api/v1/workflow-templates

Create a new user-owned template. Auth: authenticated session + workspace context + requireRole("create"). Request body: Response: 201 Created with the full template object. Broadcasts workflow_template.created on the workspace WS channel with {"id": "<id>"}.

GET /api/v1/workflow-templates/{id}

Fetch a single template by id, scoped to the calling workspace. Request: No request body. The {id} path parameter identifies the workflow template. Auth: authenticated session + workspace context. Response: 200 OK with the template object.

PATCH /api/v1/workflow-templates/{id}

Partial update. Only the mutable subset (name, description, template_json, icon, color) is writable. is_builtin, created_at, and id are immutable; updated_at is set to “now” on every successful write. Auth: authenticated session + workspace context + requireRole("create"). Request body: every field optional; only provided (non-null) keys are written. Response: 200 OK with the freshly-updated template (so callers don’t need to re-GET). Broadcasts workflow_template.updated on the workspace WS channel with {"id": "<id>"}.

DELETE /api/v1/workflow-templates/{id}

Hard delete. The template row is removed outright; the handler does not soft-delete it. Request: No request body. The {id} path parameter identifies the workflow template to delete.
Hard delete (no soft delete).
Auth: authenticated session + workspace context + requireRole("create"). Response: 204 No Content. Broadcasts workflow_template.deleted on the workspace WS channel with {"id": "<id>"}.

See also