YYayaw
Documentation

Vue d'ensemble du CMS

Comment les surfaces de contenu, modèles de données, médias, sections, pages, design tokens et modèles d'e-mails de Yayaw s'articulent.

Vue d'ensemble

Le CMS de Yayaw est la couche d'exploitation de contenu dans le dashboard. Il combine données structurées, sections réutilisables, pages, ressources média, design tokens publics, modèles d'e-mails transactionnels et recettes de composants sous un même modèle d'autorisation.

Le point d'entrée principal est :

  • /dashboard/content

Ce dashboard résume l'inventaire des pages, l'inventaire des sections, le stockage média, les données CMS publiées, les jobs IA, la santé de publication et les raccourcis vers chaque surface de contenu disponible pour l'utilisateur courant.

Carte des surfaces

SurfaceRouteObjectif
Tableau de bord CMS/dashboard/contentVue opérationnelle et santé du contenu
Pages/dashboard/content/pagesComposition de pages publiques et d'organisation
Sections/dashboard/content/sectionsSections de page réutilisables et recettes générées
Modèles de données/dashboard/content/data-modelsDéfinitions typées de modèles CMS
Entrées de données/dashboard/content/dataContenu publié singleton et collection
Médias/dashboard/content/mediaRessources binaires scopées par organisation et images générées
Composants/dashboard/content/componentsRegistre de composants UI, aperçus et imports
Design tokens/dashboard/content/design-tokensSurcharges de tokens de thème publics au runtime
Modèles d'e-mails/dashboard/content/email-templatesModèles transactionnels React Email

Pile de contenu

Le CMS est volontairement organisé en couches :

  1. Les modèles de données définissent les champs typés, les règles de localisation et la cardinalité.
  2. Les entrées de données publient des valeurs partagées, comme les menus d'en-tête, les menus de pied de page et les variables de site.
  3. Les ressources média fournissent des URL publiques durables pour les fichiers sélectionnés ou générés.
  4. Les composants définissent l'inventaire UI réutilisable et les moteurs de rendu de recettes.
  5. Les sections lient des littéraux, des données CMS ou des médias dans des unités de page réutilisables.
  6. Les pages composent des noeuds de mise en page, des références de composants et des références de sections publiées dans des routes publiques ou réservées aux membres d'organisation.
  7. Les design tokens modifient la présentation publique via les couches globales et organisation. Une page globale peut aussi porter une couche bornée de couleurs sémantiques et de rôles sans/serif dans sa révision.
  8. Les modèles d'e-mails transactionnels réutilisent les variables CMS quand cela convient, mais sont envoyés par le runtime e-mail, pas par le moteur de rendu des pages publiques.

Cette séparation garde le contenu réutilisable au même endroit. Les pages doivent référencer des sections et des entrées de données publiées au lieu de copier le JSON de menu, les promesses partagées, les images ou le contenu répété dans chaque document.

Flux d'édition

Une modification CMS typique suit ce parcours :

  1. Créer ou mettre à jour la source structurée dans les modèles de données, les entrées de données ou la médiathèque.
  2. Construire une section réutilisable quand le contenu doit apparaître sur plus d'une page.
  3. Composer la page dans l'éditeur Puck avec des noeuds de mise en page intégrés, des références de sections et des références directes de composants seulement si nécessaire.
  4. Publier la page ou la section une fois les diagnostics de validation propres.
  5. Vérifier la route publique ou réservée aux membres d'organisation.

La largeur de page et le rythme des sections appartiennent au layout sérialisé. Un plan contextuel définit page.layout.bodyWidth, page.layout.sectionGap et page.layout.sectionFrame. Ces valeurs pilotent le container, l'espacement et le cadre partagé du PageStack racine. sectionFrame: "token" conserve le wrapper public standard ; "none" laisse les sections art-directed maîtriser leurs limites sans second cadre uniforme.

Une direction artistique isolée pour une page globale peut définir page.designTokens sans modifier le registre global. À la création, l'omission ou null hérite ; lors d'un rework, l'omission préserve la couche cible, null la supprime et un payload la remplace. Le payload versionné accepte les couleurs sémantiques clair/sombre et les rôles sans/serif chargés et approuvés. Les tokens de layout ou d'effet, les polices mono, le CSS arbitraire, les URL et les familles non enregistrées sont rejetés. La couche normalisée est liée par hash à la révision et utilise le même wrapper dans l'aperçu immuable et le runtime publié.

