Commit Graph
727 Commits
Author SHA1 Message Date
MythEclipse 9e9ce463cb chore(auto): task completed - unknown 2026-06-13 14:59:00 +07:00
MythEclipse fce24278f0 chore(auto): task completed - unknown 2026-06-13 14:49:47 +07:00
MythEclipseandClaude 3965ea79bc fix(gateway): voice speaking handler, metadata cache, transmitter backpressure
- speakingHandler: check subscriptions.has() BEFORE voiceActiveUser broadcast
- segment.ts: add LRU metadata cache (200 entries, avoids Discord API in hotpath)
- transmitter.ts: add backpressure handling with drain queue/flush
  (PassThrough.write() return value was ignored — potential OOM under load)
- cleanup backpressure queue on transmitter stop

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-13 14:38:06 +07:00
MythEclipseandClaude 29d4cb87b6 fix(gateway): voice module critical bugs
- shutdown ordering: DB pool closed AFTER voice disconnect (was before)
- muxer: amix (mix) -> concat (sequential) filter for OGG segments
- upload retries: 0->3 with proper backoff 1-10s
- teleUpload retry backoff: minTimeout 0->1000, maxTimeout 0->10000
- mediaSource: 64KB buffer bound on readFirstTwoLines, 1MB on extractMediaInfo
- ffmpegProcess: pipe stderr to structured logger instead of inherit

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-13 14:35:35 +07:00
MythEclipse e6e34281ff chore(auto): task completed - unknown 2026-06-13 14:24:09 +07:00
MythEclipse 1a195b737e chore(auto): task completed - unknown 2026-06-13 14:12:09 +07:00
MythEclipse 6822cb0bd3 chore(auto): task completed - unknown 2026-06-13 14:10:34 +07:00
MythEclipse 277d982c51 chore(auto): task completed - unknown 2026-06-13 14:05:17 +07:00
MythEclipseandClaude 14c0081f01 feat(discord-gateway): implement voice & push improvements
- Voice disconnect broadcast on stopRecording
- Multi-guild voice support (VoiceController Map<guildId>)
- Session finalization + auto-enqueue muxer job
- Recordings API: duration field, channelId/userId filters
- Transmitter Redis connection reuse (shared conn)
- FFmpeg stderr memory cap (4KB limit)
- 10 new Redis event channels + Redis bridge subscriptions
- New DB tables: message_reactions, message_edits
- Webhook notification module
- Gateway metrics / Prometheus endpoint
- Multi-guild message capture (MONITOR_GUILD_IDS array)
- Thread tracking, presence, channel topic, guild member events
- Edit history snapshot on message update
- Muxer audio post-processing worker

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-13 13:51:21 +07:00
MythEclipse fd3b5c5ca5 chore(auto): task completed - unknown 2026-06-13 13:39:02 +07:00
MythEclipse 111ba0a139 chore(auto): task completed - unknown 2026-06-13 13:36:13 +07:00
MythEclipse 942c33db7e chore(auto): task completed - unknown 2026-06-13 13:35:56 +07:00
MythEclipse eab8505889 chore(auto): task completed - unknown 2026-06-13 13:35:41 +07:00
MythEclipse 2e14b5e4ed chore(auto): task completed - unknown 2026-06-13 13:35:11 +07:00
MythEclipse d569ffa2db chore(auto): task completed - unknown 2026-06-13 13:12:49 +07:00
MythEclipse 4097b23dc3 chore(auto): task completed - unknown 2026-06-13 13:12:41 +07:00
MythEclipse e413cf9fca chore(auto): task completed - unknown 2026-06-13 13:12:29 +07:00
MythEclipse ff006980f8 chore(auto): task completed - unknown 2026-06-13 13:12:01 +07:00
MythEclipse 140a0ba46a chore(auto): task completed - unknown 2026-06-13 13:11:49 +07:00
MythEclipseandClaude 4fcab6b003 refactor(frontend): reorder sidebar — messages first, voice below
Default tab is now 'messages'; Voice & Media moved below
Messages in both desktop sidebar and mobile tab bar.
Updated Header titles/subtitles to match new order.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-13 12:50:13 +07:00
MythEclipse 615c23f061 chore(auto): task completed - unknown 2026-06-13 12:24:32 +07:00
MythEclipse dcede1d676 chore(auto): task completed - unknown 2026-06-13 12:11:37 +07:00
MythEclipse 5b04a4637c docs(frontend): add design tokens documentation 2026-06-13 11:54:20 +07:00
MythEclipse 1406ce3585 chore(auto): task completed - unknown 2026-06-13 11:46:15 +07:00
MythEclipseandClaude 30f8d7cce3 feat: replace corrections/tuner with dashboard module
Replace the corrections/adaptive-prompt-tuner feature with a new
dashboard module providing server stats and user profile overview.

