Files
mesh-catalog/modules/mesh-knowledge/cmd/mesh-knowledge/milestones.go
T

62 lines
2.0 KiB
Go

package main
// A design's milestones are records of the issue tracker (novox/hq ADR 0493 §1, issue 1781): progress asks
// `issue-tracker.milestones` once per answer, on the bus, for each milestone with its issues, instead of reading the
// design's table through the records module.
import (
"encoding/json"
"fmt"
"time"
)
// MilestonesVerb is the tracker's verb that answers the milestones.
const MilestonesVerb = "seat:issue-tracker.milestones"
// trackerMilestone is a row of `issue-tracker.milestones`.
type trackerMilestone struct {
Design int `json:"design"`
ID string `json:"id"`
Outcome string `json:"outcome"`
Status string `json:"status"`
Reason string `json:"reason"`
Issues []int `json:"issues"`
Moved *stamp `json:"moved"`
}
// stamp is who did something and when, as the tracker says it.
type stamp struct {
By string `json:"by"`
At time.Time `json:"at"`
}
// withMilestones is each design with its milestones as the tracker holds them, in their table's order; design 0 asks
// every design's. The designs are copies: the cache keeps what hq says, never what the tracker said.
func (k *KB) withMilestones(ds []*Design, design int) ([]*Design, error) {
body := map[string]any{}
if design != 0 {
body["design"] = design
}
raw, err := k.Seats(MilestonesVerb, body)
if err != nil {
return nil, fmt.Errorf("the issue tracker does not answer its milestones: %v", err)
}
var l struct {
Milestones []trackerMilestone `json:"milestones"`
}
if err := json.Unmarshal(raw, &l); err != nil {
return nil, fmt.Errorf("issue-tracker.milestones answered something else: %v", err)
}
by := map[int][]Milestone{}
for _, m := range l.Milestones {
by[m.Design] = append(by[m.Design], Milestone{ID: m.ID, Outcome: m.Outcome, Issues: m.Issues, Status: m.Status, Reason: m.Reason, Moved: m.Moved})
}
out := make([]*Design, 0, len(ds))
for _, d := range ds {
c := *d
c.Milestones = by[d.Number]
out = append(out, &c)
}
return out, nil
}