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>
This commit is contained in:
MythEclipse
2026-06-09 19:46:08 +07:00
co-authored by Claude Opus 4.8
parent b68789fffc
commit 07032ab521
61 changed files with 3808 additions and 3043 deletions
@@ -7,6 +7,10 @@ import {
skipMedia,
stopMedia,
} from "../../../shared/api/client";
import { useAsyncAction } from "../../../shared/hooks/useAsyncAction.js";
import { createLogger } from "../../../shared/lib/logger.js";
const logger = createLogger("use-media-control");
const emptyMediaState: MediaState = {
playing: false,
@@ -17,8 +21,7 @@ const emptyMediaState: MediaState = {
export function useMediaControl() {
const [mediaState, setMediaState] = useState<MediaState>(emptyMediaState);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const { loading, error, execute, clearError } = useAsyncAction();
const refreshMedia = useCallback(async () => {
const state = await getMediaStatus();
@@ -28,71 +31,62 @@ export function useMediaControl() {
const enqueue = useCallback(
async (source: string, mode: "music" | "screen") => {
setLoading(true);
setError(null);
try {
const state = await queueMedia(source, mode);
setMediaState(state);
return state;
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
setError(message);
throw err;
} finally {
setLoading(false);
const result = await execute(() => queueMedia(source, mode));
if (result) {
setMediaState(result);
logger.info("Media queued", { source, mode });
} else {
logger.error("Failed to queue media", { source, mode });
}
return result;
},
[],
[execute],
);
const skip = useCallback(async () => {
setLoading(true);
setError(null);
try {
const state = await skipMedia();
setMediaState(state);
return state;
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
setError(message);
throw err;
} finally {
setLoading(false);
const result = await execute(() => skipMedia());
if (result) {
setMediaState(result);
logger.info("Media skipped");
} else {
logger.error("Failed to skip media");
}
}, []);
return result;
}, [execute]);
const stop = useCallback(async () => {
setLoading(true);
setError(null);
try {
const state = await stopMedia();
setMediaState(state);
return state;
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
setError(message);
throw err;
} finally {
setLoading(false);
const result = await execute(() => stopMedia());
if (result) {
setMediaState(result);
logger.info("Media stopped");
} else {
logger.error("Failed to stop media");
}
}, []);
return result;
}, [execute]);
const setVolume = useCallback(async (volume: number) => {
setError(null);
try {
const state = await setMediaVolume(volume);
setMediaState(state);
return state;
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
setError(message);
throw err;
}
}, []);
const setVolume = useCallback(
async (volume: number) => {
clearError();
try {
const state = await setMediaVolume(volume);
setMediaState(state);
logger.info("Volume set", { volume });
return state;
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
logger.error("Failed to set volume", { volume, error: message });
throw err;
}
},
[clearError],
);
useEffect(() => {
refreshMedia().catch((err) =>
setError(err instanceof Error ? err.message : String(err)),
logger.error("Failed to refresh media state on mount", {
error: String(err),
}),
);
}, [refreshMedia]);
@@ -8,6 +8,10 @@ import {
getVoiceChannels,
getVoiceStatus,
} from "../../../shared/api/client";
import { useAsyncAction } from "../../../shared/hooks/useAsyncAction.js";
import { createLogger } from "../../../shared/lib/logger.js";
const logger = createLogger("use-voice-control");
export function useVoiceControl() {
const [guilds, setGuilds] = useState<Guild[]>([]);
@@ -19,15 +23,14 @@ export function useVoiceControl() {
activeChannelId: null,
activeChannelName: null,
});
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const { loading, error, execute, clearError } = useAsyncAction();
const refreshGuilds = useCallback(async () => {
setError(null);
clearError();
const nextGuilds = await getGuilds();
setGuilds(nextGuilds);
return nextGuilds;
}, []);
}, [clearError]);
const refreshVoiceStatus = useCallback(async () => {
const status = await getVoiceStatus();
@@ -55,44 +58,39 @@ export function useVoiceControl() {
return channels;
}, []);
const joinVoice = useCallback(async (guildId: string, channelId: string) => {
setLoading(true);
setError(null);
try {
const status = await connectVoice(guildId, channelId);
setVoiceStatus(status);
return status;
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
setError(message);
throw err;
} finally {
setLoading(false);
}
}, []);
const joinVoice = useCallback(
async (guildId: string, channelId: string) => {
const result = await execute(() => connectVoice(guildId, channelId));
if (result) {
setVoiceStatus(result);
logger.info("Connected to voice", { guildId, channelId });
} else {
logger.error("Failed to connect to voice", { guildId, channelId });
}
return result;
},
[execute],
);
const leaveVoice = useCallback(async () => {
setLoading(true);
setError(null);
try {
const status = await disconnectVoice();
setVoiceStatus(status);
return status;
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
setError(message);
throw err;
} finally {
setLoading(false);
const result = await execute(() => disconnectVoice());
if (result) {
setVoiceStatus(result);
logger.info("Disconnected from voice");
} else {
logger.error("Failed to disconnect from voice");
}
}, []);
return result;
}, [execute]);
useEffect(() => {
refreshGuilds().catch((err) =>
setError(err instanceof Error ? err.message : String(err)),
logger.error("Failed to refresh guilds on mount", { error: String(err) }),
);
refreshVoiceStatus().catch((err) =>
setError(err instanceof Error ? err.message : String(err)),
logger.error("Failed to refresh voice status on mount", {
error: String(err),
}),
);
}, [refreshGuilds, refreshVoiceStatus]);