Skip to content

Modeles Prisma

Toutes les tables utilisent des CUID comme cle primaire et ont des timestamps createdAt / updatedAt (sauf exceptions notees).

GuildConfig

Configuration du serveur Discord. Un seul record par serveur.

ChampTypeDescription
idStringCUID
guildIdStringID Discord du serveur (unique)
birthdayChannelIdString?Salon anniversaires
thursdayChannelIdString?Salon jeudi
thursdayRoleIdString?Role jeudi
logChannelIdString?Salon logs admin
welcomeChannelIdString?Salon bienvenue
moderationLogChannelIdString?Salon logs moderation
helpChannelIdString?Salon guide public
helpMessageIdString?ID du message d'aide public
staffChannelIdString?Salon guide staff
staffMessageIdString?ID du message d'aide staff
statsCategoryIdString?Categorie stats channels
valoCategoryIdString?Categorie Valorant channels
thursdayMessageIdString?ID du message RSVP actuel
suggestionChannelIdString?Salon suggestions
clipChannelIdString?Salon clips
birthdayRoleIdString?Role anniversaire
xpEnabledBooleanXP active (defaut true)
xpMessageCooldownSecIntCooldown messages (defaut 60)
levelRolesJson?Mapping { "1": "roleId", ... }

UserProfile

Profil de base de chaque membre.

ChampTypeDescription
idStringCUID
discordIdStringID Discord (unique)
guildIdStringID du serveur
usernameStringNom d'utilisateur
isActiveBooleanActif (defaut true)

Index : @@index([guildId])

Relations : Birthday, UserXp, VoiceSession, MessageStatDaily, WeeklyEventResponse, ModerationAction (x2), GameAccountLink, AuditLog.

Birthday

ChampTypeDescription
userIdStringFK vers UserProfile (unique)
guildIdStringID du serveur
dayIntJour
monthIntMois
yearInt?Annee (optionnel)
timezoneStringDefaut Europe/Paris
isPublicBooleanDefaut true
lastWishedDateTime?Dernier souhait (idempotence)

Index : @@index([guildId, month, day])

Cascade : supprime si UserProfile supprime.

UserXp

ChampTypeDescription
userIdStringFK vers UserProfile (unique)
guildIdStringID du serveur
totalXpIntXP total cumule
levelIntNiveau actuel
messageXpIntXP gagne par messages
voiceXpIntXP gagne en vocal
weeklyXpIntXP de la semaine
weeklyResetAtDateTime?Date du dernier reset
lastMessageAtDateTime?Dernier message ayant donne XP

Index : @@index([guildId, totalXp]), @@index([guildId, weeklyXp])

VoiceSession

ChampTypeDescription
userIdStringFK vers UserProfile
guildIdStringID du serveur
channelIdStringID du salon vocal
joinedAtDateTimeDebut de session
leftAtDateTime?Fin de session
durationSecInt?Duree en secondes
xpEarnedIntXP gagne dans la session

Index : @@index([userId, joinedAt]), @@index([guildId, joinedAt])

MessageStatDaily

Statistiques de messages par jour, par utilisateur, par salon.

ChampTypeDescription
userIdStringFK vers UserProfile
guildIdStringID du serveur
channelIdStringID du salon
dateDateDate du jour (@db.Date)
countIntNombre de messages
xpEarnedIntXP gagne ce jour

Contrainte unique : @@unique([userId, channelId, date]) Index : @@index([guildId, date])

WeeklyEventResponse

ChampTypeDescription
userIdStringFK vers UserProfile
guildIdStringID du serveur
weekNumberIntNumero de semaine ISO 8601
yearIntAnnee
statusEnumPRESENT, MAYBE, ABSENT
arrivalTimeString?Heure d'arrivee
commentString?Commentaire libre
wantsThursdayDmReminderBooleanOpt-in rappel DM
thursdayDmSentAtDateTime?Quand le DM a ete envoye

Contrainte unique : @@unique([userId, weekNumber, year]) Index : @@index([guildId, weekNumber, year])

ChampTypeDescription
userIdStringFK vers UserProfile
guildIdStringID du serveur
providerStringriot, etc.
accountIdStringID du compte (PUUID)
gameNameString?Nom de jeu
tagLineString?Tag
isVerifiedBooleanDefaut false

Contrainte unique : @@unique([userId, provider])

GamePerformanceSnapshot

ChampTypeDescription
accountIdStringFK vers GameAccountLink
gameStringNom du jeu
dataJsonDonnees brutes
capturedAtDateTimeHorodatage

Index : @@index([accountId, game, capturedAt])

ModerationAction

ChampTypeDescription
guildIdStringID du serveur
targetUserIdStringFK vers UserProfile (cible)
moderatorUserIdStringFK vers UserProfile (moderateur)
typeEnumWARN, MUTE, KICK, BAN, UNBAN, UNMUTE
reasonString?Raison
durationSecInt?Duree (pour mute)
expiresAtDateTime?Expiration
isActiveBooleanDefaut true

Index : @@index([guildId, targetUserId]), @@index([guildId, createdAt])

Pas de cascade : l'historique est preserve meme si le profil est supprime.

ValorantProfile

ChampTypeDescription
discordUserIdStringID Discord (unique)
guildIdStringID du serveur
riotIdStringFormat Pseudo#TAG

ValorantTrackerCache

ChampTypeDescription
discordUserIdStringID Discord
riotIdStringRiot ID
rawDataJsonDonnees brutes (stats)
fetchedAtDateTimeHorodatage du fetch
expiresAtDateTimeExpiration du cache
errorString?Message d'erreur si echec

Contrainte unique : @@unique([discordUserId, riotId]) Index : @@index([expiresAt])

Countdown

ChampTypeDescription
guildIdStringID du serveur
nameStringNom de l'evenement
dateDateTimeDate cible
createdByStringDiscord ID du createur

Index : @@index([guildId])

AuditLog

ChampTypeDescription
guildIdStringID du serveur
userIdString?FK vers UserProfile
actionStringType d'action
detailsJson?Parametres

Index : @@index([guildId, action, createdAt])

SystemLog

ChampTypeDescription
levelSystemLogLevelDEBUG, INFO, WARN, ERROR
sourceStringModule source
messageStringDescription
detailsJson?Donnees supplementaires

Index : @@index([level, createdAt]), @@index([source, createdAt])

Conventions

  • CUID : toutes les cles primaires utilisent @default(cuid()).
  • Timestamps : createdAt avec @default(now()), updatedAt avec @updatedAt.
  • Cascade : toutes les relations vers UserProfile ont onDelete: Cascade sauf ModerationAction.
  • Champs JSON : types comme any cote TypeScript (Prisma genere JsonValue).
  • Enums : RsvpStatus, ModerationActionType, SystemLogLevel.