# @mostajs/menu — fiche LLM
> Sidebar de tableau de bord configurable, avec filtrage des entrées de menu par permissions (RBAC).

- Version: 1.0.5 · Licence: AGPL-3.0-or-later · Auteur: Dr Hamid MADANI <drmdh@msn.com>
- Chemin: mostajs/mosta-menu · Statut audit: complet (dist/)

## RÔLE
Fournit le composant `DashboardSidebar` (barre latérale d'application) et l'utilitaire
`buildMenuConfig` qui assemble dynamiquement un menu unifié à partir de contributions
de modules. Chaque module @mostajs expose une `ModuleMenuContribution` ; l'app hôte les
collecte et `buildMenuConfig` les fusionne, trie par ordre, et la sidebar masque les
entrées selon les permissions de l'utilisateur. Pure infrastructure UI : aucun schéma.

## INSTALLATION
npm i @mostajs/menu lucide-react

## EXPORTS
- DashboardSidebar — composant React (export default ré-exporté nommé)
- buildMenuConfig(contributions, baseConfig?) : function — assemble un MenuConfig unifié
- Types : MenuItem, MenuGroup, MenuConfig, SidebarUser, DashboardSidebarProps, ModuleMenuContribution
- register : function (sous-chemin ./register) — enregistrement module @mostajs/socle

## EXPORTS PAR SOUS-CHEMIN
- "." → DashboardSidebar, buildMenuConfig, tous les types
- "./components/DashboardSidebar" → le composant seul
- "./types" → MenuItem, MenuGroup, MenuConfig, SidebarUser, DashboardSidebarProps, ModuleMenuContribution
- "./register" → register(registry)

## API — SIGNATURES
- function buildMenuConfig(contributions: ModuleMenuContribution[], baseConfig?: Partial<MenuConfig>): MenuConfig
- function DashboardSidebar(props: DashboardSidebarProps): JSX.Element
- function register(registry: { register(r: ModuleRegistration): void }): void

## TYPES CLÉS
- MenuItem { label: string; href: string; icon: ElementType; permission?: string }
- MenuGroup { label: string; icon: ElementType; items: MenuItem[] }
- MenuConfig { items: MenuItem[]; groups: MenuGroup[] }   // items = liens directs, groups = sections repliables
- SidebarUser { name?: string|null; role?: string; permissions?: string[] }
- DashboardSidebarProps {
    config: MenuConfig; user: SidebarUser;
    appName?: string; appIcon?: ElementType;
    t?: (key: string) => string;                                  // i18n, défaut: identité
    hasPermission?: (perms: string[], required: string) => boolean; // défaut: toujours true
    onLogout?: () => void;
  }
- ModuleMenuContribution {
    moduleKey: string; items?: MenuItem[]; groups?: MenuGroup[];
    mergeIntoGroup?: string;   // fusionne les items dans un groupe existant/auto-créé
    order?: number;            // ordre d'affichage, plus petit = plus haut (défaut 50)
  }

## PATTERN
```tsx
import { DashboardSidebar, buildMenuConfig } from '@mostajs/menu';
import { scanMenuContribution } from '@mostajs/scan';        // ex: contribution d'un module
import { Home } from 'lucide-react';

const config = buildMenuConfig(
  [scanMenuContribution, /* autres contributions */],
  { items: [{ label: 'Accueil', href: '/', icon: Home }] }   // baseConfig optionnel
);

<DashboardSidebar
  config={config}
  user={{ name: 'Hamid', role: 'admin', permissions: ['scan.read'] }}
  appName="MostaGare"
  hasPermission={(perms, req) => perms.includes(req)}
  onLogout={handleLogout}
/>
```

## DÉPEND DE
- Aucun module @mostajs/* requis au runtime (@mostajs/socle en peer pour ./register).
- Peers : react, next (>=14), lucide-react.

## PIÈGES
- `buildMenuConfig` : les groupes de modules différents portant le MÊME `label` sont
  fusionnés ; les items avec `mergeIntoGroup` sont injectés dans le groupe nommé
  (créé s'il n'existe pas). Les contributions sont triées par `order` croissant.
- `hasPermission` a un défaut « toujours true » : sans le fournir, AUCUN filtrage RBAC
  n'a lieu et toutes les entrées (même avec `permission`) sont visibles.
- `icon` est un `ElementType` (composant), pas une chaîne — passer p.ex. un composant lucide-react.

## RÉFÉRENCES
- README.md
- CHANGELOG.md : absent
- index.ts, register.ts, components/DashboardSidebar.tsx, lib/build-menu.ts, types/