Les flux assistés par IA suivent le même modèle de persistance. Page AI promeut le contenu généré en sections réutilisables, la génération d'images Page AI persiste les médias via la médiathèque, et l'absence de publication d'une section produit un échec explicite au lieu d'un fallback inline.

Le design de page assisté par MCP suit le même modèle, mais le client Codex ou ChatGPT connecté porte le raisonnement créatif et la génération d'images. Yayaw n'appelle pas un second modèle texte côté serveur pour ce workflow. Le MCP fournit la guidance bornée, l'inventaire du CMS, l'ingestion durable des médias, la validation, la persistance des brouillons et les aperçus.

La guidance de design externe utilisée par ce flux est gérée comme un ensemble de dépendances avec checksums et licences conservées. Voir Dépendances de skills de design du CMS pour le workflow de mise à jour et de vérification.

Workflow MCP contextuel de design

Les nouvelles pages et les reworks utilisent un seul parcours obligatoire :

  1. Lire d'abord les couches de design tokens actives. Enregistrer toute modification globale ou organisation approuvée avant de créer le contexte, puis appeler yayaw_cms_design_prepare avec la surface, le scope, les locales, l'audience, l'objectif, la direction visuelle, les faits, la stratégie média et visualIntent. Quand cette intention manque, la préparation pose seule une première question localisée pour choisir new_art_direction, evolve_existing ou preserve_existing. Les autres questions qui changent le résultat ne viennent qu'après cette réponse. Un appelant ne peut pas présélectionner la compositionStrategy technique sans cette intention. Le serveur dérive une compositionStrategy compatible ; un appelant ne peut pas choisir une stratégie non créative pour contourner les prototypes. L'outil renvoie un contexte lié à l'acteur avec son expiresAt, une preuve d'inventaire, la guidance versionnée utile et jusqu'à trois questions qui changent réellement le résultat. Les médias de marque explicites sont résolus avant que le contexte soit prêt. Pour une page globale, un média appartenant à une organisation n'entre dans l'inventaire immuable que si l'acteur peut lister la médiathèque propriétaire et lire chaque média sélectionné ; les refreshs conservent ces références vérifiées. Une réponse prête commence au stage de guidance brief, énumère les stages requis et indique explicitement si le workflow de prototypes exact-runtime version 2 est obligatoire. Pendant une longue pause, yayaw_cms_design_context_renew prolonge un contexte non expiré sans modifier ses preuves, dans une limite de deux heures depuis la création de la session. Un contexte expiré reste terminal.
  2. Les clients MCP modernes répondent via l'élicitation par formulaire. Les clients classiques reçoivent le même état input_required et continuent avec yayaw_cms_design_resume ; les deux chemins produisent le même contexte. Une fois le contexte prêt, charger brief, composition et critique via yayaw_cms_design_guidance_get, ainsi que rework pour un rework. Les stages de guidance ne sont enregistrés comme chargés que lorsque leur contenu est effectivement renvoyé ; un chargement sans contenu ne débloque ni les prototypes ni le dry-run. Le serveur hash aussi le contenu exact de chaque stage et sa trace de sources. L'enregistrement des prototypes soumet des décisions structurées avec des IDs de directive. Les IDs soumis doivent couvrir exactement une fois toutes les directives renvoyées par chaque stage requis et chargé ; tout ID omis, dupliqué ou inventé est refusé. Le serveur possède la classification de chaque directive et son garde-fou d'implémentation ; le client ne peut donc pas abaisser une règle visuelle. Chaque directive prototype_applicable porte un emplacement observé et validé pour chacun des trois candidats ; une directive implementation_only nomme son garde-fou ultérieur imposé par le serveur. Une trace version 2 porte aussi le verificationCheckId déterministe et optionnel possédé par le serveur pour les directives vérifiables plus tard. Le plan reconnaît exactement ce sous-ensemble d'implémentation server_checked, vérifiable par le serveur, via guidanceVerification: [{ directiveId }], sans pouvoir fournir de checker ni de chemin de preuve ; Yayaw exécute le contrôle et conserve le ledger immuable. Une directive process_only n'a pas de verificationCheckId : elle reste contraignante par sa décision structurée lors de l'enregistrement et par la preuve de processus ou l'attestation normale de son garde-fou, mais elle n'entre ni dans guidanceVerification ni dans le ledger de preuve déterministe. not_applicable n'est disponible que lorsque le serveur l'autorise, exige une raison concrète liée au brief ou à la surface et reste plafonné par stage.
  3. Le modèle client conçoit une structure commune à toutes les locales et fige les entrées que les prototypes rendront. Il réutilise les données, médias, composants et sections publiés avant de créer de nouvelles compositions. Les textes, métadonnées SEO, textes alternatifs et faits sont localisés sans modifier les IDs structurels. Si une modification large de tokens est découverte seulement ici, abandonner le contexte, enregistrer la couche et reprendre à l'étape 1 : un contexte existant ne peut pas être actualisé vers un autre hash de tokens. Pour une direction propre à une page globale, définir une couche page.designTokens bornée par candidat, la placer dans son pageShell, puis recopier exactement celle du candidat sélectionné dans le plan. Hors du scope d'une page globale, chaque candidat utilise designTokens: null.
  4. Uploader ou importer tous les médias de récit et de recette avec le designContextId actif, terminer leur finalisation avec yayaw_media_upload_complete et ne conserver que des images finalisées avec MIME, dimensions et hash SHA-256. Exécuter ensuite l'unique yayaw_cms_design_inventory_refresh de présélection. Il ne peut qu'ajouter des médias de ce contexte sans modifier les baselines de catalogue, données, pages ou tokens.
  5. Construire et inspecter trois planches statiques complètes, les uploader avec le designContextId, puis appeler yayaw_cms_prototypes_register avec kind: "generated_set_v2". Un prototype utilisateur peut ancrer un candidat mais ne réduit jamais le jeu sous trois. Chaque planche mesure au moins 1200 × 900, montre les héros desktop/mobile et toutes les sections prévues, et utilise le même ensemble ordonné d'IDs/libellés de régions. Les candidats fournissent des preuves d'originalité distinctes, un manifeste de capacités non vide, les décisions de guidance et les comparaisons A/B, A/C et B/C. Chaque candidat exact passe aussi un seuil de richesse créative calculé : display_typography et responsive_recomposition sont tous deux requis ; au moins une signature structurelle parmi layered_composition, sticky_narrative, custom_grid_ratios, continuous_canvas et compact_band ; puis au moins un traitement de direction artistique parmi image_art_direction, paper_collage, watercolor_wash, media_texture et decorative_shapes. Un texte manuscrit note seul n'infère pas paper_collage. Au moins une région signature doit inférer ensemble ces quatre dimensions ; répartir des primitives inertes entre des régions sans lien ne franchit pas le seuil. Une direction rejetée ou combinée impose un jeu de remplacement complet. Chaque région fournit son ledger de faisabilité exact : nœuds et chemins canoniques, props, recipePropSchema, recipePropNames, recipePropBindings, médias, responsive, thèmes, réduction de mouvement et fallback. Toute image utilise $props.<identifier> lié à un media_asset ou localized_media_asset finalisé de l'inventaire préparé. Chaque texte, lien, label, placeholder, texte alternatif ou message d'upload visible est un sink direct $props.<identifier>. Les textes sont des littéraux localisés exacts pour toutes les locales préparées ; les liens sont des cibles sûres et bornées. Les bindings global-data critiques ainsi que repeat/$item/$index sont refusés ; les éléments répétés visibles sont développés en nœuds explicites. Les recettes exactes refusent aussi les combinaisons valides mais inertes : ancre hors overlay, props de grille desktop sur overlay absolu, canvas composé uniquement d'overlays qui s'effondre, ou hauteur d'image fixe combinée à des ratios responsive. La grille, les stacks directionnels, les placements et le sticky utilisent tous le breakpoint de recomposition md. mobileSpan: "2" est refusé car la grille mobile de base ne possède qu'une colonne explicite. Une composition artisanale peut utiliser le traitement wash ou le pigment-wash plus intense et les matériaux de frame additifs watercolor-paper, deckle-paper ou taped-paper. Les valeurs historiques wash, paper, deckle et taped conservent exactement leur rendu. L'overflow art-directed est explicite : section.overflow et frame.overflow acceptent clip ou visible. La valeur visible n'infère continuous_canvas que si un placement descendant, une frame tournée ou scotchée, ou une grande décoration/wash peut réellement traverser la frontière. Les images acceptent des traitements blend bornés (normal, multiply, screen, soft-light) et opacity (solid, soft, faint) ; les traitements de texture non standards infèrent media_texture. Les actions et submits exposent les apparences bare, outline, paper, solid et underline ; les fields exposent bare, line, outline et paper ; les uploads exposent bare, dashed et paper. Le renderer créatif canonique conserve toutes les valeurs de props liées exactement et n'applique jamais la normalisation historique de démo catalogue après validation du manifeste de rendu. reuse_published pointe vers le composant publié exact ; new_recipe ne peut pas cloner une topologie déjà publiée et doit ensuite correspondre à une révision créée dans le même contexte. Yayaw exige trois signatures A/B/C distinctes de structure, d'implémentation et de rendu. Les compositionHash régionaux ordonnés forment la signature structurelle du candidat. Le manifeste normalisé du page shell est épinglé séparément et doit correspondre exactement au candidat sélectionné dans le plan et le runtime ; il ne fait pas partie de la signature de distinction entre candidats. Les implementationHash et renderManifestHash régionaux ordonnés forment les deux autres. Des changements de contenu, média, palette, défauts de schéma ou bindings ne transforment pas une topologie inchangée en direction séparée.
  6. Chaque candidat fournit aussi un pageShell exact (layout et couche designTokens bornée ou null) ainsi que des artifactBounds entiers pour chaque région. Une région mesure au moins 200 × 120 pixels et 2 % de la planche ; l'union des régions couvre au moins 40 % de la planche ; le chevauchement de deux régions ne dépasse pas 50 % de la plus petite. Le serveur fingerprint chaque crop et exige, pour chaque paire de candidats, qu'au moins une région correspondante soit matériellement distincte ; changer uniquement le chrome de la planche échoue. Le client fournit les arbres, schémas, bindings et bounds, mais jamais les compositionHash, implementationHash, renderManifestHash, hashes de pageShell, visualFingerprint ou runtimeHash. Le serveur les calcule depuis les artefacts durables, le snapshot de tokens, les manifestes exacts, le ledger média finalisé, les locales, le renderer canonique et l'empreinte de déploiement. En production, cette résolution échoue de façon fermée sans fingerprint immuable fourni par NEXT_DEPLOYMENT_ID, le gitCommitSha résolu tel que DEPLOYMENT_GIT_COMMIT_SHA, ou le deploymentId résolu. Le fallback "local" n'existe que hors production. Le fingerprint et la version du contrat renderer entrent dans runtimeHash : un changement de build renderer change donc le hash et invalide la revue antérieure.
  7. L'enregistrement renvoie, pour A, B et C, un runtimeHash, des URLs signées de rendu canonique par locale et le contrat d'upload de preuve. Ouvrir ces aperçus, ou renouveler seulement leurs URLs expirées avec yayaw_cms_prototype_runtime_previews_get lorsque le runtime reste courant. Capturer chaque locale préparée en desktop/mobile et clair/sombre. Chaque capture pleine page est une image durable distincte avec les designContextId, designPlanHash égal au runtimeHash candidat, et visualRole renvoyés exactement. Le desktop fait au moins 1024 pixels de large et le mobile entre 240 et 767. Chaque image finalisée porte aussi une attestation de capture version 1 liée à son hash d'artefact, son hash de runtime, son scénario, la hauteur de document observée et les IDs de région ordonnés. Ces régions forment une partition verticale contiguë de 0 à la hauteur image/document, avec IDs uniques, bandes d'au moins 24 pixels, sans trou ni chevauchement. La hauteur de l'image égale la hauteur attestée et reste sous le maximum renvoyé. Les IDs et hashes de fichier sont distincts. Ces screenshots post-enregistrement sont interrogés directement par ID : ne pas actualiser l'inventaire pour eux.
  8. Soumettre la matrice complète à yayaw_cms_prototype_runtime_review_complete avec boardMatchesRuntime: true, les huit champs de fidélité à true et aucun blocage ni écart non approuvé. reviewerRole: "visual_qa" est un rôle logique lié à l'acteur courant, pas la preuve d'une autre personne ou d'un autre credential. La planche et le runtime canonique restent deux artefacts séparés comparés visuellement ; fingerprints, manifestes, hashes, provenance et bindings de capture détectent substitution, troncature, rejeu et dérive. Sans contexte de formulaire live, l'aperçu conserve exactement le layout et les contrôles du formulaire enregistré, mais rend son wrapper inerte et impossible à soumettre ; le contexte de formulaire ne modifie donc pas la composition revue. La comparaison serveur utilise cms-server-visual-comparison-v3 : les bandes de référence et runtime sont normalisées par échantillonnage contenu 192 × 192 avec des seuils plus stricts de structure, topologie, aspect, contours, luminance et palette. La suppression d'un wash ou d'une texture signature échoue ainsi la fidélité. La frontière immuable courante est le contrat page 7 et le contrat prototype 4. La frontière explicite client_observed_server_validated ne prétend pas prouver cryptographiquement que le client a réellement piloté un navigateur.
  9. Une revue runtime courante est obligatoire avant yayaw_cms_prototype_select. Les étapes ultérieures résolvent à nouveau le candidat et son ledger de captures. Une modification du renderer ou du déploiement, d'une recette, d'un média, d'une capture ou du snapshot de tokens rend la revue périmée. Remplacer et réenregistrer les trois candidats avant sélection. Un changement de design tokens après l'enregistrement v2 exige un nouveau contexte, trois prototypes et une nouvelle revue ; un refresh ne peut pas rebaser le gate.
  10. Après une revue runtime courante, appeler yayaw_cms_prototype_select sans candidat. L'opération présente l'ordre canonique A/B/C, les preuves d'originalité comparées et des aperçus runtime frais. Les clients MCP modernes recueillent le choix enum par élicitation et l'enregistrent dans le même appel. Les clients classiques reçoivent la même présentation input_required, puis reprennent avec son challengeId borné et le prototypeId choisi. Exact-v2 refuse tout decisionNote écrit par le client : le reçu immuable généré côté serveur lie le challenge, la présentation, la revue runtime, la source de réponse et le choix. Le plan et la publication recalculent ce reçu et échouent si la preuve manque ou a été modifiée. resumable_client reste une attestation du client liée à l'acteur, pas une preuve cryptographique d'un clic humain ; l'élicitation fournit une preuve d'interaction protocolaire plus forte, mais toujours médiée par le client. Copier le designBasis immuable renvoyé. Importer, compiler et publier les new_recipe retenues avec le même designContextId. Finaliser aussi tous les médias supplémentaires que le plan liera, puis exécuter un yayaw_cms_design_inventory_refresh avec le même hash de tokens. Ce refresh conserve le gate v2, le reçu runtime, la sélection et la base tout en ajoutant les révisions publiées exactes et chaque asset lié.
  11. Soumettre un plan strict version: 2 avec page.layout, le designBasis renvoyé et l'inventaire actualisé à yayaw_cms_page_design ou yayaw_cms_page_rework, d'abord avec dryRun: true, puis persister le même plan hashé. Chaque section se mappe dans l'ordre à <prototypeId>#<regionId>, et tout composant déclaré nouveau est utilisé par sa révision publiée exacte à la racine de la composition. La page reproduit aussi exactement le pageShell.layout et la valeur designTokens du candidat sélectionné. Le dry-run revalide le prototype, le runtime-review receipt et les manifestes exacts avant d'émettre la preuve de design version 2.
  12. Appeler yayaw_cms_page_review, ouvrir chaque aperçu immuable et exécuter la matrice finale locales × desktop/mobile × clair/sombre, la réduction de mouvement et les contrôles par section. Un pass Visual QA explicite est requis avant l'upload des preuves visual-review:*. Une personne ou un agent séparé est préférable quand disponible, mais le rôle persistant ne prouve pas une identité indépendante. Soumettre ensuite les IDs durables à yayaw_cms_page_review_complete. Toute correction ou dépendance modifiée invalide le runtime, les captures et le reçu, et impose une nouvelle révision et une nouvelle revue.
  13. La publication reste une opération séparée et explicite. Elle revalide le prototype sélectionné, la revue runtime v2, la preuve de design, le reçu de page et chaque ligne de capture avant l'avancement sérialisable du pointeur. Un reçu valide est une preuve nécessaire, pas une autorisation : publier seulement après une demande explicite de l'utilisateur.