Backend:
- Add dashboard module (routes, service, repository) with stats + user list + user detail endpoints
- Remove corrections module entirely
- Wire dashboard router in app.ts

Frontend:
- Add dashboard feature (DashboardStats, UserSummaryList, UserProfileDetail components + useDashboard hook)
- Remove tuner feature (CorrectionStats, CorrectionHistory, SubmitCorrection, useCorrections)
- Update API client from corrections → dashboard types/fns
- Rename tab 'tuner' → 'dashboard'
- Update MobileTabBar, Header, Sidebar links

Tests:
- Expand backend placeholder test with dashboard assertions
- Expand discord-gateway placeholder test with config/channel assertions

AI moderation:
- llmModerationClient: improve status/reply detection, expand safety categories, fix timer reset
- userProfileLearner: fix isReply refinement
- userProfileStore: add pending cache check
- messageMetadata: add crosspost type mapping
- migrate.ts: improve partial-index safety in schema push

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-13 11:24:42 +07:00
MythEclipseandClaude e3249edb6c feat: detect reply/forward/crosspost in message capture + inject into AI moderation
- Add is_reply, is_forward, is_crosspost, reference_message_id,
  reference_channel_id, reference_guild_id columns to messages table
- Update MessageRecord type with reference fields
- Extract reply/forward/crosspost from Discord message type/flags
- Track reference.type (DEFAULT=reply, FORWARD) and CROSSPOSTED flag
- Inject <reference> XML with parent content into LLM moderation prompt
- Add reply/forward/crosspost rules to moderation prompt rules
- Format context messages with [reply_to], [forward_from], [crosspost]
- Add migration 0009

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-13 00:55:42 +07:00
MythEclipseandClaude 0ac056dc8a fix(ai-moderation): audit prompts to reduce false positives
- ENTROPY rule: replace 'PILIH WARN' default with 'PILIH CLEAN'
- Add safe-list for code/log/stack traces/project names
- Narrow sexual_deviation: only flag explicit sexual solicitation
- Remove overbroad ontological graph (kostum hewan → furry) detection
- Add clean few-shot examples: error logs, project names, orientation disclosure
- Update simple fallback prompt with FP prevention rules
- Remove LGBT/furry from offensive username criteria

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-13 00:01:09 +07:00
MythEclipseandClaude 12f9b55000 fix(ai-moderation): implement prompt analysis recommendations
- Expand IMPHNEN domain rule to cover wildcard (*.imphnen.*)
- Trim redundant SARA examples from TEXT_ONLY_MODE (save ~950 tokens)
- Add debugging logs for channel culture injection into prompt
- Sync flag validation set with missing flags: potential_evasion, unclear_context

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 23:40:25 +07:00
MythEclipseandClaude b508a39ff7 fix(ai-moderation): prevent false positive SARA flag for IMPHNEN project name
- Add explicit system rule that IMPHNEN is the project's own name, not religion
- Rename 'Imphnemia 11:17' example to 'Kitabonia 11:17' to avoid name collision
- Ensures mentioning/promoting the project URL is not flagged as SARA

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 23:28:09 +07:00
MythEclipseandClaude 5c00c9f60b feat(ui): overhaul frontend with IMPHNEN visual identity
- Update CSS foundation: HSL→oklch color tokens, Poppins font, new utilities
- Replace Three.js sakura particles with CSS glow orbs
- Rebrand Header with IMPHNEN logo and gradient text
- Update all UI components (Button, Card, Badge, Input, Select, Tabs, Toast)
- Apply IMPHNEN design patterns (glass, gradient, grid) to layout
- Remove all hardcoded #7EC8E3/#FFB7C5/#FCA5A5 references
- Standardize rounded-xl across all components
- Replace emoji toasts with Lucide icons

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 23:00:52 +07:00
MythEclipseandClaude 7f3eb7b9ac feat(ui): add Adaptive Prompt Tuner tab with correction submission UI
- Add pgCorrectedModerationsTable to shared schema
- Create backend corrections module (stats, list, create endpoints)
- Add TunerPanel with Stats, History, and Submit sub-tabs
- Add AuthOverlay gate for Tuner (admin-only, same as Live)
- Set messages as default tab
- Wire Tuner into sidebar, header, and mobile tab bar

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 21:28:05 +07:00
MythEclipseandClaude fbc2184c6e feat(ai-moderation): add user profile self-learning system
Add user_profiles table, store, and background learner worker
that summarizes user communication style, topics, and personality.

