Production2026

Leganews Pro

Conception d’une plateforme structurée de veille juridique pour le marché congolais

Illustration de Leganews Pro

Leganews est né en 2019 d’une question difficile, mais concrète : comment permettre aux professionnels du droit en République démocratique du Congo de trouver de manière fiable les textes juridiques dont ils ont besoin, alors que l’information est dispersée entre les publications officielles, les sites institutionnels, les fichiers numérisés, les archives privées et les documents transmis de personne à personne ?

En tant que cofondateur, j’ai abordé ce problème sous les deux angles du produit. J’ai contribué à définir ce que Leganews devait devenir et travaillé sur le système technique nécessaire pour rendre cette vision fiable. Cela a impliqué de prendre des décisions produit, d’apprendre auprès des professionnels du droit et des éditeurs, de maintenir une véritable application historique et, finalement, d’accepter que certaines de nos premières abstractions n’étaient plus assez solides pour la plateforme que nous voulions construire.

Le problème ne tenait pas seulement au fait que l’information juridique n’existait que sur papier. Plus profondément, l’accès numérique ne rendait pas automatiquement le droit facile à trouver, à vérifier, à comprendre dans son contexte ni à suivre dans le temps.

Leganews est passé d’une base de données juridique à une plateforme de veille juridique fondée sur un corpus éditorialisé, une recherche structurée, des textes juridiques versionnés, une validation éditoriale, des relations juridiques, des alertes, la comparaison de documents, des droits d’accès et la facturation.

Cette évolution ne s’est pas faite au moyen d’une réécriture unique et nette. Le produit historique a démontré que les utilisateurs avaient besoin de contenus juridiques interrogeables, d’abonnements, de paiements, de favoris, d’un historique de recherche et d’une interface d’administration. Il a aussi révélé les endroits où notre modèle était trop générique, où les responsabilités étaient couplées et où chaque nouvelle fonctionnalité ajoutait davantage d’exceptions que de clarté. La plateforme actuelle résulte de la refonte de ces enseignements dans un modèle de domaine plus approfondi.

L’objectif n’est pas de remplacer les publications officielles ni le jugement d’un professionnel du droit. Il est de réduire le temps et l’incertitude entre une question juridique et les sources nécessaires pour la traiter de façon responsable.

Leganews réunit modélisation du domaine, outils éditoriaux, recherche d’information, traitement asynchrone, contrôle d’accès, intégration des paiements et conception produit autour d’une idée centrale :

Un texte juridique devient réellement utile lorsqu’il peut être trouvé, vérifié, lu dans la bonne version, relié aux textes associés et suivi au fil de ses évolutions.

Le problème

Le problème central auquel répond Leganews est l’incertitude juridique causée par un accès fragmenté à l’information juridique.

En République démocratique du Congo, un avocat, une entreprise, un chercheur, un magistrat ou un étudiant peut devoir consulter tour à tour le Journal officiel, des sites institutionnels, des moteurs de recherche, des collections de PDF, des archives physiques et des documents reçus de collègues avant de trouver un texte utile.

Même après avoir trouvé un document, plusieurs questions demeurent :

  • S’agit-il du bon texte juridique ?
  • Le titre, le numéro, la date et la source sont-ils exacts ?
  • Est-ce la version originale ou une version ultérieure ?
  • Le texte a-t-il été modifié, complété, remplacé ou abrogé ?
  • Le document est-il complet ?
  • Existe-t-il une décision connexe ou un texte d’application ?
  • Comment le retrouver lorsque je reviendrai sur le même dossier ?
  • Comment saurai-je qu’un élément pertinent a changé ?

Un dossier de PDF résout le stockage, mais pas la recherche juridique. Une recherche générique sur un site peut trouver des mots-clés, mais elle ne comprend ni les types de textes, ni les juridictions, ni les classifications, ni les matières, ni les versions, ni les relations. Une base de données simple peut répertorier des enregistrements, mais elle ne fournit pas automatiquement un processus éditorial permettant de décider ce qui devient public.

En pratique, la recherche juridique devient un travail de reconstruction répété. Chaque professionnel crée son propre système de favoris, de dossiers, de noms de fichiers, de notes et de repères mémorisés. Ce système est difficile à vérifier, à partager et à maintenir.

Leganews a été conçu pour transformer ce parcours fragmenté en une démarche structurée :

Mermaid

Le corpus est volontairement présenté comme éditorialisé plutôt qu’exhaustif. La présence d’un texte dans Leganews ne prouve pas, à elle seule, qu’il est actuellement en vigueur. La plateforme aide les utilisateurs à examiner les sources, les dates, les versions et les relations, mais l’analyse juridique finale reste une responsabilité professionnelle.

Orientation du produit