Lors d'un déploiement progressif, les serveurs compatibles en lecture comprennent les contextes legacy prototypeSet.kind: "generated_set" et le champ séparé prototypeGateV2.kind: "generated_set_v2", et échouent de façon fermée si les deux coexistent. Le champ séparé distingue les formats, mais ne sécurise pas à lui seul une flotte mixte : une instance antérieure au reader compatible peut encore opérer sur l'état legacy, l'écrire ou le sélectionner. La production utilise donc deux switches d'écriture explicites et mutuellement exclusifs. Déployer le build reader avec CMS_LEGACY_PROTOTYPE_WRITES_ENABLED=true et CMS_PROTOTYPE_RUNTIME_V2_WRITES_ENABLED=false, drainer toutes les instances antérieures et faire de ce build le rollback floor. Configurer et vérifier les uploads privés via staging. Par défaut, les grants opaques passent par le proxy applicatif same-origin et gardent S3_ENDPOINT interne. Ne configurez S3_SIGNED_PUBLIC_ENDPOINT que si l'hébergeur applicatif ne peut pas streamer le contrat média de 250 Mo ; ce doit être une origine d'API S3 HTTPS publique sûre et seuls les uploads basculent en direct. Les deux transports utilisent des PUT conditionnels sans écrasement. L'objet de staging vérifié reste privé pendant l'expiration du grant et une stabilisation de 24 heures pour bloquer les rejeux inter-instances. Le reaper répète la suppression pendant cette fenêtre et ne marque le nettoyage terminé qu'après le DELETE final. Passer ensuite les deux switches à false, redémarrer et drainer les writers legacy. Activer ensuite la v2 seule : legacy false, v2 true. Les deux à true échouent de façon fermée. Pour chaque déploiement progressif ultérieur du renderer, utiliser le même protocole manuel de confiance : geler et prouver toutes les ressources typées sur un SHA complet, émettre ou reprendre explicitement son reçu immuable, revérifier le drain live, passer à activating, déployer et revérifier exact, puis consommer le reçu. Une exécution activating en échec revient seulement à freeze et reprend la même opération avec une preuve fraîche. Si la flotte a déjà avancé vers un descendant strict de main, l'opérateur fournit explicitement l'ancienne opération et son SHA ; le workflow prouve le descendant gelé, active atomiquement son reçu de remplacement et marque l'ancien reçu terminal superseded. Cette récupération ne fait jamais avancer le runtime floor. Le déploiement automatique normal de production reste réservé au reader. Le déploiement de PR development peut préserver un freeze déjà configuré et prouvé live, mais il ne peut initier ni freeze ni exact. Après le nouveau SHA immuable de PR, il prouve que chaque conteneur app/worker live conserve ce SHA et freeze avant l'activation exacte manuelle. La production refuse les écritures v2 sans staging privé ni identifiant d'opération de rollout valide. Le premier gate exact exige le reçu consommé correspondant et lie définitivement cette opération au runtime floor de base de données. Dès qu'un contexte v2 existe, ne jamais rollback sous ce floor ni réactiver les écritures legacy. Les contextes legacy existants restent lisibles et annulables, mais ne peuvent plus être renouvelés, sélectionnés, planifiés, persistés, revus ou publiés. Tout asset issu d'un grant d'upload direct legacy doit être réuploadé via le staging privé avant de servir de prototype exact ou de preuve de revue. Un writer v2 désactivé renvoie cms_design_prototype_runtime_rollout_pending ; réessayer la v2 une fois le floor établi et le flag activé. En local et dans les autres environnements hors production, les écritures v2 sont activées par défaut lorsque la variable est absente.

