Aller au contenu principal

Context Engine et WallEngine

Version provisoire — Ce document décrit l'architecture en place et les règles de structuration actuelles. L'architecture cible (Ranking Engine, trois surfaces, unification des moteurs) est définie dans 34-ranking-engine-synthesis.md.

Principe

WallEngine ne connaît jamais l'origine métier des données.

Il reçoit uniquement un Context déjà construit.

Chaque Context agrège plusieurs Sources.

Chaque Source charge ou prépare une famille de données.

WallProvider compose ensuite les hooks de données et de state à partir du Context.

Règle de décision

Avant toute nouvelle fonctionnalité, poser la question suivante :

Est-ce un nouveau Context ou une nouvelle Source ?

  • Nouveau Context si l’utilisateur change de point de vue principal.
    • Exemples : PersonalContext, CommuneContext, ActorContext, SearchContext.
  • Nouvelle Source si l’on enrichit un Context existant.
    • Exemples : favorite_actors, interested_events, collectes, services.

WallEngine ne doit pas être modifié pour ajouter une fonctionnalité métier.

Règle fondamentale — Préservation de l’expérience utilisateur

Principe

Lorsqu’un composant existant est refactoré, extrait, déplacé ou migré vers une nouvelle architecture (WallEngine, Context Engine, hooks, providers, widgets, etc.), le produit ne doit pas changer.

Le refactoring concerne uniquement le code.

Il ne concerne jamais l’expérience utilisateur.

L’interface actuelle est la référence

Pour DMV, l’interface actuellement en production constitue la spécification fonctionnelle et graphique.

Elle n’est pas un exemple.

Elle est la référence.

Chaque composant extrait doit reproduire exactement :

  • le rendu visuel ;
  • les comportements ;
  • les interactions ;
  • les animations ;
  • les transitions ;
  • les espacements ;
  • les dimensions ;
  • les couleurs ;
  • les textes ;
  • l’ordre des éléments.

Le résultat doit être identique au pixel près.

Ce qui est autorisé

Le développeur peut :

  • améliorer l’architecture ;
  • découper un gros composant ;
  • créer des hooks ;
  • créer des Contexts ;
  • créer des Providers ;
  • créer des Widgets ;
  • améliorer les performances ;
  • améliorer la lisibilité du code ;
  • améliorer la testabilité ;
  • améliorer la réutilisabilité.

À condition que le comportement utilisateur reste strictement identique.

Ce qui est interdit

Sans demande explicite, il est interdit de :

  • modifier un padding ;
  • modifier une marge ;
  • modifier une couleur ;
  • modifier une taille ;
  • modifier une police ;
  • modifier une icône ;
  • modifier un texte ;
  • modifier un rayon ;
  • modifier une ombre ;
  • modifier une animation ;
  • modifier une transition ;
  • modifier un ordre d’affichage ;
  • modifier une interaction utilisateur ;
  • modifier un comportement.

Même si cela semble plus moderne, plus élégant ou plus cohérent.

Régression

Toute différence visuelle ou fonctionnelle non demandée est considérée comme une régression.

Une régression doit être corrigée avant la poursuite du développement.

Évolution UX

Les évolutions d’interface ne sont jamais réalisées pendant un refactoring.

Une évolution UX doit toujours faire l’objet :

  • d’une décision produit explicite ;
  • d’une User Story dédiée ;
  • d’une validation avant implémentation.

Règle pour les assistants IA

Les assistants IA (Codex, Claude Code, ChatGPT ou tout autre agent) ne doivent jamais profiter d’un refactoring pour “améliorer” l’interface.

Leur rôle est de préserver le produit existant.

Ils doivent considérer l’interface actuelle comme une spécification contractuelle.

Toute modification graphique ou comportementale doit être explicitement demandée par le Product Owner.

À défaut, ils doivent reproduire exactement le rendu et les interactions existants.

Philosophie DMV

Le produit évolue uniquement par décision produit.

Le code évolue en permanence.

Le produit ne doit jamais évoluer par accident.

Couches cibles

Context Engine

Context definitions

Context sources

WallProvider

WallEngine

Widgets

Contrats actuels

1. Business Context

Le contrat partagé côté Wall vit dans app/components/wall/contexts/types.ts.

Types actuels :

  • WallContextDefinition
  • WallCommuneContext
  • WallPersonalContext
  • WallActorContext

Règle :

  • un Context décrit ce que le mur doit afficher ;
  • il ne décrit pas comment charger chaque donnée métier.

2. React Provider

Le provider React vit dans app/components/wall/context/WallContext.tsx.

Rôle :

  • recevoir un WallContextDefinition ;
  • résoudre la commune si elle existe ;
  • composer les hooks data actuels ;
  • exposer context, state, publications, collectes, isLoading, error, refresh.

3. Presentation Engine

WallEngine et WallLayout :

  • lisent un Context déjà prêt ;
  • ne connaissent pas favorite_actors, profiles, favoris, auth/me, etc. ;
  • gèrent uniquement la composition UI et les états de rendu.

Cohérence actuelle du code

Déjà cohérent

  • WallEngine accepte maintenant un Context complet.
  • WallProvider compose les hooks à partir du Context.
  • Mon espace V2 convertit ses contextes locaux vers un WallContextDefinition.
  • ActorContext passe déjà par WallEngine, même si son flux reste expérimental.
  • La route publique MurVille ne passe plus par un point d’entrée nommé MurVilleLegacy.
  • MurVille.tsx rend désormais MurVilleHost, façade publique minimale.
  • WallMurVilleBridge porte le bridge interne transitoire qui reproduit le mur public sans changement de rendu.

