en production · v1.16
PlanOpé
Plateforme interne de gestion d’équipe
Plannings de présence, clients, rendez-vous, KPI et licences SaaS. C’est l’outil que l’équipe support ouvre le lundi matin pour savoir qui est là cette semaine.
Le problème
Le suivi de l’équipe vivait dans un tableur partagé : trois onglets, deux versions, et la même question chaque lundi : « qui est là cette semaine ? ». Les plannings changeaient sans que personne ne le sache, les congés se posaient par message, et les clients étaient suivis ailleurs encore.
Il fallait un seul endroit, lisible sur téléphone, qui réponde à trois questions sans qu’on ait à chercher : où en est l’équipe, qui suit quel client, et qu’est-ce qui a bougé depuis vendredi.
Ce que j’ai décidé
React pour l’interface, Express et PostgreSQL derrière, Socket.IO pour les notifications. Pas de framework front lourd ni de state global : TanStack Query garde le cache serveur, l’état local reste local. Les composants viennent de Radix et shadcn, pour l’accessibilité au clavier plutôt que pour le style.
Le temps réel n’était pas une option : un planning qu’il faut rafraîchir à la main ne sert à rien. Les droits tiennent en une phrase, chacun voit tout et seuls les responsables modifient, et en pratique personne n’a eu à demander qui pouvait faire quoi.
Les exports sont traités comme des fonctionnalités : PDF et Excel pour les plannings et les KPI, parce que la première chose qu’on demande à un outil interne, c’est de sortir du tableau.
Ce qui a cassé
Les premières notifications arrivaient en double. Le symptôme ressemblait à un bug serveur ; la cause était un abonnement Socket.IO recréé à chaque rendu, sans nettoyage. Depuis, la règle est simple : quand un événement arrive deux fois, on regarde d’abord qui écoute.
Deuxième casse, plus instructive : le cache persisté en IndexedDB servait des données d’avant déconnexion à un autre utilisateur sur le même poste. Le correctif était méthodologique : la clé de cache contient maintenant l’identifiant de session, et la déconnexion vide le cache avant de rendre la main.
Les garde-fous
Les connexions passent par des clés d’accès (WebAuthn) et un second facteur, avec openpgp pour ce qui doit être chiffré côté client. Le front est une PWA : installable, et consultable quand le réseau tombe, ce qui arrive en open space.
Les tests couvrent les parcours critiques côté API et les composants côté interface. Rien d’exhaustif : le but est qu’une régression de planning se voie avant l’équipe, pas après.
Ce que j’en garde
La partie la plus soignée est celle qu’on regarde tous les jours : le tableau de la semaine. Le reste doit être juste et rapide, sans fioritures. Six mois après la mise en service, personne n’a demandé à changer d’outil.