Files
orchestra/internal/operations/operations.go
T
2026-07-26 19:14:46 +04:00

79 lines
2.2 KiB
Go

// Package operations contains read-side projections and operational observability.
package operations
import (
"encoding/json"
"fmt"
"orchestra/internal/domain"
"os/exec"
"strings"
"time"
)
type Brief struct {
From, To time.Time `json:"from"`
Completed int `json:"completed"`
Failed int `json:"failed"`
Blocked int `json:"blocked"`
NeedsAttention []domain.Event `json:"needs_attention"`
Quota map[string]float64 `json:"quota_consumed"`
Git GitSync `json:"git_sync"`
}
type GitSync struct {
Branch, Head, Status string `json:"branch" json:"head" json:"status"`
}
// BuildBrief folds only events in [from,to]. It is deliberately read-only.
func BuildBrief(events []domain.Event, from, to time.Time, git GitSync) Brief {
b := Brief{From: from, To: to, Quota: map[string]float64{}, Git: git}
for _, e := range events {
if e.At.Before(from) || e.At.After(to) {
continue
}
var p map[string]any
_ = json.Unmarshal(e.Payload, &p)
switch e.Type {
case "TaskCompleted":
b.Completed++
case "TaskFailed":
b.Failed++
b.NeedsAttention = append(b.NeedsAttention, e)
case "TaskBlocked":
b.Blocked++
b.NeedsAttention = append(b.NeedsAttention, e)
case "ApprovalRequested":
b.NeedsAttention = append(b.NeedsAttention, e)
case "QuotaReported":
if h, ok := p["harness_id"].(string); ok {
if n, ok := p["consumed"].(float64); ok {
b.Quota[h] += n
}
}
}
}
return b
}
// GitState reports local checkout state for the brief. Git failures are visible,
// never silently interpreted as synchronized.
func GitState(dir string) GitSync {
g := GitSync{Status: "unavailable"}
run := func(args ...string) string {
out, err := exec.Command("git", append([]string{"-C", dir}, args...)...).Output()
if err != nil {
return ""
}
return strings.TrimSpace(string(out))
}
g.Branch, g.Head = run("branch", "--show-current"), run("rev-parse", "HEAD")
if s := run("status", "--porcelain"); s != "" {
g.Status = "dirty"
} else if g.Head != "" {
g.Status = "clean"
}
if g.Head == "" {
g.Status = fmt.Sprintf("git unavailable (%s)", dir)
}
return g
}