# Scrum Solitare Enterprise-style Scrum Poker application using Go, Gin, and SSE for real-time room updates. ## Highlights - Go backend with layered architecture (`handlers`, `state`, `routes`, `config`) - Memory-first room state with disk synchronization to JSON files - Real-time updates via Server-Sent Events (SSE) - Strict state sanitization: unrevealed votes from other users are never broadcast - Backend authorization for admin-only actions (`reveal`, `reset`) - Themeable frontend with: - CSS architecture split into `main.css`, `layout.css`, and `/themes/*` - Theme options: `win98` (default), `modern`, `No Theme` - Light/Dark mode independent from active theme - Desktop taskbar controls + mobile top controls for theme/mode switching - Config page and card deck preview - Drag-and-drop card ordering - Card add/remove with animation completion handling - Room password option - Room interface with voting area, participants, and admin controls - Username persistence through `localStorage` ## Project Layout - `src/main.go`: app bootstrap - `src/config/`: environment configuration - `src/server/`: Gin engine setup - `src/routes/`: page/api route registration - `src/handlers/`: HTTP handlers (pages + API + SSE) - `src/state/`: in-memory room manager, sanitization, persistence - `src/middleware/`: static cache headers middleware - `src/models/`: template page data models - `src/templates/`: HTML templates (`index.html`, `room.html`) - `static/css/main.css`: shared component primitives - `static/css/layout.css`: grids/flex/positioning/responsive layout - `static/css/themes/`: drop-in theme files - `static/js/ui-controls.js`: global theme + mode engine - `static/js/`: page logic (`config.js`, `room.js`) ## Environment Variables ### Quick Reference - `HOST` (default: `0.0.0.0`): network interface/address the server binds to. - `PORT` (default: `8002`): HTTP port the server listens on. - `DATA_PATH` (default: `./data`): folder where room JSON files are stored. - `MAX_ACTIVITY_LOG_ENTRIES` (default: `400`): max activity entries retained per room. - `ADMIN_LOG_BROADCAST_LIMIT` (default: `200`): max recent log entries sent to admins over SSE. - `STALE_ROOM_CLEANUP_INTERVAL` (default: `5m`): how often stale-room cleanup runs. - `STALE_ROOM_TTL` (default: `30m`): empty rooms older than this are deleted. ### Variable Guide With Use Cases `HOST` - What it controls: where the web server is reachable from. - Use case: local-only dev on one machine. ```bash HOST=localhost PORT=8002 go run ./src ``` - Use case: allow access from LAN/Docker/k8s ingress. ```bash HOST=0.0.0.0 PORT=8002 go run ./src ``` `PORT` - What it controls: server port. - Use case: avoid conflicts with another app already on `8002`. ```bash PORT=9000 go run ./src ``` - Use case: common reverse-proxy port mapping. ```bash HOST=0.0.0.0 PORT=8080 go run ./src ``` `DATA_PATH` - What it controls: disk location for persisted rooms. - Use case: keep data in a dedicated local directory. ```bash DATA_PATH=./tmp/rooms go run ./src ``` - Use case: persistent mount in containers. ```bash docker run --rm -p 8002:8002 -e DATA_PATH=/app/data -v $(pwd)/data:/app/data scrum-solitare ``` `MAX_ACTIVITY_LOG_ENTRIES` - What it controls: per-room in-memory/disk activity history cap. - Use case: retain more history for auditing/debugging. ```bash MAX_ACTIVITY_LOG_ENTRIES=1000 go run ./src ``` - Use case: reduce memory/storage in lightweight deployments. ```bash MAX_ACTIVITY_LOG_ENTRIES=100 go run ./src ``` `ADMIN_LOG_BROADCAST_LIMIT` - What it controls: maximum recent activity entries included in admin SSE payloads. - Use case: richer admin timeline in active rooms. ```bash ADMIN_LOG_BROADCAST_LIMIT=400 go run ./src ``` - Use case: smaller SSE payloads for lower bandwidth. ```bash ADMIN_LOG_BROADCAST_LIMIT=50 go run ./src ``` `STALE_ROOM_CLEANUP_INTERVAL` - What it controls: scheduler frequency for checking stale empty rooms. - Use case: aggressive cleanup in ephemeral environments. ```bash STALE_ROOM_CLEANUP_INTERVAL=1m go run ./src ``` - Use case: reduce cleanup churn in stable environments. ```bash STALE_ROOM_CLEANUP_INTERVAL=15m go run ./src ``` `STALE_ROOM_TTL` - What it controls: time since last room activity before an empty room is deleted. - Use case: auto-prune quickly for temporary team rooms. ```bash STALE_ROOM_TTL=10m go run ./src ``` - Use case: keep empty rooms around longer between sessions. ```bash STALE_ROOM_TTL=2h go run ./src ``` ### Duration Format Notes `STALE_ROOM_CLEANUP_INTERVAL` and `STALE_ROOM_TTL` use Go duration syntax: - valid examples: `30s`, `5m`, `45m`, `2h` - invalid examples: `5` (missing unit), `five minutes` ## Run Locally ```bash go mod tidy go run ./src ``` Open `http://localhost:8002`. Host binding examples: ```bash HOST=localhost PORT=8002 go run ./src HOST=0.0.0.0 PORT=8002 go run ./src ``` State tuning example: ```bash MAX_ACTIVITY_LOG_ENTRIES=600 \ ADMIN_LOG_BROADCAST_LIMIT=300 \ STALE_ROOM_CLEANUP_INTERVAL=2m \ STALE_ROOM_TTL=45m \ go run ./src ``` ## Docker Build: ```bash docker build -t scrum-solitare . ``` Run: ```bash docker run --rm -p 8002:8002 -e DATA_PATH=/app/data scrum-solitare ``` ## Real-Time Flow (SSE) - Client joins room via `POST /api/rooms/:roomID/join` - Client subscribes to `GET /api/rooms/:roomID/events?participantId=...` - Server broadcasts sanitized room state updates on critical mutations: - room creation - join/leave - vote cast - reveal - reset