CED Tunisia · stage de fin d'études · févr. à août 2026
Collaboris
Une bibliothèque de présence temps réel pour applications web d'entreprise, avec un journal conforme RGPD dès la conception et un assistant IA gouverné.
- Mon rôle
- De bout en bout : architecture, implémentation, packaging, déploiement, présentation aux dirigeants
- Période
- Février à août 2026, trois releases
Technologies
- Angular
- TypeScript
- C#
- .NET
- SignalR
- Redis
- SQL Server
- Cosmos DB
- Python
- FastAPI
- Azure OpenAI
- MCP
- Azure
- Azure DevOps
- npm
- NuGet
Sur le CV
- Développé Collaboris, une bibliothèque de présence temps réel pour applications web d'entreprise, livrée en deux paquets : une bibliothèque Angular 19 (npm) et un SDK ASP.NET Core 8 (NuGet) sur SignalR et Redis. Trois releases sous revue technique du chef de département.
- Présenté l'architecture, la gouvernance et l'intérêt métier au chef de département et aux dirigeants de CED.
- Conçu une cascade d'identification à cinq niveaux qui reconnaît l'utilisateur depuis la session existante de l'application hôte, sans double connexion.
- Conçu un résolveur de vue en couches : un MutationObserver DOM ciblé et temporisé qui situe chaque utilisateur jusqu'au dialogue, onglet ou étape ouverts, pour une co-présence exacte.
- Détecté l'activité réelle en interceptant fetch et XMLHttpRequest (méthodes d'écriture uniquement, liste d'exclusion, fenêtre de déduplication) et mutualisé tous les onglets sur un seul WebSocket via un SharedWorker.
- Développé PresenceAI, la couche données et IA : capture de changements des signaux Redis vers un journal Cosmos DB (OLTP vers OLAP, Python/FastAPI), interrogé en langage naturel via un assistant Azure OpenAI gouverné, exposé en MCP.
- Mis en œuvre la conformité RGPD dès la conception (minimisation, consentement, rétention de 30 jours par TTL, accès fermé par défaut, plafonds de coût) et couvert la couche IA par des tests unitaires.
- Déployé l'ensemble sur Azure (App Service, SQL Server, Azure Cache for Redis) via les pipelines build et release Azure DevOps, avec migration de la couche de données de l'API de PostgreSQL vers SQL Server.
Le problème
Deux gestionnaires de sinistres ouvrent le même dossier dans une application interne au même moment. Aucun ne sait que l'autre est là. Le premier enregistre. Le second, à partir de ce qu'il voyait un instant plus tôt, enregistre aussi et écrase silencieusement le premier. Pas d'alerte, pas de conflit. Le dernier enregistrement gagne, et personne ne le remarque avant un client.
Les applications web d'entreprise sont aveugles à leurs propres utilisateurs. La question : rendre n'importe quelle application interne consciente de qui s'y trouve et de ce qui change, sans la reconstruire, et sans que ces données deviennent un outil de surveillance.
Ce que j'ai construit
Collaboris est une bibliothèque prête à l'emploi : l'application Angular hôte installe un paquet npm, son backend ajoute un paquet NuGet, et un bloc de configuration relie le tout. Les utilisateurs voient qui est présent, jusqu'au dialogue, à l'onglet ou à l'étape ouverts, et sont prévenus quand la donnée sous leurs yeux change. L'identité vient de la session existante de l'hôte.
La release 3 a ajouté PresenceAI : le flux éphémère de présence est capturé dans un journal durable et à rétention bornée dans Cosmos DB, et des managers autorisés peuvent l'interroger en langage naturel via un assistant Azure OpenAI gouverné, aussi exposé en MCP. Redis contient ce qui se passe ; Cosmos ce qui s'est passé.
Tout a été livré sous forme de vrais paquets, installés par l'hôte comme un client le ferait, et déployé sur Azure via les pipelines Azure DevOps.
Comment ça marche
Défile tout seul. Cliquez sur une étape pour faire pause.
Décisions et compromis
- Deux stores plutôt qu'un
- Le temps réel veut des lectures en microsecondes et un état éphémère ; l'analytique veut de l'historique et des agrégats. Redis et Cosmos DB, reliés par un pipeline que le chemin direct n'attend jamais.
- Un pipeline déterministe plutôt qu'un journal construit par LLM
- Coût, reproductibilité et confiance. Le même historique produit toujours le même journal. Le modèle ne vit qu'aux bords.
- Synthèse de session à l'écriture
- Plutôt que tout refléter puis supprimer, le pipeline décide à l'ingestion ce qui mérite d'exister. Le stockage est borné par construction, ce que le RGPD demande aussi.
- Une liste blanche plutôt que les rôles de l'hôte pour l'accès IA
- La sémantique des rôles ne voyage pas entre pays et applications. Le propriétaire de chaque application déclare qui peut interroger ; par défaut, personne.
- L'hôte authentifie, la bibliothèque lit
- Le schéma JWT propre au SDK a été retiré en revue d'intégration : une bibliothèque ne peut pas posséder la politique de sécurité de son hôte. Retirer est un acte de conception.
- Génération augmentée par cache plutôt que recherche
- Le journal est petit par construction ; les résumés récents tiennent dans le contexte. Pas d'infrastructure vectorielle.
- Python et FastAPI pour la couche IA dans une maison .NET
- Consommation de flux asynchrone, validation typée, streaming natif et écosystème IA, en service déployable indépendamment.
Gouvernance
- Minimisation des données
- Coordonnées du travail seulement : identité, position, statut, événements de changement. Jamais de contenu, de valeurs de formulaire ni de frappes.
- Consentement
- Explicite, éclairé et révocable, recueilli avant tout suivi ; un écran de confirmation d'identité montre ce qui sera partagé.
- Rétention par le schéma
- TTL de 30 jours sur les enregistrements fins, appliqué par la base elle-même. Ce qui n'a jamais été écrit ne peut pas fuir.
- Surveillance impossible par construction
- Le journal stocke des comptages, pas des évaluations individuelles. Les questions de jugement et de prédiction sur des personnes sont refusées par conception.
- Accès fermé par défaut et plafonds de coût
- Pas d'entrée dans la liste, pas d'accès. Plafonds par question et mensuels sur la couche IA.
- Registre des traitements
- Chaque question, classification, réponse et refus est journalisé. La couche IA est couverte par des tests unitaires.
Ce que j'ai appris
- Ne jamais croire la santé auto-déclarée d'un composant. Le bug le plus dur : une connexion qui se disait saine alors que sa réception était morte ; la solution a été de suivre l'âge du dernier message reçu.
- L'auteur d'une bibliothèque ne contrôle rien : ni les habitudes de l'hôte, ni son stockage, ni son déploiement. Concevoir pour cela est une autre discipline que construire une application.
- Comparer d'abord. Chaque composant a commencé par la façon dont l'industrie résout déjà le problème, et le jour où l'état de l'art s'est tu, j'ai su quelle partie du projet était la mienne.
- Retirer est un acte de conception. Un moteur de vues heuristique, un classeur de sévérité, un chemin de stockage graphe et la couche d'authentification du SDK ont été construits, évalués et supprimés, chacun argumenté par écrit.
Construit dans un dépôt d'entreprise privé. Noms, identifiants et références internes sont volontairement omis.
Étude de cas suivante
Système de veille marché