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.
- Exemples :
- Nouvelle Source si l’on enrichit un Context existant.
- Exemples :
favorite_actors,interested_events,collectes,services.
- Exemples :
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 :
WallContextDefinitionWallCommuneContextWallPersonalContextWallActorContext
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
WallEngineaccepte maintenant un Context complet.WallProvidercompose les hooks à partir du Context.Mon espace V2convertit ses contextes locaux vers unWallContextDefinition.ActorContextpasse déjà parWallEngine, même si son flux reste expérimental.- La route publique
MurVillene passe plus par un point d’entrée nomméMurVilleLegacy. MurVille.tsxrend désormaisMurVilleHost, façade publique minimale.WallMurVilleBridgeporte le bridge interne transitoire qui reproduit le mur public sans changement de rendu.
Encore transitoire
PersonalContextmétier est encore défini dansapp/components/mon-espace/types.ts.- ses
sources[]restent pour l’instant un contrat local Mon espace ; WallProviderne consomme pas encore une liste générique de Sources ;- les hooks
usePublicationsetuseCollectesrestent des adaptateurs techniques, pas des Contexts. WallEngine/WallLayoutrestent expérimentaux pour la route publique MurVille ;- la façade publique
MurVilleHosts’appuie encore surWallMurVilleBridgeau lieu d’unWallEnginepixel-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.tsxrendMurVilleHost.app/components/MurVilleHost.tsxest la façade publique minimale du mur.- L’ancien point d’entrée public
MurVilleLegacya été retiré du flux public. app/components/wall/components/mur-ville/WallMurVilleBridge.tsxreste un bridge interne transitoire, pas une API produit.
Tracker de migration
- 🟢 Façade publique
MurVille.tsxMurVilleHost.tsx
- 🟢 Bridge interne
WallMurVilleBridgeWallMurVilleHostContainerWallVilleDrawer
- 🟢 Containers migrés
WallShellContainerWallFeedContainerWallActorsContainerWallPrimaryControlsContainerWallSecondaryPagesContainer
- 🟢 Hooks migrés
usePublicationsuseCollectesuseWallStateuseWallActorsDatauseWallTargetedPublicationsuseWallAgendaInterestsuseWallUserSignalsuseWallViewportInteractionsuseWallMurVilleRuntimeuseWallMurVilleHostProps
- 🟢 Sélecteurs migrés
publicationFeedSelectorsagendaSelectorsactorPanelSelectors
- 🟢 Leaf components migrés
WallPublicationCardWallFilterPanelWallCityHeaderWallLatestJoinedWallVisitorTipsBannerWallEmptyStateCardWallPublicationSkeletonListAgendaInterestButtonAgendaTabsBarAgendaLegendActorMiniCardAlertsTickerWebSecondaryShortcutBar
- 🟡 État restant
WallMurVilleBridgeconcentre encore les types locaux, les dérivations métier et l’orchestration finale du mur public.WallEngine/WallLayoutne sont pas encore le moteur réel de la route publique MurVille.
- 🔴 Non encore branché
- bascule de la route publique MurVille vers un
WallEngineréellement pixel-perfect - suppression finale du bridge transitoire
- bascule de la route publique MurVille vers un
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
WallEnginecomme 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 :
publicationsmairieeventscollectespractical_infomunicipal_services
PersonalContext
Point de vue : l’accueil connecté de l’utilisateur.
Sources prévues :
primary_communefavorite_actorsinterested_eventsfollowed_communesrecommendations
ActorContext
Point de vue : un acteur local.
Sources prévues :
publicationseventsservicesinfosmini_site
Contexts futurs
SearchContextAroundMeContextAssociationContextSchoolContextEventContext
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
- Un besoin métier nouveau commence par identifier un Context ou une Source.
- Un hook technique de fetch ne devient pas une API publique du produit.
- Les Sources restent dépendantes du Context, pas de
WallEngine. WallEnginereçoit un Context prêt et ne change pas pour un besoin métier.- 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
MurVilleHostcomme façade publique stable ; - garder
WallMurVilleBridgecomme bridge interne transitoire tant queWallEnginen’est pas pixel-perfect.
Phase 2 — branchement futur du vrai WallEngine
- aligner
WallEngine/WallLayoutsur 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
WallMurVilleBridgeseulement 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
WallEnginepour un besoin métier spécifique.