Leganews est parti d’une idée produit simple :

Construire une base de données numérique structurée des textes juridiques congolais.

Cette idée était utile, mais insuffisante.

Une plateforme juridique professionnelle devait faire davantage que téléverser et afficher des documents. Elle devait :

  • modéliser les actes normatifs et la jurisprudence sans les réduire à des fichiers génériques ;
  • préserver l’identité stable d’un texte juridique tout en prenant en charge plusieurs versions ;
  • structurer les textes longs en articles, sections, chapitres, paragraphes et annexes ;
  • séparer le travail éditorial en brouillon de la publication publique ;
  • relier les textes par des relations porteuses de sens juridique ;
  • proposer une recherche en texte intégral avec des filtres juridiques ;
  • permettre aux utilisateurs d’enregistrer des textes dans des dossiers contextualisés et d’y joindre des notes personnelles ;
  • suivre des domaines, des matières et des textes précis ;
  • avertir les utilisateurs lorsqu’une version correspondante est publiée ;
  • comparer deux versions ou des documents téléversés ;
  • gérer les accès individuels et ceux des organisations ;
  • traiter de manière sûre les moyens de paiement locaux ;
  • migrer des années de données historiques sans perdre leur sens métier ;
  • rester observable et testable à mesure que le produit évolue.

Le produit est ainsi passé d’un site de contenu à un système d’information juridique.

L’application publique constitue l’espace de recherche et de veille. L’application d’administration constitue l’espace éditorial et opérationnel. L’API Symfony porte les règles métier, tandis que PostgreSQL, Redis, le stockage d’objets et Mercure prennent en charge la recherche, les traitements en arrière-plan, les fichiers et les mises à jour en temps réel.

De la plateforme historique à Leganews 2.0

La première plateforme Leganews n’était pas un prototype jetable. C’était une application Symfony en production qui suivait déjà le Domain-Driven Design, traitait les abonnements et les transactions FlexPay, gérait les utilisateurs, publiait du contenu juridique, enregistrait les favoris et l’historique de recherche, générait des PDF et proposait des interfaces publiques et administratives.

Sa stack reflétait le produit à ce stade :

Plain text
Symfony + Twig
Stimulus + Turbo + Symfony UX Live Components
Webpack Encore
MariaDB / MySQL
Doctrine ORM and Doctrine Messenger
Cron-driven maintenance jobs

L’application était organisée autour de ContentManagement, IdentityAndAccess, SubscriptionBilling, Marketing et d’un SharedKernel. Cette structure nous a permis de livrer le produit et d’apprendre. Le problème n’était pas l’absence d’architecture dans le système historique, mais le fait que ses concepts étaient devenus trop larges pour la version suivante du produit.

L’entité historique Content en est un bon exemple. Un seul objet contenait le titre, le Markdown, le HTML, l’extrait, la catégorie, la sous-catégorie, la date de publication, l’état de mise en ligne, l’indicateur d’accès public, la source, le type, l’état juridique, la référence, le nombre de favoris, le nombre de vues et le nombre de vues uniques.

Ce modèle convenait à la publication d’un enregistrement courant comparable à un article. Il est devenu limitant lorsqu’il a fallu représenter un objet juridique stable comprenant plusieurs versions, des articles et chapitres structurés, des transitions éditoriales, une consolidation, des citations, des pièces jointes, des manifestations générées et différentes règles d’accès.

La même pression est apparue ailleurs :

  • Favorite ne pouvait relier qu’un utilisateur à un contenu, alors que la recherche juridique exigeait des dossiers nommés, des éléments enregistrés, des notes et du contexte.
  • SubscriptionBilling portait à la fois le comportement commercial du paiement et l’accès créé par un achat, ce qui rendait les règles de paiement et de droits plus difficiles à faire évoluer indépendamment.
  • IdentityAndAccess réunissait l’identité du compte et les préoccupations d’accès liées aux organisations et aux abonnements.
  • des références directes aux objets traversaient les frontières des contextes : charger ou modifier un concept pouvait ainsi faire intervenir le modèle d’un autre contexte dans la même opération ;
  • le site public et l’interface d’administration reposaient sur la même exécution Symfony, Twig et Symfony UX, alors que leurs parcours devenaient très différents ;
  • MariaDB stockait correctement les données du produit, mais les nouvelles exigences de recherche et d’analyse tiraient mieux parti de la recherche en texte intégral, des trigrammes, des données adaptées aux intervalles, de JSONB et d’HyperLogLog proposés par PostgreSQL.

La refonte n’était donc pas une mise à niveau de framework. Elle modifiait notre manière de décrire le métier.

