Skip to content

Resolves #228, resolves #229, resolves #230, resolves #231#268

Merged
ogazboiz merged 1 commit into
LabsCrypt:mainfrom
JONAH-6:dev
Apr 28, 2026
Merged

Resolves #228, resolves #229, resolves #230, resolves #231#268
ogazboiz merged 1 commit into
LabsCrypt:mainfrom
JONAH-6:dev

Conversation

@JONAH-6
Copy link
Copy Markdown
Contributor

@JONAH-6 JONAH-6 commented Apr 28, 2026

Summary

Resolves #228, resolves #229, resolves #230, resolves #231


What was done

#228 — Pagination for stream events list

  • GET /v1/streams/{id}/events now returns { data, total, hasMore } instead of a bare array
  • Supports limit (default 50, max 500), offset, cursor=<eventId>, and direction=asc|desc
  • Cursor-based pagination uses Prisma's native cursor API (skip-the-cursor, stable ordering by
    createdAt)
  • Added @@index([createdAt]) and @@index([streamId, createdAt]) composite index to StreamEvent in
    prisma/schema.prisma
  • Updated Swagger docs for the events endpoint

#229 — Graceful shutdown with SSE connection draining

  • On SIGTERM / SIGINT: sets a shutdown flag → sends event: reconnect to all connected SSE clients →
    stops accepting new SSE connections (503) → stops the HTTP server → waits up to 30 s for the
    in-flight indexer batch → disconnects Redis → disconnects Prisma → exits 0 (1 on timeout)
  • SorobanEventWorker.waitForDrain() tracks the active batch promise and resolves when idle
  • sseService.isShuttingDown() checked in the SSE subscribe handler

#230 — Redis pub/sub for horizontal SSE scaling

  • New backend/src/lib/redis.ts: initializes a publisher + subscriber pair using ioredis, with a
    retryStrategy and graceful fallback — if REDIS_URL is unset or Redis is unreachable, the service
    runs in single-instance in-process mode automatically
  • sseService.broadcastToStream / broadcastToUser: when Redis is available, publishes to
    sse:stream:{id} / sse:user:{key}; otherwise falls back to local broadcast
  • Each instance PSUBSCRIBEs to sse:stream:* and sse:user:* on startup and routes incoming messages
    to local SSE clients
  • REDIS_URL added to .env.example with documentation
  • ioredis ^5.3.2 added to package.json

#231 — Admin metrics endpoint

  • New backend/src/routes/adminRoutes.ts mounted at /v1/admin
  • GET /v1/admin/metrics — requires Authorization: Bearer <ADMIN_SECRET>; returns stream counts by
    status, events indexed in last 24 h, SSE connection count, indexer last ledger + lag seconds, and
    server uptime
  • GET /health updated to include db, indexer.status, and indexer.lastLedger fields; still returns
    503 when DB is down
  • ADMIN_SECRET added to .env.example

@ogazboiz ogazboiz merged commit 1d80d84 into LabsCrypt:main Apr 28, 2026
4 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants