Stream each task's transcript over its own SSE; keep session note order

This commit is contained in:
Ian Gulliver
2026-10-14 23:53:17 -07:00
parent eabfc10c8d
commit 2b4d92e7d5
18 changed files with 304 additions and 191 deletions
+31 -4
View File
@@ -314,7 +314,7 @@ func writeFile(t *testing.T, path, content string) {
func TestEventStreamResume(t *testing.T) {
h := newHarness(t)
stream := h.openStream(nil)
stream := h.openStream("", nil)
p := h.createProject("demo")
first := stream.next()
if first.Kind != "project.created" || *first.ProjectId != p.Id {
@@ -326,7 +326,7 @@ func TestEventStreamResume(t *testing.T) {
h.do("POST", "/api/projects/"+p.Id+"/tasks", api.TaskCreate{Title: "while away"}, &task)
h.do("PUT", "/api/me", api.UserUpdate{GitName: "Alice", GitEmail: "alice@example.org"}, nil)
resumed := h.openStream(&first.Seq)
resumed := h.openStream("", &first.Seq)
missed := resumed.next()
if missed.Kind != "task.created" || *missed.TaskId != task.Id || missed.Seq != first.Seq+1 {
t.Fatalf("unexpected replayed event %+v", missed)
@@ -347,6 +347,33 @@ func TestEventStreamResume(t *testing.T) {
}
}
func TestTaskEventStream(t *testing.T) {
h := newHarness(t)
p := h.createProject("demo")
mine := api.Task{}
h.do("POST", "/api/projects/"+p.Id+"/tasks", api.TaskCreate{Title: "mine"}, &mine)
other := api.Task{}
h.do("POST", "/api/projects/"+p.Id+"/tasks", api.TaskCreate{Title: "other"}, &other)
stream := h.openStream("?task_id="+mine.Id, nil)
replayed := stream.next()
if replayed.Kind != "task.created" || *replayed.TaskId != mine.Id {
t.Fatalf("unexpected replayed event %+v", replayed)
}
h.do("POST", "/api/tasks/"+other.Id+"/discard", nil, nil)
h.do("POST", "/api/tasks/"+mine.Id+"/discard", nil, nil)
if live := stream.next(); live.Kind != "task.discarded" || *live.TaskId != mine.Id {
t.Fatalf("unexpected live event %+v", live)
}
code := h.do("GET", "/api/events?task_id=nope", nil, nil)
if code != http.StatusNotFound {
t.Fatalf("want 404 streaming an unknown task, got %d", code)
}
}
type stream struct {
t *testing.T
cancel context.CancelFunc
@@ -354,11 +381,11 @@ type stream struct {
r *bufio.Reader
}
func (h *harness) openStream(lastEventID *int64) *stream {
func (h *harness) openStream(query string, lastEventID *int64) *stream {
h.t.Helper()
ctx, cancel := context.WithCancel(context.Background())
req, err := http.NewRequestWithContext(ctx, "GET", h.url+"/api/events", nil)
req, err := http.NewRequestWithContext(ctx, "GET", h.url+"/api/events"+query, nil)
if err != nil {
h.t.Fatalf("new request: %v", err)
}