Commit Graph
17 Commits
Author SHA1 Message Date
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 74400376a0 fix: vision analysis retry + fallback jelas saat gagal
Vision API call sekarang pakai retryWithBackoff (2 retries instant).
Fallback message tegas: 'GAGAL DIANALISIS — JANGAN mengasumsikan aman'.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 11:41:18 +07:00
MythEclipseandClaude Opus 4.8 64643bb066 perf: hapus semua cooldown/backoff delay — retry tanpa bottleneck
Semua retry sekarang instant (retries=0, minTimeout=0, maxTimeout=0):
- retry.ts (kedua) — default minTimeout/maxTimeout 0, factor 1
- config.ts (kedua) — DECODER_COOLDOWN_MS=0, AI_ANALYSIS_ERROR_COOLDOWN_MS=0
- llmModerationClient.ts (kedua) — retries 0 tanpa delay
- aiAnalyzer.ts (kedua) — retries 0, AI_ANALYSIS_ERROR_COOLDOWN jadi 0
- indonesianTextNormalizer.ts (kedua) — semua rate limit cooldown 0
- recorder.ts (kedua), teleUpload (3 files), uploader (2 files) — retry instant
- attachmentUploader (kedua) — retries 0
- syncRoutes.ts — BACKLOG_SYNC_COOLDOWN 0

20 files changed. Semua cooldown bottleneck dihapus.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 11:29:52 +07:00
MythEclipseandClaude Opus 4.8 62d7d19b53 fix: analysis output wajib deskriptif — bukan generic placeholder
Sebelumnya: 'Pesan hanya berisi attachment tanpa teks yang melanggar'
Sekarang: harus deskriptif berdasarkan tipe konten:
- Text only: '[user] membahas tentang <topik>. <konteks>.'
- Image only: 'Gambar berupa <jenis>. Terlihat <isi>.'
- Text+Image: '[user] mengirim <gambar> sambil membahas <topik>.'

Tambahkan contoh baik vs buruk di OUTPUT_INSTRUCTIONS sebagai format wajib.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 11:24:21 +07:00
MythEclipseandClaude Opus 4.8 a69de85564 fix: prompt dua mode — gambar+teks vs gambar saja
Sebelumnya aturan 'percaya teks terlebih dahulu' membuat model abaikan
deskripsi gambar saat teks kosong. Semua image-only message di-clean.

Fix:
- SYSTEM_RULES: pisah Mode 1 (teks+gambar) dan Mode 2 (hanya gambar)
- Mode 2: deskripsi gambar jadi bukti utama, WAJIB dibaca
- Gambar terminal/chat/editor kode/casual → clean
- Gambar dengan elemen judi NYATA (chip, roulette, odds) → flag
- 2 contoh few-shot baru: terminal clean, situs judi flag

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 11:15:53 +07:00
MythEclipseandClaude Opus 4.8 55ee8ade16 fix: vision model hanya deskripsi, tidak memutuskan moderasi
Root cause: vision model diminta untuk 'flag' dan 'menilai' gambar,
sehingga screenshot terminal/chat biasa diklaim sebagai 'situs perjudian'.

Fix:
- vision prompt: HANYA deskripsi objektif (objek, teks, layout, jenis gambar)
- larang tegas kata 'gambling', 'judi', 'pelanggaran', 'harus dihapus'
- tambah buildGeneralImageVisionPrompt di discord-gateway stickerPrompt
- MEDIA_INSTRUCTIONS: tegaskan batch LLM adalah hakim, vision hanya saksi mata
- deskripsi netral (terminal, chat, editor kode) tidak boleh jadi dasar flag

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 11:08:41 +07:00
MythEclipseandClaude Opus 4.8 5f419a6f0f feat: real guild/channel names from Discord + remove selectors in Messages/Analytics
- discord-gateway: add redis command handlers for guilds:list, guilds:text-channels, voice:channels
- backend: replace postgres synthetic names with redis commands to gateway (with fallback)
- frontend: remove guild/channel dropdowns from messages and analytics tabs
- frontend: auto-load all channels from monitor guild via guildId query param
- frontend: show guild name in messages/analytics headers instead of selector
- live tab: keeps guild/channel selectors with real discord names

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 11:02:54 +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 3b2709455e feat: implement all real backend endpoints, Redis pub/sub bridge, and gateway command handler
Backend (real implementations, no more stubs):
- Redis pub/sub bridge: subscribes to discord-gateway events (message/attachment/voice) and broadcasts to WS clients
- Redis command channel: backend publishes voice/media commands, discord-gateway executes and replies
- Voice service: connectVoice/disconnectVoice/getVoiceStatus via Redis commands with graceful fallback
- Media service: queue/skip/stop/volume via Redis commands, reads status from Redis cache
- Messages repository: ALL 7 methods now use real PostgreSQL queries (findMany, findById, findByChannel, create, update, delete, getAttachmentsByChannel)
- Analytics: period returns {start,end} epoch millis, overview includes hourly/topics/top_users, worst_flags as string[]
- Health check: actually queries SELECT 1 against database
- VoiceStatus type fixed: {connected, activeGuildId, activeChannelId, activeChannelName}
- Guild type: includes icon: string | null
- asyncHandler: accepts Promise<unknown> instead of Promise<void>