Modèle historiqueModèle actuelRaison du changement
ContentWork, Expression, Expression Unit, ManifestationSéparer l’identité juridique stable, les versions sémantiques, la structure et les rendus
Category et SubCategoryClassification, Subject, Work Type, Work Source, JurisdictionReprésenter explicitement les différentes dimensions de classification juridique
FavoriteBookmark, Bookmark Item, Work NotePréserver le contexte de la recherche juridique au lieu d’un simple indicateur d’enregistrement
Vues et compteurs de contenusConsultations de Monitoring et projections HLLSéparer l’historique utilisateur des statistiques agrégées de lecture capables de passer à l’échelle
ContentManagementCorpus et MonitoringSéparer la vérité juridique éditoriale des activités de découverte et de suivi des utilisateurs
IdentityAndAccessIdentity et AccessSéparer l’identité de l’utilisateur de ce à quoi celui-ci ou son organisation peut accéder
SubscriptionBillingBilling et AccessSéparer l’argent, les commandes et les événements du prestataire des droits et des sièges
Une application rendue par SymfonyAPI Symfony avec applications TanStack Start principale et d’administrationPermettre aux parcours clients et opérationnels d’évoluer indépendamment
Couplage de session navigateur/serveurBFF de même origine avec jetons Symfony côté serveurGarder les jetons d’accès et de renouvellement hors du stockage du navigateur
MariaDBPostgreSQLPrendre en charge une recherche, des projections, une indexation et des analyses JSONB et HLL plus riches
Entrées cron manuellesSymfony Scheduler et MessengerConserver les planifications dans le code et déplacer les traitements lents vers des files observables

L’une des améliorations les plus importantes a été la réduction du couplage entre contextes. La plateforme actuelle privilégie les identifiants, les commandes, les requêtes, les contrats de modèles de lecture et les événements de domaine, plutôt que de transmettre directement l’agrégat d’un autre contexte à une entité. Billing ne modifie pas un abonnement. Il annonce et exécute une commande payée à travers une frontière explicite. Corpus ne possède pas les favoris d’un utilisateur. Monitoring possède les bookmarks et référence les Works par leur identité.

La refonte du frontend a suivi le même principe. Au lieu de laisser les templates, les contrôleurs, le comportement des sessions et l’interface produit évoluer ensemble, la plateforme dispose désormais d’une API backend et de deux applications React dédiées. L’application principale porte les parcours publics de découverte et de libre-service. L’application d’administration porte les parcours éditoriaux et opérationnels. Des packages partagés fournissent les contrats d’API, les parcours d’authentification, la recherche, le lecteur juridique, le comportement de l’éditeur, les primitives d’interface, l’analyse et les utilitaires, sans imposer aux deux applications la même architecture d’écran.

Cette refonte nous a aussi permis de remplacer les comportements implicites par des cycles de vie explicites :

Mermaid

La plateforme historique nous a fourni les preuves. La plateforme actuelle donne à ces enseignements des noms et des frontières plus solides.

Architecture du système

Leganews est organisé autour de sept contextes métier :

  1. Corpus porte les Works juridiques, les Expressions, le texte structuré, la validation éditoriale, les pièces jointes et les relations juridiques.
  2. Monitoring porte la recherche, les alertes, les notifications, les bookmarks, les notes, les consultations et les recherches récentes.
  3. Identity porte les utilisateurs, l’authentification, le cycle de vie des comptes, les identités fédérées et les vérifications de sécurité.
  4. Access porte les abonnements, les organisations, les membres, les invitations et les droits d’accès directs aux Works.
  5. Billing porte les produits, les prix, les commandes, les transactions de paiement et les événements des prestataires.
  6. Compare porte les parcours de comparaison de documents et de versions juridiques.
  7. Policy porte les conditions et les documents de confidentialité versionnés de la plateforme.

Le backend suit le Domain-Driven Design et une architecture en couches au sein de chaque contexte délimité :

Mermaid

Les commandes modifient l’état. Les requêtes renvoient des projections conçues pour un usage précis. Doctrine ORM persiste les agrégats, tandis que Doctrine DBAL gère les recherches optimisées, les rapports, les tableaux et les modèles de lecture couvrant plusieurs enregistrements.

Mermaid

Cette séparation est importante, car la publication juridique, la recherche, les abonnements et les paiements évoluent pour des raisons différentes. Conserver leurs langages et leurs règles distincts facilite la navigation dans le code et évite qu’un grand modèle générique ne porte l’ensemble du système.

Modélisation d’un corpus juridique

La décision la plus difficile en matière de conception concernait ce que la plateforme devait réellement stocker.

Un modèle naïf pourrait utiliser une table nommée documents, avec un titre, un PDF et une date de publication. Cela fonctionne jusqu’à ce que le même acte juridique reçoive une nouvelle version, qu’un éditeur structure son contenu, qu’un texte ultérieur le modifie ou que les utilisateurs aient besoin de comparer deux états du droit.

