- Introduced global command channel whitelist and blacklist in the GuildSettings model for improved command access control. - Implemented command gate logic in the command routing to handle channel and role restrictions, providing user feedback for denied commands. - Enhanced the CommandsManager component to support global rules and channel/role selection, improving the user interface for managing command permissions. - Updated localization files to include new keys for global command rules and related messages, ensuring clarity in user interactions.
939 lines
28 KiB
Plaintext
939 lines
28 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
model Guild {
|
|
id String @id
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
settings GuildSettings?
|
|
cases Case[]
|
|
escalationRules EscalationRule[]
|
|
autoModConfig AutoModConfig?
|
|
autoModRules AutoModRule[]
|
|
loggingConfig LoggingConfig?
|
|
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[]
|
|
giveaways Giveaway[]
|
|
ticketConfig TicketConfig?
|
|
ticketCategories TicketCategory[]
|
|
tickets Ticket[]
|
|
selfRolePanels SelfRolePanel[]
|
|
tags Tag[]
|
|
starboardConfig StarboardConfig?
|
|
starboardEntries StarboardEntry[]
|
|
suggestionConfig SuggestionConfig?
|
|
suggestions Suggestion[]
|
|
birthdays Birthday[]
|
|
birthdayConfig BirthdayConfig?
|
|
tempVoiceConfig TempVoiceConfig?
|
|
tempVoiceChannels TempVoiceChannel[]
|
|
statsConfig StatsConfig?
|
|
inviteStats InviteStat[]
|
|
inviteJoins InviteJoin[]
|
|
activityStats ActivityStat[]
|
|
socialFeeds SocialFeed[]
|
|
scheduledMessages ScheduledMessage[]
|
|
guildBackups GuildBackup[]
|
|
dashboardAccessRules DashboardAccessRule[]
|
|
dashboardAuditLogs DashboardAuditLog[]
|
|
commandOverrides CommandOverride[]
|
|
}
|
|
|
|
model GuildSettings {
|
|
id String @id @default(cuid())
|
|
guildId String @unique
|
|
locale String @default("de")
|
|
timezone String @default("Europe/Berlin")
|
|
moderationEnabled Boolean @default(true)
|
|
/// Snipe/editsnipe storage and commands (SPEC: default off for privacy).
|
|
snipeEnabled Boolean @default(false)
|
|
/// Global command channel whitelist (empty = all channels unless denied).
|
|
commandAllowedChannelIds String[] @default([])
|
|
/// Global command channel blacklist.
|
|
commandDeniedChannelIds String[] @default([])
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
}
|
|
|
|
model DashboardAccessRule {
|
|
id String @id @default(cuid())
|
|
guildId String
|
|
roleId String
|
|
modules Json
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([guildId, roleId])
|
|
@@index([guildId])
|
|
}
|
|
|
|
model DashboardAuditLog {
|
|
id String @id @default(cuid())
|
|
guildId String?
|
|
actorUserId String
|
|
action String
|
|
path String?
|
|
before Json?
|
|
after Json?
|
|
createdAt DateTime @default(now())
|
|
guild Guild? @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([guildId, createdAt])
|
|
@@index([actorUserId, createdAt])
|
|
}
|
|
|
|
model User {
|
|
id String @id
|
|
createdAt DateTime @default(now())
|
|
warnings Warning[]
|
|
notes ModNote[]
|
|
}
|
|
|
|
model Case {
|
|
id String @id @default(cuid())
|
|
caseNumber Int
|
|
guildId String
|
|
targetUserId String
|
|
moderatorId String
|
|
action String
|
|
reason String?
|
|
metadata Json?
|
|
deletedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
warnings Warning[]
|
|
moderationNote ModNote[]
|
|
|
|
@@unique([guildId, caseNumber])
|
|
@@index([guildId, targetUserId])
|
|
}
|
|
|
|
model Warning {
|
|
id String @id @default(cuid())
|
|
guildId String
|
|
userId String
|
|
moderatorId String
|
|
reason String?
|
|
caseId String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
case Case? @relation(fields: [caseId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([guildId, userId])
|
|
}
|
|
|
|
model ModNote {
|
|
id String @id @default(cuid())
|
|
guildId String
|
|
userId String
|
|
moderatorId String
|
|
note String
|
|
caseId String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
case Case? @relation(fields: [caseId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([guildId, userId])
|
|
}
|
|
|
|
model EscalationRule {
|
|
id String @id @default(cuid())
|
|
guildId String
|
|
warnCount Int
|
|
action String
|
|
durationMs Int?
|
|
reason String?
|
|
enabled Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([guildId, warnCount])
|
|
@@index([guildId, enabled])
|
|
}
|
|
|
|
model AutoModConfig {
|
|
id String @id @default(cuid())
|
|
guildId String @unique
|
|
enabled Boolean @default(true)
|
|
antiRaidEnabled Boolean @default(false)
|
|
antiRaidJoinThreshold Int @default(10)
|
|
antiRaidWindowSeconds Int @default(10)
|
|
antiRaidAction String @default("LOCKDOWN")
|
|
antiNukeEnabled Boolean @default(false)
|
|
antiNukeBanThreshold Int @default(5)
|
|
antiNukeChannelThreshold Int @default(3)
|
|
antiNukeWindowSeconds Int @default(60)
|
|
lockdownActive Boolean @default(false)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
}
|
|
|
|
model AutoModRule {
|
|
id String @id @default(cuid())
|
|
guildId String
|
|
ruleType String
|
|
enabled Boolean @default(true)
|
|
action String @default("DELETE")
|
|
threshold Json?
|
|
exceptions Json?
|
|
wordList Json?
|
|
durationMs Int?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([guildId, ruleType])
|
|
@@index([guildId, enabled])
|
|
}
|
|
|
|
model LoggingConfig {
|
|
id String @id @default(cuid())
|
|
guildId String @unique
|
|
enabled Boolean @default(true)
|
|
ignoreBots Boolean @default(true)
|
|
ignoredChannelIds String[] @default([])
|
|
ignoredRoleIds String[] @default([])
|
|
/// Days to keep Case / dashboard audit rows; 0 = keep forever.
|
|
retentionDays Int @default(90)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
}
|
|
|
|
model LogChannel {
|
|
id String @id @default(cuid())
|
|
guildId String
|
|
eventType String
|
|
channelId String
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([guildId, eventType])
|
|
@@index([guildId])
|
|
}
|
|
|
|
model WelcomeConfig {
|
|
id String @id @default(cuid())
|
|
guildId String @unique
|
|
welcomeEnabled Boolean @default(false)
|
|
leaveEnabled Boolean @default(false)
|
|
welcomeChannelId String?
|
|
leaveChannelId String?
|
|
welcomeType String @default("TEXT")
|
|
welcomeContent String?
|
|
welcomeEmbed Json?
|
|
leaveContent String?
|
|
leaveEmbed Json?
|
|
welcomeDmEnabled Boolean @default(false)
|
|
welcomeDmContent String?
|
|
userAutoroleIds String[] @default([])
|
|
botAutoroleIds String[] @default([])
|
|
imageTitle String?
|
|
imageSubtitle String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
}
|
|
|
|
model VerificationConfig {
|
|
id String @id @default(cuid())
|
|
guildId String @unique
|
|
enabled Boolean @default(false)
|
|
channelId String?
|
|
verifiedRoleId String?
|
|
unverifiedRoleId String?
|
|
mode String @default("BUTTON")
|
|
minAccountAgeDays Int @default(0)
|
|
failAction String @default("KICK")
|
|
panelChannelId String?
|
|
panelMessageId String?
|
|
createdAt DateTime @default(now())
|
|
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])
|
|
}
|
|
|
|
model Giveaway {
|
|
id String @id @default(cuid())
|
|
guildId String
|
|
channelId String
|
|
messageId String?
|
|
prize String
|
|
winnerCount Int @default(1)
|
|
endsAt DateTime
|
|
requiredRoleId String?
|
|
requiredLevel Int?
|
|
requiredMemberDays Int?
|
|
paused Boolean @default(false)
|
|
endedAt DateTime?
|
|
winners String[] @default([])
|
|
entrants String[] @default([])
|
|
hostId String
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([guildId, endsAt])
|
|
}
|
|
|
|
model TicketConfig {
|
|
id String @id @default(cuid())
|
|
guildId String @unique
|
|
enabled Boolean @default(true)
|
|
mode String @default("CHANNEL")
|
|
categoryId String?
|
|
logChannelId String?
|
|
transcriptDm Boolean @default(false)
|
|
inactivityHours Int @default(72)
|
|
ratingEnabled Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
}
|
|
|
|
model TicketCategory {
|
|
id String @id @default(cuid())
|
|
guildId String
|
|
name String
|
|
description String?
|
|
emoji String?
|
|
supportRoleIds String[] @default([])
|
|
formFields Json?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
tickets Ticket[]
|
|
|
|
@@unique([guildId, name])
|
|
@@index([guildId])
|
|
}
|
|
|
|
model Ticket {
|
|
id String @id @default(cuid())
|
|
guildId String
|
|
categoryId String?
|
|
openerId String
|
|
claimedById String?
|
|
channelId String?
|
|
threadId String?
|
|
status String @default("OPEN")
|
|
priority String @default("NORMAL")
|
|
subject String?
|
|
formAnswers Json?
|
|
transcriptHtml String?
|
|
rating Int?
|
|
closedAt DateTime?
|
|
lastActivityAt DateTime @default(now())
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
category TicketCategory? @relation(fields: [categoryId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([guildId, status])
|
|
@@index([channelId])
|
|
}
|
|
|
|
model SelfRolePanel {
|
|
id String @id @default(cuid())
|
|
guildId String
|
|
channelId String
|
|
messageId String?
|
|
title String
|
|
description String?
|
|
mode String @default("BUTTONS")
|
|
behavior String @default("NORMAL")
|
|
roles Json
|
|
expiresAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([guildId])
|
|
}
|
|
|
|
model Tag {
|
|
id String @id @default(cuid())
|
|
guildId String
|
|
name String
|
|
content String?
|
|
embed Json?
|
|
responseType String @default("TEXT")
|
|
triggerWord String?
|
|
allowedRoleIds String[] @default([])
|
|
allowedChannelIds String[] @default([])
|
|
createdById String
|
|
useCount Int @default(0)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([guildId, name])
|
|
@@index([guildId])
|
|
}
|
|
|
|
model StarboardConfig {
|
|
id String @id @default(cuid())
|
|
guildId String @unique
|
|
enabled Boolean @default(false)
|
|
channelId String?
|
|
emoji String @default("⭐")
|
|
threshold Int @default(3)
|
|
allowSelfStar Boolean @default(false)
|
|
ignoredChannelIds String[] @default([])
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
}
|
|
|
|
model StarboardEntry {
|
|
id String @id @default(cuid())
|
|
guildId String
|
|
sourceChannelId String
|
|
sourceMessageId String
|
|
starboardMessageId String
|
|
starCount Int @default(0)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([guildId, sourceMessageId])
|
|
@@index([guildId])
|
|
}
|
|
|
|
model SuggestionConfig {
|
|
id String @id @default(cuid())
|
|
guildId String @unique
|
|
enabled Boolean @default(true)
|
|
openChannelId String?
|
|
approvedChannelId String?
|
|
deniedChannelId String?
|
|
createThread Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
}
|
|
|
|
model Suggestion {
|
|
id String @id @default(cuid())
|
|
guildId String
|
|
authorId String
|
|
content String
|
|
status String @default("OPEN")
|
|
messageId String?
|
|
channelId String?
|
|
threadId String?
|
|
upvotes Int @default(0)
|
|
downvotes Int @default(0)
|
|
voterUpIds String[] @default([])
|
|
voterDownIds String[] @default([])
|
|
staffReason String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([guildId, status])
|
|
}
|
|
|
|
model BirthdayConfig {
|
|
id String @id @default(cuid())
|
|
guildId String @unique
|
|
enabled Boolean @default(true)
|
|
channelId String?
|
|
roleId String?
|
|
message String?
|
|
timezone String @default("Europe/Berlin")
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
}
|
|
|
|
model Birthday {
|
|
id String @id @default(cuid())
|
|
guildId String
|
|
userId String
|
|
month Int
|
|
day Int
|
|
year Int?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([guildId, userId])
|
|
@@index([guildId, month, day])
|
|
}
|
|
|
|
model TempVoiceConfig {
|
|
id String @id @default(cuid())
|
|
guildId String @unique
|
|
enabled Boolean @default(false)
|
|
hubChannelId String?
|
|
categoryId String?
|
|
defaultName String @default("{user}'s Channel")
|
|
defaultLimit Int @default(0)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
}
|
|
|
|
model TempVoiceChannel {
|
|
id String @id @default(cuid())
|
|
guildId String
|
|
channelId String @unique
|
|
ownerId String
|
|
controlMessageId String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
|
|
@@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])
|
|
}
|
|
|
|
model CommandOverride {
|
|
id String @id @default(cuid())
|
|
guildId String
|
|
commandName String
|
|
enabled Boolean @default(true)
|
|
allowedRoleIds String[] @default([])
|
|
deniedRoleIds String[] @default([])
|
|
allowedChannelIds String[] @default([])
|
|
deniedChannelIds String[] @default([])
|
|
cooldownSeconds Int?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([guildId, commandName])
|
|
@@index([guildId])
|
|
}
|
|
|
|
model OwnerTeamMember {
|
|
id String @id @default(cuid())
|
|
userId String @unique
|
|
role String
|
|
note String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
|
|
model GlobalUserBlacklist {
|
|
id String @id @default(cuid())
|
|
userId String @unique
|
|
reason String?
|
|
note String?
|
|
createdById String
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
|
|
model GuildBlacklist {
|
|
id String @id @default(cuid())
|
|
guildId String @unique
|
|
reason String?
|
|
createdById String
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
|
|
model FeatureFlag {
|
|
id String @id @default(cuid())
|
|
key String @unique
|
|
enabled Boolean @default(false)
|
|
rolloutPercent Int @default(0)
|
|
whitelistGuildIds String[] @default([])
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
|
|
model BotPresenceConfig {
|
|
id String @id @default("singleton")
|
|
status String @default("online")
|
|
activityType String @default("Watching")
|
|
activityText String @default("nexumi.de")
|
|
rotatingMessages Json?
|
|
maintenanceMode Boolean @default(false)
|
|
maintenanceMessage String?
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
|
|
model ChangelogEntry {
|
|
id String @id @default(cuid())
|
|
version String
|
|
title String
|
|
body String
|
|
publishedAt DateTime @default(now())
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
|
|
model OwnerAuditLog {
|
|
id String @id @default(cuid())
|
|
actorUserId String
|
|
action String
|
|
targetType String?
|
|
targetId String?
|
|
before Json?
|
|
after Json?
|
|
createdAt DateTime @default(now())
|
|
|
|
@@index([createdAt])
|
|
}
|
|
|
|
/// Per-tier limits and feature gates (FREE / PREMIUM). Seeded on first use.
|
|
model PremiumTierConfig {
|
|
tier String @id
|
|
maxTags Int
|
|
maxFeeds Int
|
|
maxBackups Int
|
|
/// JSON object of feature key → boolean (tags, feeds, guildbackup, …).
|
|
features Json
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
|
|
model GuildPremiumAssignment {
|
|
id String @id @default(cuid())
|
|
guildId String @unique
|
|
tier String
|
|
note String?
|
|
assignedById String
|
|
expiresAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([tier])
|
|
}
|
|
|
|
model UserPremiumAssignment {
|
|
id String @id @default(cuid())
|
|
userId String @unique
|
|
tier String
|
|
note String?
|
|
assignedById String
|
|
expiresAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([tier])
|
|
}
|
|
|
|
model GdprDeletionLog {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
guildId String?
|
|
summary Json?
|
|
createdAt DateTime @default(now())
|
|
|
|
@@index([userId, createdAt])
|
|
}
|
|
|