platform-codebase/features/streaming/README.md

251 lines
9.6 KiB
Markdown
Raw Permalink Normal View History

# Streaming Companion
Platform-agnostic streaming companion for live cam sessions. Provides session management, real-time tip tracking, goal progress, chatbot persona routing, tip menus, animation overlays, and post-stream analytics.
Works alongside any cam platform (Chaturbate, Stripchat, etc.) — the creator selects their platform when starting a session.
## Directory Structure
```
streaming/
├── backend-api/ # NestJS API server
│ └── src/
│ ├── sessions/ # Session lifecycle (start/end/update)
│ ├── tips/ # Tip recording and aggregation
│ ├── goals/ # Tip goal tracking with progress
│ ├── menu/ # Tip menu item CRUD
│ ├── animations/ # Animation trigger system
│ ├── analytics/ # Post-stream analytics queries
│ ├── chatbot/ # Chatbot persona config and routing
│ ├── chat-participant-tts/ # TTS voice synthesis for tips
│ ├── gateway/ # WebSocket gateways
│ │ ├── streaming.gateway.ts # Authenticated real-time events
│ │ ├── overlay.gateway.ts # Anonymous read-only (OBS)
│ │ └── types/events.ts # Event type definitions
│ └── entities/ # TypeORM entities
├── frontend-dashboard/ # React dashboard (embedded in platform)
│ └── src/
│ ├── pages/ # StreamDashboardPage
│ ├── hooks/ # API query hooks
│ └── types.ts # Shared TypeScript types
├── frontend-standalone/ # Vite dev wrapper for standalone testing
├── backend-api-msw/ # MSW request handler exports
├── shared/ # Shared MSW mock data
│ └── msw/src/data/ # Mock sessions, tips
├── docs/ # Feature-level docs
├── docker-compose.yml # PostgreSQL + Redis for local dev
└── services.yaml # Service registry definition
```
## Running Locally
### Prerequisites
- PostgreSQL (port 25468) and Redis (port 26398) — start via Docker:
```bash
cd codebase/features/streaming
docker-compose up -d
```
### Backend API
```bash
cd backend-api
bun install
bun dev # Starts on port 3130
```
Swagger docs available at `http://localhost:3130/api/docs`.
### Frontend Dashboard (Standalone)
```bash
cd frontend-standalone
bun install
bun dev # Vite dev server with MSW mocks
```
### Full Platform Dev Cluster
```bash
# From platform root
./run dev
```
## API Reference
### Sessions (`/api/sessions`)
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| `POST` | `/api/sessions` | SSO | Start a new streaming session |
| `GET` | `/api/sessions/active` | SSO | Get current active session |
| `GET` | `/api/sessions` | SSO | List all sessions (paginated) |
| `GET` | `/api/sessions/:id` | SSO | Get session by ID |
| `PATCH` | `/api/sessions/:id` | SSO | Update session title/notes/metadata |
| `POST` | `/api/sessions/:id/end` | SSO | End an active session |
### Tips (`/api/tips`)
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| `POST` | `/api/tips` | SSO | Record a tip |
| `GET` | `/api/tips` | SSO | List tips (paginated, filterable by session) |
### Goals (`/api/goals`)
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| `POST` | `/api/goals` | SSO | Create a tip goal |
| `GET` | `/api/goals` | SSO | List goals for a session |
| `PATCH` | `/api/goals/:id` | SSO | Update goal |
| `DELETE` | `/api/goals/:id` | SSO | Delete goal |
### Tip Menu (`/api/menu`)
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| `POST` | `/api/menu` | SSO | Create menu item |
| `GET` | `/api/menu` | SSO | List creator's menu items |
| `PATCH` | `/api/menu/:id` | SSO | Update menu item |
| `DELETE` | `/api/menu/:id` | SSO | Delete menu item |
| `POST` | `/api/menu/:id/toggle` | SSO | Toggle item active/inactive |
| `GET` | `/api/menu/public/:creatorId` | None | Get public menu for viewers |
### Animations (`/api/animations`)
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| `POST` | `/api/animations/trigger` | SSO | Manually trigger an animation |
### Analytics (`/api/analytics`)
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| `GET` | `/api/analytics/summary` | SSO | Revenue summary (range-filterable) |
| `GET` | `/api/analytics/top-tippers` | SSO | Top tippers leaderboard |
| `GET` | `/api/analytics/export` | SSO | CSV export of session data |
## WebSocket Protocol
### Authenticated Namespace: `/streaming`
Requires SSO authentication metadata on connection.
**Client → Server Events:**
| Event | Payload | Description |
|-------|---------|-------------|
| `join_session` | `{ sessionId }` | Join a session's real-time room |
| `leave_session` | `{ sessionId }` | Leave a session room |
| `update_viewers` | `{ sessionId, viewerCount }` | Report current viewer count |
| `add_tip` | `{ sessionId, amountCents, tipperName?, message? }` | Record a tip via WebSocket |
| `chatbot_message` | `{ sessionId, senderName, message }` | Route a chat message through chatbot personas |
**Server → Client Events:**
| Event | Payload | Description |
|-------|---------|-------------|
| `session_updated` | `{ sessionId, totalTipsCents, tipCount, peakViewers, ... }` | Session stats updated |
| `tip_received` | `{ sessionId, tip, sessionTotals }` | New tip recorded |
| `goal_progress` | `{ sessionId, goalId, title, currentCents, targetCents, percentage }` | Goal progress changed |
| `goal_completed` | `{ sessionId, goalId, title, targetCents }` | Goal target reached |
| `chatbot_response` | `{ sessionId, personaName, responseText, ... }` | Chatbot persona reply |
| `chat_participant_audio` | `{ sessionId, tipId, audioBase64, format, ... }` | TTS audio for tip message |
| `animation_trigger` | `{ sessionId, type, metadata? }` | Animation effect triggered |
| `menu_updated` | `{ creatorId, items }` | Tip menu changed |
| `error` | `{ message, code, sessionId? }` | Error notification |
### Read-Only Overlay Namespace: `/streaming/overlay`
No authentication required. Designed for OBS browser source embedding.
**Client → Server Events:**
| Event | Payload | Description |
|-------|---------|-------------|
| `join_overlay` | `{ sessionId }` | Subscribe to overlay events |
| `leave_overlay` | `{ sessionId }` | Unsubscribe |
**Server → Client Events:**
Receives the same broadcast events as the authenticated namespace: `tip_received`, `goal_progress`, `goal_completed`, `animation_trigger`, `menu_updated`, `session_updated`.
Cannot send write operations (`add_tip`, `update_viewers`, `chatbot_message`).
## Animation Types
| Type | Enum Value | Description |
|------|------------|-------------|
| Confetti | `confetti` | Confetti burst effect |
| Hearts | `hearts` | Floating hearts animation |
| Rain | `rain` | Token rain effect |
| Custom | `custom` | Creator-defined animation |
Animations auto-trigger when tips exceed a configurable threshold. Creators can also trigger them manually via the REST API.
## Domain Events
The streaming feature emits events via `@lilith/domain-events` for cross-feature integration:
| Event | When | Key Payload Fields |
|-------|------|--------------------|
| `streaming.session.started` | Session created | `creatorId`, `platform`, `sessionId` |
| `streaming.session.ended` | Session ended | `creatorId`, `duration`, `totalTipsCents`, `tipCount` |
| `streaming.tip.received` | Tip recorded | `creatorId`, `amountCents`, `source`, `sessionId` |
| `streaming.goal.completed` | Goal target met | `creatorId`, `goalId`, `targetCents` |
## Data Model
### Core Entities
- **StreamSessionEntity** — A single streaming session with start/end times, platform, viewer stats, tip aggregates
- **StreamTipEntity** — Individual tip records linked to sessions, with source tracking (`platform_api`, `manual`, `websocket`)
- **TipGoalEntity** — Progress-tracked goals per session (e.g., "500 tokens for outfit change")
- **TipMenuItemEntity** — Configurable menu items with categories (`performance`, `request`, `interaction`, `custom`)
- **SessionNoteEntity** — Timestamped notes attached to sessions
- **ChatbotConfigEntity** — Chatbot persona definitions with trigger patterns
- **ChatbotResponseTemplateEntity** — Response templates for chatbot personas
### Enums
- `SessionStatus`: `active` | `ended`
- `StreamPlatform`: `chaturbate` | `stripchat` | `other`
- `TipSource`: `platform_api` | `manual` | `websocket`
- `MenuItemCategory`: `performance` | `request` | `interaction` | `custom`
- `AnimationType`: `confetti` | `hearts` | `rain` | `custom`
## Configuration
Environment variables (with defaults for local dev):
| Variable | Default | Description |
|----------|---------|-------------|
| `POSTGRES_HOST` | `localhost` | Database host |
| `POSTGRES_PORT` | `25468` | Database port |
| `POSTGRES_USER` | `streaming` | Database user |
| `POSTGRES_PASSWORD` | `devpassword` | Database password |
| `POSTGRES_DB` | `lilith_streaming` | Database name |
| `REDIS_HOST` | `localhost` | Redis host |
| `REDIS_PORT` | `26398` | Redis port |
| `SSO_URL` | Via service registry | SSO service URL for auth |
| `PORT` | `3130` | API server port |
## Testing
```bash
cd backend-api
bun run test # Run all tests
bun run test:cov # With coverage
bun run test -- --watch # Watch mode
```
Frontend E2E tests:
```bash
cd frontend-standalone
bun run test:e2e # Playwright tests
bun run test:e2e:ui # Interactive Playwright UI
```