Leganews distingue plutôt quatre concepts reliés : le Work juridique stable, ses Expressions sémantiques, leurs Expression Units structurelles et les Manifestations techniques utilisées pour la lecture ou le téléchargement.

Cette distinction est centrale dans la plateforme.

Un Work peut être un acte normatif ou une décision de jurisprudence. Il porte des métadonnées stables, telles que son titre, son type, sa source, sa classification, sa matière, sa date de publication, sa référence juridique, sa politique d’accès et son état éditorial courant dérivé.

Une Expression représente une version de ce Work. Les Expressions possèdent un type, un numéro de version, une date d’expression, une période de validité, un état de structuration, un état éditorial et un résumé. Les types d’expression actuels sont « originale » et « consolidée ».

Une Expression Unit représente la structure interne de la version : corps, préambule, livre, partie, titre, chapitre, section, article, paragraphe, alinéa, point ou annexe. Les Units forment une hiérarchie au moyen d’identifiants parents et de chemins matérialisés.

Une Manifestation est le rendu technique présenté au lecteur, comme du HTML structuré, du Markdown, du texte brut ou un PDF généré.

Mermaid

Ce modèle permet à la plateforme de conserver une page stable pour l’objet juridique tout en indiquant la version exacte consultée par l’utilisateur. Il fournit aussi une base pour les périodes de validité, la consolidation, les comparaisons, les citations et de futures améliorations de la recherche juridique temporelle.

Parcours éditorial

Une information juridique ne doit pas devenir publique uniquement parce qu’un enregistrement existe dans la base de données.

Leganews utilise une machine à états éditoriaux explicite pour les Expressions :

Mermaid

Les éditeurs peuvent soumettre une Expression structurée à la validation. Les réviseurs peuvent l’approuver ou demander des modifications en ajoutant obligatoirement un commentaire. Le contenu approuvé peut ensuite être publié. Un contenu retiré ou approuvé peut être rouvert comme brouillon.

La publication est un événement métier, pas la mise à jour d’un booléen.

Lorsqu’une Expression est publiée, la plateforme peut :

  • dériver l’état éditorial public du Work ;
  • actualiser le résumé du Work à partir de la dernière Expression publiée ;
  • construire une Manifestation lisible ;
  • projeter les citations juridiques intégrées dans des relations entre Works ;
  • mettre à jour le document de recherche ;
  • générer des comparaisons avec d’autres Expressions publiées ;
  • planifier les notifications correspondant aux alertes des utilisateurs.
Mermaid

Un détail important est que l’état public du Work est dérivé de ses Expressions. La publication d’un nouveau brouillon n’est pas nécessaire pour maintenir visible une ancienne version publiée, et la création d’un brouillon plus récent ne dépublie pas le Work par inadvertance.

L’application d’administration accompagne ce parcours au moyen d’un éditeur de textes juridiques et de contrôles de validation. L’éditeur stocke une représentation destinée à l’édition, tandis que le backend persiste séparément les Expression Units au niveau du domaine. L’expérience d’édition reste ainsi distincte du modèle structuré canonique utilisé pour la recherche, la lecture, l’exportation et la comparaison.

Relations juridiques

Les textes juridiques ne sont pas des enregistrements indépendants.

Un texte peut en citer, modifier, modifier partiellement, abroger, abroger partiellement, mettre en œuvre, appliquer, ratifier, interpréter, consolider ou remplacer un autre. Traiter ces liens comme de simples hyperliens génériques leur ferait perdre leur sens juridique.

Leganews les modélise sous forme de Work Relations.

Une relation confirmée enregistre un Work source, un Work cible, un type de relation et, éventuellement, un ancrage dans une Expression ou une Expression Unit. Certaines relations modifient aussi l’état du domaine. Par exemple, appliquer une relation d’abrogation à un acte normatif peut faire passer le statut du Work cible à « abrogé ». Une relation de modification peut éventuellement initialiser une Expression consolidée à partir du contenu pertinent le plus récent.

Les références intégrées créées par les éditeurs sont projetées en relations cites lors de la publication d’une Expression. Le système modélise aussi des Work Relation Suggestions, afin qu’un processus automatisé, une règle d’importation ou un système d’IA puisse proposer une relation assortie d’éléments probants et d’un niveau de confiance sans modifier silencieusement les faits juridiques.

Cette séparation est délibérée :

Mermaid

L’automatisation peut aider à découvrir des liens possibles. Elle ne doit pas être autorisée à publier une signification juridique sans validation.

Recherche et accès à l’information

Une fois le contenu juridique structuré, le défi suivant est de le retrouver.

