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>
This commit is contained in:
MythEclipse
2026-06-09 17:34:18 +07:00
co-authored by Claude Opus 4.8
parent 7108f6bb47
commit b68789fffc
37 changed files with 3620 additions and 2345 deletions
+26 -12
View File
@@ -1,3 +1,17 @@
import {
DISCORD_ANALYSIS_QUEUE_STATUS,
DISCORD_ATTACHMENT_CREATED,
DISCORD_ATTACHMENT_UPLOADED,
DISCORD_MESSAGE_ANALYZED,
DISCORD_MESSAGE_CREATED,
DISCORD_MESSAGE_DELETED,
DISCORD_MESSAGE_UPDATED,
DISCORD_VOICE_ACTIVE_USER,
DISCORD_VOICE_PCM,
DISCORD_VOICE_STARTED,
DISCORD_VOICE_STOPPED,
DISCORD_VOICE_UPLOADED,
} from "@bete/shared";
import { createChildLogger } from "@bete/shared/logger";
import Redis from "ioredis";
import { config } from "../shared/config/index.js";
@@ -11,21 +25,21 @@ interface ChannelMapping {
}
const SUBSCRIPTIONS: ChannelMapping[] = [
{ channel: "discord:message:created", eventType: "message_created" },
{ channel: "discord:message:updated", eventType: "message_updated" },
{ channel: "discord:message:deleted", eventType: "message_deleted" },
{ channel: "discord:message:analyzed", eventType: "message_analyzed" },
{ channel: "discord:attachment:created", eventType: "attachment_created" },
{ channel: "discord:attachment:uploaded", eventType: "attachment_uploaded" },
{ channel: "discord:voice:started", eventType: "voice_recording_started" },
{ channel: "discord:voice:stopped", eventType: "voice_recording_stopped" },
{ channel: "discord:voice:uploaded", eventType: "voice_recording_uploaded" },
{ channel: DISCORD_MESSAGE_CREATED, eventType: "message_created" },
{ channel: DISCORD_MESSAGE_UPDATED, eventType: "message_updated" },
{ channel: DISCORD_MESSAGE_DELETED, eventType: "message_deleted" },
{ channel: DISCORD_MESSAGE_ANALYZED, eventType: "message_analyzed" },
{ channel: DISCORD_ATTACHMENT_CREATED, eventType: "attachment_created" },
{ channel: DISCORD_ATTACHMENT_UPLOADED, eventType: "attachment_uploaded" },
{ channel: DISCORD_VOICE_STARTED, eventType: "voice_recording_started" },
{ channel: DISCORD_VOICE_STOPPED, eventType: "voice_recording_stopped" },
{ channel: DISCORD_VOICE_UPLOADED, eventType: "voice_recording_uploaded" },
{
channel: "discord:analysis:queue_status",
channel: DISCORD_ANALYSIS_QUEUE_STATUS,
eventType: "analysis_queue_status",
},
{ channel: "discord:voice:active_user", eventType: "voice_active_user" },
{ channel: "discord:voice:pcm", eventType: "voice_pcm_data" },
{ channel: DISCORD_VOICE_ACTIVE_USER, eventType: "voice_active_user" },
{ channel: DISCORD_VOICE_PCM, eventType: "voice_pcm_data" },
];
let subscriber: Redis | null = null;
+3 -2
View File
@@ -1,4 +1,5 @@
import type { Server } from "node:http";
import { BACKEND_COMMAND, BACKEND_VOICE_TRANSMIT } from "@bete/shared";
import { createChildLogger } from "@bete/shared/logger";
import { WebSocket, WebSocketServer } from "ws";
import { setBroadcastFunctions } from "./broadcast.js";
@@ -92,7 +93,7 @@ export function createWebSocketServer(server: Server): WebSocketServer {
const publisher = getCommandPublisher();
publisher
.publish(
"backend:voice:transmit",
BACKEND_VOICE_TRANSMIT,
JSON.stringify({
type: "pcm",
buffer: message.buffer,
@@ -114,7 +115,7 @@ export function createWebSocketServer(server: Server): WebSocketServer {
const commandId = `cmd-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
publisher
.publish(
"backend:command",
BACKEND_COMMAND,
JSON.stringify({
id: commandId,
type: message.command,