DOC
Accueil/ Projets/ MJY Task Platform/ ADR 0009 : Système de logging centralisé avec priorités et persistance Supabase

ADR 0009 : Système de logging centralisé avec priorités et persistance Supabase

  • Statut : Accepté (le 9 juillet 2026, à la clôture du Sprint 06 - logger livré des deux côtés, table app_logs créée)
  • Décideurs : Seer MENSAH-ASSIAKOLEY (Développeur)
  • Date : 9 juillet 2026

Contexte et Problème

Actuellement, l'application ne dispose pas d'un système de journalisation unifié permettant de suivre les événements critiques, les requêtes réseau et les erreurs dans un format structuré et persistant. Le débogage et le suivi des incidents en production sont donc difficiles, d'autant plus que les données de session d'authentification restent strictement locales au navigateur.

Julien souhaite un système de logger complet, inspiré du fonctionnement robuste de Java (loggers hiérarchiques par package/namespace, niveaux de priorité) et de Winston/Morgan sous Node.js, facilement reproductible sur toutes ses applications React. Ce système doit également s'intégrer dans tous les appels et requêtes API et stocker ces logs dans une table Supabase accessible de manière sécurisée.

Facteurs de Décision

  • Priorités de logs : Support des niveaux de sévérité standard (TRACE, DEBUG, INFO, WARN, ERROR, FATAL).
  • Héritage hiérarchique : Pouvoir configurer le niveau de verbosité globalement ou par module (ex: passer services.auth en DEBUG tout en gardant le reste de l'application en WARN).
  • Structure des logs : Chaque log doit enregistrer un message simple (message), une description détaillée ou stack d'erreur (description), un horodatage (timestamp / created_at), ainsi que le contexte utilisateur (user_id).
  • Persistance de fichier et BDD :
    • Côté navigateur : Stockage dans un buffer en mémoire avec option de téléchargement sous forme de fichier .log.
    • Côté base de données : Synchronisation automatique des logs critiques dans une table publique Supabase public.app_logs.
  • Zéro boucle infinie : Les requêtes d'envoi de logs vers Supabase ne doivent pas s'auto-journaliser (risque d'appel récursif infini).
  • Performance : Limiter la charge réseau en filtrant/filtrant par lot les logs envoyés en base (ex: uniquement INFO et plus).

Options Envisagées

Option A : Utilisation de Winston côté client (via polyfills) et Morgan côté serveur

Winston est puissant pour Node.js mais lourd et non adapté nativement au navigateur (nécessite des polyfills Webpack/Vite pour les modules Node fs, path, etc.).

  • Avantage : Même API des deux côtés.
  • Inconvénient : Augmente drastiquement la taille du bundle frontend, difficile à faire fonctionner avec Vite, pas de support natif pour le téléchargement de fichier en navigateur ou l'intégration Supabase RLS.

Option B : Logger sur mesure pour React (logger.js) + Configuration Winston/Morgan pour Node (logger.server.js)

On conçoit un module de logging autonome en JS/TS pur pour React avec une interface inspirée de Java (LoggerFactory.getLogger('Name')), supportant les namespaces hiérarchiques, l'écriture en base via Supabase, et un export fichier natif. Côté serveur Node, on utilise la configuration Winston/Morgan standard pour conserver les meilleures pratiques de chaque environnement.

  • Avantage : Zéro dépendance sur le frontend (léger), parfaitement adapté aux contraintes du navigateur (stockage en mémoire, téléchargement HTML5 de fichier .log), et flexible pour cibler Supabase.
  • Inconvénient : Nécessite l'écriture du module de base sur mesure.

Décision Retenue

L'Option B a été retenue. Nous allons créer un logger autonome côté React (src/utils/logger.js) et configurer Winston/Morgan pour le backend.

Justification

Cette option garantit la légèreté de l'application frontend tout en offrant un comportement proche de Java (namespaces, priorités) et en résolvant élégamment le besoin d'un "fichier de log" dans le navigateur grâce au buffer téléchargeable. L'intégration Supabase s'effectue via un SupabaseTransport dédié et filtré pour éviter les surcharges.

Structure des logs (Schéma)

Chaque log généré par le système contiendra les informations suivantes :

Champ Type Description
timestamp / created_at timestamptz Date et heure de l'événement (généré automatiquement).
level text Niveau de priorité (TRACE, DEBUG, INFO, WARN, ERROR, FATAL).
category text Namespace du logger (ex: network.fetch, services.auth, components.TaskDetail).
message text Message simple et court de résumé (ex: Connexion utilisateur réussie).
description text Détails supplémentaires (paramètres de requête, corps de réponse, stack trace d'erreur).
payload jsonb Données brutes optionnelles (payload de requête, détails d'erreur).
user_id uuid Identifiant du membre Supabase connecté (si disponible).
browser_info jsonb Métadonnées système (User Agent, URL courante, résolution d'écran).

Mesures de Sécurité (RLS Supabase)

La table public.app_logs sera protégée par Row Level Security (RLS) :

  1. INSERT : Autorisé publiquement pour permettre à n'importe quel client (anonyme ou connecté) de signaler une erreur ou un événement.
  2. SELECT : Restreint aux utilisateurs ayant le rôle super_manager dans la table public.member.
  3. UPDATE / DELETE : Complètement bloqués pour tout le monde afin de garantir que les journaux soient immuables et infalsifiables.