Leganews ne lance pas directement la recherche dans chaque table normalisée au moment de la requête. Les données des Works publiés sont projetées dans un modèle search_documents dédié, qui contient la dernière Expression publiée, le titre, les intertitres, le corps, les références juridiques et les métadonnées filtrables.

PostgreSQL fournit le premier moteur de recherche.

La couche de recherche utilise :

  • une configuration française de recherche en texte intégral ;
  • la normalisation unaccent ;
  • des valeurs tsvector pondérées pour les titres, les intertitres et le corps du texte ;
  • des index GIN pour la recherche en texte intégral ;
  • des index trigrammes pour la correspondance approximative de repli ;
  • des résultats classés avec mise en évidence dans le titre et le corps ;
  • des filtres par catégorie de Work, type, source, juridiction, classification, matière, accès et date ;
  • des portées explicites limitées au titre, au corps ou au texte intégral.

La première tentative utilise la recherche en texte intégral de PostgreSQL. Si elle ne renvoie aucun résultat, le moteur se replie sur la similarité par trigrammes. Cela aide à gérer les variations orthographiques, les références incomplètes et les requêtes qui se prêtent mal à la tokenisation.

Mermaid

La recherche se trouve dans le contexte Monitoring plutôt que dans Corpus, car elle s’inscrit dans l’activité de recherche continue de l’utilisateur. Ce même contexte porte les recherches récentes, les suggestions, les Works enregistrés, les notes, les consultations et les alertes.

Le frontend regroupe cette expérience dans un module de recherche réutilisable, partagé entre les interfaces publiques et administratives. Les utilisateurs peuvent commencer par une recherche large, sélectionner une portée, appliquer des filtres juridiques, examiner les fragments mis en évidence et conserver suffisamment de contexte pour vérifier le résultat, plutôt que de considérer une correspondance de mots-clés comme une conclusion juridique.

Veille, alertes et recherche personnelle

Trouver un texte une première fois ne représente qu’une partie du travail juridique. Les professionnels doivent aussi revenir sur un dossier et le suivre dans le temps.

Leganews modélise la veille au moyen de plusieurs fonctionnalités ciblées :

Mermaid

Les bookmarks sont plus utiles qu’une liste de favoris sans structure, car ils préservent le contexte. Un utilisateur peut organiser les Works par client, question de recherche, dossier contentieux ou matière suivie. Les notes personnelles restent attachées au Work afin de ne pas perdre la raison de son enregistrement.

Les alertes peuvent cibler une classification juridique entière, une matière ou un Work précis. Lorsqu’une Expression est publiée, un gestionnaire asynchrone recherche par lots limités les utilisateurs abonnés correspondants. Il déduplique les notifications, applique les politiques d’accès, enregistre une notification non lue, publie un événement Mercure en temps réel et envoie un courriel lorsque ce canal est activé.

La plateforme propose aussi un récapitulatif hebdomadaire de veille aux utilisateurs qui préfèrent recevoir une synthèse regroupée.

Mermaid

La publication devient ainsi une boucle de rétroaction produit. L’équipe éditoriale ajoute ou actualise une source juridique, le système la rend accessible à la recherche, puis les utilisateurs qui suivent le périmètre concerné sont informés sans devoir répéter la même recherche chaque jour.

Comparaison de documents et de versions

Le travail juridique implique souvent de comparer ligne par ligne deux versions d’un document.

Leganews prend en charge deux parcours de comparaison associés :

  1. comparer deux Expressions publiées du même Work ;
  2. comparer deux fichiers PDF ou DOCX privés téléversés par un utilisateur abonné.

Le parcours de documents téléversés accepte deux fichiers d’une taille maximale de 10 Mo chacun. Le traitement s’exécute de manière asynchrone, car l’extraction et la génération du diff ne doivent pas bloquer la requête HTTP.

Pour les fichiers PDF, la plateforme extrait le texte UTF-8 avec pdftotext. Pour les fichiers DOCX, elle lit le document WordprocessingML directement depuis l’archive ZIP et préserve la séparation des paragraphes et des tableaux. Le texte est normalisé avant que l’algorithme unifié diff du système d’exploitation ne produise les ajouts, les suppressions et les blocs de contexte.

L’agrégat de comparaison possède un cycle de vie clair :

Mermaid

Les téléversements temporaires sont supprimés après le traitement. Les résultats sont conservés pendant sept jours, puis supprimés par un nettoyage planifié. L’utilisateur reçoit l’état en temps réel par Mercure ainsi qu’un courriel lorsque le traitement aboutit ou échoue.

L’implémentation gère aussi les cas limites opérationnels : sommes de contrôle identiques, texte extrait vide, suivi des modifications dans les fichiers DOCX, diffs trop volumineux, fichiers non pris en charge et motifs d’échec sûrs qui n’exposent aucun détail interne.

