Commit Graph
30 Commits
Author SHA1 Message Date
MythEclipse 7108f6bb47 feat(system): implement graceful shutdown and expand websocket events
Improve system reliability and real-time capabilities by implementing a robust lifecycle management system and adding new broadcast events for attachments and voice recordings.

- Implement asynchronous graceful shutdown in backend to close HTTP, WebSocket, Redis, and database connections.
- Add new WebSocket broadcast events: `attachment_created`, `voice_recording_started`, `voice_recording_stopped`, `voice_recording_uploaded`, and `analysis_queue_status`.
- Refactor media status handling to use boolean `playing` state instead of string-based status.
- Centralize `PageResult` and `VoiceRecording` types to improve consistency between frontend and backend.
- Update frontend API client to include `listRecordings` and handle new WebSocket event types.
- Fix type mismatches in voice command handling and media status reporting.
2026-06-09 16:56:44 +07:00
MythEclipseandClaude Opus 4.8 3a7b005d95 fix: resolve architecture disconnects and codebase weaknesses
- Add TEXT_CHANNEL_ID and TEXT_GUILD_ID to config schema (fix silent channel monitoring)
- Remove dead files: message-capture/broadcaster.ts, voice-recording/index.ts
- Fix WebSocket voice_command payload to forward from frontend
- Implement moderation:action handler in commandHandler
- Fix useMascotChat to use canonical request() wrapper
- Fix useAudioPlayback userId hash collision (use string not parseInt)
- Add catch blocks to useMediaControl.skip/stop
- Add typed broadcast functions (messageAnalyzed, voicePcmData, voiceActiveUser)
- Apply Biome formatting and lint fixes

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 16:36:23 +07:00
MythEclipseandClaude Opus 4.8 7d6612bb2d refactor: resolve architecture disconnects and codebase weaknesses
- Consolidate eventTypes.ts as single source of truth for Redis channels:
  - Remove duplicate DiscordGatewayEvent interface from eventBroadcaster.ts
  - Replace all hardcoded channel strings with EventChannels constants
  - eventTypes.ts is no longer an orphan file

- Remove dangerous moderation action feature (selfbot safety):
  - Remove /messages/:id/moderate endpoint from backend
  - Remove moderation:action handler from commandHandler.ts
  - Remove publishFireAndForgetCommand (wrong envelope format)
  - Verified no remaining references to moderation:action in code

- Remove unused getCommandPublisher import from redis-bridge.ts

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 13:22:09 +07:00
MythEclipseandClaude Opus 4.8 3614d32701 fix: resolve architecture disconnects and codebase weaknesses
- Standardize MessageRecord types — single source of truth from @bete/shared
- Clean up config: remove unused GUILD_ID/TEXT_GUILD_ID/TEXT_CHANNEL_ID, fix WEBSERVER_PORT default (3001), remove default admin password
- Move mascot_chat_messages table to Drizzle schema with proper migration
- Remove runtime DDL (CREATE TABLE IF NOT EXISTS) from mascot-chat repository
- Remove phantom analytics/ module from documentation
- Add better-sqlite3 dependency to root devDependencies
- Replace 'as any' casts with proper type assertions across AI moderation
- Add error logging to silent catch blocks in LLM client
- Apply Biome formatting and import organization

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 13:07:01 +07:00
MythEclipse f84b380f4f fix: resolve architecture disconnects and codebase weaknesses
- fix(backend): replace raw .parse() with proper loadConfig() + ConfigError
- fix(gateway): connect voice recording uploader to EventBroadcaster
- fix(gateway): remove dead globalThis.moderationBroadcaster path in AI analyzer
- fix(gateway): eliminate audioStream race condition by attaching handlers before pipe
- fix(gateway): enable inlineVolume by default for setMusicVolume to work
- fix(gateway): reuse persistent redisPub for command replies (no new connection per cmd)
- fix(frontend): add missing voice_active_user/voice_pcm_data to WsEventMap
- fix(frontend): correct onAttachmentUploaded handler signature to accept data
- chore: move @types/pg from dependencies to devDependencies
- chore: translate remaining Indonesian comments to English
- chore: remove stale P3 TODO comment
2026-06-09 11:06:14 +07:00
MythEclipseandClaude Opus 4.8 4becf0d6f1 refactor: comprehensive codebase cleanup and architecture hardening
- Sprint 1 (Quick Wins): Remove dead analytics modules, fix 4 unresolved
  imports, replace 3 console.warn with logger, remove mock-crc import
