docs: expand architecture documentation with scaling strategy, API surface reference, and video normalization spec

This commit is contained in:
zwitschi committed 2026-08-04 20:57:33 +02:00
1 parent d4d7806189
commit 207401b5fb
2 files changed
+161 -1

No files matched your search

+1
View File
@@ -13,6 +13,7 @@
- Added admin UI runtime display for schedule/dashboard plus media library edit/delete actions.
- Added a dedicated plain TypeScript admin module for tab navigation, media CRUD actions, schedule/system analytics refresh, and moderation workflows without Alpine dependencies.
- Added resumable chunked admin media upload flow with upload-session endpoints and client progress indicators.
- Expanded architecture documentation with scaling strategy, API surface reference, detailed video normalization spec, and Cloudflare configuration reference.
### Changed
+160 -1
View File
@@ -311,7 +311,39 @@ Immutable segment naming + targeted Cloudflare Cache Rules + R2 ($0 egress) = ne
### Video Normalization & Playout
All source assets must be pre-normalized (H.264/AVC, AAC-LC, constant 30 fps, 2s keyframe interval, CRF). Prevents glitches during continuous concat. FFmpeg `-c copy` preferred for efficiency.
All source assets must be pre-normalized before they are accepted into production playlists. This prevents decode resets, timestamp drift, and audio/video discontinuities during continuous concat playout.
#### Required Source Profile (Linear Void v1)
| Field | Required Value | Notes |
| ----------------------- | ---------------------------------- | ------------------------------------------------------- |
| Container | MP4 | Single-video-asset input format |
| Video codec | H.264/AVC (`libx264`) | Baseline delivery codec for broad compatibility |
| Audio codec | AAC-LC | Stereo preferred |
| Resolution | 1280x720 or 1920x1080 | Keep single resolution per playlist block when possible |
| Framerate | Constant 30 fps (`-r 30`) | Variable frame rate content must be normalized |
| GOP / keyframe interval | 2 seconds (`-g 60 -keyint_min 60`) | Matches HLS segment boundaries better |
| Pixel format | `yuv420p` | Browser compatibility baseline |
| Audio sample rate | 48 kHz | Stable timing for concat playout |
| Audio bitrate | 128k-192k | Predictable quality envelope |
#### Reference Normalization Command
```bash
ffmpeg -i input.mov \
-c:v libx264 -preset medium -crf 21 \
-r 30 -g 60 -keyint_min 60 -sc_threshold 0 \
-pix_fmt yuv420p \
-c:a aac -b:a 160k -ar 48000 -ac 2 \
-movflags +faststart \
output-normalized.mp4
```
#### Verification Gate (ffprobe)
- Validate codec, fps, resolution, and keyframe cadence before upload acceptance.
- Reject non-conforming files from admin ingest with actionable error feedback.
- Keep verification logic aligned with runtime playout assumptions to preserve `-c copy` efficiency where possible.
### Monitoring & Resilience
@@ -366,6 +398,98 @@ Operational resilience baseline:
- Weekly backup and restore drills for stateful data (`data/chat`, playlist metadata, Postgres).
- Incident runbook with triage order: edge reachability -> origin health -> playout progression -> chat connectivity -> data-plane dependencies.
### API Documentation Reference
Linear Void currently exposes three operational API surfaces. The canonical detailed contract should live in `API.md`, while this section provides the architecture-level map.
#### Chat WebSocket API
- Endpoint: `/ws`
- Transport: `wss://` in production, `ws://` locally
- Query parameters:
- `username`
- `room`
- Message envelope (typical):
- `room`
- `username`
- `text`
- `type` (`public`, `private`, `system`)
- Responsibilities:
- room fan-out
- private DM channel routing
- moderation command handling
- rate limiting and presence integration
#### Playout and Delivery REST API
- Health endpoints:
- playout health (`/health` on playout service)
- edge/origin health (`/health` via nginx)
- Stream delivery:
- HLS manifest and segment path namespace under `/hls/`
- Responsibilities:
- expose liveness for orchestration and monitoring
- provide stable HLS path contract for viewer and CDN
#### Admin REST API
- Auth/session:
- `/api/admin/login`
- `/api/admin/logout`
- `/api/admin/session`
- Operational/admin domains:
- overview, analytics, users, moderation, schedule, playlist, media
- Media upload domain:
- `/api/admin/media/uploads` (init/resume)
- `/api/admin/media/uploads/{uploadId}/chunk`
- `/api/admin/media/uploads/{uploadId}/complete`
- Responsibilities:
- protected control plane for operator workflows
- media metadata + upload orchestration
- moderation/audit and system status management
### Cloudflare Configuration Reference
Cloudflare is part of the production control plane, not only a CDN edge. The following configuration set is required to maintain cost, latency, and reliability targets.
#### DNS and Zone Routing
- `linearvoid.tv` -> application origin (nginx)
- `www.linearvoid.tv` -> redirect to apex
- `media.linearvoid.tv` -> media domain for HLS/object delivery when split-domain mode is enabled
#### Cache Rules Baseline
- HLS segments (`.ts`, `.m4s`):
- Cache Everything
- long TTL (immutable)
- respect immutable semantics
- Manifests (`.m3u8`):
- short TTL (1-10s)
- revalidation-friendly policy for timeline freshness
#### Edge Security and Controls
- Enforce HTTPS/WSS and redirect HTTP to HTTPS.
- Enable WAF baseline protections for common web exploits.
- Apply rate limits for abusive request patterns (especially auth/admin paths).
- Keep origin exposure minimized (prefer Cloudflare-only public ingress where feasible).
#### Worker and Header Policy
- Use Worker logic for immutable cache headers and request normalization where cache rules alone are insufficient.
- Keep CORS behavior explicit for HLS resources to support browser playback.
#### Operations and Validation
- Validate cache behavior after deployment:
- expected cache status progression (MISS -> HIT)
- manifest freshness under active playout
- Track edge metrics and adjust:
- cache hit ratio
- request volume and error rates
- ToS/cost posture for sustained traffic profiles
### Security & Moderation
Security is split between edge controls (Cloudflare), reverse proxy controls (nginx), and application controls (chat/admin backend).
@@ -490,6 +614,41 @@ See **Quality Goals** table in the Introduction section. Primary scenarios focus
- Trigger: origin CPU/memory pressure on playout host.
- Action: optimize FFmpeg profile, isolate services, add secondary origin.
### Scaling Strategy
Scaling is designed to preserve cost efficiency first, then increase throughput and resilience in controlled phases.
#### Phase 1: Vertical + Cache-First (Current Baseline)
- Single primary origin in US-East with strong Cloudflare edge caching.
- Optimize segment immutability and manifest TTL before adding infrastructure.
- Scale compute vertically when CPU/memory pressure appears on playout/chat host.
#### Phase 2: Service Separation
- Split playout, chat, and observability workloads across dedicated nodes/VMs.
- Isolate noisy workloads (analytics, heavy admin tasks) from latency-sensitive chat paths.
- Introduce managed PostgreSQL/Redis or dedicated state nodes where operationally justified.
#### Phase 3: Multi-Origin Resilience
- Add warm standby or active-secondary origin.
- Use health-aware DNS/origin failover strategy.
- Keep HLS path and cache contract stable so viewer impact during failover is minimized.
#### Phase 4: Regional and Throughput Expansion
- Add additional origin region only when audience distribution and latency justify it.
- Keep chat affinity strategy explicit (regional routing, state replication considerations).
- Continuously evaluate cache miss economics vs additional origin complexity.
#### Scaling Triggers
- Rising cache miss ratio with sustained traffic growth.
- Chat p95/p99 latency drift or websocket error growth.
- Persistent origin resource saturation despite optimization.
- Increased blast-radius concerns from single-host dependency.
### Disaster Recovery and Backup Procedures
#### Recovery Targets