- Create withCommandErrorHandling utility in bot/lib/commandUtils.ts - Migrate economy commands: daily, exam, pay, trivia - Migrate inventory command: use - Migrate admin/moderation commands: warn, case, cases, clearwarning, warnings, note, notes, create_color, listing, webhook, refresh, terminal, featureflags, settings, prune - Add 9 unit tests for the utility - Update AGENTS.md with new recommended error handling pattern
73 lines
3.4 KiB
TypeScript
73 lines
3.4 KiB
TypeScript
import { createCommand } from "@shared/lib/utils";
|
|
import { SlashCommandBuilder } from "discord.js";
|
|
import { createErrorEmbed, createSuccessEmbed } from "@lib/embeds";
|
|
import { examService, ExamStatus } from "@shared/modules/economy/exam.service";
|
|
import { withCommandErrorHandling } from "@lib/commandUtils";
|
|
|
|
const DAYS = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
|
|
|
|
export const exam = createCommand({
|
|
data: new SlashCommandBuilder()
|
|
.setName("exam")
|
|
.setDescription("Take your weekly exam to earn rewards based on your XP progress."),
|
|
execute: async (interaction) => {
|
|
await withCommandErrorHandling(
|
|
interaction,
|
|
async () => {
|
|
// First, try to take the exam or check status
|
|
const result = await examService.takeExam(interaction.user.id);
|
|
|
|
if (result.status === ExamStatus.NOT_REGISTERED) {
|
|
// Register the user
|
|
const regResult = await examService.registerForExam(interaction.user.id, interaction.user.username);
|
|
const nextRegTimestamp = Math.floor(regResult.nextExamAt!.getTime() / 1000);
|
|
|
|
await interaction.editReply({
|
|
embeds: [createSuccessEmbed(
|
|
`You have registered for the exam! Your exam day is **${DAYS[regResult.examDay!]}** (Server Time).\n` +
|
|
`Come back on <t:${nextRegTimestamp}:D> (<t:${nextRegTimestamp}:R>) to take your first exam!`,
|
|
"Exam Registration Successful"
|
|
)]
|
|
});
|
|
return;
|
|
}
|
|
|
|
const nextExamTimestamp = Math.floor(result.nextExamAt!.getTime() / 1000);
|
|
|
|
if (result.status === ExamStatus.COOLDOWN) {
|
|
await interaction.editReply({
|
|
embeds: [createErrorEmbed(
|
|
`You have already taken your exam for this week (or are waiting for your first week to pass).\n` +
|
|
`Next exam available: <t:${nextExamTimestamp}:D> (<t:${nextExamTimestamp}:R>)`
|
|
)]
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (result.status === ExamStatus.MISSED) {
|
|
await interaction.editReply({
|
|
embeds: [createErrorEmbed(
|
|
`You missed your exam day! Your exam day is **${DAYS[result.examDay!]}** (Server Time).\n` +
|
|
`You verify your attendance but score a **0**.\n` +
|
|
`Your next exam opportunity is: <t:${nextExamTimestamp}:D> (<t:${nextExamTimestamp}:R>)`,
|
|
"Exam Failed"
|
|
)]
|
|
});
|
|
return;
|
|
}
|
|
|
|
// If it reached here with AVAILABLE, it means they passed
|
|
await interaction.editReply({
|
|
embeds: [createSuccessEmbed(
|
|
`**XP Gained:** ${result.xpDiff?.toString()}\n` +
|
|
`**Multiplier:** x${result.multiplier?.toFixed(2)}\n` +
|
|
`**Reward:** ${result.reward?.toString()} Currency\n\n` +
|
|
`See you next week: <t:${nextExamTimestamp}:D>`,
|
|
"Exam Passed!"
|
|
)]
|
|
});
|
|
}
|
|
);
|
|
}
|
|
});
|