- Sprint 2 (Architecture): Create MascotChatRepository, AnalysisRepository,
  3 Zod schemas (mascot-chat, analysis, voice), deduplicate error classes,
  move 3 SQL queries from routes to repository
- Sprint 3 (Complexity): Replace 7 any types with proper interfaces,
  extract 6 helpers from prepareMediaMessage (CC 85 -> ~15)
- Sprint 4 (Config): Remove 22 dead env vars from .env, add 30 missing
  vars to .env.example, standardize naming

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 10:16:04 +07:00
MythEclipseandClaude Opus 4.8 d0d9e1669e revert(voice): restore working transmit pipeline
- Rollback frontend latency changes (keep processor.connect(destination))
- Rollback FFmpeg aggressive optimizations (keep 20ms frames)
- Transmit was working before latency optimization; restore stable state

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 01:43:41 +07:00
MythEclipseandClaude Opus 4.8 7b74061788 perf(voice): reduce transmit latency
- FFmpeg: frame_duration 10ms, compression_level 0, nobuffer/low_delay flags, minimal probe
- Frontend: buffer 4096→1024 samples (~170ms→~42ms), faster base64 with chunking
- Remove processor.connect(destination) to avoid audio feedback loop

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 01:07:35 +07:00
MythEclipseandClaude Opus 4.8 3252b323d3 fix(voice): correct API URL path for voice command
- Change /voice/command to /api/voice/command
- Nginx proxies /api/* routes; /voice/command returns 405

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 23:54:02 +07:00
MythEclipseandClaude Opus 4.8 fc2bd3baf1 fix(voice): use HTTP-only for transmit commands
Send voice:transmit:start/stop via POST /api/voice/command
instead of WebSocket. The WebSocket approach failed because:
1. Separate WS connections weren't handled by backend
2. HTTP fallback wasn't working correctly

Now uses HTTP API directly which is more reliable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 23:09:19 +07:00
MythEclipseandClaude Opus 4.8 52f2968d8f fix(voice): add HTTP API fallback for transmit commands
- Add POST /api/voice/command endpoint in backend
- Frontend transmit now sends commands via dedicated WebSocket connection
  with HTTP API fallback if WebSocket fails
- Fixes issue where transmit start command was never received by discord-gateway

Previously commands were sent via the existing dashboard WebSocket,
which may not be connected when the Transmit button is pressed.
Now each command opens a fresh WebSocket connection with HTTP fallback.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 22:55:11 +07:00
MythEclipseandClaude Opus 4.8 314d2baec4 feat(voice): implement full voice transmit (Browser → Discord)
Frontend (useAudioTransmit.ts):
- Capture microphone via getUserMedia
- Convert Float32 to Int16 PCM at 24kHz mono
- Base64 encode and send as JSON via WebSocket
- Send voice:transmit:start/stop commands on start/stop

Backend (ws/server.ts):
- Handle voice_transmit messages from browser
- Forward PCM data to Redis channel backend:voice:transmit
- Handle voice_command messages and forward to backend:command
- discord-gateway VoiceTransmitter receives and plays to voice channel

Flow:
   Browser Mic → getUserMedia → ScriptProcessor → Int16 PCM → base64 →
   WebSocket JSON → Backend → Redis → VoiceTransmitter → Discord Voice Channel

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 21:29:41 +07:00
MythEclipseandClaude Opus 4.8 2e9e9c1a06 fix(frontend): handle voice PCM data as JSON instead of binary
- Add onVoicePcmData and onVoiceActiveUser handlers to WebSocket interface
- Add voice_pcm_data and voice_active_user event cases in socket message handler
- Update useAudioPlayback to decode base64 PCM from JSON format
- Connect onVoicePcmData to audio.handleIncomingPcm in App.tsx

Format change:
- Old: Binary (4 bytes userId + PCM buffer)
- New: JSON {userId: string, pcm: base64string}

This matches the format sent by discord-gateway via Redis.
Now PCM audio will flow correctly: Discord → Gateway → Redis → Backend → WebSocket → Browser!

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 21:22:00 +07:00
MythEclipse a39c7a91c2 refactor(api): replace URLSearchParams param with structured object in listMessages 2026-06-03 20:29:34 +07:00
MythEclipse b5a218daa1 style(analytics): format JSX and object literals consistently 2026-06-03 18:27:41 +07:00
MythEclipse f1bc36d6d8 feat(analytics): add moderation actions, AI stats, and attachment stats endpoints 2026-06-03 18:16:55 +07:00
MythEclipse 7904d7f38d ``` 2026-06-03 15:01:34 +07:00
MythEclipse 84d1b55113 feat(mascot): integrate mascot chatbot with AI-powered responses in sidebar 2026-06-03 14:34:28 +07:00
MythEclipse 9f454b57bb feat(mascot): add AI-powered chat insights to sidebar mascot with useMascotSummary hook 2026-06-03 14:17:21 +07:00
MythEclipse bb65178210 refactor(mascot): replace ChibiMascot SVG with MascotImage PNG and simplify empty states 2026-06-03 13:56:11 +07:00
MythEclipse 4a1c7925fe style(frontend): organize imports alphabetically and improve code formatting 2026-06-03 03:21:20 +07:00
MythEclipse e2003cd9f6 style(frontend): refactor UI components with rounded corners, light theme, and design polish 2026-06-03 03:12:14 +07:00
MythEclipse 09119ef1c2 feat(frontend): add useGsapTransition hook for page animations with reduced motion support 2026-06-03 03:04:17 +07:00
MythEclipse b667805ff3 style: add light theme tokens and framer motion variants 2026-06-03 03:02:00 +07:00
MythEclipse 8d34aa7125 refactor(frontend): remove warn moderation status — hardcode warn to 0 in charts, drop warn filter/badge/buttons/Api, simplify to flagged-only 2026-06-03 01:13:47 +07:00
MythEclipseandClaude Opus 4.8 6da8a32c9b feat: add "Retry All Errors" batch reanalyze button
Backend:
- POST /api/messages/reanalyze-batch — bulk reset error messages to pending
- messages.repository.reanalyzeErrorBatch() — scoped by guildId/channelId/messageIds
- messages.service.reanalyzeErrorBatch() — validation layer

Frontend:
- reanalyzeErrorBatch() API client function
- useMessages.reanalyzeAllErrors() — optimistic state + batch call
- MessagesPanel: destructive button visible when error count > 0
- Shows confirmation text with queued count

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 00:17:51 +07:00
MythEclipse 2d79d8aefd feat(shared): reorder AppError constructor to (message, code, status), add singleton logger, retry and TTL cache utilities 2026-06-02 21:06:42 +07:00
MythEclipseandClaude Opus 4.8 c5c667b147 feat: comprehensive UX improvements — messages, analysis, moderation
Fix #1 (CRITICAL): Wire message_analyzed through Redis EventBroadcaster
- DG aiAnalyzer.ts: Add broadcastAnalysisCompleted() helper that publishes
  to both in-memory WS broadcaster AND Redis EventBroadcaster
- DG bootstrap.ts: Pass eventBroadcaster to startPendingAIAnalysisWorker()
- Fixes broken real-time chain so analysis results appear instantly

Fix #2: Collapsible AI Analysis with Rich Formatting
- MessageCard: AI analysis now collapsible with color-coded severity border
  (red/yellow/blue), summary line showing categories + confidence + severity
- Default collapsed for clean, expanded for warn/flagged

Fix #3: Toast Notifications for Flagged Content
- Wrap app in ToastProvider; ModerationAlertListener component listens for
  moderation_alert custom events and shows toast with emoji + details

Fix #4: Discord-style Message Grouping
- MessageFeed: Group consecutive messages from same user within 5 min
- MessageCard: Compact variant hides avatar, reduces padding for non-first

Fix #5: Moderation Action Buttons in UI
- BE: POST /api/messages/:id/moderate endpoint + publishCommand() for Redis
- FE: Delete/Warn buttons on flagged/warned cards with confirmation dialog

Fix #6: Search Results Include Full Data
- BE analysis.service.ts: SELECT all 26 message columns instead of just 11
- Search results now render with full MessageCard including images/analysis

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 12:17:51 +07:00
MythEclipseandClaude Opus 4.8 f1ddca5eee fix: false positive gambling detection + route collision + WS events (#1)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 10:44:27 +07:00
MythEclipseandClaude Opus 4.8 c48a0c5e3b refactor: split monolith into 3 microservices (frontend, backend, discord-gateway)
- Extract services into services/{frontend,backend,discord-gateway}
- Create packages/shared/ for shared logger, errors, utils, types
- Setup Modular MVC pattern in backend (controller→service→repository)
- Setup event-driven architecture in discord-gateway with Redis pub/sub
- Move Docker files to infra/docker/ with per-service Dockerfiles
- Update docker-compose.yml to use Traefik-only routing (no port exposes)
- Update GitHub Actions deploy workflow for multi-service matrix build
- Fix all import paths and resolve type errors across all services
- All 3 services pass tsc --noEmit clean

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 21:44:29 +07:00