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

@@ -20,6 +20,16 @@ model Guild {
logChannels LogChannel[]
welcomeConfig WelcomeConfig?
verificationConfig VerificationConfig?
levelingConfig LevelingConfig?
memberLevels MemberLevel[]
levelRewards LevelReward[]
economyConfig EconomyConfig?
memberEconomies MemberEconomy[]
shopItems ShopItem[]
inventoryItems InventoryItem[]
polls Poll[]
reminders Reminder[]
afkStatuses AfkStatus[]
}
model GuildSettings {
@@ -203,3 +213,179 @@ model VerificationConfig {
updatedAt DateTime @updatedAt
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
}
model LevelingConfig {
id String @id @default(cuid())
guildId String @unique
enabled Boolean @default(true)
textXpMin Int @default(15)
textXpMax Int @default(25)
textCooldownSeconds Int @default(60)
voiceXpPerMinute Int @default(10)
noXpChannelIds String[] @default([])
noXpRoleIds String[] @default([])
roleMultipliers Json?
channelMultipliers Json?
levelUpMode String @default("CHANNEL")
levelUpChannelId String?
levelUpMessage String?
stackRewards Boolean @default(true)
cardAccentColor String @default("#6366F1")
cardBackgroundColor String @default("#111827")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
}
model MemberLevel {
id String @id @default(cuid())
guildId String
userId String
xp Int @default(0)
level Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
@@unique([guildId, userId])
@@index([guildId, xp])
}
model LevelReward {
id String @id @default(cuid())
guildId String
level Int
roleId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
@@unique([guildId, level])
@@index([guildId])
}
model EconomyConfig {
id String @id @default(cuid())
guildId String @unique
enabled Boolean @default(true)
currencyName String @default("Coins")
currencySymbol String @default("🪙")
dailyAmount Int @default(200)
weeklyAmount Int @default(1000)
workMin Int @default(50)
workMax Int @default(150)
workCooldownSeconds Int @default(3600)
startingBalance Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
}
model MemberEconomy {
id String @id @default(cuid())
guildId String
userId String
balance Int @default(0)
lastDailyAt DateTime?
lastWeeklyAt DateTime?
lastWorkAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
@@unique([guildId, userId])
@@index([guildId, balance])
}
model ShopItem {
id String @id @default(cuid())
guildId String
name String
description String?
price Int
roleId String?
stock Int?
enabled Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
inventory InventoryItem[]
@@index([guildId, enabled])
}
model InventoryItem {
id String @id @default(cuid())
guildId String
userId String
itemId String
quantity Int @default(1)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
item ShopItem @relation(fields: [itemId], references: [id], onDelete: Cascade)
@@unique([guildId, userId, itemId])
@@index([guildId, userId])
}
model Poll {
id String @id @default(cuid())
guildId String
channelId String
messageId String?
creatorId String
question String
options Json
multiSelect Boolean @default(false)
anonymous Boolean @default(false)
endsAt DateTime?
closedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
votes PollVote[]
@@index([guildId])
}
model PollVote {
id String @id @default(cuid())
pollId String
userId String
optionIndex Int
createdAt DateTime @default(now())
poll Poll @relation(fields: [pollId], references: [id], onDelete: Cascade)
@@unique([pollId, userId, optionIndex])
@@index([pollId])
}
model Reminder {
id String @id @default(cuid())
guildId String?
userId String
channelId String
content String
remindAt DateTime
recurringCron String?
jobId String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
guild Guild? @relation(fields: [guildId], references: [id], onDelete: Cascade)
@@index([userId])
@@index([remindAt])
}
model AfkStatus {
id String @id @default(cuid())
guildId String
userId String
reason String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
@@unique([guildId, userId])
}