- arc42 template fully populated in docs/architecture/README.md with Mermaid diagrams, quality goals, deployment view, cross-cutting concepts, risks and glossary - Consolidated ADR-001 (merged all previous root ADR drafts) - ADR-002: Module/folder structure decision and rationale - ADR-003: Technology stack, language choices per module (TypeScript, Go, Bash/Python), Docker-first approach, and explicit implicit assumptions - Updated root README.md with comprehensive Project Structure section and links to all ADRs - Created .github/instructions/TODO.md with detailed tracking (architecture phase marked complete) - Folder structure created matching ADR-002 (frontend/, backend/playout/, backend/chat/, backend/shared/, infrastructure/, scripts/, monitoring/) - Git repository initialized with main branch This establishes the foundation defined in the arc42 documentation and the three ADRs.
88 lines
5.7 KiB
Markdown
88 lines
5.7 KiB
Markdown
# ADR-003: Technology Stack, Languages, and Implicit Assumptions
|
||
|
||
**Status:** Accepted
|
||
**Date:** 2026-08-02
|
||
**Author:** AI Assistant (based on arc42 and ADR-001)
|
||
**Related ADRs:** [ADR-001](./ADR-001.md), [ADR-002](./ADR-002-module-structure.md)
|
||
|
||
## Context
|
||
|
||
From ADR-001 and the arc42 documentation we have the following constraints and preferences:
|
||
|
||
- Lightweight, cost-efficient, maintainable stack.
|
||
- Strong preference for US-East hosting (Hetzner), Cloudflare R2/CDN, HLS.
|
||
- Playout must be reliable and low-CPU (FFmpeg + MediaMTX/SRS).
|
||
- Chat needs real-time WebSockets, persistence, moderation, and presence.
|
||
- Frontend must be a minimal static SPA with good browser compatibility.
|
||
- Operational simplicity and easy monitoring are critical.
|
||
- Implicit assumptions include Docker for deployment, normalization of all video assets, heavy reliance on Cloudflare caching, and a focus on immutable infrastructure.
|
||
|
||
We must explicitly document language/runtime choices per module and the assumptions that were made.
|
||
|
||
## Decision
|
||
|
||
**Chosen Stack:**
|
||
|
||
| Layer | Technology | Language | Rationale |
|
||
| ------------------- | ------------------------------------------ | ----------------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
||
| **Frontend SPA** | HTML + Tailwind + Alpine.js + hls.js | TypeScript / JavaScript | Minimal bundle, excellent HLS support, fast iteration. Vite for build. |
|
||
| **Playout Service** | FFmpeg + MediaMTX (or SRS) | Bash + Go (wrapper) | FFmpeg is the proven tool for continuous playlist HLS. Go wrapper for reliability and monitoring. |
|
||
| **Chat Backend** | Go (preferred) or Node.js + Socket.io | Go | High-performance WebSockets, low memory, excellent Redis/PostgreSQL clients. Node.js acceptable for rapid prototyping. |
|
||
| **Shared Code** | TypeScript definitions + Go structs | TS + Go | Clear contracts between frontend and backend. |
|
||
| **Infrastructure** | Docker, Docker Compose, Nginx, Cloudflare | YAML + Bash | Standard, reproducible, Cloudflare-native. |
|
||
| **Scripts** | Bash (with Python helpers where needed) | Bash/Python | Simple, no extra runtime for normalization and R2 sync. |
|
||
| **Monitoring** | Prometheus + Grafana + UptimeRobot | - | Standard open-source stack that integrates well with Docker. |
|
||
| **Storage** | Cloudflare R2 (primary), SQLite/PostgreSQL | - | $0 egress, simple for chat history. |
|
||
|
||
**Implicit Assumptions** (now made explicit):
|
||
|
||
1. All video assets **must** be normalized before being added to any playlist (H.264, AAC, 30 fps constant, 2s keyframes, CRF encoding).
|
||
2. Deployment is **Docker-first**; services will be containerized.
|
||
3. Cloudflare is the primary CDN and will be configured with specific Cache Rules (`.ts` immutable long TTL, `.m3u8` short TTL).
|
||
4. Chat does **not** require end-to-end encryption in v1 (separate ADR if needed).
|
||
5. Single VPS origin initially; multi-region is a later evolution.
|
||
6. Monitoring focuses on playout health, cache hit ratio, and R2 operation counts.
|
||
7. Development environment uses `docker compose` for local testing of playout + chat + frontend.
|
||
|
||
## Decision Drivers
|
||
|
||
- Match the low-resource, high-reliability requirements from ADR-001.
|
||
- Minimize new language overhead (Go for performance-critical services, JS/TS for frontend and rapid scripting).
|
||
- Leverage mature tools (FFmpeg, hls.js, Redis) rather than reinventing.
|
||
- Keep operational complexity low (Docker + Bash scripts).
|
||
|
||
## Alternatives Considered
|
||
|
||
- **Full Node.js stack**: Simpler for small team but higher memory usage for WebSockets and less efficient HLS packaging.
|
||
- **Python for everything**: Excellent for scripting but poor real-time WebSocket performance.
|
||
- **Rust for chat/playout**: Overkill for initial velocity.
|
||
- **Separate repositories per service**: Considered but rejected for early stage (monorepo with clear folders is better).
|
||
|
||
Go was chosen for the chat backend because it offers excellent concurrency, small binaries, and native performance for WebSockets and Redis.
|
||
|
||
## Consequences
|
||
|
||
**Positive**:
|
||
|
||
- Clear, justified choices that align with cost, performance, and maintainability goals.
|
||
- Easy onboarding — developers know exactly which language belongs where.
|
||
- Explicit documentation of assumptions prevents future architectural drift.
|
||
|
||
**Risks**:
|
||
|
||
- Go learning curve if team is primarily JS (mitigated by allowing Node.js fallback for chat).
|
||
- Assumption that normalization scripts will be followed (enforce via CI/validation in playout service).
|
||
|
||
**Future ADRs**:
|
||
|
||
- ADR-004: Docker Compose and deployment pipeline.
|
||
- ADR-005: Monitoring and alerting strategy.
|
||
- ADR-006: API contracts between playout, chat, and frontend.
|
||
|
||
## References
|
||
|
||
- ADR-001 (overall architecture, HLS, Cloudflare caching, normalization requirements)
|
||
- ADR-002 (folder structure that this stack maps into)
|
||
- arc42 documentation (`docs/architecture/README.md`) – Building Block View, Deployment View, Cross-cutting Concepts
|
||
- MediaMTX, hls.js, Go WebSocket best practices, Cloudflare R2 caching documentation
|