Les menus d’un back-office viennent souvent du serveur : chaque rôle voit des entrées différentes et l’ajout de pages ne demande pas de republier le frontend. Le travail ne consiste pas à afficher ce qui arrive, mais à soumettre le menu, les routes et les actions à un même ensemble de règles.
Le contrat du menu
Le menu arrive sous forme de groupes et d’entrées. Chaque entrée porte un chemin, un libellé ou une clé de libellé, une icône, son groupe, un ordre, un indicateur de masquage, des codes de permission et des enfants. Les groupes fixent l’ordre de la barre latérale et la hiérarchie s’arrête à quatre niveaux pour qu’une charge anormale ne fasse pas exploser la navigation.
Les entrées externes déclarent leur adresse et leur mode d’ouverture : nouvelle fenêtre, même fenêtre ou intégration. L’intégration ne fonctionne que si le site l’autorise : une page qui envoie X-Frame-Options: DENY restera vide.
La tolérance incombe aussi au frontend : chemins inhabituels, icônes inconnues et enfants trop profonds sont normalisés et laissent une liste d’avertissements lisible. Lors du branchement d’une API réelle, on lit cette liste plutôt que d’attendre le signalement d’un utilisateur.
Les routes ne connaissent que les pages enregistrées
Les routes dynamiques tirent leurs composants d’un registre local : l’API peut référencer une page enregistrée, mais pas introduire du code. Une session ou une permission manquante aboutit à la page de connexion ou à un 403, jamais à une page vide.
Trois couches, un seul jeu de règles
- Menu : les entrées sont filtrées par code de permission, les points d’entrée indisponibles ne sont pas rendus.
- Routes : saisir l’URL directement déclenche le même contrôle et aboutit à un 403.
- Actions :
<Can permission="customer:create">couvre les opérations comme la création ou l’export et affiche un état désactivé au lieu d’échouer en silence.
Les codes de permission acceptent * pour tout, module:* pour un module entier et les correspondances exactes, ce qui permet de décrire les rôles dans une seule liste. La documentation contient le contrat complet et la démonstration permet de comparer deux comptes : à la même adresse, l’administrateur voit le journal d’audit, le compte de test reçoit un 403.