refactor: large codebase cleanup - consolidate schemas, migrate to Drizzle ORM, extract frontend components, modernize Docker builds
Build & Deploy / build-and-push (discord-gateway) (push) Failing after 2m22s
Build & Deploy / build-and-push (backend) (push) Failing after 3m22s
Build & Deploy / build-and-push (proxy) (push) Successful in 1m36s
Build & Deploy / deploy (push) Skipped
Build & Deploy / build-and-push (discord-gateway) (push) Failing after 2m22s
Build & Deploy / build-and-push (backend) (push) Failing after 3m22s
Build & Deploy / build-and-push (proxy) (push) Successful in 1m36s
Build & Deploy / deploy (push) Skipped
- Consolidate all DB schema definitions into packages/shared as single source of truth - Migrate backend from raw SQL to Drizzle ORM across all modules - Extract frontend inline UI into separate component files - Refactor discord-gateway circuitBreaker into conversationState + moderationState - Convert messageStore to Proxy singleton pattern - Add validateBody/validateQuery middleware + Zod schemas for API endpoints - Modernize Docker builds with multi-stage + pnpm deploy - Migrate CI/CD from deployment to image-based pipeline - Remove 60+ unused/dead files (~15K lines) - Update color scheme from sky-blue to teal-cyan - Move DB connection management to @bete/shared/database Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
63f21513bd
commit
5802d02e29
@@ -1,27 +1,4 @@
|
||||
import {
|
||||
DISCORD_ANALYSIS_QUEUE_STATUS,
|
||||
DISCORD_ATTACHMENT_CREATED,
|
||||
DISCORD_ATTACHMENT_UPLOADED,
|
||||
DISCORD_CHANNEL_TOPIC_UPDATED,
|
||||
DISCORD_GUILD_MEMBER_ADDED,
|
||||
DISCORD_GUILD_MEMBER_REMOVED,
|
||||
DISCORD_MESSAGE_ANALYZED,
|
||||
DISCORD_MESSAGE_CREATED,
|
||||
DISCORD_MESSAGE_DELETED,
|
||||
DISCORD_MESSAGE_UPDATED,
|
||||
DISCORD_PRESENCE_UPDATED,
|
||||
DISCORD_REACTION_ADDED,
|
||||
DISCORD_REACTION_REMOVED,
|
||||
DISCORD_THREAD_CREATED,
|
||||
DISCORD_THREAD_DELETED,
|
||||
DISCORD_THREAD_UPDATED,
|
||||
DISCORD_VOICE_ACTIVE_USER,
|
||||
DISCORD_VOICE_ANALYZED,
|
||||
DISCORD_VOICE_PCM,
|
||||
DISCORD_VOICE_STARTED,
|
||||
DISCORD_VOICE_STOPPED,
|
||||
DISCORD_VOICE_UPLOADED,
|
||||
} from "@bete/shared";
|
||||
import { DISCORD_CHANNEL_TO_WS_EVENT, DISCORD_VOICE_PCM } from "@bete/shared";
|
||||
import { createChildLogger } from "@bete/shared/logger";
|
||||
import Redis from "ioredis";
|
||||
import { config } from "../shared/config/index.js";
|
||||
@@ -29,41 +6,8 @@ import { broadcastBinary, broadcastEvent } from "./broadcast.js";
|
||||
|
||||
const logger = createChildLogger("ws.redis-bridge");
|
||||
|
||||
interface ChannelMapping {
|
||||
channel: string;
|
||||
eventType: string;
|
||||
}
|
||||
|
||||
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_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_ANALYZED, eventType: "voice_analyzed" },
|
||||
{ channel: DISCORD_REACTION_ADDED, eventType: "reaction_added" },
|
||||
{ channel: DISCORD_REACTION_REMOVED, eventType: "reaction_removed" },
|
||||
{ channel: DISCORD_THREAD_CREATED, eventType: "thread_created" },
|
||||
{ channel: DISCORD_THREAD_DELETED, eventType: "thread_deleted" },
|
||||
{ channel: DISCORD_THREAD_UPDATED, eventType: "thread_updated" },
|
||||
{
|
||||
channel: DISCORD_CHANNEL_TOPIC_UPDATED,
|
||||
eventType: "channel_topic_updated",
|
||||
},
|
||||
{ channel: DISCORD_PRESENCE_UPDATED, eventType: "presence_updated" },
|
||||
{ channel: DISCORD_GUILD_MEMBER_ADDED, eventType: "guild_member_added" },
|
||||
{ channel: DISCORD_GUILD_MEMBER_REMOVED, eventType: "guild_member_removed" },
|
||||
];
|
||||
/** Channels we subscribe to = all keys in DISCORD_CHANNEL_TO_WS_EVENT */
|
||||
const SUBSCRIPTION_CHANNELS = Object.keys(DISCORD_CHANNEL_TO_WS_EVENT);
|
||||
|
||||
let subscriber: Redis | null = null;
|
||||
|
||||
@@ -72,8 +16,8 @@ function createSubscriber(): Redis {
|
||||
}
|
||||
|
||||
function handleSubscriptionMessage(channel: string, message: string): void {
|
||||
const mapping = SUBSCRIPTIONS.find((m) => m.channel === channel);
|
||||
if (!mapping) {
|
||||
const eventType = DISCORD_CHANNEL_TO_WS_EVENT[channel];
|
||||
if (!eventType) {
|
||||
logger.warn({ channel }, "Received message for unmapped Redis channel");
|
||||
return;
|
||||
}
|
||||
@@ -97,7 +41,7 @@ function handleSubscriptionMessage(channel: string, message: string): void {
|
||||
const data = envelope.data !== undefined ? envelope.data : envelope;
|
||||
|
||||
// Voice PCM: decode base64 → binary broadcast instead of JSON
|
||||
if (mapping.eventType === "voice_pcm_data") {
|
||||
if (channel === DISCORD_VOICE_PCM) {
|
||||
const pcmPayload = data as { userId?: string; pcm?: string };
|
||||
if (pcmPayload?.pcm && pcmPayload?.userId) {
|
||||
try {
|
||||
@@ -115,11 +59,8 @@ function handleSubscriptionMessage(channel: string, message: string): void {
|
||||
}
|
||||
}
|
||||
|
||||
logger.debug(
|
||||
{ channel, eventType: mapping.eventType },
|
||||
"Broadcasting Redis event",
|
||||
);
|
||||
broadcastEvent(mapping.eventType, data);
|
||||
logger.debug({ channel, eventType }, "Broadcasting Redis event");
|
||||
broadcastEvent(eventType, data);
|
||||
}
|
||||
|
||||
/** Simple 32-bit FNV-1a hash for userId → 4-byte identifier */
|
||||
@@ -162,7 +103,7 @@ export async function startRedisBridge(): Promise<void> {
|
||||
await subscriber.ping();
|
||||
logger.info("Redis ping OK");
|
||||
|
||||
const channels = SUBSCRIPTIONS.map((m) => m.channel);
|
||||
const channels = SUBSCRIPTION_CHANNELS;
|
||||
await subscriber.subscribe(...channels);
|
||||
logger.info({ channels }, "Subscribed to Redis channels");
|
||||
|
||||
@@ -184,8 +125,9 @@ export async function stopRedisBridge(): Promise<void> {
|
||||
logger.info("Redis bridge stopped");
|
||||
} catch (err) {
|
||||
logger.error({ err }, "Error stopping Redis bridge");
|
||||
} finally {
|
||||
// Force-close on error
|
||||
subscriber.disconnect();
|
||||
} finally {
|
||||
subscriber = null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user