Overview
The Events module handles platform event logging and alerting for streaming events such as followers, subscribers, cheers, raids, channel point redemptions, and tips. Events are stored in a TimescaleDB hypertable with automatic compression for efficient time-series queries. Events are broadcast in real time via Redis pub/sub to WebSocket clients for overlay alerts and dashboard panels. The module supports paginated queries with filters by type, platform, date range, and full-text search.
Architecture
Backend
- GraphQL (
apps/api/src/graphql/events.rs) -- Queries for listing/fetching events with filters. Mutation for emitting test/manual events.
- Crate (
crates/lo-events/src/) -- Core event logic including EventFilter, EventInput, EventRow types, list_events, get_event, insert_event, and broadcast_event functions.
- Database -- Events are stored in TimescaleDB (
platform_events hypertable) with time-based partitioning and compression.
- Real-time -- Events are broadcast via
RedisPubSub using the GqlPubSub wrapper to all WebSocket subscribers for the account.
Frontend
- Next.js API proxy routes call GraphQL internally.
- Event panel displays events with filters by type and platform.
- Overlay alerts consume events via WebSocket for real-time display.
API
GraphQL Queries
| Query | Permission | Description |
|---|
events(filter: EventFilterInput) | events:read | Paginated event list with filters for types, platform, search, date range |
event(id: UUID) | events:read | Get a single event by ID (account-scoped) |
GraphQL Mutations
| Mutation | Permission | Description |
|---|
emitEvent(input: EmitEventInput) | events:create | Emit a test/manual event, insert into TimescaleDB and broadcast via pub/sub |
REST Endpoints
All paths live under /v1. Bodies are snake_case.
| Method | Path | Permission | Description |
|---|
GET | /v1/events | events:read | Paginated event list (accepts the same filters as EventFilterInput) |
GET | /v1/events/{id} | events:read | Fetch a single event by ID (account-scoped) |
POST | /v1/events/emit | events:create | Emit a manual event (insert + broadcast) |
POST | /v1/events/test | events:create | Emit a test event (broadcast only, not persisted in all paths) |
| Field | Type | Description |
|---|
types | [String] | Filter by event types (e.g., ["twitch:follower", "twitch:subscriber"]) |
platform | String | Filter by platform (comma-separated for multiple) |
search | String | Case-insensitive text search in raw JSON data |
from | String | ISO 8601 timestamp -- only events after this time |
to | String | ISO 8601 timestamp -- only events before this time |
page | u32 | Page number (1-based, default 1) |
limit | u32 | Items per page (default 25, max 100) |
Permissions
| Permission | Description |
|---|
events:read | Read/list events |
events:create | Create events (test events, emit) |
events:delete | Delete events |
events:userinfo | View user cards/profiles from event entries |
Database
| Table | Database | Description |
|---|
platform_events | TimescaleDB | Hypertable with compression. Fields: id (UUID), account_id, event_type (platform:action format), platform, external_id, raw (JSONB), created_at |
Event Types
Events follow the platform:action naming convention:
twitch:follower, twitch:subscriber, twitch:cheer, twitch:raid, twitch:redemption
youtube:subscriber, youtube:member, youtube:superchat
spotify:track, spotify:play, spotify:pause, spotify:skip, spotify:volume, spotify:queue_add, spotify:device
streamelements:tip
Data Flow
- Platform adapter detects an event (e.g., Twitch EventSub webhook receives a follow).
- Event is inserted into TimescaleDB via
lo_events::insert_event().
- Event is broadcast via
lo_events::broadcast_event() through Redis pub/sub.
- WebSocket server forwards the event to all connected clients for the account.
- Overlay alerts render the event. Dashboard event panel updates in real time.
- Users can query historical events with filters and pagination via
events query.
Key Files
| Path | Description |
|---|
apps/api/src/graphql/events.rs | GraphQL queries and mutations |
crates/lo-events/src/ | Core events crate (insert, list, broadcast, filter types) |
crates/lo-events-db/ | TimescaleDB event storage layer |