Files
Agent-System/internal/server/workflow_catalog_handlers.go
T
weichenandCursor 909384c335 feat(workflow): SWBOOT-02..04 software manifests and catalog allowlist
Add software_bootstrap/delivery v2 manifests, expand selectable keys to
five, keep medical doc-count gates, and filter catalog by product_domain.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:39:01 +00:00

69 lines
2.1 KiB
Go

package server
import (
"net/http"
"strings"
"chat-agent-system/internal/workflowdef"
)
type workflowCatalogItem struct {
Key string `json:"key"`
Name string `json:"name"`
LatestVersion int `json:"latest_version"`
ProductDomain string `json:"product_domain,omitempty"`
SoftwareOnly bool `json:"software_only,omitempty"`
}
func (s *Server) handleWorkflowCatalog(w http.ResponseWriter, r *http.Request) {
if s.wfDefSvc == nil || !s.wfDefSvc.Available() {
writeSafeError(w, r, http.StatusServiceUnavailable, `{"error":"ERR_NOT_AVAILABLE","message":"workflow catalog unavailable"}`)
return
}
defs, err := s.wfDefSvc.Store().ListProjectSelectableDefinitions(r.Context())
if err != nil {
writeSafeError(w, r, http.StatusInternalServerError, `{"error":"ERR_INTERNAL","message":"`+err.Error()+`"}`)
return
}
productDomain := strings.TrimSpace(r.URL.Query().Get("product_domain"))
projectType := strings.TrimSpace(r.URL.Query().Get("project_type"))
_ = projectType // reserved for project_type_workflows join; domain filter is authoritative for now
items := make([]workflowCatalogItem, 0, len(workflowdef.OfficialWorkflowKeys()))
seen := map[string]bool{}
for _, d := range defs {
if !workflowdef.IsOfficialWorkflowKey(d.Key) || seen[d.Key] {
continue
}
if !workflowdef.CompatibleWithProductDomain(d.Key, productDomain) {
continue
}
seen[d.Key] = true
name := d.Name
if name == "" {
name = workflowdef.OfficialWorkflowName(d.Key)
}
items = append(items, workflowCatalogItem{
Key: d.Key,
Name: name,
LatestVersion: d.LatestPublishedVersion,
ProductDomain: d.ProductDomain,
SoftwareOnly: workflowdef.IsSoftwareWorkflowKey(d.Key),
})
}
for _, key := range workflowdef.OfficialWorkflowKeys() {
if seen[key] {
continue
}
if !workflowdef.CompatibleWithProductDomain(key, productDomain) {
continue
}
items = append(items, workflowCatalogItem{
Key: key,
Name: workflowdef.OfficialWorkflowName(key),
SoftwareOnly: workflowdef.IsSoftwareWorkflowKey(key),
})
}
writeJSONResponse(w, http.StatusOK, map[string]any{"workflows": items})
}