Skip to main content

Realtime and Notifications

Realtime updates and notifications keep campaign screens current without forcing manual reloads.

Server-Sent Events

Campaign event streaming lives around:

  • server/app/routers/events.py
  • server/app/lib/sse.py
  • web/src/lib/useCampaignEvents.ts

SSE is used for campaign-scoped events such as invite acceptance, session scheduling, and recap extraction status changes.

When adding an event:

  1. Define the payload shape.
  2. Broadcast from the backend mutation that changes state.
  3. Handle the event in the relevant frontend screen or shared hook.
  4. Keep event handling idempotent; events can race with normal fetch responses.

Rules Chat Streaming

Rules Chat uses a separate streaming path over SSE-like event parsing in web/src/lib/api.ts. Events include:

  • sources
  • delta
  • done
  • error
  • dice_roll
  • stat_block
  • encounter
  • npc
  • loot
  • table

The frontend card renderers live in the Rules Chat screen and shared card components.

Email

Email helpers live in server/app/lib/email.py, with notification orchestration in server/app/lib/notify.py.

Current email-related flows include verification, password reset, scheduled session notifications, and availability-related notifications.

In development, email can fall back to console logging depending on provider configuration.

Discord

Discord OAuth helpers live in server/app/lib/discord.py, with auth routes in server/app/routers/auth.py and the frontend button in web/src/components/DiscordButton.tsx.

Change Checklist

  • Keep realtime payloads small and scoped.
  • Make frontend event application idempotent.
  • Do not let notification failures roll back core user actions unless the flow explicitly requires delivery.
  • Keep OAuth state signed and short-lived.