- New user_profiles table (user_id PK, guild_id, profile_summary, last_analyzed_at)
- userProfileStore.ts — CRUD (get/update) following channelCultureStore pattern
- userProfileLearner.ts — background worker: queries 100 recent msgs per user,
  calls LLM for personality summary, updates every 12h
- Inject <user_profile> XML tag per-message in moderation prompt
- Start worker alongside cultureLearner in aiAnalyzer.ts
- Migration 0008 for user_profiles table

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 20:11:34 +07:00
MythEclipseandClaude 6effb51b5d fix(ai-moderation): don't cache text-only results for messages with media
- hasMediaContent now also checks evidence.attachments from metadata
  (not just DB attachment records), catching the race where attachment
  DB rows aren't inserted yet when analysis runs.
- Cache-hit guard: treat cached entries as miss when the message has
  media evidence in metadata, so stale 24h-freezes are avoided.
- Cache-write guard: skip storing text-only analysis results for
  messages whose metadata shows attachments/stickers/embeds. This
  prevents a text-only 'clean' result (from failed vision) being
  frozen for 24h, blocking future re-analysis with full media context.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 18:45:33 +07:00
MythEclipseandClaude 33b787dbd6 fix(migration): make all DDL idempotent with IF NOT EXISTS
- 0000: CREATE TABLE IF NOT EXISTS, CREATE INDEX IF NOT EXISTS,
  FK constraint wrapped in DO 539994 EXCEPTION WHEN duplicate_object
- 0001: ALTER ADD COLUMN wrapped in DO 539994 EXCEPTION WHEN duplicate_column
- 0002: CREATE TABLE IF NOT EXISTS, CREATE INDEX IF NOT EXISTS
- 0003: CREATE TABLE IF NOT EXISTS, CREATE INDEX IF NOT EXISTS
- 0006: ALTER ADD COLUMN wrapped in DO 539994 EXCEPTION,
  DROP COLUMN IF EXISTS

Allows migrations to run cleanly regardless of DB state —
handles fresh DB, partial migration, or wiped __drizzle_migrations.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 18:05:09 +07:00
MythEclipseandClaude fcb199a6ae fix(capture): exclude threads inside excluded channels
- Resolve parent channel ID for threads before checking
  EXCLUDED_CHANNEL_IDS set
- Thread messages now blocked if their parent channel is excluded

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 17:07:34 +07:00
MythEclipseandClaude c91f9f18cc refactor(capture): DRY age-restricted check, use Set for excluded IDs
- Move isAgeRestrictedMessage to messageMetadata.ts alongside
  isAgeRestrictedMetadata — single source of truth for NSFW logic