Accès et facturation

L’accès au contenu juridique constitue un domaine distinct du paiement.

Cette distinction est importante. Un paiement est un événement commercial. L’accès est une décision relative à un droit.

Leganews prend en charge deux modes d’accès :

Mermaid

Lorsqu’un utilisateur demande un Work protégé, le mécanisme d’autorisation vérifie d’abord l’existence d’un droit direct actif. À défaut, il évalue l’accès par abonnement, y compris la couverture de l’organisation et les rôles privilégiés.

Billing porte les produits, les prix, les commandes, les lignes de commande, les transactions de paiement et les événements des prestataires. Access porte les abonnements, les organisations, les adhésions, les invitations, les sièges et les droits sur les Works. Les deux contextes collaborent au moyen de services d’exécution et d’événements explicites.

Le parcours de paiement répond aux besoins locaux au moyen de FlexPay, notamment pour les paiements par mobile money et par carte en CDF ou en USD.

Mermaid

Les callbacks de paiement sont conçus pour être idempotents. Le système calcule une empreinte stable pour chaque événement du prestataire, ignore les répétitions exactes, verrouille la transaction de paiement pendant l’application du résultat et n’exécute pas deux fois une commande. L’exécution valide chaque ligne de commande avant de créer le moindre droit et ne marque la commande comme exécutée qu’après la réussite de tous les éléments.

C’est l’un des cas où la séparation des domaines apporte une sécurité concrète. Billing peut confirmer que l’argent a été encaissé. Access détermine ce que cet achat est autorisé à débloquer.

API et applications web

Leganews dispose de deux applications React construites avec TanStack Start :

Mermaid

Les deux applications utilisent React, TanStack Router, TanStack Query, Tailwind CSS, Zod et des packages d’espace de travail partagés, gérés avec Bun et Turborepo.

Le navigateur ne stocke pas directement les jetons d’accès et de renouvellement Symfony. Chaque application TanStack Start possède une frontière de session backend-for-frontend de même origine. Après l’authentification, les jetons sont stockés côté serveur derrière un cookie de session HTTP-only. Les requêtes du navigateur passent par la route /api de l’application, qui les transmet à Symfony, ajoute le jeton d’accès approprié, renouvelle si possible une session expirée, puis relance la requête protégée.

L’API reçoit également un en-tête X-Client-Platform. Symfony utilise les métadonnées des contrôleurs et une protection de plateforme centralisée pour empêcher l’application principale d’appeler les interfaces administratives, ou l’application d’administration d’utiliser par inadvertance une route non prise en charge.

Côté TypeScript, @workspace/api expose des clients propres à chaque plateforme :

Mermaid

Les contrats sont définis avec Zod et les types TypeScript sont inférés à partir de ces schémas. Le package masque la construction brute des URL, les détails HTTP et les utilitaires de requête derrière de petites interfaces orientées produit.

Cela crée une frontière utile :

Mermaid

Le frontend peut se concentrer sur les parcours utilisateur. Symfony reste responsable des décisions métier.

Migration de la plateforme historique

Leganews n’est pas un produit créé de zéro. L’initiative a commencé plusieurs années avant l’architecture actuelle, et la nouvelle plateforme doit préserver les données utiles de l’application précédente.

L’environnement de développement exécute à la fois PostgreSQL et la base MariaDB historique. Un importateur fondé sur des plans déplace les enregistrements dans l’ordre de leurs dépendances :

Mermaid

Chaque plan d’importation associe un concept historique au nouveau modèle de domaine, détecte les conflits, prend en charge les simulations et les filtres, puis indique si chaque ligne a été insérée, ignorée, rejetée ou a échoué.

Les importations s’exécutent par lots limités afin qu’un grand jeu de données historiques n’ait pas à tenir entièrement en mémoire. Le parcours de réinitialisation peut reconstruire la base PostgreSQL, importer les données historiques et d’amorçage, reconstruire les projections de recherche, téléverser de nouveau les pièces jointes dans le stockage d’objets, rapprocher les relations de citation et synchroniser les abonnements expirés.

La migration n’est pas traitée comme une copie SQL ponctuelle. L’ancien schéma et le nouveau modèle de domaine n’expriment pas les mêmes concepts. Une correspondance au moyen de plans explicites rend ces différences visibles et permet aux nouvelles règles du domaine de rester la référence.

Ce fut un enseignement important : préserver les données ne signifie pas préserver l’ancien modèle.

IA appliquée et frontières éditoriales

Leganews confie délibérément un rôle limité à l’IA.