Discord Gateway:
- CommandHandler: subscribes to 'backend:command' Redis channel, executes voice/media commands, publishes replies
- Publishes voice:status and media:status to Redis for backend caching
- Shutdown handler updated to close command handler

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 00:32:38 +07:00
MythEclipseandClaude Opus 4.8 9b41eb9c12 feat(backend): implement all missing endpoints, real analytics queries, and WebSocket server
- Replace stub analytics.repository.ts with real PostgreSQL queries using pg.Pool
- Add /api/guilds, /api/config, /api/auth/login, /api/ui-state (GET/POST)
- Add /api/review, /api/recordings, /api/analysis/search
- Add /api/messages/:id/reanalyze endpoint
- Add /api/analytics/heatmap and /api/analytics/topics
- Implement media routes (stub responses, backend has no Discord voice client)
- Add WebSocket server at /ws with heartbeat and broadcast functions
- Fix analytics route paths to match frontend contract (dual paths for backward compat)
- Export getPool() from database module for raw SQL queries
- Register all new routers in app.ts

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 00:11:29 +07:00
MythEclipseandClaude Opus 4.6 ccd3ccd556 fix(frontend): add vite preview allowedHosts and port config
Vite preview blocks unknown hosts by default. Added allowedHosts for
imphnen.asepharyana.my.id and set port/host in preview config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-01 23:22:14 +07:00
MythEclipseandClaude Opus 4.6 0f6cdff8ee fix(frontend): set preview port to 3000 to match traefik loadbalancer
Vite preview defaults to port 4173 but traefik routes to port 3000.
Added --port 3000 to the preview script in package.json.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-01 23:11:47 +07:00
MythEclipseandClaude Opus 4.6 58afa98132 fix(discord-gateway): skip migration if schema tables already exist
Instead of failing on CREATE TABLE when tables already exist, check
information_schema for all 10 schema tables. If all exist, skip
migration gracefully. This handles deployments where DB was created
by a previous deployment with different migration files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-01 23:09:04 +07:00
MythEclipseandClaude Opus 4.6 5e3c2dddb9 fix(discord-gateway): add missing dependencies (axios, ws, @types/pg, @types/ws)
After removing root package deps, discord-gateway service was missing:
- axios (used in indonesianTextNormalizer.ts)
- ws (used in broadcaster.ts)
- @types/pg (needed for TypeScript pg declarations)
- @types/ws (needed for ws types)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-01 22:55:30 +07:00
MythEclipseandClaude Opus 4.6 e2c1197caf fix(discord-gateway): generate Drizzle migrations and copy to Docker image
Container crashed with 'Can't find meta/_journal.json file' because
Drizzle ORM migration files were never generated. Generated migrations
for all 10 schema tables and updated Dockerfile to copy drizzle/ to
/app/drizzle/ where the migrator expects them.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-01 22:52:03 +07:00
MythEclipseandClaude Opus 4.6 f20c2389a4 refactor(backend): flatten module structure, move routes to .routes.ts files
- Remove empty controllers/, services/, repositories/ subdirectories
- Move routes/index.ts into module.routes.ts (flat naming convention)
- Update imports in http/app.ts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-01 21:53:08 +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