Files
Agent-System/internal/projectinstance/approval.go
T
weichenandCursor 32b88beee0 feat(projectinstance): refresh stage readiness after document approval.
Sync doc task status on approve and evaluate whether to emit stage advance readiness; chain docgov hooks.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00

79 lines
1.8 KiB
Go

package projectinstance
import "context"
// DocumentApprovedResult 文档批准后阶段就绪评估结果。
type DocumentApprovedResult struct {
StageReady bool
InstanceID int64
StageInstanceID int64
StageKey string
StageName string
ConfigRevision int
RequiredDocCount int
ApprovedDocCount int
}
// HandleDocumentApproved 同步文档任务状态并评估是否首次满足阶段推进条件。
func (s *Service) HandleDocumentApproved(ctx context.Context, projectID int64, taskKey string) (*DocumentApprovedResult, error) {
out := &DocumentApprovedResult{}
if s == nil || !s.Available() || projectID <= 0 || taskKey == "" {
return out, nil
}
if err := s.store.MarkDocTaskApproved(ctx, projectID, taskKey); err != nil {
return nil, err
}
live, err := s.store.GetLiveInstance(ctx, projectID)
if err != nil || live == nil {
return out, err
}
detail, err := s.store.GetInstanceByID(ctx, live.ID)
if err != nil || detail == nil || detail.ActiveStageKey == "" {
return out, err
}
readiness, err := s.GetStageReadiness(ctx, live.ID, detail.ActiveStageKey, 0, true)
if err != nil {
return nil, err
}
if !readiness.Ready {
return out, nil
}
var stageInstID int64
for _, st := range detail.Stages {
if st.StageKey == detail.ActiveStageKey {
stageInstID = st.ID
break
}
}
if stageInstID <= 0 {
return out, nil
}
required := 0
approved := 0
for _, dt := range readiness.DocTasks {
if !dt.Enabled || !dt.Required {
continue
}
required++
if dt.Approved {
approved++
}
}
out.StageReady = true
out.InstanceID = live.ID
out.StageInstanceID = stageInstID
out.StageKey = readiness.StageKey
out.StageName = readiness.StageName
out.ConfigRevision = readiness.ConfigRevision
out.RequiredDocCount = required
out.ApprovedDocCount = approved
return out, nil
}