Skip to content

v7.18

Choose a tag to compare

@Klaynight-dev Klaynight-dev released this 31 May 18:16
· 3150 commits to main since this release

📝 BILAN EXHAUSTIF DES ÉVOLUTIONS ET NOTES TECHNIQUES : KOTBO (v7.8 ➔ v7.17)

🏗️ I. CONFIGURATION DU RUNTIME, ARCHITECTURE & ECOSYSTÈME

1. Robustesse du Build et Gestion des Dépendances

  • Validation Strict des Types : Ajout d'un script de build intégrant une vérification statique stricte des types (bun run typecheck) au sein du paquet @kotbo/bot.
  • Évolution des Versions : Rehaussement de la version de l'application Bot à la version v7.17 et du Dashboard à la version v4.20.

2. Optimisation de l'Interface Utilisateur (Compact UI)

  • Design Card Adaptatif : Intégration d'ajustements de rayons de bordures (border-radius: 1.25rem) sur la classe .section-card en mode d'affichage compact.
  • Marges et Paddings : Réduction des marges inférieures sur les en-têtes de page (margin-bottom: 1.5rem) et ajustement du rembourrage des KPIs de statistiques (padding: 0.85rem 1rem) sous la directive de style :root.compact-ui.

🚨 II. PRÉFÉRENCES APPLICATIVES, THÉMATISATION ET SYNC DOUBLE SENS

