Implement leveling and economy features with associated models and commands

- Added new models for leveling and economy functionalities in the Prisma schema, including LevelingConfig, MemberLevel, LevelReward, EconomyConfig, MemberEconomy, ShopItem, and InventoryItem.
- Introduced commands for managing XP, economy transactions, and shop interactions, enhancing user engagement.
- Updated job handling to include reminders and poll closing functionalities.
- Enhanced localization support for new commands and features in both German and English.
- Improved the bot's job processing capabilities with a dedicated reminder worker for scheduled tasks.
This commit is contained in:
smueller
2026-07-22 12:49:17 +02:00
parent 2518119257
commit fa5910ec43
38 changed files with 6759 additions and 144 deletions

View File

@@ -0,0 +1,121 @@
import {
SlashCommandBuilder,
type SlashCommandIntegerOption,
type SlashCommandStringOption,
type SlashCommandUserOption
} from 'discord.js';
import {
applyCommandDescription,
applyOptionDescription,
localizedChoice,
type CommandLocaleKey
} from '@nexumi/shared';
function amountOpt(o: SlashCommandIntegerOption, key: CommandLocaleKey = 'economy.common.options.amount') {
return applyOptionDescription(o.setName('amount').setRequired(true).setMinValue(1), key);
}
function userOpt(o: SlashCommandUserOption, key: CommandLocaleKey = 'economy.common.options.user') {
return applyOptionDescription(o.setName('user').setRequired(true), key);
}
function optionalUserOpt(o: SlashCommandUserOption) {
return applyOptionDescription(o.setName('user'), 'economy.common.options.userOptional');
}
function choiceOpt(o: SlashCommandStringOption) {
return applyOptionDescription(o.setName('choice').setRequired(true), 'economy.coinflip.options.choice').addChoices(
localizedChoice('economy.choice.heads', 'heads'),
localizedChoice('economy.choice.tails', 'tails')
);
}
export const balanceCommandData = applyCommandDescription(
new SlashCommandBuilder().setName('balance'),
'economy.balance.description'
).addUserOption((o) => optionalUserOpt(o));
export const dailyCommandData = applyCommandDescription(
new SlashCommandBuilder().setName('daily'),
'economy.daily.description'
);
export const weeklyCommandData = applyCommandDescription(
new SlashCommandBuilder().setName('weekly'),
'economy.weekly.description'
);
export const workCommandData = applyCommandDescription(
new SlashCommandBuilder().setName('work'),
'economy.work.description'
);
export const payCommandData = applyCommandDescription(
new SlashCommandBuilder().setName('pay'),
'economy.pay.description'
)
.addUserOption((o) => userOpt(o))
.addIntegerOption((o) => amountOpt(o));
export const gambleCommandData = applyCommandDescription(
new SlashCommandBuilder().setName('gamble'),
'economy.gamble.description'
).addIntegerOption((o) => amountOpt(o));
export const slotsCommandData = applyCommandDescription(
new SlashCommandBuilder().setName('slots'),
'economy.slots.description'
).addIntegerOption((o) => amountOpt(o));
export const blackjackCommandData = applyCommandDescription(
new SlashCommandBuilder().setName('blackjack'),
'economy.blackjack.description'
).addIntegerOption((o) => amountOpt(o));
export const coinflipCommandData = applyCommandDescription(
new SlashCommandBuilder().setName('coinflip'),
'economy.coinflip.description'
)
.addIntegerOption((o) => amountOpt(o))
.addStringOption((o) => choiceOpt(o));
export const shopCommandData = applyCommandDescription(
new SlashCommandBuilder().setName('shop'),
'economy.shop.description'
)
.addSubcommand((s) =>
applyCommandDescription(s.setName('view'), 'economy.shop.view.description')
)
.addSubcommand((s) =>
applyCommandDescription(s.setName('buy'), 'economy.shop.buy.description').addStringOption((o) =>
applyOptionDescription(o.setName('item_id').setRequired(true), 'economy.shop.options.item_id')
)
);
export const inventoryCommandData = applyCommandDescription(
new SlashCommandBuilder().setName('inventory'),
'economy.inventory.description'
);
export const ecoCommandData = applyCommandDescription(
new SlashCommandBuilder().setName('eco'),
'economy.eco.description'
)
.addSubcommand((s) =>
applyCommandDescription(s.setName('leaderboard'), 'economy.eco.leaderboard.description')
)
.addSubcommand((s) =>
applyCommandDescription(s.setName('give'), 'economy.eco.give.description')
.addUserOption((o) => userOpt(o, 'economy.common.options.target'))
.addIntegerOption((o) => amountOpt(o))
)
.addSubcommand((s) =>
applyCommandDescription(s.setName('remove'), 'economy.eco.remove.description')
.addUserOption((o) => userOpt(o, 'economy.common.options.target'))
.addIntegerOption((o) => amountOpt(o))
)
.addSubcommand((s) =>
applyCommandDescription(s.setName('reset'), 'economy.eco.reset.description').addUserOption((o) =>
userOpt(o, 'economy.common.options.target')
)
);