Add stats, feeds, scheduler, and guild backup features to the bot

- Introduced new models in the Prisma schema for statistics, social feeds, scheduled messages, and guild backups, enhancing the bot's functionality.
- Implemented command modules for managing stats channels, feeds, scheduling messages, and creating/restoring backups, improving user engagement and server management.
- Updated job handling to include dedicated workers for stats updates, feed polling, scheduling, and backup restoration, enhancing automation.
- Enhanced command localization for new features in both German and English.
- Documented the new features and their setup processes in PHASE-TRACKING.md for clarity on implementation steps.
This commit is contained in:
smueller
2026-07-22 13:36:39 +02:00
parent 52b10c9536
commit 12066befa8
36 changed files with 4032 additions and 42 deletions

View File

@@ -44,6 +44,13 @@ model Guild {
birthdayConfig BirthdayConfig?
tempVoiceConfig TempVoiceConfig?
tempVoiceChannels TempVoiceChannel[]
statsConfig StatsConfig?
inviteStats InviteStat[]
inviteJoins InviteJoin[]
activityStats ActivityStat[]
socialFeeds SocialFeed[]
scheduledMessages ScheduledMessage[]
guildBackups GuildBackup[]
}
model GuildSettings {
@@ -639,3 +646,116 @@ model TempVoiceChannel {
@@index([guildId, ownerId])
}
model StatsConfig {
id String @id @default(cuid())
guildId String @unique
enabled Boolean @default(false)
membersChannelId String?
onlineChannelId String?
boostsChannelId String?
membersTemplate String @default("Members: {count}")
onlineTemplate String @default("Online: {count}")
boostsTemplate String @default("Boosts: {count}")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
}
model InviteStat {
id String @id @default(cuid())
guildId String
inviterId String
code String?
joins Int @default(0)
leaves Int @default(0)
fakes Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
@@unique([guildId, inviterId])
@@index([guildId, joins])
}
model InviteJoin {
id String @id @default(cuid())
guildId String
userId String
inviterId String?
code String?
isFake Boolean @default(false)
leftAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
@@unique([guildId, userId])
@@index([guildId, inviterId])
}
model ActivityStat {
id String @id @default(cuid())
guildId String
userId String
channelId String?
messageCount Int @default(0)
voiceMinutes Int @default(0)
day DateTime
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
@@unique([guildId, userId, channelId, day])
@@index([guildId, day])
}
model SocialFeed {
id String @id @default(cuid())
guildId String
type String
sourceId String
channelId String
rolePingId String?
template String?
lastItemId String?
enabled Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
@@index([guildId, type])
@@index([enabled])
}
model ScheduledMessage {
id String @id @default(cuid())
guildId String
channelId String
creatorId String
content String?
embed Json?
rolePingId String?
cron String?
runAt DateTime?
jobId String?
enabled Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
@@index([guildId, enabled])
}
model GuildBackup {
id String @id @default(cuid())
guildId String
name String
createdById String
payload Json
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
@@index([guildId, createdAt])
}