refactor: migrate all code to use getGuildConfig() for guild settings

- Update all commands and events to fetch guild config once per execution
- Pass config to service methods that need it (ModerationService.issueWarning)
- Update terminal service to use guildSettingsService for persistence
- Remove direct imports of config for guild-specific settings

This consolidates configuration to database-backed guild settings,
eliminating the dual config system.
This commit is contained in:
syntaxbullet
2026-02-12 16:09:37 +01:00
parent ae6a068197
commit 58374d1746
11 changed files with 110 additions and 54 deletions

View File

@@ -116,7 +116,7 @@ class LootdropService {
});
// Trigger Terminal Update
terminalService.update();
terminalService.update(channel.guildId);
} catch (error) {
console.error("Failed to spawn lootdrop:", error);
@@ -153,7 +153,7 @@ class LootdropService {
`Claimed lootdrop in channel ${drop.channelId}`
);
// Trigger Terminal Update
// Trigger Terminal Update (uses primary guild from env)
terminalService.update();
return { success: true, amount: drop.rewardAmount, currency: drop.currency };

View File

@@ -2,10 +2,14 @@ import { moderationCases } from "@db/schema";
import { eq, and, desc } from "drizzle-orm";
import { DrizzleClient } from "@shared/db/DrizzleClient";
import type { CreateCaseOptions, ClearCaseOptions, SearchCasesFilter } from "@/modules/moderation/moderation.types";
import { config } from "@shared/lib/config";
import { getUserWarningEmbed } from "@/modules/moderation/moderation.view";
import { CaseType } from "@shared/lib/constants";
export interface ModerationConfig {
dmOnWarn?: boolean;
autoTimeoutThreshold?: number;
}
export class ModerationService {
/**
* Generate the next sequential case ID
@@ -62,6 +66,7 @@ export class ModerationService {
guildName?: string;
dmTarget?: { send: (options: any) => Promise<any> };
timeoutTarget?: { timeout: (duration: number, reason: string) => Promise<any> };
config?: ModerationConfig;
}) {
const moderationCase = await this.createCase({
type: CaseType.WARN,
@@ -77,9 +82,10 @@ export class ModerationService {
}
const warningCount = await this.getActiveWarningCount(options.userId);
const config = options.config ?? {};
// Try to DM the user if configured
if (config.moderation.cases.dmOnWarn && options.dmTarget) {
if (config.dmOnWarn !== false && options.dmTarget) {
try {
await options.dmTarget.send({
embeds: [getUserWarningEmbed(
@@ -96,8 +102,8 @@ export class ModerationService {
// Check for auto-timeout threshold
let autoTimeoutIssued = false;
if (config.moderation.cases.autoTimeoutThreshold &&
warningCount >= config.moderation.cases.autoTimeoutThreshold &&
if (config.autoTimeoutThreshold &&
warningCount >= config.autoTimeoutThreshold &&
options.timeoutTarget) {
try {

View File

@@ -12,24 +12,36 @@ import { AuroraClient } from "@/lib/BotClient";
import { DrizzleClient } from "@shared/db/DrizzleClient";
import { users, transactions, lootdrops, inventory } from "@db/schema";
import { desc, sql } from "drizzle-orm";
import { config, saveConfig } from "@shared/lib/config";
import { getGuildConfig, invalidateGuildConfigCache } from "@shared/lib/config";
import { guildSettingsService } from "@shared/modules/guild-settings/guild-settings.service";
import { env } from "@shared/lib/env";
// Color palette for containers (hex as decimal)
const COLORS = {
HEADER: 0x9B59B6, // Purple - mystical
LEADERS: 0xF1C40F, // Gold - achievement
ACTIVITY: 0x3498DB, // Blue - activity
ALERT: 0xE74C3C // Red - active events
HEADER: 0x9B59B6,
LEADERS: 0xF1C40F,
ACTIVITY: 0x3498DB,
ALERT: 0xE74C3C
};
function getPrimaryGuildId(): string | null {
return env.DISCORD_GUILD_ID ?? null;
}
export const terminalService = {
init: async (channel: TextChannel) => {
// Limit to one terminal for now
if (config.terminal) {
const guildId = channel.guildId;
if (!guildId) {
console.error("Cannot initialize terminal: no guild ID");
return;
}
// Clean up old terminal if exists
const currentConfig = await getGuildConfig(guildId);
if (currentConfig.terminal?.channelId && currentConfig.terminal?.messageId) {
try {
const oldChannel = await AuroraClient.channels.fetch(config.terminal.channelId) as TextChannel;
const oldChannel = await AuroraClient.channels.fetch(currentConfig.terminal.channelId).catch(() => null) as TextChannel | null;
if (oldChannel) {
const oldMsg = await oldChannel.messages.fetch(config.terminal.messageId);
const oldMsg = await oldChannel.messages.fetch(currentConfig.terminal.messageId).catch(() => null);
if (oldMsg) await oldMsg.delete();
}
} catch (e) {
@@ -39,25 +51,37 @@ export const terminalService = {
const msg = await channel.send({ content: "🔄 Initializing Aurora Station..." });
config.terminal = {
channelId: channel.id,
messageId: msg.id
};
saveConfig(config);
// Save to database
await guildSettingsService.upsertSettings({
guildId,
terminalChannelId: channel.id,
terminalMessageId: msg.id,
});
invalidateGuildConfigCache(guildId);
await terminalService.update();
await terminalService.update(guildId);
},
update: async () => {
if (!config.terminal) return;
update: async (guildId?: string) => {
const effectiveGuildId = guildId ?? getPrimaryGuildId();
if (!effectiveGuildId) {
console.warn("No guild ID available for terminal update");
return;
}
const guildConfig = await getGuildConfig(effectiveGuildId);
if (!guildConfig.terminal?.channelId || !guildConfig.terminal?.messageId) {
return;
}
try {
const channel = await AuroraClient.channels.fetch(config.terminal.channelId).catch(() => null) as TextChannel;
const channel = await AuroraClient.channels.fetch(guildConfig.terminal.channelId).catch(() => null) as TextChannel | null;
if (!channel) {
console.warn("Terminal channel not found");
return;
}
const message = await channel.messages.fetch(config.terminal.messageId).catch(() => null);
const message = await channel.messages.fetch(guildConfig.terminal.messageId).catch(() => null);
if (!message) {
console.warn("Terminal message not found");
return;