All checks were successful
CI/CD / detect-changes (push) Successful in 4s
CI/CD / test-runners (push) Has been skipped
CI/CD / e2e-smoke (push) Has been skipped
CI/CD / test-frontend (push) Successful in 5s
CI/CD / test-go-pg (push) Successful in 2m44s
CI/CD / test-sqlite (push) Successful in 3m6s
CI/CD / build-and-deploy (push) Successful in 29s
Co-authored-by: Jeffrey Smith <jasafpro@gmail.com> Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
218 lines
8.0 KiB
Go
218 lines
8.0 KiB
Go
package models
|
|
|
|
import (
|
|
"encoding/json"
|
|
"time"
|
|
)
|
|
|
|
// ── Workflow ────────────────────────────────
|
|
|
|
// Workflow is a team-owned or global staged process definition.
|
|
type Workflow struct {
|
|
ID string `json:"id"`
|
|
TeamID *string `json:"team_id,omitempty"`
|
|
Name string `json:"name"`
|
|
Slug string `json:"slug"`
|
|
Description string `json:"description"`
|
|
Branding json.RawMessage `json:"branding"`
|
|
EntryMode string `json:"entry_mode"` // public_link | team_only
|
|
IsActive bool `json:"is_active"`
|
|
Version int `json:"version"`
|
|
OnComplete json.RawMessage `json:"on_complete,omitempty"`
|
|
Retention json.RawMessage `json:"retention"`
|
|
WebhookURL string `json:"webhook_url,omitempty"`
|
|
WebhookSecret string `json:"webhook_secret,omitempty"`
|
|
StalenessTimeoutHours *int `json:"staleness_timeout_hours,omitempty"`
|
|
CreatedBy string `json:"created_by"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
|
|
// Joined data (not stored directly)
|
|
Stages []WorkflowStage `json:"stages,omitempty"`
|
|
}
|
|
|
|
// WorkflowPatch contains optional fields for updating a workflow.
|
|
type WorkflowPatch struct {
|
|
Name *string `json:"name,omitempty"`
|
|
Description *string `json:"description,omitempty"`
|
|
TeamID *string `json:"team_id,omitempty"`
|
|
Branding *json.RawMessage `json:"branding,omitempty"`
|
|
EntryMode *string `json:"entry_mode,omitempty"`
|
|
IsActive *bool `json:"is_active,omitempty"`
|
|
OnComplete *json.RawMessage `json:"on_complete,omitempty"`
|
|
Retention *json.RawMessage `json:"retention,omitempty"`
|
|
WebhookURL *string `json:"webhook_url,omitempty"`
|
|
WebhookSecret *string `json:"webhook_secret,omitempty"`
|
|
StalenessTimeoutHours *int `json:"staleness_timeout_hours,omitempty"`
|
|
}
|
|
|
|
// ── Workflow Stage ──────────────────────────
|
|
|
|
// WorkflowStage is an ordered step within a workflow definition.
|
|
type WorkflowStage struct {
|
|
ID string `json:"id"`
|
|
WorkflowID string `json:"workflow_id"`
|
|
Ordinal int `json:"ordinal"`
|
|
Name string `json:"name"`
|
|
AssignmentTeamID *string `json:"assignment_team_id,omitempty"`
|
|
FormTemplate json.RawMessage `json:"form_template"`
|
|
StageMode string `json:"stage_mode"` // form | review | delegated | automated
|
|
Audience string `json:"audience"` // team | public | system
|
|
StageType string `json:"stage_type"` // simple | dynamic | automated
|
|
AutoTransition bool `json:"auto_transition"`
|
|
StageConfig json.RawMessage `json:"stage_config"`
|
|
BranchRules json.RawMessage `json:"branch_rules"`
|
|
StarlarkHook *string `json:"starlark_hook,omitempty"`
|
|
SurfacePkgID *string `json:"surface_pkg_id,omitempty"`
|
|
SLASeconds *int `json:"sla_seconds,omitempty"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
}
|
|
|
|
// ── Stage Mode Constants ────────────────────
|
|
|
|
const (
|
|
StageModeForm = "form"
|
|
StageModeReview = "review"
|
|
StageModeDelegated = "delegated"
|
|
StageModeAutomated = "automated"
|
|
)
|
|
|
|
// ValidStageModes is the set of valid stage_mode values.
|
|
var ValidStageModes = map[string]bool{
|
|
StageModeForm: true,
|
|
StageModeReview: true,
|
|
StageModeDelegated: true,
|
|
StageModeAutomated: true,
|
|
}
|
|
|
|
// ── Stage Type Constants ────────────────────
|
|
|
|
const (
|
|
StageTypeSimple = "simple"
|
|
StageTypeDynamic = "dynamic"
|
|
StageTypeAutomated = "automated"
|
|
)
|
|
|
|
// ValidStageTypes is the set of valid stage_type values.
|
|
var ValidStageTypes = map[string]bool{
|
|
StageTypeSimple: true,
|
|
StageTypeDynamic: true,
|
|
StageTypeAutomated: true,
|
|
}
|
|
|
|
// ── Audience Constants ──────────────────────
|
|
|
|
const (
|
|
AudienceTeam = "team"
|
|
AudiencePublic = "public"
|
|
AudienceSystem = "system"
|
|
)
|
|
|
|
// ValidAudiences is the set of valid audience values.
|
|
var ValidAudiences = map[string]bool{
|
|
AudienceTeam: true,
|
|
AudiencePublic: true,
|
|
AudienceSystem: true,
|
|
}
|
|
|
|
// ── Instance Status Constants ───────────────
|
|
|
|
const (
|
|
InstanceStatusActive = "active"
|
|
InstanceStatusCompleted = "completed"
|
|
InstanceStatusCancelled = "cancelled"
|
|
InstanceStatusStale = "stale"
|
|
InstanceStatusError = "error"
|
|
)
|
|
|
|
// ValidInstanceStatuses is the set of valid workflow instance status values.
|
|
var ValidInstanceStatuses = map[string]bool{
|
|
InstanceStatusActive: true,
|
|
InstanceStatusCompleted: true,
|
|
InstanceStatusCancelled: true,
|
|
InstanceStatusStale: true,
|
|
InstanceStatusError: true,
|
|
}
|
|
|
|
// ── Assignment Status Constants ─────────────
|
|
|
|
const (
|
|
AssignmentStatusUnassigned = "unassigned"
|
|
AssignmentStatusClaimed = "claimed"
|
|
AssignmentStatusCompleted = "completed"
|
|
AssignmentStatusCancelled = "cancelled"
|
|
)
|
|
|
|
// ValidAssignmentStatuses is the set of valid workflow assignment status values.
|
|
var ValidAssignmentStatuses = map[string]bool{
|
|
AssignmentStatusUnassigned: true,
|
|
AssignmentStatusClaimed: true,
|
|
AssignmentStatusCompleted: true,
|
|
AssignmentStatusCancelled: true,
|
|
}
|
|
|
|
// ── Workflow Instance ───────────────────────
|
|
|
|
// WorkflowInstance tracks a single execution of a workflow definition.
|
|
type WorkflowInstance struct {
|
|
ID string `json:"id"`
|
|
WorkflowID string `json:"workflow_id"`
|
|
WorkflowVersion int `json:"workflow_version"`
|
|
CurrentStage string `json:"current_stage"`
|
|
StageData json.RawMessage `json:"stage_data"`
|
|
Status string `json:"status"`
|
|
StartedBy string `json:"started_by"`
|
|
EntryToken *string `json:"entry_token,omitempty"`
|
|
Metadata json.RawMessage `json:"metadata"`
|
|
StageEnteredAt time.Time `json:"stage_entered_at"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
}
|
|
|
|
// ── Workflow Assignment ─────────────────────
|
|
|
|
// WorkflowAssignment tracks per-stage work items in the team queue.
|
|
type WorkflowAssignment struct {
|
|
ID string `json:"id"`
|
|
InstanceID string `json:"instance_id"`
|
|
Stage string `json:"stage"`
|
|
TeamID string `json:"team_id"`
|
|
AssignedTo *string `json:"assigned_to,omitempty"`
|
|
Status string `json:"status"`
|
|
ReviewData json.RawMessage `json:"review_data"`
|
|
ClaimedAt *time.Time `json:"claimed_at,omitempty"`
|
|
CompletedAt *time.Time `json:"completed_at,omitempty"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
}
|
|
|
|
// ── Workflow Signoff ───────────────
|
|
|
|
// WorkflowSignoff records a user's approval or rejection at a stage boundary.
|
|
type WorkflowSignoff struct {
|
|
ID string `json:"id"`
|
|
InstanceID string `json:"instance_id"`
|
|
Stage string `json:"stage"`
|
|
UserID string `json:"user_id"`
|
|
Decision string `json:"decision"` // approve | reject
|
|
Comment string `json:"comment"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
}
|
|
|
|
// Signoff decision constants.
|
|
const (
|
|
SignoffApprove = "approve"
|
|
SignoffReject = "reject"
|
|
)
|
|
|
|
// ── Workflow Version (immutable snapshot) ───
|
|
|
|
// WorkflowVersion is an immutable snapshot of a workflow definition
|
|
// at a point in time. Active workflow instances run against a pinned version.
|
|
type WorkflowVersion struct {
|
|
ID string `json:"id"`
|
|
WorkflowID string `json:"workflow_id"`
|
|
VersionNumber int `json:"version_number"`
|
|
Snapshot json.RawMessage `json:"snapshot"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
}
|