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>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
d0d9e1669e
commit
4becf0d6f1
@@ -0,0 +1,39 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const voiceCommandSchema = z.object({
|
||||
command: z.string().min(1, "command is required"),
|
||||
});
|
||||
|
||||
export const connectVoiceSchema = z.object({
|
||||
guildId: z.string().min(1, "guildId is required"),
|
||||
channelId: z.string().min(1, "channelId is required"),
|
||||
});
|
||||
|
||||
export const guildIdParamSchema = z.object({
|
||||
guildId: z.string().min(1),
|
||||
});
|
||||
|
||||
export const guildSchema = z.object({
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
icon: z.string().nullable(),
|
||||
});
|
||||
|
||||
export const channelSchema = z.object({
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
type: z.enum(["voice", "text"]),
|
||||
});
|
||||
|
||||
export const voiceStatusSchema = z.object({
|
||||
connected: z.boolean(),
|
||||
activeGuildId: z.string().nullable(),
|
||||
activeChannelId: z.string().nullable(),
|
||||
activeChannelName: z.string().nullable(),
|
||||
});
|
||||
|
||||
export type VoiceCommand = z.infer<typeof voiceCommandSchema>;
|
||||
export type ConnectVoice = z.infer<typeof connectVoiceSchema>;
|
||||
export type Guild = z.infer<typeof guildSchema>;
|
||||
export type Channel = z.infer<typeof channelSchema>;
|
||||
export type VoiceStatus = z.infer<typeof voiceStatusSchema>;
|
||||
@@ -1,9 +1,6 @@
|
||||
import { getPool } from "../../shared/database/index.js";
|
||||
import {
|
||||
publishCommand,
|
||||
readRedisStatus,
|
||||
} from "../../shared/redis/index.js";
|
||||
import { createChildLogger } from "@bete/shared/logger";
|
||||
import { getPool } from "../../shared/database/index.js";
|
||||
import { publishCommand, readRedisStatus } from "../../shared/redis/index.js";
|
||||
|
||||
const logger = createChildLogger("voice.service");
|
||||
|
||||
@@ -32,8 +29,7 @@ export interface VoiceStatus {
|
||||
*/
|
||||
export async function getGuilds(): Promise<Guild[]> {
|
||||
const reply = await publishCommand<Guild[]>("guilds:list", {});
|
||||
if (reply?.success && reply.data && reply.data.length > 0)
|
||||
return reply.data;
|
||||
if (reply?.success && reply.data && reply.data.length > 0) return reply.data;
|
||||
|
||||
// Fallback: Postgres with synthetic names
|
||||
logger.warn(
|
||||
@@ -59,8 +55,7 @@ export async function getTextChannels(guildId: string): Promise<Channel[]> {
|
||||
const reply = await publishCommand<Channel[]>("guilds:text-channels", {
|
||||
guildId,
|
||||
});
|
||||
if (reply?.success && reply.data && reply.data.length > 0)
|
||||
return reply.data;
|
||||
if (reply?.success && reply.data && reply.data.length > 0) return reply.data;
|
||||
|
||||
// Fallback: Postgres with synthetic names
|
||||
logger.warn(
|
||||
@@ -117,12 +112,14 @@ export async function connectVoice(
|
||||
|
||||
// Fallback: read from Redis status key
|
||||
const cached = await readRedisStatus("voice:status");
|
||||
return (cached as unknown as VoiceStatus) ?? {
|
||||
connected: false,
|
||||
activeGuildId: null,
|
||||
activeChannelId: null,
|
||||
activeChannelName: null,
|
||||
};
|
||||
return (
|
||||
(cached as unknown as VoiceStatus) ?? {
|
||||
connected: false,
|
||||
activeGuildId: null,
|
||||
activeChannelId: null,
|
||||
activeChannelName: null,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,10 +130,12 @@ export async function disconnectVoice(): Promise<VoiceStatus> {
|
||||
if (reply?.success && reply.data) return reply.data;
|
||||
|
||||
const cached = await readRedisStatus("voice:status");
|
||||
return (cached as unknown as VoiceStatus) ?? {
|
||||
connected: false,
|
||||
activeGuildId: null,
|
||||
activeChannelId: null,
|
||||
activeChannelName: null,
|
||||
};
|
||||
return (
|
||||
(cached as unknown as VoiceStatus) ?? {
|
||||
connected: false,
|
||||
activeGuildId: null,
|
||||
activeChannelId: null,
|
||||
activeChannelName: null,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user