1. Store Centralisé de Préférences (userPreferences)

  • Couleurs d'Accents Dynamiques : Implémentation d'une palette d'accents de couleur au niveau du document d'après une structure de hachage prédéfinie :

  • violet (#8b5cf6), blue (#3b82f6), green (#10b981), rose (#f43f5e), orange (#f97316), et cyan (#06b6d4).

  • Isolation du SSR (Server-Side Rendering) : Sécurisation du chargement et de la persistence locale à l'aide de gardes DOM (canUseDom), empêchant les plantages d'exécution lors du rendu initial côté serveur.

  • Synchronisation Multi-onglets : Enregistrement d'un écouteur d'événement global storage pour réaligner instantanément les thèmes et les couleurs d'accent sur toutes les instances de fenêtres actives du même navigateur.

2. Expérience de Gestion et Import/Export

  • Persistence de l'état : Centralisation du pipeline applyPreferences qui orchestre à la volée le mode sombre, l'activation des animations, le format de date (relative/absolute), la langue de l'UI (fr/en) et la politique de visibilité de la barre latérale.
  • Portabilité des Réglages : Ajout de fonctions CRUD d'exportation et d'importation de fichiers de configuration standardisés au format JSON (kotbo-user-preferences.json) avec validation de clés de structure autorisées.

📊 III. MODULE COGNITIF DE LEVELING & MULTIPLICATEURS D'EXPÉRIENCE (XP)

Un moteur complet d'accumulation de points d'expérience textuels et vocaux a été adossé au backend de Kotbo :

1. Attribution Rythmée et Multiplicateurs de Rôles

  • Algorithme d'XP Vocale : Activation d'une routine d'évaluation cyclique asynchrone s'exécutant toutes les 60 secondes. Elle inspecte les membres connectés dans les salons vocaux éligibles, vérifie qu'ils ne sont pas muets/sourds (selfMute, serverDeaf) et distribue une quantité fixe d'XP paramétrable.
  • Calcul Matriciel d'XP : Prise en compte de coefficients multiplicateurs par rôle. Le système analyse les rôles Discord d'un membre et applique le multiplicateur le plus élevé de sa matrice (xpMultipliers) pour indexer le gain de base textuel ou vocal.
  • Formule Mathématique de Palier : L'évaluation des transitions de niveaux s'appuie sur une courbe quadratique cumulative pour calibrer l'expérience requise ($XP$) en fonction du niveau cible ($L$) :

$$XP = 100 \times L^2 + 200 \times L$$

2. Logique de Passage de Niveau (Level Up)

  • Routage Polymorphe des Alertes : Les félicitations peuvent être dirigées au choix dans le salon d'action courant, un canal fixe dédié, ou directement par Message Privé (DM).
  • Gestion des Récompenses Empilables (stackRewards) : Ajout d'une option permettant soit de cumuler tous les rôles de paliers atteints, soit de purger automatiquement les rôles inférieurs afin de ne conserver que le grade le plus élevé du membre.

🛡️ IV. MOTEURS D'AUTOMODÉRATION, AUTO-RESPONSES ET SUGGESTIONS

1. Inspecteur AutoMod d'Infrastructures

  • Anti-Spam et Verrou de Flux : Surveillance temporelle glissante stockant les empreintes de messages par utilisateur dans un registre en mémoire volatile (userMessageTimestamps). Tout dépassement du quota (spamLimit) sur la fenêtre choisie déclenche l'effacement immédiat et une mesure d'exclusion temporaire (TIMEOUT) ou d'avertissement automatique.
  • Analyseur de Payload et Limiteurs :
  • Anti-Liens : Interception des expressions régulières d'invitations Discord avec possibilité de définir une liste blanche de domaines autorisés.
  • Caps Lock : Calcul du ratio majuscules/lettres sur les longs messages pour intercepter les excès d'agressivité textuelle.
  • Flood d'Émojis & Mentions : Comptabilisation stricte des émojis (Unicode et personnalisés) ainsi que des mentions @ de rôles et d'utilisateurs.

2. Moteur d'Auto-R├®ponses Riches

  • Correspondance Avancée : Prise en charge des analyses par détection globale (CONTAINS), correspondance stricte (EXACT) ou expressions régulières évoluées (REGEX).
  • Rendu JSON / Embeds : Si la réponse stockée en base de données correspond à une structure d'objet JSON, Kotbo l'intercepte et instancie un EmbedBuilder enrichi au lieu d'un simple message textuel.

3. Cycle de Vie des Suggestions Communautaires

  • Mécanisme de Scrutin : Génération automatique de messages d'embed de vote munis de boutons d'action asynchrones. Les identifiants des votants sont mémorisés dans des tableaux (upvoters/downvoters) pour empêcher le double scrutin.
  • Résolution Finale : Possibilité pour le personnel d'encadrement de statuer sur une suggestion (APPROVED, REJECTED, IMPLEMENTED) depuis le Dashboard, ce qui gèle instantanément le scrutin Discord et met à jour la couleur de l'embed.

📰 V. CONCOURS (GIVEAWAYS) ET CRÉATEUR D'EMBED VISUEL

[Dashboard / Commande Slash] ➔ Génération d'une entrée Giveaway (BDD)
                                        │
                                        ▼
                         [Publication sur Canal Discord]
                         Embed Rich + Bouton Interactif 🎫
                                        │
                                        ▼
                  [Vérification de l'Échéance via Horloge de Task]
                                        │
                        ┌───────────────┴───────────────┐
                        ▼                               ▼
               [Candidats Absents]            [Candidats Présents]
                        │                               │
             Clôture Sans Vainqueur          Sélection Aléatoire (Pool)
                                                        │
                                                        ▼
                                             Annonce & Édition Embed

1. Gestion des Giveaways sur Boutons

  • Enrôlement Synchrone : Remplacement des anciennes réactions par un bouton interactif lié à l'ID unique de la table Prisma. Un second clic sur le bouton désinscrit proprement le membre.
  • Reroll asynchrone : Possibilité de relancer un tirage sur un concours expiré en excluant les anciens vainqueurs de la liste des candidats éligibles.

2. Concepteur d'Embed à la Volée (EmbedBuilder)

  • Un module complet d'édition graphique a été déployé, permettant de structurer visuellement un message d'embed Discord :
  • Configuration des structures de l'auteur, du titre, des descriptions complexes, de la couleur hexadécimale, des vignettes d'illustration, des images de bannières principales et des pieds de page (footer).
  • Gestion dynamique d'une collection de sous-champs (fields) alignables en grille ou en bloc unitaire (limite Discord fixée à 25 champs).
  • Capacité de cibler un messageId existant afin de modifier en direct un embed précédemment publié par le Bot.

👥 VI. EXTENSION DE LA STRUCTURE DE LA BASE DE DONNÉES (PRISMA)

Le schéma de persistance a été enrichi de nouveaux modèles pour supporter ces briques applicatives :

// Nouveau modèle pour le suivi d'XP et des niveaux
model MemberLevel {
  id          String   @id @default(uuid())
  guildId     String
  userId      String
  xp          Int      @default(0)
  level       Int      @default(0)
  lastXpGain  DateTime @default(now())

  @@unique([guildId, userId])
}

// Configuration fine du système de leveling
model LevelConfig {
  guildId          String   @id
  enabled          Boolean  @default(false)
  xpMin            Int      @default(15)
  xpMax            Int      @default(25)
  cooldownSeconds  Int      @default(60)
  vocalXpPerMin    Int      @default(5)
  levelUpChannelId String?
  levelUpMessage   String
  stackRewards     Boolean  @default(false)
  ignoredChannels  String[]
  ignoredRoles     String[]
  xpMultipliers    Json     @default("{}")
}

// Rôles à attribuer lors du passage de niveaux
model LevelRoleReward {
  id      String @id @default(uuid())
  guildId String
  level   Int
  roleId  String
}

// Modèle de gestion des concours automatiques
model Giveaway {
  id           String   @id @default(uuid())
  guildId      String
  channelId    String
  messageId    String?
  prize        String
  description  String?
  winnerCount  Int      @default(1)
  endsAt       DateTime
  ended        Boolean  @default(false)
  participants String[] @default([])
  winners      String[] @default([])
  createdAt    DateTime @default(now())
}

// Menus de rôles sur boutons (Reaction Roles)
model ReactionRoleMenu {
  id        String   @id @default(uuid())
  guildId   String
  channelId String
  messageId String?
  title     String
  options   Json     // Contient la liste des objets { emoji, label, roleId }
  createdAt DateTime @default(now())
}

// Réponses automatiques programmables
model AutoResponse {
  id        String   @id @default(uuid())
  guildId   String
  trigger   String
  response  String
  matchType String   @default("CONTAINS") // EXACT, CONTAINS, REGEX
  enabled   Boolean  @default(true)
  createdAt DateTime @default(now())
}

// Configuration des filtres de l'automodération
model AutoModConfig {
  guildId              String   @id
  spamEnabled          Boolean  @default(false)
  spamLimit            Int      @default(5)
  spamIntervalSeconds  Int      @default(5)
  spamAction           String   @default("TIMEOUT")
  linksEnabled         Boolean  @default(false)
  linksAction          String   @default("DELETE_AND_WARN")
  linksWhitelist       String[] @default([])
  capsEnabled          Boolean  @default(false)
  capsThresholdPercent Int      @default(80)
  capsMinLength        Int      @default(10)
  emojisEnabled        Boolean  @default(false)
  emojisLimit          Int      @default(10)
  mentionsEnabled      Boolean  @default(false)
  mentionsLimit        Int      @default(5)
  bypassRoles          String[] @default([])
  bypassChannels       String[] @default([])
}

// Boîte à idées et suggestions communautaires
model Suggestion {
  id           String    @id @default(uuid())
  guildId      String
  userId       String
  username     String
  content      String
  status       String    @default("PENDING") // PENDING, APPROVED, REJECTED, IMPLEMENTED
  responseText String?
  respondedById String?
  respondedAt  DateTime?
  channelId    String
  messageId    String?
  upvoters     String[]  @default([])
  downvoters   String[]  @default([])
  createdAt    DateTime  @default(now())
}

📡 VII. SYSTÈME DE SIGNALEMENT DE FEEDBACK ET INFRASTRUCTURE DU DASHBOARD

1. Routage des Feedbacks et Alertes Administrateurs

  • Canal de signalement direct : Ajout du point de terminaison POST /api/report-feedback adossé à un limiteur de requêtes strict par IP (feedbackReportRateLimiter : 5 requêtes par tranche de 15 minutes).
  • Notification Instantanée du Staff Global : La soumission d'un retour formate un EmbedBuilder structuré (contenant l'IP nettoyée, l'URL source de l'application et le type de rapport : retour, bloquage, suggestion, autre) et le distribue directement par message privé à l'ensemble des administrateurs déclarés en base de données et au propriétaire du jeton d'application (DISCORD_CLIENT_OWNER_ID).

2. Refonte du Composant Sidebar de Navigation

  • Mode Élastique (Collapsible) : La barre latérale dispose désormais d'un mode icônes rétracté persistant en base localStorage, faisant passer la largeur de 16rem à 4.5rem.
  • Système de Favoris et Filtrage : Les utilisateurs peuvent marquer des pages d'administration d'une étoile pour les épingler en haut de leur menu. Un champ de recherche textuel filtre instantanément les routes visibles.

🛠️ VIII. RÉPERTOIRE MÉTHODIQUE DES NOUVELLES COMMANDES SLASH DISCORD

Les interactions suivantes ont été rattachées à l'arbre des commandes globales du Bot :

Commande Options réglementées Services Consommés & Comportement Applicatif
/rank [membre] (Optionnel) Appelle le service Canvas natif pour générer et retourner une carte d'expérience au format PNG (statut de présence, niveau, XP textuelle/vocale et barre de progression).
/giveaway start prix, gagnants, duree, [description], [salon] Instancie un nouveau concours minuté sur le canal visé et attache le gestionnaire de clic de bouton giveaway_join.
/giveaway end id (Identifiant UUID) Interrompt immédiatement un concours actif et procède au tirage au sort des vainqueurs éligibles.
/giveaway reroll id (Identifiant UUID) Sélectionne un nouveau gagnant au sort parmi la liste des inscrits en excluant les vainqueurs initiaux.
/suggest suggestion (Chaîne de texte) Enregistre une suggestion en base de données, la publie dans le salon configuré et y adjoint les boutons de vote asynchrones.

What's Changed

  • feat(dashboard): implement real-time websocket sync for nickname mode by @Intercalaire in #6
  • feat(automod): add undo option for deleted banned words and improve UI by @Intercalaire in #7
  • Rate-limit and sanitize dashboard error reports by @Klaynight-dev in #26
  • Harden dashboard API auth and security by @Klaynight-dev in #27
  • fix(automod): overhaul nickname moderation detection to eliminate false positive by @Intercalaire in #33
  • feat(dashboard/automod): add dynamic nickname whitelist and member bypass exceptions by @Intercalaire in #38

Full Changelog: v7.8...v7.18