refactor: convert TradeService to object export pattern

Convert from class-based to object-based export for consistency with
other services (economy, inventory, quest, etc).

Changes:
- Move sessions Map and helper functions to module scope
- Convert static methods to object properties
- Update executeTrade to use withTransaction helper
- Update all imports from TradeService to tradeService

Updated files:
- trade.service.ts (main refactor)
- trade.interaction.ts (update usages)
- trade.ts command (update import and usage)

All tests passing with no breaking changes.
This commit is contained in:
syntaxbullet
2025-12-24 21:57:30 +01:00
parent 77d3fafdce
commit 2933eaeafc
3 changed files with 110 additions and 103 deletions

View File

@@ -7,7 +7,7 @@ import {
TextChannel,
EmbedBuilder
} from "discord.js";
import { TradeService } from "./trade.service";
import { tradeService } from "./trade.service";
import { inventoryService } from "@/modules/inventory/inventory.service";
import { createErrorEmbed, createWarningEmbed, createSuccessEmbed, createInfoEmbed } from "@lib/embeds";
import { getTradeDashboard, getTradeMoneyModal, getItemSelectMenu, getTradeCompletedEmbed } from "./trade.view";
@@ -55,10 +55,10 @@ export async function handleTradeInteraction(interaction: Interaction) {
}
async function handleCancel(interaction: ButtonInteraction | StringSelectMenuInteraction | ModalSubmitInteraction, threadId: string) {
const session = TradeService.getSession(threadId);
const session = tradeService.getSession(threadId);
const user = interaction.user;
TradeService.endSession(threadId);
tradeService.endSession(threadId);
await interaction.deferUpdate();
@@ -70,11 +70,11 @@ async function handleCancel(interaction: ButtonInteraction | StringSelectMenuInt
async function handleLock(interaction: ButtonInteraction | StringSelectMenuInteraction | ModalSubmitInteraction, threadId: string) {
await interaction.deferUpdate();
const isLocked = TradeService.toggleLock(threadId, interaction.user.id);
const isLocked = tradeService.toggleLock(threadId, interaction.user.id);
await updateTradeDashboard(interaction, threadId);
// Check if trade executed (both locked)
const session = TradeService.getSession(threadId);
const session = tradeService.getSession(threadId);
if (session && session.state === 'COMPLETED') {
// Trade executed during updateTradeDashboard
return;
@@ -95,7 +95,7 @@ async function handleMoneySubmit(interaction: ModalSubmitInteraction, threadId:
if (amount < 0n) throw new Error("Amount must be positive");
TradeService.updateMoney(threadId, interaction.user.id, amount);
tradeService.updateMoney(threadId, interaction.user.id, amount);
await interaction.deferUpdate(); // Acknowledge modal
await updateTradeDashboard(interaction, threadId);
}
@@ -128,14 +128,14 @@ async function handleItemSelect(interaction: StringSelectMenuInteraction, thread
const item = await inventoryService.getItem(itemId);
if (!item) throw new Error("Item not found");
TradeService.addItem(threadId, interaction.user.id, { id: item.id, name: item.name }, 1n);
tradeService.addItem(threadId, interaction.user.id, { id: item.id, name: item.name }, 1n);
await interaction.update({ content: `Added ${item.name} x1`, components: [] });
await updateTradeDashboard(interaction, threadId);
}
async function handleRemoveItemClick(interaction: ButtonInteraction, threadId: string) {
const session = TradeService.getSession(threadId);
const session = tradeService.getSession(threadId);
if (!session) return;
const participant = session.userA.id === interaction.user.id ? session.userA : session.userB;
@@ -158,7 +158,7 @@ async function handleRemoveItemSelect(interaction: StringSelectMenuInteraction,
const value = interaction.values[0];
if (!value) return;
const itemId = parseInt(value);
TradeService.removeItem(threadId, interaction.user.id, itemId);
tradeService.removeItem(threadId, interaction.user.id, itemId);
await interaction.update({ content: `Removed item.`, components: [] });
await updateTradeDashboard(interaction, threadId);
@@ -168,14 +168,14 @@ async function handleRemoveItemSelect(interaction: StringSelectMenuInteraction,
// --- DASHBOARD UPDATER ---
export async function updateTradeDashboard(interaction: Interaction, threadId: string) {
const session = TradeService.getSession(threadId);
const session = tradeService.getSession(threadId);
if (!session) return;
// Check Auto-Execute (If both locked)
if (session.userA.locked && session.userB.locked) {
// Execute Trade
try {
await TradeService.executeTrade(threadId);
await tradeService.executeTrade(threadId);
const embed = getTradeCompletedEmbed(session);
await updateDashboardMessage(interaction, { embeds: [embed], components: [] });