168 lines
4.6 KiB
Go
168 lines
4.6 KiB
Go
package httpapi
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
workflowrunapp "inbox/internal/app/workflowrun"
|
|
"inbox/internal/base/httpx"
|
|
"inbox/internal/domain/workflow"
|
|
)
|
|
|
|
func (h *Handler) getWorkflowRun(w http.ResponseWriter, r *http.Request) {
|
|
item, err := h.WorkflowRun.Get(r.Context(), r.PathValue("runID"))
|
|
if err != nil {
|
|
writeStoreError(w, err)
|
|
return
|
|
}
|
|
httpx.WriteJSON(w, http.StatusOK, workflowRunResponse(item))
|
|
}
|
|
|
|
func (h *Handler) listWorkflowRuns(w http.ResponseWriter, r *http.Request) {
|
|
items, err := h.WorkflowRun.ListByTopic(r.Context(), r.PathValue("topicID"))
|
|
if err != nil {
|
|
writeStoreError(w, err)
|
|
return
|
|
}
|
|
out := make([]map[string]any, 0, len(items))
|
|
for _, item := range items {
|
|
out = append(out, workflowRunResponse(item))
|
|
}
|
|
httpx.WriteJSON(w, http.StatusOK, map[string]any{"workflow_runs": out})
|
|
}
|
|
|
|
func (h *Handler) createWorkflowRun(w http.ResponseWriter, r *http.Request) {
|
|
type request struct {
|
|
WorkspaceID string `json:"workspace_id"`
|
|
RoleName string `json:"role_name"`
|
|
Stage string `json:"stage"`
|
|
Mode string `json:"mode"`
|
|
RequestMessageID string `json:"request_message_id"`
|
|
CommandJSON string `json:"command_json"`
|
|
}
|
|
var req request
|
|
if err := httpx.DecodeJSON(r, &req); err != nil {
|
|
httpx.WriteError(w, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
item, err := h.WorkflowRun.Start(r.Context(), workflow.Run{
|
|
WorkspaceID: req.WorkspaceID,
|
|
TopicID: r.PathValue("topicID"),
|
|
RoleName: req.RoleName,
|
|
Stage: workflow.Stage(req.Stage),
|
|
Mode: req.Mode,
|
|
RequestMessageID: req.RequestMessageID,
|
|
CommandJSON: req.CommandJSON,
|
|
})
|
|
if err != nil {
|
|
writeStoreError(w, err)
|
|
return
|
|
}
|
|
httpx.WriteJSON(w, http.StatusCreated, item)
|
|
}
|
|
|
|
func (h *Handler) patchWorkflowRun(w http.ResponseWriter, r *http.Request) {
|
|
type request struct {
|
|
Status *workflow.RunStatus `json:"status"`
|
|
ReplyMessageID *string `json:"reply_message_id"`
|
|
ExitCode *int `json:"exit_code"`
|
|
CompletedAt *string `json:"completed_at"`
|
|
ErrorMessage *string `json:"error_message"`
|
|
CommandJSON *string `json:"command_json"`
|
|
}
|
|
var req request
|
|
if err := httpx.DecodeJSON(r, &req); err != nil {
|
|
httpx.WriteError(w, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
item, err := h.WorkflowRun.Patch(r.Context(), r.PathValue("runID"), workflowrunapp.Patch{
|
|
Status: req.Status,
|
|
ReplyMessageID: req.ReplyMessageID,
|
|
ExitCode: req.ExitCode,
|
|
CompletedAt: req.CompletedAt,
|
|
ErrorMessage: req.ErrorMessage,
|
|
CommandJSON: req.CommandJSON,
|
|
})
|
|
if err != nil {
|
|
writeStoreError(w, err)
|
|
return
|
|
}
|
|
httpx.WriteJSON(w, http.StatusOK, item)
|
|
}
|
|
|
|
func (h *Handler) listWorkflowRunLogs(w http.ResponseWriter, r *http.Request) {
|
|
afterSeq := 0
|
|
if raw := r.URL.Query().Get("after_seq"); raw != "" {
|
|
value, err := strconv.Atoi(raw)
|
|
if err != nil {
|
|
httpx.WriteError(w, http.StatusBadRequest, "after_seq must be an integer")
|
|
return
|
|
}
|
|
afterSeq = value
|
|
}
|
|
items, err := h.WorkflowRun.ListLogs(r.Context(), r.PathValue("runID"), afterSeq)
|
|
if err != nil {
|
|
writeStoreError(w, err)
|
|
return
|
|
}
|
|
httpx.WriteJSON(w, http.StatusOK, map[string]any{"logs": items})
|
|
}
|
|
|
|
func (h *Handler) appendWorkflowRunLog(w http.ResponseWriter, r *http.Request) {
|
|
type request struct {
|
|
Stream string `json:"stream"`
|
|
Content string `json:"content"`
|
|
CreatedAt string `json:"created_at"`
|
|
}
|
|
var req request
|
|
if err := httpx.DecodeJSON(r, &req); err != nil {
|
|
httpx.WriteError(w, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
item, err := h.WorkflowRun.AppendLog(r.Context(), workflow.RunLog{
|
|
RunID: r.PathValue("runID"),
|
|
Stream: workflow.LogStream(req.Stream),
|
|
Content: req.Content,
|
|
CreatedAt: req.CreatedAt,
|
|
})
|
|
if err != nil {
|
|
writeStoreError(w, err)
|
|
return
|
|
}
|
|
httpx.WriteJSON(w, http.StatusCreated, item)
|
|
}
|
|
|
|
func workflowRunResponse(item workflow.Run) map[string]any {
|
|
payload := map[string]any{}
|
|
raw, err := json.Marshal(item)
|
|
if err == nil {
|
|
_ = json.Unmarshal(raw, &payload)
|
|
}
|
|
if payload == nil {
|
|
payload = map[string]any{}
|
|
}
|
|
if planning, ok := decodeWorkflowRunPlanning(item.CommandJSON); ok {
|
|
payload["planning"] = planning
|
|
}
|
|
return payload
|
|
}
|
|
|
|
func decodeWorkflowRunPlanning(commandJSON string) (map[string]any, bool) {
|
|
if commandJSON == "" {
|
|
return nil, false
|
|
}
|
|
var payload map[string]any
|
|
if err := json.Unmarshal([]byte(commandJSON), &payload); err != nil {
|
|
return nil, false
|
|
}
|
|
planning, ok := payload["planning"]
|
|
if !ok {
|
|
return nil, false
|
|
}
|
|
typed, ok := planning.(map[string]any)
|
|
return typed, ok
|
|
}
|