- Replace || chain of channel IDs with a Set for O(1) lookup
- Import isAgeRestrictedMessage in capture layer instead of inline

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 17:03:01 +07:00
MythEclipseandClaude ebfe942db9 fix(capture): skip age-restricted/NSFW channels entirely
Auto-filter all age-restricted and NSFW channels at capture layer
so messages never enter the database or reach frontend.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 17:00:02 +07:00
MythEclipseandClaude 1efa7b6505 feat(ignore): exclude channel 1323365288447574128 from capture
Add hardcoded channel ID to shouldCaptureMessageLocation so messages
from this channel are not stored, analyzed by AI, or sent to frontend.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 16:49:14 +07:00
MythEclipseandClaude Fable 5 906aef1807 fix(database): handle PG15+ public schema CREATE privilege error in seedDrizzleHistory
In PG15+, the CREATE privilege on the public schema is revoked from
non-owner roles by default. The seedDrizzleHistory function's
CREATE TABLE IF NOT EXISTS for __drizzle_migrations fails with 42501,
causing the gateway to crash-loop on startup.

Wrap the CREATE in a try/catch for 42501 — if the table already exists
(created by a prior run), we continue gracefully; otherwise re-throw.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 04:06:11 +07:00
MythEclipseandClaude Fable 5 490aad7704 fix(ci): add build tools to backend Dockerfile for native deps
@discordjs/opus requires Python and C++ build tools for native
compilation. The discord-gateway Dockerfile already had these but
the backend Dockerfile was missing them, causing CI build failure.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 03:58:47 +07:00
MythEclipse 2e5371f3ee fix(discord-gateway): bypass Drizzle PG15 schema creation restrictions 2026-06-11 03:53:48 +07:00
MythEclipseandClaude Fable 5 378f1b6bdc fix(database): use public schema for drizzle migrations to avoid permission error
PostgreSQL error 42501 when Drizzle tries CREATE SCHEMA IF NOT EXISTS
"drizzle" — the DB user lacks schema creation privileges. Configuring
migrationsSchema: "public" keeps __drizzle_migrations in the existing
public schema, matching what seedDrizzleHistory already expects.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 03:34:16 +07:00
MythEclipse 8b114ca278 refactor(ai-moderation): expand SARA and religious blasphemy detection rules
Update the moderation prompt to include high-priority detection categories for:
- Fake scripture/verse parodies
- Claims of divinity or false religious movements
- Misuse of theological terms as internet slang/memes
- Mockery of religious figures and rituals

This change ensures stricter enforcement of SARA (Suku, Agama, Ras, Antargolongan) policies by explicitly defining religious blasphemy and parody as high-severity violations.
2026-06-11 02:40:11 +07:00
MythEclipse 2557a07916 feat(core): implement data retention, metrics, and enhanced media handling
This commit introduces several significant improvements across the backend and gateway services:

- **Data Retention**: Added an automated cleanup scheduler in `discord-gateway` to prune expired messages, attachments, and voice recordings based on configurable retention policies.
- **Observability**: Integrated `prom-client` in the `backend` service to expose Prometheus metrics via `/api/metrics` and added default Node.js runtime metrics.
- **Media Handling**: Enhanced `MediaHandler` in `discord-gateway` to support media URL resolution and improved playback status tracking.
- **API & Config**: Expanded the configuration endpoint to expose more system settings and reorganized `.env.example` for better readability.
- **Refactoring & Cleanup**:
    - Removed unused `better-sqlite3` dependency.
    - Refactored voice channel routing.
    - Improved error handling and testing coverage with comprehensive unit tests for shared utilities and error classes.
- **Documentation**: Added `MEMORY.md` for project context.
2026-06-10 20:56:16 +07:00
MythEclipse f04b0f0b42 refactor(voice): optimize recording pipeline and improve performance
Refactor the voice recording and playback systems to improve efficiency, reduce latency, and enhance Docker build performance.

