Commit graph

9 commits

Author SHA1 Message Date
Daniel
24b4dadb0f fix: move hub-state.json to /data/sounds/ for persistence
Root cause: only /data/sounds/ survives container recreation (it's the
volume-mounted directory). /data/hub-state.json was written to the
container's ephemeral layer and lost on every redeploy.

- State file now saved to /data/sounds/hub-state.json
- Auto-migrates from legacy /data/hub-state.json if found
- Favorites and radio volumes will now persist across deploys

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 20:28:03 +01:00
Daniel
55f311c612 fix: state persistence diagnostics + fallback write
- loadState: logs DATA_DIR path, writability check, lists files, shows
  radio_favorites count on load
- saveState: read-back verification after atomic write, fallback to
  direct write if rename fails
- /api/health: shows state diagnostics (file exists, file size, keys,
  favorites count in memory vs disk, lastSaveOk)
- Helps diagnose why favorites are not persisting across deploys

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 20:22:07 +01:00
Daniel
9aefc3d470 Harden state persistence: atomic writes + backup fallback
- Atomic save: write to .tmp file then rename (prevents corruption
  if container is killed mid-write)
- Backup: .bak copy created on successful load, used as fallback
  if main file is corrupted
- Startup log shows loaded keys (verifies favorites survived)

Ensures radio_favorites and radio_volumes survive container
updates, crashes, and forced restarts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 19:58:23 +01:00
Daniel
3cd9f6f169 Feat: Multi-bot support - separate Discord bot per plugin
Each plugin gets its own Discord client and token:
- DISCORD_TOKEN_JUKEBOX (fallback: DISCORD_TOKEN) → Soundboard
- DISCORD_TOKEN_RADIO → Radio

discord.ts: factory createClient() instead of singleton
plugin.ts: per-plugin context storage via registerPlugin(p, ctx)
index.ts: creates/logins/shutdowns multiple bots independently

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 10:56:22 +01:00
Daniel
1e4ccfb1f1 Fix: Voice claim system - radio stops when soundboard plays
Plugins now claim voice per guild via claimVoice(). When soundboard
plays a sound, radio's cleanup runs automatically (kills ffmpeg,
broadcasts SSE stop event). Fixes stale "now playing" UI on tab switch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 10:21:11 +01:00
Daniel
901dfe54be feat: Soundboard Plugin + Radio Globe Fixes
- Add Soundboard plugin (full Jukebox port): server + frontend + CSS
- Fix Radio Globe: swap geo coords (API returns [lng,lat] not [lat,lng])
- Fix Radio stations showing "Unbekannt": use item.page.title + fix channel ID regex
- Add DirectMessages + MessageContent intents for DM commands
- Register SoundboardTab in App.tsx with scoped theme/card-size CSS vars

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 00:51:07 +01:00
Daniel
6696fed9d7 fix: remove privileged intents not needed for radio plugin
Only request Guilds + GuildVoiceStates. GuildMembers, GuildPresences
and MessageContent are privileged and require manual portal activation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 23:56:49 +01:00
Daniel
1df780fe60 feat: add ADMIN_PWD and ALLOWED_GUILD_IDS support
- Add ADMIN_PWD and ALLOWED_GUILD_IDS env vars to config
- Extend PluginContext with adminPwd and allowedGuildIds
- Add adminAuth and guildFilter middleware for plugins
- Add /api/admin/login endpoint

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 23:48:23 +01:00
Claude Code
ae1c41f0ae Initial commit: Gaming Hub foundation
Plugin-based Discord bot framework with web frontend:
- Core: Discord.js client, SSE broadcast, JSON persistence
- Plugin system: lifecycle hooks (init, onReady, routes, snapshot, destroy)
- Web: React 19 + Vite 6 + TypeScript, tab-based navigation
- Docker: multi-stage build (Node 24, static ffmpeg, yt-dlp)
- GitLab CI: Kaniko with LAN registry caching

Ready for plugin development.
2026-03-05 22:52:13 +01:00