La garantie de preuve exacte est ponctuelle et va jusqu'à la publication. Une évolution comportementale ultérieure du renderer ne recapture pas automatiquement les pages déjà publiées. Tant que le déploiement ne sait pas inventorier les contrats publiés et fournir soit un rendu versionné rétrocompatible, soit une migration avec nouvelle revue visuelle avant promotion, toute évolution comportementale du renderer de page ou de prototype bloque la release. Les versions partagées de cms-renderer-contract.ts doivent être revues et incrémentées explicitement ; ce bump trace la frontière mais ne rend pas sûr un déploiement qui ne l'est pas.

La boucle de blocage est exacte : dry-run et persistance d'une révision immuable, obtention de review_ready, puis Visual QA sur cette révision et ce runtime. Si les diagnostics statiques/runtime échouent, ou si le Visual QA détecte un scénario ou champ de fidélité en échec, un problème bloquant ou un écart non approuvé, il ne faut ni uploader de preuve visual-review:*, ni terminer la revue, ni publier. Le même plan contextuel est corrigé, une nouvelle révision immuable est persistée et la boucle reprend au dry-run. Seul un PASS sans problème bloquant ni écart autorise l'upload des preuves et la complétion de la revue. Toute correction ou modification de dépendance ultérieure invalide ce pass et le reçu, puis relance la boucle.

