Feat v0.3.0 workflow schema redesign + stage CRUD modernization
Some checks failed
CI/CD / detect-changes (pull_request) Successful in 4s
CI/CD / test-frontend (pull_request) Successful in 5s
CI/CD / test-go-pg (pull_request) Failing after 1m56s
CI/CD / test-sqlite (pull_request) Successful in 2m47s
CI/CD / build-and-deploy (pull_request) Has been skipped

Drop chat-era columns (persona_id, history_mode) from workflow_stages.
Rename transition_rules → stage_config. Add audience, stage_type,
starlark_hook, branch_rules columns. Update stage_mode CHECK to
(form, review, delegated, automated). All Go stores, handlers,
routing engine, Starlark module, and frontend editors updated.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-27 17:48:14 +00:00
parent 8580e1d93e
commit 1b08769f09
16 changed files with 414 additions and 161 deletions

View File

@@ -54,28 +54,35 @@ func (h *WorkflowPackageHandler) ExportWorkflowPackage(c *gin.Context) {
"name": s.Name,
"ordinal": s.Ordinal,
"stage_mode": s.StageMode,
"history_mode": s.HistoryMode,
"audience": s.Audience,
"stage_type": s.StageType,
"auto_transition": s.AutoTransition,
}
if s.PersonaID != nil {
sd["persona_id"] = *s.PersonaID
}
if s.AssignmentTeamID != nil {
sd["assignment_team_id"] = *s.AssignmentTeamID
}
if s.SurfacePkgID != nil {
sd["surface_pkg_id"] = *s.SurfacePkgID
}
if s.StarlarkHook != nil {
sd["starlark_hook"] = *s.StarlarkHook
}
if len(s.FormTemplate) > 0 && string(s.FormTemplate) != "{}" {
var ft any
if json.Unmarshal(s.FormTemplate, &ft) == nil {
sd["form_template"] = ft
}
}
if len(s.TransitionRules) > 0 && string(s.TransitionRules) != "{}" {
var tr any
if json.Unmarshal(s.TransitionRules, &tr) == nil {
sd["transition_rules"] = tr
if len(s.StageConfig) > 0 && string(s.StageConfig) != "{}" {
var sc any
if json.Unmarshal(s.StageConfig, &sc) == nil {
sd["stage_config"] = sc
}
}
if len(s.BranchRules) > 0 && string(s.BranchRules) != "[]" {
var br any
if json.Unmarshal(s.BranchRules, &br) == nil {
sd["branch_rules"] = br
}
}
stageDefs = append(stageDefs, sd)
@@ -208,27 +215,34 @@ func InstallWorkflowFromManifest(ctx *gin.Context, stores store.Stores, pkgID st
// Create stages from definition
for _, s := range wfDef.Stages {
st := &models.WorkflowStage{
WorkflowID: workflowID,
Ordinal: s.Ordinal,
Name: s.Name,
StageMode: s.StageMode,
HistoryMode: s.HistoryMode,
AutoTransition: s.AutoTransition,
PersonaID: s.PersonaID,
WorkflowID: workflowID,
Ordinal: s.Ordinal,
Name: s.Name,
StageMode: s.StageMode,
Audience: s.Audience,
StageType: s.StageType,
AutoTransition: s.AutoTransition,
AssignmentTeamID: s.AssignmentTeamID,
SurfacePkgID: s.SurfacePkgID,
SurfacePkgID: s.SurfacePkgID,
StarlarkHook: s.StarlarkHook,
}
if st.StageMode == "" {
st.StageMode = models.StageModeCustom
st.StageMode = models.StageModeDelegated
}
if st.HistoryMode == "" {
st.HistoryMode = "full"
if st.Audience == "" {
st.Audience = models.AudienceTeam
}
if st.StageType == "" {
st.StageType = models.StageTypeSimple
}
if s.FormTemplate != nil {
st.FormTemplate, _ = json.Marshal(s.FormTemplate)
}
if s.TransitionRules != nil {
st.TransitionRules, _ = json.Marshal(s.TransitionRules)
if s.StageConfig != nil {
st.StageConfig, _ = json.Marshal(s.StageConfig)
}
if s.BranchRules != nil {
st.BranchRules, _ = json.Marshal(s.BranchRules)
}
if err := stores.Workflows.CreateStage(reqCtx, st); err != nil {
log.Printf("[workflow-pkg] failed to create stage %q: %v", s.Name, err)
@@ -245,14 +259,16 @@ func InstallWorkflowFromManifest(ctx *gin.Context, stores store.Stores, pkgID st
// workflowPkgStage is the stage definition within a workflow package manifest.
type workflowPkgStage struct {
Name string `json:"name"`
Ordinal int `json:"ordinal"`
StageMode string `json:"stage_mode"`
HistoryMode string `json:"history_mode"`
AutoTransition bool `json:"auto_transition"`
PersonaID *string `json:"persona_id,omitempty"`
AssignmentTeamID *string `json:"assignment_team_id,omitempty"`
SurfacePkgID *string `json:"surface_pkg_id,omitempty"`
FormTemplate any `json:"form_template,omitempty"`
TransitionRules any `json:"transition_rules,omitempty"`
Name string `json:"name"`
Ordinal int `json:"ordinal"`
StageMode string `json:"stage_mode"`
Audience string `json:"audience"`
StageType string `json:"stage_type"`
AutoTransition bool `json:"auto_transition"`
AssignmentTeamID *string `json:"assignment_team_id,omitempty"`
SurfacePkgID *string `json:"surface_pkg_id,omitempty"`
StarlarkHook *string `json:"starlark_hook,omitempty"`
FormTemplate any `json:"form_template,omitempty"`
StageConfig any `json:"stage_config,omitempty"`
BranchRules any `json:"branch_rules,omitempty"`
}