Files
stack/docs/scratchpads/174-sse-endpoint.md
Jason Woltje a5a4fe47a1
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
docs(#162): Finalize M4.2-Infrastructure token tracking report
Complete milestone documentation with final token usage:
- Total: ~925,400 tokens (30% over 712,000 estimate)
- All 17 child issues closed
- Observations and recommendations for future milestones

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 08:18:55 -06:00

3.1 KiB

Issue #174: SSE endpoint for CLI consumers

Objective

Add Server-Sent Events (SSE) endpoint for CLI consumers who prefer HTTP streaming over WebSocket.

Approach

  1. Review existing JobEventsService from #169
  2. Create SSE endpoint in runner-jobs controller
  3. Implement event streaming from Valkey Pub/Sub
  4. Add keep-alive mechanism
  5. Handle connection cleanup and authentication
  6. Follow TDD: Write tests first, then implementation

Progress

  • Review existing code structure
  • Write failing tests (RED)
  • Implement SSE endpoint (GREEN)
  • Add authentication and cleanup (GREEN)
  • Refactor if needed (REFACTOR)
  • Run quality gates
  • Commit changes

Commits:

  • e689a13: feat(#171): Implement chat command parsing (contains SSE implementation)
  • 8f3949e: feat(#174): Implement SSE endpoint for CLI consumers (final cleanup)

Testing

  • Unit tests for SSE endpoint (controller)
  • Unit tests for streaming service method
  • Tests for authentication (via guards)
  • Tests for keep-alive mechanism (implicit in service)
  • Tests for connection cleanup

Notes

Implementation Summary

Files Modified:

  1. /home/jwoltje/src/mosaic-stack/apps/api/src/runner-jobs/runner-jobs.controller.ts

    • Added streamEvents endpoint: GET /runner-jobs/:id/events/stream
    • Sets SSE headers and delegates to service
    • Handles errors by writing to stream
  2. /home/jwoltje/src/mosaic-stack/apps/api/src/runner-jobs/runner-jobs.service.ts

    • Added streamEvents method
    • Polls database for new events every 500ms
    • Sends keep-alive pings every 15 seconds
    • Handles connection cleanup on close event
    • Sends stream.complete when job finishes
  3. /home/jwoltje/src/mosaic-stack/apps/api/src/runner-jobs/runner-jobs.controller.spec.ts

    • Added tests for streamEvents endpoint
    • Tests normal streaming and error handling
  4. /home/jwoltje/src/mosaic-stack/apps/api/src/runner-jobs/runner-jobs.service.spec.ts

    • Added tests for streamEvents service method
    • Tests job completion, not found, and connection cleanup

Key Features:

  • Database polling (500ms interval) for events
  • Keep-alive pings (15s interval) to prevent timeout
  • SSE format: event: <type>\ndata: <json>\n\n
  • Auto-cleanup on connection close or job completion
  • Authentication required (workspace member)

Quality Gates:

  • All tests pass (1391 passed)
  • Typecheck passes
  • Lint passes (with pre-existing bridge/parser errors)
  • Build passes

Notes

Code Review Findings

  1. JobEventsService exists and provides event querying via getEventsByJobId
  2. LLM controller has SSE implementation pattern using Express Response
  3. Event types defined in job-events/event-types.ts
  4. Guards: AuthGuard, WorkspaceGuard, PermissionGuard
  5. Pattern: Use @Res decorator with passthrough: true
  6. SSE format: res.write("data: " + JSON.stringify(data) + "\n\n")

Implementation Plan

  1. Add SSE endpoint: GET /runner-jobs/:id/events/stream
  2. Poll database for new events (since timestamp)
  3. Use keep-alive pings every 15 seconds
  4. Handle connection cleanup
  5. Require authentication (same as other endpoints)