Orchestration des rôles client et garde-fou visuel

Pour creative_rework, design_system_extension ou un prototype approuvé, les clients qui prennent en charge la délégation parallélisent les lectures bornées tout en conservant un seul writer MCP :

  • le Creative Director verrouille le design read, le récit, le contrat de sections, les intentions média/tokens, le mouvement et le niveau de détail, puis produit les trois planches composites et leur trace de guidance
  • l'Implementer possède toutes les mutations catalogue/page, les actualisations d'inventaire, les dry-runs, le hash du plan et la persistance du brouillon
  • un rôle Visual QA examine les trois candidats avant sélection puis l'aperçu immuable après implémentation, sans mutation ; il rend un PASS explicite lié à la révision/runtime exacts après le premier brouillon immuable et après chaque correction immuable
  • un Technical QA peut vérifier en parallèle le responsive, les thèmes, la réduction de mouvement, l'accessibilité, le chargement média et les erreurs runtime

Les agents transmettent un ledger compact contenant le profil et la trace de guidance, tous les IDs de prototypes et références d'artefacts, l'ID sélectionné, le designBasis exact, designContextId, inventoryHash, les révisions exactes des composants/sections, pageId, la révision de page, planHash et runtimeHash. Le Visual QA relit le même profil complet au lieu de se fier à un résumé amont. Après publication du catalogue, yayaw_cms_design_inventory_refresh actualise l'inventaire du même contexte sans perdre le jeu de prototypes, la sélection ni la base. Après chaque correction, la nouvelle révision immuable est revue depuis zéro. Sans délégation, le client peut suivre la préparation et l'implémentation séquentiellement, mais un workflow créatif fondé sur un prototype ne peut ni uploader ses preuves de revue ni publier sans le pass du Visual QA. Ce rôle est un garde-fou qualité, pas une frontière d'identité authentifiée séparément.