Encore transitoire

  • PersonalContext métier est encore défini dans app/components/mon-espace/types.ts.
  • ses sources[] restent pour l’instant un contrat local Mon espace ;
  • WallProvider ne consomme pas encore une liste générique de Sources ;
  • les hooks usePublications et useCollectes restent des adaptateurs techniques, pas des Contexts.
  • WallEngine / WallLayout restent expérimentaux pour la route publique MurVille ;
  • la façade publique MurVilleHost s’appuie encore sur WallMurVilleBridge au lieu d’un WallEngine pixel-perfect.

Conclusion :

le code actuel est compatible avec la cible, mais la couche Context sources n’est pas encore centralisée dans wall/contexts/.

État de migration MurVille — post-renommage

Entrées publiques

  • app/components/MurVille.tsx rend MurVilleHost.
  • app/components/MurVilleHost.tsx est la façade publique minimale du mur.
  • L’ancien point d’entrée public MurVilleLegacy a été retiré du flux public.
  • app/components/wall/components/mur-ville/WallMurVilleBridge.tsx reste un bridge interne transitoire, pas une API produit.

Tracker de migration

  • 🟢 Façade publique
    • MurVille.tsx
    • MurVilleHost.tsx
  • 🟢 Bridge interne
    • WallMurVilleBridge
    • WallMurVilleHostContainer
    • WallVilleDrawer
  • 🟢 Containers migrés
    • WallShellContainer
    • WallFeedContainer
    • WallActorsContainer
    • WallPrimaryControlsContainer
    • WallSecondaryPagesContainer
  • 🟢 Hooks migrés
    • usePublications
    • useCollectes
    • useWallState
    • useWallActorsData
    • useWallTargetedPublications
    • useWallAgendaInterests
    • useWallUserSignals
    • useWallViewportInteractions
    • useWallMurVilleRuntime
    • useWallMurVilleHostProps
  • 🟢 Sélecteurs migrés
    • publicationFeedSelectors
    • agendaSelectors
    • actorPanelSelectors
  • 🟢 Leaf components migrés
    • WallPublicationCard
    • WallFilterPanel
    • WallCityHeader
    • WallLatestJoined
    • WallVisitorTipsBanner
    • WallEmptyStateCard
    • WallPublicationSkeletonList
    • AgendaInterestButton
    • AgendaTabsBar
    • AgendaLegend
    • ActorMiniCard
    • AlertsTickerWeb
    • SecondaryShortcutBar
  • 🟡 État restant
    • WallMurVilleBridge concentre encore les types locaux, les dérivations métier et l’orchestration finale du mur public.
    • WallEngine / WallLayout ne sont pas encore le moteur réel de la route publique MurVille.
  • 🔴 Non encore branché
    • bascule de la route publique MurVille vers un WallEngine réellement pixel-perfect
    • suppression finale du bridge transitoire

Résultat actuel

  • La migration UI publique de MurVille est terminée.
  • Le rendu public est conservé à l’identique.
  • Le legacy n’est plus un point d’entrée public, mais un bridge interne transitoire existe encore.
  • Le prochain chantier n’est plus la migration des composants, mais la sécurisation du branchement futur de WallEngine comme moteur réel.
  • Le jalon documentaire associé est : WallEngine V1 — Parité MurVille atteinte.
  • La QA associée est suivie via la Checklist QA MurVille.

Contexts cibles

CommuneContext

Point de vue : une commune.

Sources prévues :

  • publications
  • mairie
  • events
  • collectes
  • practical_info
  • municipal_services

PersonalContext

Point de vue : l’accueil connecté de l’utilisateur.

Sources prévues :

  • primary_commune
  • favorite_actors
  • interested_events
  • followed_communes
  • recommendations

ActorContext

Point de vue : un acteur local.

Sources prévues :

  • publications
  • events
  • services
  • infos
  • mini_site

Contexts futurs

  • SearchContext
  • AroundMeContext
  • AssociationContext
  • SchoolContext
  • EventContext

Arborescence cible recommandée

app/components/
MurVille.tsx
MurVilleHost.tsx
app/components/wall/
contexts/
README.md
types.ts
personal/
sources/
commune/
sources/
actor/
sources/
context/
WallContext.tsx
hooks/
useWallState.ts
components/
WallLayout.tsx
legacy/
WallMurVilleBridge.tsx
...
WallEngine.tsx

Règles d’évolution

  1. Un besoin métier nouveau commence par identifier un Context ou une Source.
  2. Un hook technique de fetch ne devient pas une API publique du produit.
  3. Les Sources restent dépendantes du Context, pas de WallEngine.
  4. WallEngine reçoit un Context prêt et ne change pas pour un besoin métier.
  5. Les widgets affichent un résultat consolidé, jamais les détails d’agrégation.

Prochaine étape recommandée

Phase 1 — sécurisation post-migration

  • maintenir la QA manuelle de non-régression sur la route publique MurVille ;
  • garder MurVilleHost comme façade publique stable ;
  • garder WallMurVilleBridge comme bridge interne transitoire tant que WallEngine n’est pas pixel-perfect.

Phase 2 — branchement futur du vrai WallEngine

  • aligner WallEngine / WallLayout sur le rendu exact du mur public ;
  • conserver la règle contractuelle : aucune différence visuelle ou comportementale ;
  • brancher ensuite la route publique MurVille sur le vrai WallEngine ;
  • supprimer WallMurVilleBridge seulement après validation complète de cette bascule.

Phase 3 — poursuite de l’architecture Context Engine

  • centraliser progressivement les Sources métier dans wall/contexts/ ;
  • continuer personal/sources/primaryCommune, personal/sources/favoriteActors, puis les Sources acteur et commune ;
  • ne jamais modifier WallEngine pour un besoin métier spécifique.