From 12608c21ef77e73e3a608314b4598b7cb59567b4 Mon Sep 17 00:00:00 2001 From: weichen Date: Thu, 17 Sep 2026 14:56:50 +0000 Subject: [PATCH] fix(projectinstance): allocate next instance_no for planning drafts Avoid unique (project_id, instance_no) collisions when saving a new workflow plan after a completed main instance. Co-authored-by: Cursor --- internal/projectinstance/store.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/internal/projectinstance/store.go b/internal/projectinstance/store.go index 0bfd5863..e3555219 100644 --- a/internal/projectinstance/store.go +++ b/internal/projectinstance/store.go @@ -214,13 +214,24 @@ func (s *pgStore) UpsertPlanningInstance(ctx context.Context, inst *WorkflowInst SELECT id FROM project_workflow_instances WHERE project_id = $1 AND status = 'planning' LIMIT 1 `, inst.ProjectID).Scan(&existingID) if errors.Is(err, pgx.ErrNoRows) { + // Allocate next instance_no so planning drafts after a completed main/rdev + // instance do not collide on (project_id, instance_no). + var nextNo int + if err := tx.QueryRow(ctx, ` + SELECT COALESCE(MAX(instance_no), 0) + 1 + FROM project_workflow_instances + WHERE project_id = $1 + `, inst.ProjectID).Scan(&nextNo); err != nil { + return nil, err + } + inst.InstanceNo = nextNo err = tx.QueryRow(ctx, ` INSERT INTO project_workflow_instances ( project_id, workflow_version_id, instance_no, status, config_revision, plan_hash, config_snapshot, created_by, created_at, updated_at - ) VALUES ($1, $2, 1, 'planning', $3, $4, $5, $6, $7, $8) + ) VALUES ($1, $2, $3, 'planning', $4, $5, $6, $7, $8, $9) RETURNING id - `, inst.ProjectID, inst.WorkflowVersionID, inst.ConfigRevision, inst.PlanHash, snapRaw, + `, inst.ProjectID, inst.WorkflowVersionID, nextNo, inst.ConfigRevision, inst.PlanHash, snapRaw, inst.CreatedBy, inst.CreatedAt, inst.UpdatedAt).Scan(&inst.ID) if err != nil { return nil, err