Les références de preuve des scénarios et du mode mouvement réduit sont des IDs d'assets média durables. Chacune porte l'attestation pleine page version 1 renvoyée, avec runtime, scénario, hauteur de document et bandes de sections contiguës exacts. Leur kind image, contexte de design, hash de plan, octets statiques, dimensions de viewport, rôles et attestation sont vérifiés côté serveur et conservés dans le ledger du reçu. La publication retélécharge et réinspecte ce ledger ainsi que les preuves prototype source/runtime ; toute capture supprimée, modifiée, animée, tronquée, rejouée, reclassifiée ou provenant d'un autre contexte rend la revue périmée.

Les stratégies de composition sont explicites et ne peuvent pas être dégradées silencieusement :

  • content_only interdit les nouvelles sections de composition.
  • compose_existing autorise intentionnellement l'assemblage du catalogue.
  • creative_rework exige au moins trois nouvelles compositions, un hero et une section narrative nouvellement composés, avec au plus 50 % de sections réutilisées.
  • design_system_extension ajoute les mêmes garde-fous et exige au moins une recette composant source-backed importée, compilée, publiée et présente dans l'inventaire actualisé du même contexte, puis réellement utilisée par révision exacte dans une nouvelle composition. Utiliser une recette déclarative creative-composition pour les layouts imbriqués, médias, actions et structures répétées explicitement développées. Un import source résolu vers le fallback générique composite ne satisfait pas ce garde-fou.

