et alignement des panneaux
Aperçu
L'administrateur du navigateur /webadmin et Internal Content API sont deux portes d'entrée vers les mêmes données CMS, mais ils n'ont pas été construits en même temps et ne couvrent pas le même terrain. Le panneau constitue la surface opérateur complète. L’API est une surface délibérément plus étroite pour les outils d’IA et d’opérateur fiables.
Ce document fait autorité pour déterminer où les deux sont d'accord, où l'API couvre moins et où l'écart est une limite délibérée plutôt qu'un travail inachevé. Il existe pour que :
- une IA ou un outil opérateur peut découvrir ce qu’il ne peut pas faire avant d’essayer ;
- un réviseur peut distinguer une limite intentionnelle d'un point final manquant ;
- le travail sur la feuille de route a une liste unique sur laquelle se clôturer.
Il s'agit d'un enregistrement de statut, pas d'une spécification. Lorsqu'un point de terminaison est expédié, mettez à jour la ligne ici dans le même commit.
Comment lire ceci
Chaque ligne comporte un statut :
| Statut | Signification |
|---|---|
| Aligné | L'API peut accomplir ce que le panneau accomplit. La forme peut différer. |
| Partielle | Un point de terminaison existe mais couvre moins de champs ou moins d’opérations que le panneau. |
| Manquant | Aucun chemin d'API n'existe. Panneau uniquement par omission, pas par conception. |
| Panneau uniquement par conception | Délibérément exclu. La raison est enregistrée dans la ligne. |
« Panneau uniquement par conception » n'est pas synonyme de « dur ». Cela signifie que l'exclusion est la posture de sécurité décrite dans la section Limites de Internal Content API : pas de publication automatique, pas d'exploration ou de récupération à distance, pas de remplacement d'importation/exportation arbitraire et aucune élévation de privilèges via un jeton.
API
L'API n'est pas un préfixe unique. Un outil s'intégrant au CMS parle à deux :
| Préfixe | Authentification | Portée |
|---|---|---|
| /webadmin/api | internal-api.token plus une capacité par route | Tout |
| /admin-api | internal-api.token plus une capacité par route | Enregistrements de site et de domaine, alias hérités |
La scission est historique plutôt que fondée sur des principes. /admin-api est antérieur au modèle de capacités et ses routes ne vérifiaient rien au-delà de la validité du jeton jusqu'à l'introduction de domains.write et domains.delete : tout jeton valide pouvait ajouter ou supprimer un domaine. Les routes de domaine résident désormais également sous /webadmin/api, c'est là que devraient pointer les nouvelles intégrations ; le préfixe hérité continue de fonctionner pour les outils de provisionnement existants.
Les capacités sont définies dans CmsApiTokenCapabilities. Une lacune dans ce document est parfois autant une capacité manquante qu'un itinéraire manquant.
Pages
| Capacité | Panneau | API | Statut |
|---|---|---|---|
| Liste et lecture des pages | Oui | GET /pages, GET /pages/{page} | Aligné |
| Créer un brouillon de page | Oui | POST /content/apply (create_draft_page) | Aligné |
| Remplacer le contenu de l'emplacement sur une page de brouillon | Oui | POST /content/apply (replace_existing_draft_page) | Aligné |
| Mises à jour échelonnées pour les pages publiées | Oui | POST /content/apply (staged-update modes) | Aligné |
| Publier une page | Oui | POST /pages/{page}/publish | Aligné |
| Modifier la disposition du shell public | Oui | PATCH /pages/{page}/layout | Aligné |
| Emplacements de mise en page de synchronisation | Oui | POST /pages/{page}/sync-layout-slots | Aligné |
| Supprimer une page | Oui | DELETE /pages/{page} | Aligné |
| Actifs CSS et JS de la page | Oui | /pages/{page}/assets/* | Aligné |
| Renommer une page, ou modifier son slug ou son chemin | Oui | PATCH /pages/{page}/translations/{translation} | Aligné |
| Traductions de pages : ajouter des paramètres régionaux, modifier le nom, le slug, le chemin, le référencement, Open Graph | Oui | /pages/{page}/translations/* | Aligné |
| Aperçu d'une page | Oui | GET /pages/{page}/render, and /webadmin/pages/{page}/preview already took a Bearer token | Aligné |
| Versions des pages et restauration des candidats | Oui | /pages/{page}/versions/* and /pages/{page}/version-candidates/* | Aligné : préparez un aperçu du candidat avant de postuler avec prudence |
| Ajouter, supprimer ou réorganiser un emplacement de page | Oui | Uniquement les emplacements de mise en page de synchronisation et la source d'emplacement | Partielle |
| Effacer chaque bloc dans un emplacement de page | Oui | Les emplacements partagés sont clairs ; les pages ne | Partielle |
| Dupliquer une page | Oui | Aucun | Manquant |
| Déplacer une page vers un autre site | Oui | Aucun | Manquant |
| Importer une page depuis JSON | Oui | Aucun | Manquant |
| Convertisseur de page HTML en bloc | Oui | Aucun | Manquant |
| Supprimer des pages en masse | Oui | Suppression unique uniquement | Partielle |
| Transitions de workflow autres que la publication | Oui | Aucun | Manquant |
Les deux qui dominaient cette liste sont fermés.
Identité de page et traductions de page. create_draft_page écrit name, slug et path sur une ligne de traduction de page pour un paramètre régional, et jusqu'à ce que l'API de traduction de page arrive, rien ne peut toucher cette ligne par la suite : les modes de remplacement et de mise à jour par étapes se normalisent page à null et gère uniquement le contenu des emplacements. Une page créée avec le mauvais chemin ne pouvait être corrigée qu'en la supprimant et en la recréant, aucune page ne pouvait obtenir un deuxième paramètre régional et le référencement au niveau de la page - seo_title, seo_description, seo_keywords, og_title, og_description, og_image_media_id, qui se trouvent tous sur cette ligne - était inscriptible et absent de lire également les charges utiles.
/pages/{page}/translations/* couvre désormais tout cela, et comme le titre et le slug Page lisent la traduction par défaut, renommer cette traduction renomme la page. Voir Localization pour savoir pourquoi ces champs appartiennent à la ligne de traduction et Internal Content API pour le contrat d'écriture.
Les valeurs par défaut du référencement au niveau du site sont toujours inaccessibles, pour une raison distincte ; voir les sites ci-dessous.
Blocks
| Panneau | API | Statut | |
|---|---|---|---|
| Liste et lecture des blocs | Oui | GET /blocks, GET /blocks/{block} | Aligné |
| Créer un bloc dans un emplacement de page | Oui | POST /pages/{page}/slots/{slot}/blocks | Aligné |
| Mettre à jour le contenu et les paramètres du bloc | Oui | PATCH /blocks/{block} | Aligné |
| Réorganiser les blocs | Oui | PATCH /pages/{page}/slots/{slot}/blocks/reorder | Aligné |
| Supprimer un bloc | Oui | DELETE /pages/{page}/slots/{slot}/blocks/{block} | Aligné |
| Auteur html blocs | Oui | Rejeté avec block_type_not_api_writable | De par sa conception, il s'agit uniquement d'un panneau : le balisage brut reste examiné par un humain. |
À partir de la version 1.91.0, huit blocs multimédias natifs exposent également mobile_media_id dans les plans et PATCH, avec la même sélection et le même repli que le panneau. Voir Variantes d'images Media.
Les blocs constituent la zone la mieux alignée du CMS. Les écritures de paramètres sont en outre limitées par BlockSettingsPatchPolicy, qui constitue une protection plutôt qu'un écart.
Fentes partagées
| Fonctionnalité | Interface d’administration | API | État |
|---|---|---|---|
| Lister, consulter, créer | Oui | GET/POST /shared-slots | Conforme |
| Créer, réordonner, supprimer ou vider des blocs | Oui | /shared-slots/{sharedSlot}/blocks/* | Conforme |
| Publier les blocs d’un Shared Slot | Oui | POST /shared-slots/{sharedSlot}/publish-blocks | Conforme |
| Attribuer un Shared Slot à un slot de page | Oui | POST /pages/{page}/slots/{slot}/shared-slot | Conforme |
| Modifier un Shared Slot (libellé, identifiant, type de slot, layout, état actif) | Oui | PATCH /shared-slots/{sharedSlot} | Conforme |
| Supprimer un Shared Slot | Oui | DELETE /shared-slots/{sharedSlot} | Conforme |
| Déplacer un Shared Slot vers un autre site | Oui | Rejeté avec unsupported_shared_slot_fields | Réservé à l’interface : déplacement entre sites, pas simple renommage |
| Révisions des Shared Slots : lister, consulter, restaurer | Oui | Aucune | Fonction absente |
La suppression nécessite la capacité destructrice shared-slots.delete et refuse de supprimer un Shared Slot de tout emplacement de page encore référencé, répertoriant les emplacements de référence afin qu'un outil puisse les détacher en premier.
Media
| Panneau | API | Statut | |
|---|---|---|---|
| Répertorier, lire, télécharger, récupérer à distance | Oui | /media, /media/fetch | Aligné |
| Mettre à jour les métadonnées descriptives | Oui | PATCH /media/{media} | Aligné |
| Remplacer, déplacer, supprimer | Oui | /media/{media}/replace, /move, DELETE | Aligné |
| Créer un dossier multimédia | Oui | POST /media/folders | Aligné |
| Régénérer les transformations d'image | Oui | Aucun | Manquant |
| Suppression groupée | Oui | Suppression unique uniquement | Partielle |
| Modifiez les champs de stockage, le binaire ou le dossier via PATCH | Oui | Rejeté avec unsupported_media_update_fields | De par leur conception, panneau uniquement : les écritures de métadonnées ne doivent pas déplacer d'octets |
POST /media/folders refuse un nom qui existe déjà sous le même parent et renvoie le dossier existant, donc un outil de nouvelle tentative le réutilise au lieu d'accumuler des doublons.
Navigation
| Capacité | Panneau | API | Statut |
|---|---|---|---|
| Liste et lecture des menus | Oui | /navigation-menus | Aligné |
| Créer un menu | Oui | POST /navigation-menus | Aligné |
| Article créer, mettre à jour, réorganiser, supprimer | Oui | /navigation-menus/{menu}/items/* | Aligné |
| Supprimer un menu entier | Oui | Aucun | Manquant |
| Supprimer un élément qui a des enfants | Oui | Rejeté jusqu'à ce que les enfants soient traités | De par sa conception, il s'agit uniquement d'un panneau – pas de cascade silencieuse |
Engagements et messages
| Capacité | Panneau | API | Statut |
|---|---|---|---|
| Lire les commentaires et les évaluations | Oui | /engagement/comments, /engagement/ratings | Aligné |
| Statut du commentaire modéré | Oui | PATCH /engagement/comments/{comment} | Aligné |
| Supprimer un commentaire | Oui | Aucun | Manquant |
| Messages du formulaire de contact : liste, lecture, statut, suppression | Oui | Aucun | Manquant |
Les messages Contact n’ont aucune représentation API. Un outil peut créer un formulaire de contact via l'API mais ne peut ni lire ses soumissions ni savoir où elles sont livrées — voir Sites.
Sites et configuration
Le formulaire du site du panel écrit plus de vingt champs. L'API les couvre via des points de terminaison étroits à usage unique : branding, head, timezone, public-theme, seo, contact-recipient et locales.
| Champ ou fonctionnalité | Interface d’administration | API | État |
|---|---|---|---|
| Nom affiché, slogan, favicon, image sociale, palette de marque, polices | Oui | PATCH /sites/{site}/branding | Conforme |
| HTML personnalisé dans l’en-tête | Oui | PATCH /sites/{site}/head | Conforme |
| Fuseau horaire | Oui | PATCH /sites/{site}/timezone | Conforme |
| Préréglage du thème public | Oui | POST /sites/{site}/public-theme | Conforme |
| Fichiers CSS et JS spécifiques au site | Oui | /sites/{site}/assets/{type} | Conforme |
| Paramètres SEO par défaut du site (seo_title, seo_description, seo_keywords) | Oui | PATCH /sites/{site}/seo | Conforme |
| Adresse e-mail du destinataire des contacts | Oui | PATCH /sites/{site}/contact-recipient | Conforme |
| Affectation des langues (locale_ids) | Oui | PUT /sites/{site}/locales | Conforme — plus strict : refuse de retirer une langue utilisée par des traductions de pages |
| Nom et identifiant du site | Oui | Aucune | Fonction absente |
| Indicateur de site principal | Oui | Aucune | Fonction absente |
| Variables du site | Oui | Aucune | Fonction absente |
| Créer ou supprimer un site | Oui | Aucune | Réservé à l’interface : site_create est une clé de plan interdite |
| Dupliquer un site | Oui | Aucune | Réservé à l’interface : la duplication complète appartient à l’opérateur |
| Promouvoir un site | Oui | Aucune | Réservé à l’interface : voir Opérations |
| Export et import d’un site | Oui | Aucune | Réservé à l’interface : le remplacement par import arbitraire est hors périmètre |
| Domaines : lister, ajouter, modifier, définir comme principal, supprimer, gérer l’état | Oui | /webadmin/api/sites/{site}/domains/* | Conforme |
Ce qui manque ici, c'est l'identité du site (nom, identifiant, indicateur principal) et les variables du site. Ceux-ci sont plus proches du provisionnement que du contenu, et aucun outil n’en a encore eu besoin.
Formulaire de recherche
Tout ce qui se trouve dans ce groupe est lisible et rien n'est accessible en écriture.
| Panneau | API | Statut | |
|---|---|---|---|
| Mises en page : création, mise à jour, gestion des emplacements | Oui | GET /page-layouts only | Partiel – lecture seule |
| Types de blocs : créer, mettre à jour, supprimer | Oui | GET /block-types only | Partiel – lecture seule |
| Types de machines à sous | Liste en lecture seule | Aucun | Manquant – même pas lisible |
| Paramètres régionaux : créer, mettre à jour, activer, désactiver | Oui | POST /locales, PATCH /locales/{locale} | Aligné |
| Paramètres régionaux : supprimer | Oui | Aucun | Manquant |
| Catalogue d'icônes : lire | Oui | GET /icon-catalog | Aligné |
| Catalogue d'icônes : synchronisation et activation | Oui | Aucun | Manquant |
L'accès au schéma en lecture seule est défendable : les types de blocs et les dispositions sont des contrats structurels, et laisser un jeton les inventer élargit le rayon d'action de chaque écriture de contenu ultérieure. Elle est enregistrée comme partielle plutôt que comme intentionnelle, car aucune décision de ce type n'est écrite nulle part.
Utilisateurs, système et opérations
| Panneau | API | Statut | |
|---|---|---|---|
| Gestion des utilisateurs | Oui | Aucun | De par sa conception, uniquement sur panneau : aucune élévation de privilèges via un jeton |
| Gestion des jetons API | Oui | Aucun | De par sa conception, il s'agit uniquement d'un panneau : un jeton ne doit pas émettre de jetons. |
| Paramètres système et test de messagerie | Oui | Aucun | De par sa conception, il s'agit d'un panneau uniquement : la configuration à l'échelle de l'installation appartient à l'opérateur. |
| Création d'un point de restauration de sauvegarde | Oui | backups.create bras create_restore_point sur POST /content/apply | Aligné pour cette opération étroite |
| Restauration et téléchargement de sauvegarde | Oui | Aucun | Conception à panneau uniquement |
| Aperçu et exécution du nettoyage de sauvegarde | Oui | GET /system/backup-cleanup, POST /system/backup-cleanup/run | Aligné avec les backups.read et backups.delete accordés séparément |
| Vérifier et exécuter une mise à jour du système | Oui | /system/updates/check, POST /system/updates, /system/updates/operations/{operation} | Aligné sur la version 1.90.0 — jeton système à l'échelle de l'installation et approbation explicite de la version/somme de contrôle ; voir les mises à jour |
| Reconstruire l'index de recherche | Oui | Aucun | Manquant |
| Rapports de visiteurs | Oui | Aucun | Manquant |
| Plugins : parcourir et installer le catalogue, activer, désactiver, configurer, désinstaller, télécharger ZIP | Oui | /plugins/* | Aligné |
| Plugins : mettre à jour un plugin installé depuis le catalogue | Oui | POST /plugins/catalog/{plugin}/update | Aligné |
| Plugins : lire les détails d'un plugin | Oui | index uniquement | Partielle |
Transversal : Clés de plan inconnues
Jusqu'à ce que ce problème soit résolu, chaque lacune dans ce document était silencieuse du côté de l'appelant.
POST /content/validate et POST /content/apply ont rejeté une liste fixe de clés interdites (clés de publication et de planification, création de site, récupération à distance et verbes destructeurs) mais rien n'est simplement méconnu. La normalisation du plan a lu les clés qu'elle connaissait et a ignoré le reste, donc un plan portant page.seo_title a renvoyé ok: true et un 201 n'en ayant rien écrit. Un outil a signalé un succès ; il ne s'était rien passé. La lecture de la page ne l'a pas non plus révélé, car les champs que l'API ne peut pas écrire sont également absents de ses charges utiles de lecture.
Les clés non reconnues sont désormais rejetées avec 422 et le code stable unsupported_plan_fields, et le chemin d'erreur nomme chaque champ rejeté. Le jeu de clés accepté est limité au plan mode : replace_slots est significatif lors du remplacement d'une page et rejeté lors de sa création.
Cela ne comble aucun écart ci-dessous. Cela les rend détectables, ce qui est la condition préalable pour qu'un outil puisse revenir au panneau au lieu de signaler une écriture qui n'a jamais eu lieu.
Feuille de route
Ordonné par combien chacun débloque, pas par effort.
Niveau 1 — complet
Rejectez les clés de plan non reconnues avecVoir Clés de plan inconnues ci-dessus.422.Point de terminaison d'écriture de traduction de page./pages/{page}/translations/*écrit le nom, le slug, le chemin, le référencement et l'Open Graph, et les relit.Mise à jour de l'identité de la page.Livré avec 2 : le titre, le slug et le chemin sont des champs de traduction, et la traduction locale par défaut est la propre identité de la page.Shared Slot met à jour et supprime.PATCHetDELETE /shared-slots/{sharedSlot}, ce dernier derrière la nouvelle fonctionnalitéshared-slots.delete.
Niveau 2 — complet
Extend les paramètres du site : valeurs par défaut SEO,contact_recipient_email,locale_ids./sites/{site}/seo,/contact-recipientet/locales.Aperçu de page ou instantané de rendu.GET /pages/{page}/render, avecformat=htmlet rendu par paramètres régionaux. Celui-ci avait une mauvaise portée lors de la rédaction de la liste :/webadmin/pages/{page}/previewacceptait déjà un jeton Bearer, donc l'écart résidait dans la découverte et la sélection des paramètres régionaux, pas du tout dans la capacité de rendu.- Création du dossier
Media.GET/POST /media/folders. Capability-gate les routes de domaine et les déplacez sousTerminé, et/webadmin/api.updateetset primaryl'accompagnaient.
Ce qui reste
Tout ce qui est encore marqué Manquant ci-dessus est de second ordre : la duplication de pages et les déplacements de sites, les opérations groupées, le convertisseur HTML en bloc, la suppression de commentaires, les messages de contact, la création de schémas, la réindexation de recherche et les rapports de visiteurs. Aucun d’entre eux n’empêche un outil de créer, vérifier, corriger et publier une page, ce qui correspond aux niveaux 1 et 2. Choisissez parmi eux en fonction de la demande plutôt que de parcourir la liste.
Niveau 3 — limites délibérées
Les utilisateurs, l'émission de jetons, les paramètres système, la restauration/téléchargement de sauvegarde, la création et la suppression de sites, le clonage, la promotion et le transfert restent uniquement sur le panneau. Les mises à jour du système sont disponibles via des fonctionnalités API accordées séparément à l'échelle de l'installation à partir de la version 1.90.0. Ils sont répertoriés ici afin que « pas dans l'API » soit une décision enregistrée plutôt qu'une absence non examinée.
Cycle de vie et récupération du plugin via 1.94.2
À partir de la version 1.92.0, l'installation/mise à jour/activation du panneau et de l'API applique automatiquement les modifications requises de la base de données du plug-in et conserve un état désactivé après un échec. L'activation/la configuration utilise la même porte de compatibilité ; les requêtes incompatibles renvoient HTTP 409 et plugin_incompatible. À partir de la version 1.94.0, la validation de démarrage s'exécute dans un nouveau processus avant l'activation, les mises à jour réussies conservent le package précédent et les échecs de source/route d'exécution mettent le plugin en quarantaine.
Recovery à /webadmin/plugin-recovery est une surface de panneau authentifiée distincte. CMS 1.94.2 nécessite un Super admin actif avec un accès administrateur normal. Il peut désactiver un plugin géré défaillant ou restaurer le package conservé uniquement lorsqu'aucune migration de base de données n'a été exécutée. L'accès par jeton à /plugins/* ne remplace pas cette autorité de récupération du navigateur. Voir Plugin System.