3.0 KiB
3.0 KiB
Tasks: enterprise-api-plugin-sse
Change ID: enterprise-api-plugin-sse
Package: @suaveplan/api-plugin-sse
Target path: api/data/api-plugin-sse
Prerequisite packages on Verdaccio: @suaveplan/api, @suaveplan/api-shared, @suaveplan/api-plugin-auth, @suaveplan/events, @suaveplan/rate-limiter, @suaveplan/error
0. Pre-flight (non-negotiable)
- 0.1 Confirm clean working tree (
git statusreports nothing) and no in-flight worktrees with uncommitted work (git worktree listthengit statusin each) - 0.2 If any worktrees exist under
.claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against. - 0.3 Confirm the package set in
MANIFEST.mdmatchesfind packages -maxdepth 3 -name package.jsoncount. Drift here means a prior change archived without regenerating the manifest.
1. Scaffold + types + errors + events
- Create directory;
package.jsonv0.0.0; standard tooling. - Types:
SseEvent,SseConnection,SsePluginConfig(Zod). - Errors: 3-code union + registration. Test + doc.
- Events:
SsePluginEventMap(sse:client:connected, sse:client:disconnected).
2. Connection manager
ConnectionManager:Map<clientId, SseConnection>keyed byuserId:topic. On connect: auth check, rate-limit, max-connections check; create connection; start heartbeat. On disconnect: remove + emit event.- Heartbeat: send
event: pingeveryheartbeatIntervalMs(default 30 s); connection dropped if client disconnects. - Backpressure: bounded send queue per connection; drop oldest on full.
connection-manager.test.ts+connection-manager.md.
3. SseService
publish(topic, event)— fan out to all connections subscribed totopic; encode as SSE wire format (data: ...\n\n).broadcast(event)— fan out to all connections.connectionCount(),getTopicConnectionCount(topic).- Subscribe to
@suaveplan/eventsbus topics inonInit; forward to matching SSE connections. - OTel gauge
sse.connections_active; countersse.events_sent_total. sse.service.test.ts+sse.service.md.
4. Routes
GET /sse/stream?topic=...—requireAuth; returns SSE stream (HonostreamSSE). Rate-limited on connections.GET /sse/stats— admin; returns connection counts.- Route
.test.ts+.md.
5. Plugin factory + integration tests + publish
createSsePlugin:definePlugin,dependencies: ["auth"]; subscribe to bus inonInit; detach inonClose.- Integration: connect client → publish event via bus → received by SSE stream.
bunx turbo lint typecheck test --filter=@suaveplan/api-plugin-sse— green; 100% coverage.bun scripts/publish.ts --package @suaveplan/api-plugin-sse.- Archive →
openspec/archive/2026-04-24-enterprise-api-plugin-sse/.