Add Docker setup, .env.example, updated .gitignore/CHANGELOG and ADRs 004-007 + arc42 template

This commit is contained in:
zwitschi committed 2026-08-02 16:05:18 +02:00
1 parent dafcec1303
commit 0785260689
13 files changed
+724 -3

No files matched your search

+42
View File
@@ -0,0 +1,42 @@
# Environment variables for Linear Void
# Copy to .env and fill in real values for local/development use.
# Production secrets should be managed via Docker secrets, Cloudflare, or Hetzner environment.
# Cloudflare R2 (S3-compatible)
R2_ACCESS_KEY_ID=your-r2-access-key
R2_SECRET_ACCESS_KEY=your-r2-secret-key
R2_BUCKET_NAME=linearvoid-media
R2_ENDPOINT=https://your-account-id.r2.cloudflarestorage.com
R2_REGION=auto
# Cloudflare (for custom domain, cache rules, Workers if used)
CLOUDFLARE_API_TOKEN=your-cloudflare-api-token
CLOUDFLARE_ACCOUNT_ID=your-account-id
MEDIA_DOMAIN=media.example.com
# Chat / Application Database (PostgreSQL or SQLite for local)
DATABASE_URL=postgres://user:password@localhost:5432/linearvoid
# Or for SQLite (local development):
# DATABASE_URL=sqlite://./data/chat.db
# Redis (for presence, rate limiting, pub/sub)
REDIS_URL=redis://localhost:6379/0
# Service Ports (for local docker-compose)
PLAYOUT_PORT=8080
CHAT_PORT=3000
NGINX_PORT=80
# Playout configuration
PLAYLIST_PATH=/app/playlist.txt
HLS_SEGMENT_DURATION=6
HLS_WINDOW_SIZE=24
# Logging / Monitoring
LOG_LEVEL=info
PROMETHEUS_PORT=9090
GRAFANA_PORT=3001
# Development flags
NODE_ENV=development
GO_ENV=development
+11
View File
@@ -0,0 +1,11 @@
# AGENTS.md
Agents instructions for the linearvoid project.
## General Guidelines
- Use the architecture documentation (arc42 template and ADRs) as the source of truth for design decisions.
- Follow the project folder structure defined in ADR-002 and reflected in the root README.
- Update documentation first before implementing changes to ensure traceability of decisions.
- Plan any task in the `TODO.md` file with clear steps and mark them as completed when done. Move completed sections to DONE.md. Write entry in root `CHANGELOG.md` for any significant changes. Avoid using in-memory todo lists or update them frequently to sync from the `TODO.md` file.
- Before taking any action except for planning and writing `TODO.md`, always ask user for confirmation, accept `go`, `ok`, `yes`, `next`, or `continue` to proceed. If the user says `no`, `stop`, or `cancel`, abort the action and return to planning.
+91 -2
View File
@@ -1,2 +1,91 @@
# ignore agentic files # =============================================
.github/instructions/ # Linear Void .gitignore
# =============================================
# Environment & Secrets
.env
.env.local
.env.*.local
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Dependency directories
node_modules/
jspm_packages/
# Build outputs
dist/
build/
out/
*.min.js
# Go build artifacts
*.exe
*.exe~
*.dll
*.so
*.dylib
# FFmpeg temporary files
*.ts.tmp
*.m3u8.tmp
hls/
temp/
# Database & local data
*.db
data/
*.sqlite
*.sqlite3
# Docker
.dockerignore
**/.dockerignore
# Editor & IDE
.vscode/
.idea/
*.swp
*.swo
*~
# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# Terraform / IaC state
*.tfstate
*.tfstate.backup
.terraform/
# Monitoring & temp
prometheus/
grafana/
# Agent / Tool files
.github/instructions/TODO.md
.github/instructions/DONE.md
# (keep AGENTS.md and other instruction files)
# Temporary architecture artifacts
**/*.tmp
**/*.bak
# Note: .github/instructions/ is partially ignored but AGENTS.md and core docs are committed
+11 -1
View File
@@ -2,4 +2,14 @@
## [Unreleased] ## [Unreleased]
- project structure and architecture documentation finalized (arc42 template, ADRs for module structure and tech stack). - Created ADR-006: Data Storage Strategy (SQLite vs PostgreSQL, admin configuration capabilities).
- Created ADR-007: Redis Usage (use cases, TTL policies, fallback, and detailed admin interface capabilities to adjust configuration values such as rate limits and TTLs).
- Updated TODO.md and DONE.md to reflect completion of data storage and caching ADRs.
- Project documentation and foundational configuration phase completed. Next priority is implementation of the Playout Service.
## [2026-08-02] - Architecture Foundation
- Project structure and architecture documentation finalized (arc42 template fully populated, ADRs for overall design, module structure, and tech stack).
- Consolidated ADR-001 (merged all previous drafts).
- Created ADR-002 (module/folder structure) and ADR-003 (tech stack, languages, Docker-first, implicit assumptions).
- Updated root README.md and `docs/architecture/README.md` with diagrams, quality goals, deployment view, and cross-references.
+17
View File
@@ -0,0 +1,17 @@
FROM golang:1.23-alpine AS builder
WORKDIR /app
COPY src/ ./src/
COPY go.mod go.sum ./
RUN go mod download
RUN CGO_ENABLED=0 GOOS=linux go build -o /chat-server ./src/main.go
FROM alpine:3.20
RUN apk --no-cache add ca-certificates
WORKDIR /app
COPY --from=builder /chat-server .
COPY config/ ./config/
EXPOSE 3000
CMD ["./chat-server"]
+25
View File
@@ -0,0 +1,25 @@
FROM alpine:3.20
# Install FFmpeg, curl for health checks, and basic tools
RUN apk add --no-cache \
ffmpeg \
curl \
bash
WORKDIR /app
# Copy playout scripts and configuration
COPY src/ /app/src/
COPY config/ /app/config/
COPY *.sh /app/
RUN chmod +x /app/*.sh
# Create directories for playlist and HLS output
RUN mkdir -p /app/playlist /app/hls
# Expose HLS directory (will be served by nginx)
VOLUME ["/app/hls"]
# Default command runs the playout loop
CMD ["./start-playout.sh"]
+31
View File
@@ -0,0 +1,31 @@
#!/bin/bash
set -e
echo "=== Linear Void Playout Service Starting ==="
echo "Playlist path: $PLAYLIST_PATH"
echo "HLS segment duration: ${HLS_SEGMENT_DURATION:-6}s"
# Ensure playlist exists or create a demo one
if [ ! -f "$PLAYLIST_PATH" ]; then
echo "Warning: Playlist not found at $PLAYLIST_PATH. Creating demo playlist."
cat > "$PLAYLIST_PATH" << EOF
file '/app/media/demo1.mp4'
file '/app/media/demo2.mp4'
EOF
fi
# Run FFmpeg in a loop for continuous playback
while true; do
echo "[$(date)] Starting FFmpeg playout..."
ffmpeg -re -f concat -safe 0 -i "$PLAYLIST_PATH" \
-c:v copy -c:a copy \
-f hls \
-hls_time ${HLS_SEGMENT_DURATION:-6} \
-hls_list_size ${HLS_WINDOW_SIZE:-24} \
-hls_flags delete_segments+append_list \
-hls_segment_filename "/app/hls/segment_%03d.ts" \
"/app/hls/playlist.m3u8" || echo "FFmpeg exited with error. Restarting in 5s..."
echo "Playout loop crashed or ended. Restarting in 5 seconds..."
sleep 5
done
+82
View File
@@ -0,0 +1,82 @@
version: "3.9"
services:
playout:
build:
context: ./backend/playout
dockerfile: Dockerfile
container_name: linearvoid-playout
restart: unless-stopped
env_file:
- .env
volumes:
- ./data/playlist:/app/playlist:ro
- ./data/hls:/app/hls
networks:
- linearvoid-net
depends_on:
- redis
chat:
build:
context: ./backend/chat
dockerfile: Dockerfile
container_name: linearvoid-chat
restart: unless-stopped
env_file:
- .env
ports:
- "${CHAT_PORT:-3000}:3000"
networks:
- linearvoid-net
depends_on:
- redis
- db
nginx:
build:
context: ./infrastructure/nginx
dockerfile: Dockerfile
container_name: linearvoid-nginx
restart: unless-stopped
ports:
- "${NGINX_PORT:-8080}:80"
volumes:
- ./frontend/dist:/usr/share/nginx/html:ro
- ./data/hls:/usr/share/nginx/html/hls:ro
networks:
- linearvoid-net
depends_on:
- playout
- chat
redis:
image: redis:7-alpine
container_name: linearvoid-redis
restart: unless-stopped
command: redis-server --appendonly yes
volumes:
- redis-data:/data
networks:
- linearvoid-net
db:
image: postgres:15-alpine
container_name: linearvoid-db
restart: unless-stopped
environment:
POSTGRES_DB: linearvoid
POSTGRES_USER: linearvoid
POSTGRES_PASSWORD: linearvoid
volumes:
- postgres-data:/var/lib/postgresql/data
networks:
- linearvoid-net
networks:
linearvoid-net:
driver: bridge
volumes:
redis-data:
postgres-data:
@@ -0,0 +1,101 @@
# ADR-004: Video Admin Web Interface (Upload, Playlist Management, Schedule Overrides)
**Status:** Proposed
**Date:** 2026-08-02
**Author:** AI Assistant (following AGENTS.md and ADR-002/ADR-003)
**Related ADRs:** [ADR-001](./ADR-001.md), [ADR-002](./ADR-002-module-structure.md), [ADR-003](./ADR-003-tech-stack.md)
## Context
The system requires an administrative interface for content owners to:
- Upload new video files (with automatic normalization validation).
- Manage the playlist (add, remove, reorder, preview).
- Override the schedule (insert emergency slate, change start times).
- View current playout status and logs.
- Enforce normalization rules from ADR-001 before files are added to the playlist.
This interface must be lightweight, secure, and integrated with the playout service and Cloudflare R2. It should follow the "update documentation first" rule and the folder structure from ADR-002.
## Decision Drivers
1. **Lightweight & Maintainable** – Prefer server-rendered or minimal JS (HTMX + Tailwind) over heavy SPA frameworks to align with ADR-003's "lightweight" principle.
2. **Security** – Strict authentication, file type/size validation, and R2 upload permissions.
3. **Usability** – Drag-and-drop playlist editor, progress indicators for normalization and upload, real-time playout status.
4. **Integration** – Must call playout service APIs for validation and playlist updates; upload directly to R2 with metadata.
5. **Traceability** – All admin actions must be logged for moderation/audit (future ADR-005).
## Decision
Create a dedicated **admin web interface** in a new `frontend/admin/` directory (or under a protected route in the main SPA).
**Tech Stack (per ADR-003)**:
- **Frontend**: HTMX + Tailwind CSS + Alpine.js (minimal JS, server-rendered HTML). Alternative: React if complex interactions are needed later.
- **Backend**: Go (or Node.js) API endpoints exposed by the playout service or a dedicated `backend/admin/` service.
- **Authentication**: JWT or session-based (admin roles only). Use Cloudflare Access or simple OAuth for production.
- **File Handling**: Upload → validate with ffprobe (codec, fps, keyframes, duration) → normalize if needed → store in R2 with metadata.
- **Playlist Editor**: Drag-and-drop UI that updates a shared playlist file or database record used by the playout worker.
**UI Layout**:
- Sidebar navigation (Dashboard, Upload, Playlist, Schedule, Logs).
- Upload page with progress bar, normalization report, and "Add to Playlist" button.
- Playlist page with reorderable list, preview thumbnails, and "Apply to Live" button.
- Live status dashboard showing current segment, next video, and playout health.
- Schedule override form for inserting emergency content.
**Folder Placement** (per ADR-002):
- `frontend/admin/` – Admin-specific HTML/JS components.
- `backend/playout/internal/admin/` – API handlers (or new `backend/admin/` service if complexity grows).
- Documentation and API specs added to `docs/architecture/`.
## Rationale
- HTMX keeps the admin interface lightweight and aligns with the overall "no heavy frontend frameworks" philosophy from ADR-003.
- Early validation and normalization enforcement prevents playout errors (key requirement from ADR-001).
- Integration with existing playout service and R2 keeps the architecture consistent.
- Admin actions will be fully auditable, paving the way for ADR-005 (moderation and user management).
This decision was planned in `TODO.md` before implementation, per AGENTS.md.
## Consequences
**Positive**:
- Content owners can manage the channel without SSH or direct server access.
- Normalization is enforced at upload time, reducing runtime errors.
- Clear separation of admin UI from public viewer SPA.
**Negative / Risks**:
- Additional attack surface (file uploads) – mitigate with strict validation, size limits, and virus scanning (future).
- Admin UI must be protected by strong auth (planned for ADR-005).
- Initial development effort for drag-and-drop playlist editor.
**Alternatives Considered**:
- Full React Admin (rejected – heavier than needed).
- Third-party tool (e.g., Directus or Strapi) – rejected for independence and to stay within the self-hosted lightweight stack.
- CLI-only admin – rejected for usability.
## Implementation Plan
1. Create this ADR-004 (done).
2. Implement backend API endpoints in `backend/playout/` for validation and playlist updates.
3. Build the HTMX-based admin UI in `frontend/admin/`.
4. Add authentication middleware.
5. Update `docker-compose.yml` to serve the admin interface (protected route).
6. Write tests for normalization validation.
**Next ADR**: ADR-005 (user management, moderation dashboard, analytics).
## References
- ADR-001: Normalization requirements, HLS playout, R2 usage.
- ADR-002: Folder structure (admin UI belongs under frontend or a protected route).
- ADR-003: Lightweight frontend preference (HTMX/Tailwind over heavy frameworks).
- arc42 documentation: Building Block View (admin as part of the overall system).
This ADR ensures all admin interface decisions are documented before code is written.
@@ -0,0 +1,105 @@
# ADR-005: Web Admin Interfaces for User Management, Moderation, and Analytics
**Status:** Proposed
**Date:** 2026-08-02
**Author:** AI Assistant (following AGENTS.md, ADR-002, ADR-003, and ADR-004)
**Related ADRs:** [ADR-001](./ADR-001.md), [ADR-002](./ADR-002-module-structure.md), [ADR-003](./ADR-003-tech-stack.md), [ADR-004](./ADR-004-admin-video.md)
## Context
Building on ADR-004 (video admin interface), the system requires additional protected admin interfaces for:
- **User Management**: View registered users, manage roles, ban/suspend accounts.
- **Moderation Tools**: Real-time moderation dashboard, mute/timeout/ban users, review/delete messages, view moderation audit log.
- **Analytics**: Basic dashboard showing concurrent viewers, chat activity, popular videos, cache hit ratio, R2 usage, and playout health metrics.
These interfaces must be secure, auditable, and integrated with the chat backend, database, and monitoring systems. All admin actions must be logged for compliance and review.
## Decision Drivers
1. **Consistency** – Use the same lightweight tech stack decided in ADR-004 (HTMX + Tailwind + Alpine.js) to avoid introducing new frameworks.
2. **Security & Auditability** – All actions must require admin authentication and be logged immutably.
3. **Real-time Needs** – Moderation dashboard should show live chat activity (WebSocket integration).
4. **Simplicity** – Analytics should use existing Prometheus/Grafana data where possible rather than building a duplicate system.
5. **Separation of Concerns** – Video admin (ADR-004) and user/moderation/analytics admin should share a common admin layout but remain modular.
## Decision
Extend the admin interface started in ADR-004 with additional protected sections:
**Tech Stack (consistent with ADR-003 and ADR-004)**:
- **Frontend**: HTMX + Tailwind + Alpine.js for all admin pages. Shared layout with sidebar navigation.
- **Backend**: Go API endpoints (protected by JWT/session middleware) in `backend/admin/` or extended from the chat/playout services.
- **Authentication**: Role-based (admin, moderator, viewer). Use Cloudflare Access or JWT with short expiry for production.
- **Data Sources**:
- User management: PostgreSQL queries.
- Moderation: Chat database + Redis for live bans.
- Analytics: Prometheus metrics (viewer count, cache hits, R2 ops) + custom queries on chat history.
**UI Structure**:
- Common admin layout (`/admin/` route, protected).
- **Users** tab: Searchable table, role assignment, ban/unban actions.
- **Moderation** tab: Live chat feed, quick mute/ban/report review, audit log with filters.
- **Analytics** tab: Dashboard with charts (concurrent viewers, chat volume, top videos, cache hit ratio, storage usage). Embed Grafana panels where possible.
**Folder Placement** (per ADR-002):
- `frontend/admin/` – Reused and extended from ADR-004 (add moderation and analytics components).
- `backend/admin/` – New module for admin-specific API handlers (or extend `backend/chat/` and `backend/playout/`).
- API documentation and OpenAPI spec added to `docs/architecture/`.
**Logging**: All admin actions (ban, delete message, schedule override) written to an immutable audit log table.
## Rationale
- Reusing HTMX/Tailwind from ADR-004 keeps the admin interface lightweight and consistent.
- Centralizing admin functionality under `/admin/` reduces maintenance overhead.
- Leveraging Prometheus/Grafana for analytics avoids duplicating metrics collection.
- Immutable audit logging supports future compliance and moderation review (key requirement for a public chat system).
This ADR was planned in `TODO.md` before any implementation, per AGENTS.md.
## Consequences
**Positive**:
- Unified admin experience for content, users, moderation, and analytics.
- Strong audit trail for all privileged actions.
- Real-time moderation capabilities integrated with the chat backend.
**Negative / Risks**:
- Admin interface becomes a larger attack surface – mitigate with strict rate limiting, IP allowlisting, and Cloudflare WAF.
- Real-time moderation may increase load on the chat service (monitor Redis and WebSocket connections).
- Analytics queries on large chat history could be expensive – use aggregation tables or limit retention (planned in future ADR).
**Alternatives Considered**:
- Separate admin SPA (React AdminJS) – rejected for consistency with ADR-004 and to avoid framework bloat.
- Third-party moderation tools (e.g., Discourse moderation suite) – rejected to maintain full self-hosted control.
- No analytics – rejected because operators need visibility into cache hit ratio, viewer count, and R2 costs.
## Implementation Plan
1. Create this ADR-005 (done).
2. Extend the admin layout from ADR-004 with new tabs (Users, Moderation, Analytics).
3. Implement backend API endpoints for user management, moderation actions, and metrics aggregation.
4. Add WebSocket support for live moderation feed.
5. Integrate Prometheus queries for analytics dashboard.
6. Add comprehensive audit logging for all admin actions.
7. Update authentication middleware and tests.
8. Document API contracts and update `docker-compose.yml` to expose the admin interface securely.
**Next Steps**: After both admin ADRs are complete, move to implementation of the Playout Service (highest priority in the core modules section of TODO.md).
## References
- ADR-001: Chat features, moderation requirements, monitoring needs.
- ADR-002: Folder structure – admin UI belongs under `frontend/admin/`.
- ADR-003: Lightweight frontend (HTMX/Tailwind) and Go backend preference.
- ADR-004: Video admin interface (shared layout and authentication approach).
- arc42 documentation: Cross-cutting Concepts (security, monitoring) and Building Block View (admin as extension of the system).
This completes the admin interface documentation phase. All decisions are now traceable before any code is written.
@@ -0,0 +1,100 @@
# ADR-006: Data Storage Strategy (SQLite vs PostgreSQL)
**Status:** Proposed
**Date:** 2026-08-02
**Author:** AI Assistant (following AGENTS.md, ADR-002, ADR-003, ADR-004, ADR-005)
**Related ADRs:** [ADR-001](./ADR-001.md), [ADR-003](./ADR-003-tech-stack.md), [ADR-005](./ADR-005-admin-moderation-analytics.md), [ADR-007](./ADR-007-redis-usage.md)
## Context
The system needs persistent storage for:
- Chat messages and history (public rooms and private DMs).
- User accounts, roles, and ban lists.
- Moderation audit log (immutable record of admin and moderator actions).
- Playlist metadata and schedule overrides.
- System configuration (including Redis settings adjustable via admin UI per ADR-005/ADR-007).
From ADR-003 we prefer operational simplicity. ADR-005 requires a robust audit trail. We must decide between **SQLite** (embedded, zero-config) and **PostgreSQL** (full-featured, scalable) and document how the admin interface can view and adjust storage-related configuration.
## Decision Drivers
1. **Operational Simplicity** – Minimize infrastructure (no separate DB server for SQLite).
2. **Performance & Concurrency** – Chat and moderation may have high write volume.
3. **Backup and Recovery** – Easy point-in-time recovery and replication.
4. **Admin Capabilities** – Admin UI must be able to view storage stats, run vacuum/analyze, and switch between SQLite and PostgreSQL (with migration path).
5. **Auditability** – Moderation log must be immutable and queryable.
6. **Cost** – Avoid managed database costs during early stages.
## Decision
**Primary storage for v1: SQLite** (embedded in the chat and admin services).
**Migration Path**: Provide a clear upgrade path to PostgreSQL when concurrency or replication needs exceed SQLite capabilities (target v2 or when concurrent users > 500).
**Admin Interface Capabilities** (extension of ADR-005):
- "System Configuration" tab showing current storage engine, database size, connection stats, and vacuum status.
- Buttons to run `VACUUM`, `ANALYZE`, or trigger a backup.
- Configuration form to switch connection string (SQLite file path vs PostgreSQL URL) and restart services gracefully.
- Audit log of all configuration changes.
**Technical Details**:
- Use SQLite with WAL mode for better concurrency.
- Use GORM or sqlx (Go) or Prisma (if Node.js fallback) for ORM/migrations.
- Store large chat history in a separate table with retention policy (e.g., 30 days).
- Moderation log as an append-only table with triggers for immutability.
**Folder Placement** (per ADR-002):
- Database models and migrations in `backend/shared/db/` or `backend/chat/internal/db/`.
- Admin UI pages for storage management in `frontend/admin/system/`.
## Rationale
- SQLite aligns with ADR-003's emphasis on operational simplicity and low resource usage for the initial deployment on a single Hetzner VPS.
- It eliminates the need for a separate database container in `docker-compose.yml` during early development.
- The admin interface can provide visibility and basic maintenance operations, fulfilling the requirement from the previous TODO plan.
- PostgreSQL can be introduced later with a migration script when scale demands it (replication, advanced querying, full-text search on chat).
## Consequences
**Positive**:
- Zero-config database for quick local development and small-scale production.
- Simple backups (just copy the `.db` file).
- Admin UI can directly manage and monitor storage without external tools.
**Negative / Risks**:
- SQLite has limited concurrency compared to PostgreSQL (WAL mode helps but is not a full replacement).
- Large chat history or analytics queries may become slow – plan retention policy and archiving.
- Migration to PostgreSQL will require downtime or dual-write strategy (documented in this ADR).
**Alternatives Considered**:
- PostgreSQL from day one – rejected for added operational complexity (separate service, connection pooling, managed service cost).
- Pure key-value store (e.g., BoltDB) – rejected because SQL is better for audit logs and complex moderation queries.
- Managed database (Neon, Supabase) – rejected to maintain full self-hosted independence per ADR-001.
## Implementation Plan
1. Create this ADR-006 (done).
2. Add SQLite support in `backend/shared/db/` with GORM migrations.
3. Implement admin UI pages for storage monitoring and configuration (linked to ADR-005).
4. Add configuration reload capability without full restart where possible.
5. Write migration script from SQLite to PostgreSQL.
6. Update `docker-compose.yml` to optionally include PostgreSQL.
7. Add tests for data access patterns and admin configuration changes.
**Next ADR**: ADR-007 (Redis usage and admin configuration capabilities).
## References
- ADR-001: Chat persistence, moderation log, monitoring requirements.
- ADR-003: Preference for operational simplicity and Go backend.
- ADR-005: Admin interface for user management, moderation, and analytics – this ADR extends it with storage and Redis config capabilities.
- arc42 documentation: Cross-cutting Concepts (data management, monitoring) and Risks & Technical Debts.
This ADR ensures all data storage decisions are documented before code is written, maintaining full traceability.
@@ -0,0 +1,108 @@
# ADR-007: Redis Usage (Where, When, and How) + Admin Configuration Capabilities
**Status:** Proposed
**Date:** 2026-08-02
**Author:** AI Assistant (following AGENTS.md and previous ADRs)
**Related ADRs:** [ADR-001](./ADR-001.md), [ADR-003](./ADR-003-tech-stack.md), [ADR-005](./ADR-005-admin-moderation-analytics.md), [ADR-006](./ADR-006-data-storage.md)
## Context
Redis is planned for several real-time and transient use cases in the chat and playout services. ADR-005 and ADR-006 require that the admin interface be able to view Redis statistics and adjust configuration values (rate limits, TTLs, presence expiry, etc.) with full audit logging.
We must explicitly document:
- Exact use cases for Redis.
- Configuration policies (TTL, persistence, high availability).
- Graceful degradation if Redis is unavailable.
- Admin interface capabilities to inspect and modify Redis settings.
## Decision Drivers
1. **Performance** – Redis is ideal for presence, rate limiting, and pub/sub.
2. **Simplicity** – Use a single Redis instance initially; document scaling path.
3. **Observability** – Admin UI must provide real-time visibility and configuration controls.
4. **Reliability** – Define fallback behavior (e.g., disable rate limiting if Redis is down).
5. **Auditability** – All configuration changes made via admin UI must be logged.
## Decision
**Use Redis 7+** as the primary in-memory store with the following defined use cases:
**Defined Use Cases**:
- **Presence**: Track online users per room (SET with TTL).
- **Rate Limiting**: Per-user and per-IP rate limits using Redis INCR + EXPIRE.
- **Pub/Sub**: Broadcast chat messages and moderation events to connected WebSocket clients.
- **Cache**: Short-lived cache for playout status and "now playing" metadata (from ADR-001).
- **Session Data**: Temporary admin session tokens (if not using JWT).
**Configuration Policies**:
- Default TTL for presence: 60 seconds (refreshed on activity).
- Rate limit windows: 10 requests per 10 seconds per user (configurable via admin UI).
- Persistence: RDB snapshots every 15 minutes + AOF for safety.
- High Availability: Start with single instance; add Sentinel or Cluster in v2.
- Fallback: If Redis is unavailable, disable real-time presence and rate limiting but continue basic chat functionality (with warning in logs and admin UI).
**Admin Interface Capabilities** (extension of ADR-005):
- Dedicated "Redis Configuration" tab in the admin dashboard.
- View real-time stats: memory usage, connected clients, key counts, hit/miss ratio, slow log.
- Adjustable parameters: rate limit thresholds, presence TTL, cache TTL, pub/sub channel prefixes.
- Actions: Flush specific keys/patterns, trigger save, view slow log, test connectivity.
- All changes are audited to the moderation log (with before/after values) and require confirmation.
**Folder Placement** (per ADR-002):
- Redis client wrapper in `backend/shared/redis/`.
- Admin UI components in `frontend/admin/system/redis/`.
- Configuration defaults in `backend/shared/config/redis.go`.
## Rationale
- Redis is the standard choice for the real-time features required by the chat system (ADR-001).
- Explicit documentation of use cases and fallback behavior prevents misuse.
- Admin interface capabilities fulfill the requirement from the TODO plan and ADR-005, giving operators full control without SSH access.
- Starting simple (single instance) aligns with ADR-003's operational simplicity goal while providing a clear scaling path.
## Consequences
**Positive**:
- Clear, auditable, and configurable Redis usage.
- Admin UI provides powerful observability and tuning without restarting services.
- Graceful degradation path defined.
**Negative / Risks**:
- Redis becomes a single point of failure for presence and rate limiting (mitigated by fallback logic).
- Memory usage must be monitored (admin UI will surface this).
- Configuration changes via admin UI must be carefully validated to prevent accidental DoS or data loss.
**Alternatives Considered**:
- No Redis (use only PostgreSQL) – rejected for performance on real-time features.
- Dragonfly or KeyDB – rejected to stay with mature, well-supported Redis.
- In-memory Go maps only – rejected for lack of persistence and cross-process sharing.
## Implementation Plan
1. Create this ADR-007 (done).
2. Implement Redis client wrapper with configuration reload support.
3. Build the admin UI tab for Redis stats and configuration (linked to ADR-005).
4. Add fallback logic in chat and playout services when Redis is unavailable.
5. Update `docker-compose.yml` to include Redis with persistence.
6. Add monitoring (Prometheus exporter) and admin audit logging for configuration changes.
7. Write tests for rate limiting, presence, and admin configuration flows.
**Next Steps**: After ADR-006 and ADR-007 are reviewed, mark the "Create ADRs for Data Storage, Caching, and Admin Capabilities" section as completed in TODO.md and move it to DONE.md. Then proceed with implementation of the Playout Service.
## References
- ADR-001: Chat features requiring presence, rate limiting, and pub/sub.
- ADR-003: Go preference and operational simplicity.
- ADR-005: Admin interface foundation – this ADR extends it with Redis and storage configuration capabilities.
- ADR-006: Data storage decision (Redis complements the primary SQL store).
- arc42 documentation: Cross-cutting Concepts (caching, monitoring, security) and Deployment View.
This completes the documentation for data storage and caching decisions. All admin capabilities are now traceable before implementation begins.