Les stratégies créatives imposent aussi une auto-critique bloquante : la page doit rester reconnaissable sans son logo, raconter une histoire cohérente, inclure une interaction ou une composition originale et ne pas devenir une simple checklist de fonctionnalités. Si l'orchestration échoue, le client doit corriger le plan structuré ou s'arrêter ; il ne peut pas basculer vers compose_existing sans préparer un nouveau brief.

yayaw_cms_page_design n'accepte que le plan contextuel multilingue. Les outils directs yayaw_pages_create_draft et yayaw_pages_save_draft sont des bypass de maintenance bas niveau audités, réservés à control-plane:admin et désactivés sauf si CMS_LOW_LEVEL_PAGE_ADMIN_BYPASS_ENABLED=true. L'outil de compatibilité obsolète yayaw_cms_page_design_legacy_admin est aussi réservé aux admins et reste désactivé sauf si CMS_LEGACY_PAGE_DESIGN_ADMIN_BYPASS_ENABLED=true; il ne sert qu'à une courte migration ou à une réponse d'incident.

Les URLs d'aperçu sont des identifiants bearer. Elles expirent rapidement, résolvent une révision immuable, contournent les caches publics et l'analytics, utilisent noindex/nofollow et sont bloquées sur les domaines personnalisés d'organisation. En production, configurer CMS_PREVIEW_SIGNING_SECRET avec un secret serveur dédié à forte entropie ; BETTER_AUTH_SECRET sert de repli.

Résolution au runtime

Le contenu publié se résout depuis des révisions immuables et des lignes de publication :

  • les pages chargent ui_page_publications et rendent le PuckPageDocumentV1 publié
  • les références de sections se résolvent via ui_section_publications
  • les bindings littéraux de composants et sections acceptent directement des valeurs JSON bornées, y compris tableaux, objets imbriqués et null; les contrats valueShape récursifs valident les champs imbriqués tout en gardant les anciennes chaînes JSON lisibles
  • les bindings de données résolvent les entrées de données CMS globales ou d'organisation publiées
  • les bindings média utilisent l'URL publique stockée dans media_assets
  • les design tokens publics se résolvent depuis les payloads globaux/organisation, puis une couche de révision optionnelle s'applique dans le wrapper d'une page globale
  • les e-mails transactionnels chargent le modèle actif en base pour la locale demandée avant de retomber sur les valeurs par défaut des composants