Lorsqu’une Expression publiée ne possède aucun résumé éditorial, la plateforme peut générer un court résumé en français au moyen d’un modèle OpenAI ou Gemini configuré. Le prompt exige un résumé factuel, sans interprétation ni information absente de la source. La taille de l’entrée est limitée, les défaillances du fournisseur sont journalisées et le résumé conserve sa provenance : manuelle, générée ou extraite.

Si aucun fournisseur n’est configuré ou si la génération échoue, le parcours de publication peut se replier sur un résumé déterministe extrait des Expression Units. La publication ne doit pas devenir indisponible parce qu’un modèle externe l’est.

Le même principe s’applique aux relations juridiques. Les systèmes automatisés peuvent créer des suggestions de relation assorties d’éléments probants et d’un niveau de confiance, mais une suggestion reste distincte d’une relation juridique confirmée.

La règle de conception est la suivante :

L’IA peut accélérer le travail éditorial, mais elle ne doit pas devenir silencieusement la source de la vérité juridique.

Fiabilité, observabilité et tests

Une plateforme qui dépend de tâches en arrière-plan, de paiements, d’un stockage externe, d’une diffusion en temps réel et de parcours éditoriaux ne peut pas se contenter de réponses HTTP réussies.

Leganews utilise Symfony Messenger adossé à Redis pour le travail asynchrone et le stockage des messages en échec. Des tâches planifiées gèrent notamment les abonnements expirés, le nettoyage des comparaisons, les récapitulatifs de veille, le nettoyage des comptes et les rapports mensuels de la plateforme.

Les signaux opérationnels sont séparés selon leur finalité :

  • journaux applicatifs structurés avec rotation ;
  • journaux d’audit métier ;
  • capture des erreurs compatible avec Sentry ;
  • notifications Telegram pour les défaillances métier critiques ;
  • identifiants de corrélation entre les bus et les requêtes ;
  • contrôles d’état pour les tableaux de bord opérationnels ;
  • événements Google Analytics après assainissement des données personnelles dans les applications web.

Les statistiques de consultation des Works utilisent HyperLogLog pour estimer le nombre de lecteurs uniques. Les métriques de lecture agrégées restent ainsi utiles sans conserver une ligne d’historique anonyme détaillée pour chaque visite.

Les tests sont eux aussi répartis par responsabilité :

Mermaid

Les scénarios Behat sont particulièrement utiles, car ils décrivent le comportement de l’application dans le langage du produit : une Expression publiée rend un Work lisible, un webhook de paiement dupliqué n’est traité qu’une fois, un abonné expiré ne reçoit plus d’alerte et une organisation avec un abonnement actif ne peut pas être archivée.

Les tests sont ainsi plus qu’une suite de régression. Ils constituent une documentation exécutable du domaine.

Principales décisions d’ingénierie

Modéliser le sens juridique avant les fichiers

La plateforme ne traite pas un PDF comme l’objet juridique. Work, Expression, Unit et Manifestation séparent l’identité stable, la version sémantique, la structure et le rendu technique.

Ce modèle ouvre la voie au versionnement, à la consolidation, à la recherche, aux citations, à la comparaison et aux futures requêtes temporelles.

Faire de la publication un événement

La publication d’une Expression est le moment où le travail éditorial devient un comportement du produit. L’indexation de recherche, les résumés, les manifestations, les citations, les comparaisons et les alertes réagissent tous à cette transition.

L’éditeur reste ainsi concentré sur le travail éditorial, tandis que les fonctionnalités en aval demeurent découplées.

Séparer les suggestions des faits juridiques

Une suggestion de relation générée par l’IA ou importée n’est pas une Work Relation confirmée. Les éléments probants, le niveau de confiance et la validation éditoriale établissent une frontière explicite entre assistance et autorité.

Utiliser PostgreSQL avant d’ajouter un cluster de recherche distinct

PostgreSQL fournit déjà la recherche française en texte intégral, le classement, la mise en évidence, les trigrammes, les filtres relationnels et les index. Un service de recherche distinct ajouterait des coûts de déploiement et de synchronisation avant que le produit ait démontré les limites de PostgreSQL.

Séparer la facturation de l’accès

La réussite d’un paiement ne signifie pas directement « afficher le contenu ». Billing enregistre la vérité commerciale ; Access accorde les droits dans le produit. Une exécution idempotente relie les deux.

Garder les jetons hors du stockage du navigateur

Le BFF TanStack Start porte la session de chaque application, transmet les requêtes de même origine et renouvelle les jetons Symfony côté serveur. Les sessions principale et d’administration restent séparées.

Traiter la migration historique comme une traduction du domaine

L’ancien schéma MariaDB est une source, et non le modèle cible. Des plans d’importation ordonnés traduisent les anciens enregistrements dans le domaine actuel et signalent explicitement les conflits.

