Skip to content

Commit 8a3cb32

Browse files
committed
DRY
1 parent 07f1c4d commit 8a3cb32

11 files changed

Lines changed: 548 additions & 731 deletions

File tree

Lines changed: 1 addition & 217 deletions
Original file line numberDiff line numberDiff line change
@@ -1,219 +1,3 @@
1-
import { MongoClient } from "mongodb";
2-
3-
// ===== CONSTANTS =====
4-
5-
const CONFIG = {
6-
COLLECTION_NAMES: {
7-
BANK: "bank",
8-
BANK_AUDIT_LOG: "bank_audit_log",
9-
BANK_SETTINGS: "bank_settings",
10-
},
11-
};
12-
13-
const ERROR_MESSAGES = {
14-
DATABASE_ERROR: "An error occurred while accessing the database.",
15-
};
16-
17-
// ===== DATABASE UTILITIES =====
18-
19-
async function connectToDatabase() {
20-
try {
21-
const client = new MongoClient(process.env.MONGODB_URI, {
22-
retryWrites: true,
23-
writeConcern: "majority",
24-
maxPoolSize: 10,
25-
minPoolSize: 2,
26-
maxIdleTimeMS: 30000,
27-
serverSelectionTimeoutMS: 5000,
28-
socketTimeoutMS: 45000,
29-
});
30-
31-
await client.connect();
32-
return client;
33-
} catch (error) {
34-
console.error("Failed to connect to MongoDB:", error);
35-
throw new Error("Database connection failed");
36-
}
37-
}
38-
39-
async function withDatabase(operation) {
40-
let client = null;
41-
try {
42-
client = await connectToDatabase();
43-
return await operation(client);
44-
} catch (error) {
45-
console.error("Database operation failed:", error);
46-
throw error;
47-
} finally {
48-
if (client) {
49-
try {
50-
await client.close();
51-
} catch (closeError) {
52-
console.error("Error closing database connection:", closeError);
53-
}
54-
}
55-
}
56-
}
57-
58-
// ===== BANK UTILITIES =====
59-
60-
async function migrateBankSettings(client, channel) {
61-
const settingsCollection = client.db().collection(CONFIG.COLLECTION_NAMES.BANK_SETTINGS);
62-
63-
// Check if settings already exist for this channel
64-
const existingSettings = await settingsCollection.findOne({ channel });
65-
if (existingSettings) {
66-
return; // Already migrated or settings exist
67-
}
68-
69-
// Migrate from old bank_fees collection
70-
try {
71-
const bankFeesCollection = client.db().collection("bank_fees");
72-
const oldFeeConfig = await bankFeesCollection.findOne({ channel, currencySystem: "dnd" });
73-
74-
// Migrate from old bank_decimal_currency_config collection
75-
const decimalConfigCollection = client.db().collection("bank_decimal_currency_config");
76-
const oldDecimalConfig = await decimalConfigCollection.findOne({ channel, currencySystem: "decimal" });
77-
78-
const newSettings = {
79-
channel,
80-
createdAt: new Date(),
81-
updatedAt: new Date(),
82-
};
83-
84-
// Add DND settings if they exist
85-
if (oldFeeConfig) {
86-
newSettings.currencySystem = "dnd";
87-
newSettings.dnd = {
88-
feeRate: oldFeeConfig.feeRate,
89-
updatedAt: oldFeeConfig.updatedAt,
90-
updatedBy: oldFeeConfig.updatedBy,
91-
};
92-
}
93-
94-
// Add decimal settings if they exist
95-
if (oldDecimalConfig) {
96-
newSettings.currencySystem = oldDecimalConfig.currencySystem;
97-
newSettings.decimal = {
98-
prefix: oldDecimalConfig.prefix,
99-
suffix: oldDecimalConfig.suffix,
100-
prefixSpaceAfter: oldDecimalConfig.prefixSpaceAfter,
101-
suffixSpaceBefore: oldDecimalConfig.suffixSpaceBefore,
102-
updatedAt: oldDecimalConfig.updatedAt,
103-
updatedBy: oldDecimalConfig.updatedBy,
104-
};
105-
}
106-
107-
// Insert the new settings document if there's anything to migrate
108-
if (oldFeeConfig || oldDecimalConfig) {
109-
await settingsCollection.insertOne(newSettings);
110-
}
111-
} catch (error) {
112-
console.error("Error during bank settings migration:", error);
113-
// Don't throw error, migration failure shouldn't block operations
114-
}
115-
}
116-
117-
async function getDecimalCurrencyFormat(client, channel) {
118-
const settingsCollection = client.db().collection(CONFIG.COLLECTION_NAMES.BANK_SETTINGS);
119-
120-
// First, migrate any existing config documents from old collections
121-
await migrateBankSettings(client, channel);
122-
123-
const settings = await settingsCollection.findOne({ channel, currencySystem: "decimal" });
124-
return {
125-
prefix: settings?.decimal?.prefix || "$",
126-
suffix: settings?.decimal?.suffix || "",
127-
prefixSpaceAfter: settings?.decimal?.prefixSpaceAfter || false,
128-
suffixSpaceBefore: settings?.decimal?.suffixSpaceBefore !== undefined ? settings.decimal.suffixSpaceBefore : true
129-
};
130-
}
131-
132-
function formatDecimalCurrency(amount, prefix = "$", suffix = "", prefixSpaceAfter = false, suffixSpaceBefore = true) {
133-
const formattedAmount = amount.toFixed(2);
134-
const prefixPart = prefix + (prefixSpaceAfter && prefix ? " " : "");
135-
const suffixPart = (suffixSpaceBefore && suffix ? " " : "") + suffix;
136-
return `${prefixPart}${formattedAmount}${suffixPart}`;
137-
}
138-
139-
async function recordDecimalBankAuditLog(client, channel, action, userId, username, details = {}) {
140-
try {
141-
const auditCollection = client.db().collection(CONFIG.COLLECTION_NAMES.BANK_AUDIT_LOG);
142-
143-
const logEntry = {
144-
channel,
145-
action,
146-
userId,
147-
username,
148-
currencySystem: "decimal",
149-
timestamp: new Date(),
150-
details,
151-
};
152-
153-
await auditCollection.insertOne(logEntry);
154-
} catch (error) {
155-
console.error("Failed to record decimal bank audit log:", error);
156-
}
157-
}
158-
159-
// ===== COMMAND HANDLER =====
160-
161-
/**
162-
* Handles decimal bank deposit subcommand
163-
* @param {ChatInputCommandInteraction} interaction - Discord interaction
164-
*/
165-
async function handleDecimalBankDeposit(interaction) {
166-
try {
167-
const amount = parseFloat(interaction.options.getNumber("amount"));
168-
169-
if (amount <= 0) {
170-
await interaction.editReply("Amount must be greater than 0.");
171-
return;
172-
}
173-
174-
await withDatabase(async (client) => {
175-
const collection = client.db().collection(CONFIG.COLLECTION_NAMES.BANK);
176-
const format = await getDecimalCurrencyFormat(client, interaction.channel.id);
177-
178-
const updateResult = await collection.findOneAndUpdate(
179-
{ channel: interaction.channel.id, currency: "decimal", currencySystem: "decimal" },
180-
{
181-
$inc: { amount },
182-
$setOnInsert: {
183-
channel: interaction.channel.id,
184-
currency: "decimal",
185-
currencySystem: "decimal",
186-
createdAt: new Date(),
187-
},
188-
$set: { updatedAt: new Date() },
189-
},
190-
{ upsert: true, returnDocument: "after" }
191-
);
192-
193-
const oldAmount = updateResult.amount - amount;
194-
195-
// Record audit log
196-
await recordDecimalBankAuditLog(
197-
client,
198-
interaction.channel.id,
199-
"deposit",
200-
interaction.user.id,
201-
interaction.user.username,
202-
{
203-
amount,
204-
oldAmount,
205-
newAmount: updateResult.amount,
206-
}
207-
);
208-
209-
await interaction.editReply(
210-
`Deposited ${formatDecimalCurrency(amount, format.prefix, format.suffix, format.prefixSpaceAfter, format.suffixSpaceBefore)}. Balance: ${formatDecimalCurrency(oldAmount, format.prefix, format.suffix, format.prefixSpaceAfter, format.suffixSpaceBefore)}${formatDecimalCurrency(updateResult.amount, format.prefix, format.suffix, format.prefixSpaceAfter, format.suffixSpaceBefore)}.`
211-
);
212-
});
213-
} catch (error) {
214-
console.error("Error in decimal bank deposit:", error);
215-
await interaction.editReply(ERROR_MESSAGES.DATABASE_ERROR);
216-
}
217-
}
1+
import { handleDecimalBankDeposit } from '../shared/decimalOperations.js';
2182

2193
export { handleDecimalBankDeposit };

0 commit comments

Comments
 (0)