- **Infrastructure**: Optimize Dockerfiles using build mounts for pnpm cache and reorder layers for better caching of dependencies and build tools.
- **Backend/Gateway**:
  - Refactor `broadcast` module to use a generic event-based system instead of hardcoded functions.
  - Simplify voice recording logic by merging metadata and segment management into a unified `segment.ts`.
  - Optimize audio downsampling in `streamSetup.ts` using `Int16Array` views for better performance.
  - Implement `withFallback` utility for more robust Redis/Database command execution.
- **Frontend**:
  - Optimize audio playback visualization using pre-computed level shapes and efficient RMS calculation.
  - Reduce latency in voice commands by prioritizing WebSocket communication over HTTP.
  - Improve base64 encoding efficiency in audio transmission.
- **General**:
  - Add default value for `ADMIN_PASSWORD` in shared config.
  - Fix Docker healthcheck to use `127.0.0.1` instead of `localhost`.
2026-06-09 22:04:05 +07:00
MythEclipseandClaude Opus 4.8 823b342c2c fix: remove --wait flag from docker compose up
The --wait flag causes the deploy to abort when a container exits
immediately (e.g., due to transient DB connection issue on startup).
With restart: unless-stopped, containers will auto-recover without
blocking the deployment pipeline.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 20:48:39 +07:00
MythEclipseandClaude Opus 4.8 c371317755 fix: add retry logic for docker compose pull transient errors
GitHub Container Registry pulls occasionally fail with 'connection reset
by peer'. Adding a 3-attempt retry loop with 5s backoff between pulls
to handle transient network errors gracefully.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 20:39:32 +07:00
MythEclipseandClaude Opus 4.8 655380dd8d fix: build @bete/shared before frontend in Dockerfile
TypeScript compilation in the frontend Docker build fails with TS2307:
Cannot find module '@bete/shared' because the shared package's .d.ts
files in dist/ were never generated. The backend and discord-gateway
Dockerfiles already have this build step — frontend was missing it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 20:35:35 +07:00
MythEclipseandClaude Opus 4.8 07032ab521 refactor: atomic, DRY, and logging improvements across codebase
- Split llmModerationClient.ts (2170 lines) into 5 focused sub-modules
- Split aiAnalyzer.ts (1282 lines) into 4 modular pipelines
- Split messages.db.ts (826 lines) into 5 domain-specific modules
- Moved shared schema to @bete/shared, eliminated backend duplication
- Added createChildLogger to all voice-recording and AI moderation modules
- Extracted tryCommandThenFallback, normalizeMediaState, DEFAULT_VOICE_STATUS
- Created shared pagination.ts utility, eliminated 5+ cursor-pagination duplications
- Created shared messageMapper.ts for row mapping
- Standardized backend error handling with asyncHandler
- Added frontend createLogger utility and useAsyncAction hook
- Added structured logging to frontend hooks, socket, and API client

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 19:46:08 +07:00
MythEclipseandClaude Opus 4.8 b68789fffc refactor: atomic, DRY, and logging improvements
- Shared Redis channel constants as single source of truth (redis-channels.ts)
- commandHandler.ts split into VoiceHandler, MediaHandler, GuildHandler,
  ModerationHandler with handler-registry.ts dispatch
- messageStore.ts (1322 lines) split into domain-specific DB files:
  messages.db.ts, attachments.db.ts, reviews.db.ts,
  moderation-actions.db.ts, retention.db.ts
- recorder.ts startSpeaking callback extracted into speakingHandler.ts,
  streamSetup.ts, segmentFinalizer.ts
- autoDeleteManager.ts split into autoDeleteEligibility.ts,
  autoDeleteNotify.ts, autoDeleteLogger.ts
- Added createChildLogger() logging across 8 service files
- Backend messages.repository.ts migrated from raw SQL to Drizzle ORM
- Fixed biome.json to exclude packages/**/dist/* from lint
- Fixed config.ts GUILD_ID pre-existing type error

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 17:34:18 +07:00