Aller au contenu

Architecture de l'administration web

L'administration web reste une application statique sans framework ni bundler. nginx assemble le document HTML avec SSI, sert les modules ES natifs et relaie les appels relatifs /api/... vers FastAPI. Le navigateur ne contient ni clé interne ni autorité d'autorisation : les permissions client pilotent la visibilité, tandis que l'API revalide chaque action.

Organisation

  • public/index.html contient uniquement le head, la connexion et le shell applicatif.
  • public/partials/shell/ contient topbar, navigation et modale partagée.
  • public/partials/{community,world-edit,administration}/ contient un fragment par panneau.
  • public/js/core/ possède session, client HTTP/CSRF, modale, navigation, registre de features et registre d'actions transverses.
  • public/js/features/ contient une factory par ensemble fonctionnel et features/index.js compose explicitement l'application.
  • public/app.js ne fait que composer les services, établir la session, monter les features, configurer la navigation, précharger les panneaux autorisés et gérer la déconnexion.

Chaque factory reçoit un contexte partagé immuable et retourne le contrat suivant :

{ id: 'identifiant-unique', panels: ['example-panel'], mount() {}, load(panelId) {}, shouldPreload() {} }

L'état mutable appartient à la closure de la feature. Une feature n'importe jamais une autre feature. Un parcours transverse s'enregistre dans core/actions.js, par exemple l'ouverture de l'inventaire depuis la fiche Personnage.

Ajouter une page

  1. Ajouter un partial sans <script>, <style> ni élément racine global, puis l'inclure dans index.html.
  2. Ajouter le bouton tab-button et son data-panel, avec sa permission.
  3. Créer la factory, garder ses caches/timers privés et l'enregistrer dans features/index.js.
  4. Réutiliser le core et openAdminModal; ne jamais utiliser alert, confirm ou prompt.
  5. Mettre à jour la recette et exécuter les contrôles structurels.

Contrat des champs de modale

openAdminModal choisit le contrôle avant d'appliquer ses attributs : un champ avec options produit un <select>, multiline produit un <textarea>, et les autres champs produisent un <input> dont le type vaut text par défaut. La propriété type ne doit jamais être affectée à un select ou à un textarea. Les contraintes communes (required, min, max, minlength, maxlength, pattern) restent portées par la description du champ. Le premier input, textarea ou select reçoit le focus à l'ouverture.

Le test admin/tests/modal-contracts.mjs protège ce choix sans navigateur. Le contrat HTML vérifie également que le fragment SSI contient une paire <dialog>...</dialog> équilibrée.

Assemblage et contrôles

SSI est activé uniquement pour /index.html. /partials/ est internal; le navigateur reçoit un DOM complet sans flash de template incomplet. Les imports ES restent same-origin et compatibles avec la CSP existante.

node admin/tests/module-graph.mjs
node admin/tests/html-contracts.mjs
node admin/tests/modal-contracts.mjs

Le premier valide imports, cycles, factories, IDs et ownership des panneaux. Le second résout les includes SSI, contrôle l'unicité des IDs, les cibles de navigation, la fermeture du dialog et le markup interdit. Le troisième protège la sélection du bon élément pour chaque description de champ de modale.