docs: update server implementation gaps

This commit is contained in:
kami
2026-07-26 19:47:08 +04:00
parent 073d5c69b0
commit aa6719ca16
3 changed files with 120 additions and 11 deletions
+57 -3
View File
@@ -20,6 +20,7 @@ type Store struct {
tasks map[string]domain.Task
external map[string]string
snapshot string
seq uint64
}
func Open(dir string) (*Store, error) {
@@ -30,6 +31,23 @@ func Open(dir string) (*Store, error) {
if err := os.MkdirAll(s.cas, 0755); err != nil {
return nil, err
}
var snapshotSeq uint64
if b, readErr := os.ReadFile(s.snapshot); readErr == nil {
var snap struct {
Seq uint64 `json:"seq"`
Tasks []domain.Task `json:"tasks"`
}
if json.Unmarshal(b, &snap) != nil {
return nil, fmt.Errorf("invalid snapshot")
}
for _, t := range snap.Tasks {
s.tasks[t.ID] = t
s.external[t.Source+"\x00"+t.ExternalID] = t.ID
}
snapshotSeq = snap.Seq
} else if !errors.Is(readErr, os.ErrNotExist) {
return nil, readErr
}
f, err := os.Open(s.path)
if os.IsNotExist(err) {
return s, nil
@@ -39,13 +57,31 @@ func Open(dir string) (*Store, error) {
}
defer f.Close()
sc := bufio.NewScanner(f)
var expected uint64 = snapshotSeq + 1
for sc.Scan() {
var e domain.Event
if err := json.Unmarshal(sc.Bytes(), &e); err == nil {
if err := domain.ValidateEvent(e); err != nil {
return nil, err
}
if e.Seq < expected {
continue
}
if e.Seq != expected {
return nil, fmt.Errorf("event sequence gap: got %d, want %d", e.Seq, expected)
}
if t, ok := s.tasks[e.TaskID]; ok && e.Version != t.Version+1 {
return nil, domain.ErrConflict
}
if _, ok := s.tasks[e.TaskID]; !ok && e.Type != "TaskCreated" {
return nil, domain.ErrNotFound
}
s.events = append(s.events, e)
s.seq = e.Seq
if err := s.apply(e); err != nil {
return nil, err
}
expected++
} else {
return nil, err
}
@@ -64,6 +100,23 @@ func (s *Store) apply(e domain.Event) error {
return err
}
t = domain.Task{ID: e.TaskID, Source: p["source"].(string), ExternalID: p["external_id"].(string), Project: p["project"].(string), State: domain.StateQueued}
if v, ok := p["parent"].(string); ok {
t.Parent = v
}
if v, ok := p["inherent_priority"].(float64); ok {
t.InherentPriority = int(v)
}
if v, ok := p["due"].(string); ok {
if d, err := time.Parse(time.RFC3339, v); err == nil {
t.Due = &d
}
}
if v, ok := p["estimate"].(map[string]any); ok {
t.Estimate = &domain.Estimate{}
t.Estimate.Value, _ = v["value"].(float64)
t.Estimate.Who, _ = v["who"].(string)
t.Estimate.Confidence, _ = v["confidence"].(float64)
}
if v, ok := p["capability"].([]any); ok {
for _, x := range v {
if z, ok := x.(string); ok {
@@ -111,7 +164,7 @@ func (s *Store) Append(e domain.Event) error {
e.At = time.Now().UTC()
}
if e.Seq == 0 {
e.Seq = uint64(len(s.events) + 1)
e.Seq = s.seq + 1
}
if e.Type == "TaskCreated" {
var p map[string]any
@@ -133,7 +186,7 @@ func (s *Store) Append(e domain.Event) error {
_ = json.Unmarshal(e.Payload, &p)
for _, k := range []string{"handoff_ref", "report_ref"} {
if ref, ok := p[k].(string); ok {
if _, err := os.Stat(filepath.Join(s.cas, ref)); err != nil {
if _, err := s.Artifact(ref); err != nil {
return fmt.Errorf("%w: missing artifact %s", domain.ErrInvalid, ref)
}
}
@@ -155,6 +208,7 @@ func (s *Store) Append(e domain.Event) error {
return err
}
s.events = append(s.events, e)
s.seq = e.Seq
if err := s.writeSnapshot(); err != nil {
return err
}
@@ -168,7 +222,7 @@ func (s *Store) writeSnapshot() error {
b, err := json.Marshal(struct {
Seq uint64 `json:"seq"`
Tasks []domain.Task `json:"tasks"`
}{uint64(len(s.events)), tasks})
}{s.seq, tasks})
if err != nil {
return err
}