Utiliser le traitement asynchrone lorsque l’utilisateur ne doit pas attendre

L’extraction de documents, les comparaisons, les alertes, les courriels et les autres parcours en arrière-plan passent par Messenger. Mercure referme la boucle de rétroaction en actualisant l’interface lorsque le traitement change d’état.

Utiliser l’IA comme un adaptateur remplaçable

La génération de résumés se trouve derrière une interface applicative, prend en charge plusieurs fournisseurs, conserve la provenance et dispose d’une solution de repli déterministe. Le cœur du corpus ne dépend pas d’un fournisseur d’IA unique.

Ce que j’ai appris

Le principal enseignement de Leganews est que l’accès à l’information juridique ne se résout pas en téléversant davantage de fichiers.

Mon rôle de cofondateur a changé ma façon d’aborder la refonte. Je ne pouvais pas évaluer le système uniquement comme ingénieur. Chaque changement d’architecture devait protéger des années de travail éditorial, les utilisateurs existants, les règles commerciales et la confiance attachée au nom Leganews. La meilleure conception n’était pas le modèle le plus pur pris isolément, mais celui qui pouvait faire progresser le produit sans faire comme si son histoire n’existait pas.

La difficulté réside dans la préservation du contexte.

Un professionnel du droit doit savoir de quel texte il s’agit, d’où il vient, quelle version est consultée, comment il est structuré, ce qu’il modifie, ce qui le modifie et si la source suffit à la décision envisagée.

J’ai également appris que le parcours éditorial fait partie de l’architecture du système. Dans un produit juridique, la qualité des données ne peut pas être séparée de la manière dont le contenu est créé, relu, corrigé, approuvé, publié et retiré. Une expérience publique de recherche solide dépend d’un processus éditorial interne tout aussi solide.

La recherche a pris plus d’importance que prévu. Une fois le corpus structuré, le défi suivant n’était plus le stockage, mais l’accès à l’information : normalisation du français, classement, correspondance approximative de repli, filtres, mise en évidence et métadonnées suffisantes pour permettre aux utilisateurs d’évaluer un résultat.

La veille a aussi modifié l’orientation du produit. Une recherche juridique se limite rarement à une seule requête : c’est une activité continue. Les bookmarks, les notes, les recherches récentes, les alertes, les notifications en temps réel et les récapitulatifs hebdomadaires transforment le corpus en espace de travail plutôt qu’en bibliothèque statique.

La migration depuis la plateforme historique a renforcé un autre enseignement : une réécriture doit préserver l’histoire métier sans conserver toutes les anciennes abstractions. Des plans d’importation explicites ont permis de traduire des années de données dans un modèle de domaine plus clair, tout en consignant ce qui ne pouvait pas être associé en toute sécurité.

Les paiements m’ont appris l’importance de l’idempotence. Les prestataires relancent les callbacks, les utilisateurs répètent des actions et les parcours distribués peuvent échouer entre deux étapes. Des empreintes d’événement stables, des verrous d’enregistrement, une validation préalable et une exécution idempotente rendent le parcours commercial fiable.

Enfin, l’IA est surtout utile lorsque son autorité est limitée. Les résumés générés et les suggestions de relation peuvent réduire l’effort éditorial, mais la provenance, les solutions de repli déterministes et la validation humaine importent davantage que de placer l’IA au centre de l’architecture.

Conclusion

Leganews Pro est une plateforme d’information et de veille juridique destinée au marché congolais.

Pour moi, en tant que cofondateur, c’est aussi un travail de longue haleine : transformer un véritable problème institutionnel en produit, puis avoir la discipline de repenser ce produit lorsque son premier modèle atteint ses limites.

Sa principale valeur technique ne réside pas dans le stockage de lois et de décisions. Elle tient au système qui entoure ces documents : un modèle de domaine pour l’identité et les versions juridiques, des parcours éditoriaux structurés, des relations juridiques porteuses de sens, une recherche indexée, une veille personnelle, une comparaison asynchrone, une attribution sûre des accès, la migration des données historiques et une assistance par IA soigneusement encadrée.

La plateforme transforme des ressources juridiques dispersées en un parcours éditorialisé dans lequel un texte peut être enregistré, structuré, relu, publié, recherché, lu, cité, comparé, sauvegardé et suivi.

Telle est l’idée qui sous-tend Leganews : réduire la distance entre une question juridique et les sources fiables nécessaires pour y répondre.

Autres projets

Tout voir

2025

Basango

Vers un système évolutif et intelligent de curation de l’actualité congolaise

Voir

2025

PHP Packages Graph

Explorer l’écosystème PHP à partir des paquets publiés sur packagist.org

Voir

2025

Points of Interest

Cartographie collaborative des zones d’activité par contributions anonymes

Voir