Skip to content

Commit 6a3eae1

Browse files
cursor[bot]cursoragenttyler-dane
authored
docs(docs): clarify sse stream contracts and legacy flow (#1589)
Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Tyler Dane <tyler-dane@users.noreply.github.com> Co-authored-by: Tyler Dane <tyler@switchback.tech>
1 parent 584aa0f commit 6a3eae1

3 files changed

Lines changed: 77 additions & 474 deletions

File tree

docs/backend/api-documentation.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
- [Common Routes](#common-routes)
1010
- [Priority Routes](#priority-routes)
1111
- [Sync Routes](#sync-routes)
12+
- [Events Stream Routes](#events-stream-routes)
1213
- [Event Routes](#event-routes)
1314
- [Operational Headers](#operational-headers)
1415

@@ -373,6 +374,36 @@ Authenticated user trigger for full import restart:
373374

374375
---
375376

377+
## Events Stream Routes
378+
379+
**Source**: `packages/backend/src/events/events.routes.config.ts`, `packages/backend/src/events/controllers/events.controller.ts`, `packages/backend/src/servers/sse/sse.server.ts`
380+
381+
### /api/events/stream
382+
383+
Authenticated realtime stream endpoint used by the web `EventSource` client.
384+
385+
- `GET /api/events/stream`
386+
- middleware: `verifySession()`
387+
- response type: `text/event-stream` (long-lived HTTP response)
388+
- transport notes:
389+
- server sends named events (`event: <NAME>`) with JSON data payloads
390+
- server sends heartbeat comments (`: keepalive`) roughly every 25 seconds
391+
- stream fan-out is per authenticated Compass user id (all active tabs for that user receive published events)
392+
393+
On stream connect:
394+
395+
1. backend subscribes the response to SSE fan-out first
396+
2. backend fetches current user metadata
397+
3. backend immediately publishes `USER_METADATA` to that connection
398+
399+
Operational constraints:
400+
401+
- stream requires a valid SuperTokens session cookie; unauthenticated requests are rejected by middleware
402+
- import progress (`IMPORT_GCAL_START` / `IMPORT_GCAL_END`) and background refresh notifications (`EVENT_CHANGED`, `SOMEDAY_EVENT_CHANGED`, `GOOGLE_REVOKED`) are delivered over this stream
403+
- clients should treat stream events as asynchronous hints and refetch through normal API/repository paths where applicable
404+
405+
---
406+
376407
## Event Routes
377408

378409
**Source**: `packages/backend/src/event/event.routes.config.ts`
@@ -513,6 +544,7 @@ When this payload accompanies `401` or `410`, web clients should keep the sessio
513544
- `/api/signinup`, `/api/signout`, `/api/session/*` - SuperTokens OAuth/session APIs
514545
- SuperTokens EmailPassword APIs (invoked through SDK methods in auth form hooks)
515546
- `/api/user/*` - User profile and metadata
547+
- `/api/events/stream` - authenticated SSE stream for realtime sync events
516548
- `/api/event/*` - Calendar event CRUD operations
517549
- `/api/calendars/*` - Calendar list and selection
518550
- `/api/sync/*` - Google Calendar synchronization

docs/development/troubleshoot.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,36 @@ Interpret the result like this:
1414
- `500`: the backend is running but database connectivity failed
1515
- connection refused or timeout: the backend is not listening yet, or the port/base URL is wrong
1616

17+
## SSE Stream Not Connected Or Not Receiving Events
18+
19+
Compass realtime updates now use Server-Sent Events over:
20+
21+
- `GET /api/events/stream`
22+
23+
If UI data is stale after backend writes or sync activity, verify transport before
24+
digging into business logic.
25+
26+
Quick checks:
27+
28+
1. confirm session exists (browser has valid SuperTokens session cookie)
29+
2. open browser Network tab and verify `/api/events/stream` stays open with `200`
30+
3. verify response headers include `content-type: text/event-stream`
31+
4. confirm periodic `: keepalive` frames are visible (roughly every 25 seconds)
32+
5. trigger a known publish path (for example event write or import) and verify
33+
named events appear (`EVENT_CHANGED`, `IMPORT_GCAL_*`, `USER_METADATA`)
34+
35+
If the stream does not open:
36+
37+
- check auth first (`verifySession()` guards the stream route)
38+
- verify backend route registration for `EventsRoutes`
39+
- confirm `ENV_WEB.BACKEND_BASEURL` points to the same backend origin expected by the session cookie
40+
41+
If the stream opens but no events arrive:
42+
43+
- check backend logs for publish call sites (`sseServer.handle...`)
44+
- verify user-id correlation (events fan out by authenticated user id)
45+
- check reverse-proxy buffering behavior; backend sets `X-Accel-Buffering: no` and uses heartbeats to reduce buffering delays
46+
1747
## Unable to Sign In with Google in Local Compass Instance
1848

1949
### Missing User id

0 commit comments

Comments
 (0)