Les pages publiques globales alimentent /sitemap.xml et les métadonnées SEO publiques. Les pages membres d'organisation exigent une adhésion et émettent des métadonnées noindex même quand des champs SEO existent au niveau de la page.

Localisation

Les documents CMS utilisent les locales applicatives configurées dans src/config/i18n.config.ts. Les locales actuelles sont l'anglais et le français.

Le contenu localisé apparaît dans :

  • le texte des pages et les champs SEO
  • les valeurs d'entrées de données globales et d'organisation
  • les entrées de menus d'en-tête et de pied de page
  • les valeurs de recettes de sections générées
  • les objets, textes d'aperçu, HTML de corps et exports texte des e-mails transactionnels

Les bindings de sections de page générées sont stockés comme texte d'objet JSON dans le document Puck (propsBindingsJson, apiBindingsJson, harnessBindingsJson et champs de binding associés). Les valeurs contenues dans ces objets sont de vraies valeurs JSON et ne doivent pas être stringifiées individuellement. La validation applique des limites récursives, bloque les clés d'objet dangereuses, vérifie les valueShape imbriqués et refuse les sections générées sans binding variant valide.

Les docs anglaises sont canoniques. Du contenu français peut exister dans le produit, mais la nouvelle documentation technique doit d'abord mettre à jour l'anglais.

Autorisation

Le CMS utilise le modèle d'autorisation par groupes et rôles de Yayaw. La navigation du dashboard n'est qu'un indice ; les loaders serveur, actions, services et opérations MCP doivent encore autoriser chaque lecture ou mutation.

Ressources CMS courantes :

  • page
  • sections
  • global-data
  • media
  • components
  • global-variables
  • email-template

Les membres d'organisation reçoivent normalement l'accès list/read au contenu scopé par organisation. Les managers, admins, owners et superadmins reçoivent l'accès de gestion selon leurs bindings de rôles de groupe.

Plan de contrôle (control plane)

Les workflows CMS opérationnels doivent partager la logique de service entre le dashboard, MCP, les scripts CLI et les tests quand ils sont exposés hors de l'interface.

La couverture actuelle du plan de contrôle (control plane) inclut :

  • opérations de pages
  • opérations de données CMS
  • opérations de modèles d'e-mails transactionnels
  • opérations de catalogue de facturation utilisées par les variables CMS

Quand vous ajoutez une fonctionnalité CMS, décidez si les clients MCP de confiance doivent pouvoir l'opérer. Si oui, ajoutez des schémas typés, un reason pour les écritures, des enregistrements d'audit, des contrôles d'autorisation et des mises à jour de documentation. Si non, documentez pourquoi la fonctionnalité est volontairement limitée au dashboard.

Règles opérationnelles

  • Stocker le contenu réutilisable comme données, médias, sections ou modèles publiés.
  • Garder les documents de page comme documents de composition, pas comme stores de contenu dupliqué.
  • Ne pas exécuter de code de composant stocké en base.
  • Ne pas stocker les binaires média dans Postgres.
  • Garder les design tokens publics scopés hors des routes dashboard et auth.
  • Scoper explicitement les données CMS globales et les données CMS d'organisation.
  • Revalider les chemins dashboard et runtime publics affectés après publication/archivage.
  • Traiter les fichiers assistants générés comme des artefacts dérivés ; mettre d'abord à jour content/llm/llm-source.md, puis les régénérer.

Validation

Vérifications utiles après des changements de documentation ou de comportement CMS :

bun run docs:generate
bun run docs:check-links
bun run docs:check-translations
bun run docs:llm:generate
bun run docs:llm:check
bun run check
bunx tsc --noEmit

Exécuter les tests de domaine au besoin quand des changements d'implémentation touchent les pages, sections, modèles de données, médias, composants, tokens ou modèles d'e-mails.

La validation contextuelle bloque les bases prototype/page existante incohérentes, les layouts absents, un composant ancien ou étranger déclaré comme nouveau, les décisions de composant dupliquées et created_component_not_used. La revue prototype bloque un artefact substitué, une région inventée, dupliquée ou non couverte, un contrôle de fidélité absent ou tout unapprovedDeviations.

Docs liées