# @mostajs/rbac — fiche LLM
> RBAC : schémas User/Role/Permission/PermissionCategory, repositories, seed idempotent, création d'admin, handlers API Next.js et UI d'administration.

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

## RÔLE
Couche d'autorisation (Role-Based Access Control) de l'écosystème mostajs. Fournit les schémas d'entités (User, Role, Permission, PermissionCategory, Account), les repositories serveur pour les manipuler, un seed idempotent des rôles/permissions/catégories, un helper de création d'admin, des handlers API Next.js prêts à brancher, et des composants React d'administration (matrice de permissions, managers). Consommé par `@mostajs/auth` qui lui délègue toute la résolution rôle→permissions. Fonctionne en mode ORM ou NET selon `MOSTA_DATA`.

## INSTALLATION
npm i @mostajs/rbac @mostajs/orm

## EXPORTS
Point d'entrée racine (`.`) — client-safe :
- Schémas Zod: UserSchema, RoleSchema, PermissionSchema, PermissionCategorySchema, AccountSchema
- Composants React: UsersManager, RBACManager, RolesManager, PermissionsManager, CategoriesManager, PermissionMatrix
- Pages: UsersPage (default), RolesPage (default)
- Helpers: hasPermission, matchesPermission
- API client factories: createUsersApi, createRolesApi, createPermissionsApi, createMatrixApi, createCategoriesApi
- Menu/i18n: rbacMenuContribution, rbacT
- Types: UserDTO, RoleDTO, PermissionDTO, PermissionCategoryDTO, User, RoleOption, RoleData, PermissionData, CategoryData, MatrixData, RBACConfig, PermissionDefinition, RoleDefinition, CategoryDefinition + tous les *HandlerConfig

## EXPORTS PAR SOUS-CHEMIN
- `./server` — UserRepository, RoleRepository, PermissionRepository, PermissionCategoryRepository, AccountRepository, seedRBAC, createAdmin, resolveUserAccountId, getSchemas, moduleInfo, getPermissionsForRoleFromDB, hasPermission, matchesPermission, OCTONET_RBAC_SEED, OCTONET_PERMS + tous les schémas
- `./lib/rbac-seed` — seedRBAC ; type SeedRBACOptions
- `./lib/create-admin` — createAdmin ; types CreateAdminOptions, CreateAdminResult
- `./lib/module-info` — getSchemas, moduleInfo (pour @mostajs/setup)
- `./lib/repos-factory` — getRbacRepos, resetRbacRepos ; types RbacRepos, IUserRepository, IRoleRepository, IPermissionRepository, IPermissionCategoryRepository
- `./lib/permissions-server` — getPermissionsForRoleFromDB
- `./lib/data-mode`, `./lib/menu`, `./lib/i18n`
- `./helpers/permissions` — hasPermission, matchesPermission
- `./register` — register(registry)
- `./api/users`, `./api/users-id`, `./api/roles`, `./api/roles-id`, `./api/permissions`, `./api/permissions-id`, `./api/matrix`, `./api/categories`, `./api/categories-id`, `./api/seed` — chaque sous-chemin exporte un `create<X>Handler(config)` retournant des route handlers Next.js { GET, POST, ... }
- Composants: `./components/UsersManager`, `./components/RBACManager`, `./components/RolesManager`, `./components/PermissionsManager`, `./components/CategoriesManager`, `./components/PermissionMatrix`
- Pages: `./pages/UsersPage`, `./pages/RolesPage`

## API — SIGNATURES
hasPermission(userPermissions: string[], requiredPermission: string): boolean  // exact, wildcard '*', glob 'cloud.admin.*'
matchesPermission(required: string, userPerm: string): boolean
seedRBAC(options: SeedRBACOptions): Promise<{ categoryCount, permissionCount, roleCount }>  // idempotent (upsert)
createAdmin(options: CreateAdminOptions): Promise<CreateAdminResult>  // idempotent ; hash bcrypt + lien rôle admin
getPermissionsForRoleFromDB(role: string, fallbackMap?: Record<string,string[]>): Promise<string[]>
getRbacRepos(): Promise<RbacRepos>  // { users, roles, permissions, categories } ; dialect résolu ORM ou NET
getSchemas(): EntitySchema[]  // [User, Role, Permission, PermissionCategory]
createUsersHandler(config: UsersHandlerConfig): { GET, POST }  // idem pour roles/permissions/matrix/categories/seed
resolveUserAccountId(options: ResolveAccountOptions)

UserRepository(dialect) — méthodes : findByEmail, findByIdWithRoles, findAllWithRoles, findAllSafe, findByIdSafe, addRole, removeRole, updateLastLogin, countByRole, create, update, delete, findById, findOne, findAll, count
RoleRepository(dialect) — findByName, findAllWithPermissions, findByIdWithPermissions, addPermission, removePermission, removePermissionFromAll, create, update, delete, ...
PermissionRepository(dialect) — findAllSorted, findByName, countByCategory, ...
PermissionCategoryRepository(dialect) — findAllOrdered, findByName, upsert, ...

## TYPES CLÉS
UserDTO { id, email, password?, firstName, lastName, phone?, roles[], status:'active'|'locked'|'disabled', lastLoginAt?, createdAt, updatedAt }
RoleDTO { id, name, description?, permissions[], createdAt, updatedAt }
PermissionDTO { id, name, description?, category?, createdAt, updatedAt }
PermissionCategoryDTO { id, name, label, description?, icon?, order, system, createdAt, updatedAt }
AccountDTO { id, name, type:'personal'|'organization'|'trial'|'system', plan, status:'active'|'suspended'|'deleted', stripeCustomerId?, metadata?, owner, members?, ... }
SeedRBACOptions { categories: CategoryDefinition[], permissions: PermissionDefinition[], roles: Record<string,RoleDefinition> }
PermissionDefinition { code, name, description, category }
RoleDefinition { name, description, system, permissions: string[] }
CategoryDefinition { name, label, description, icon, order, system }
CreateAdminOptions { email, password, firstName, lastName, roleName? }
CreateAdminResult { ok, userId?, email?, error? }
RbacRepos { users: IUserRepository, roles: IRoleRepository, permissions: IPermissionRepository, categories: IPermissionCategoryRepository }
UsersHandlerConfig { checkPermission(perm), adminPermission, knownRoles?, getPermissionsForRole?, logAudit?, getAuditUser? }
RBACConfig { apiBasePath?, t?, systemRoles?, roleColors?, statusColors? }
MatrixData { roles[], categories, categoryLabels, matrix: Record<role,Record<perm,boolean>> }

## PATTERN
```ts
// Seed RBAC (idempotent)
import { seedRBAC, createAdmin, UserRepository } from '@mostajs/rbac/server'
await seedRBAC({
  categories: [{ name:'admin', label:'Administration', description:'', icon:'Settings', order:0, system:true }],
  permissions: [{ code:'admin:access', name:'admin:access', description:'Admin', category:'admin' }],
  roles: { admin: { name:'admin', description:'Administrator', system:true, permissions:['*'] } },
})
await createAdmin({ email:'admin@x.com', password:'Admin123!', firstName:'Admin', lastName:'X' })

// Repository serveur
const userRepo = new UserRepository(await getDialect())
const u = await userRepo.findByEmail('admin@x.com')
await userRepo.addRole(u.id, roleId)

// Vérif de permission
import { hasPermission } from '@mostajs/rbac/helpers/permissions'
if (hasPermission(user.permissions, 'cloud.admin.users')) { /* ... */ }

// Handler API Next.js
import { createUsersHandler } from '@mostajs/rbac/api/users'
export const { GET, POST } = createUsersHandler({ checkPermission, adminPermission:'admin:access' })
```

## DÉPEND DE
- @mostajs/orm (dependency) — repositories, EntitySchema, dialect.
- @mostajs/data-plug (dependency) — bascule mode ORM/NET.
- Peers : @mostajs/auth (requis, fournit checkPermission), @mostajs/audit (^1.0.0), @mostajs/menu (optionnel), @mostajs/socle (>=2.0.0), next >=14, react >=18, @tanstack/react-query >=5, radix-ui, lucide-react, sonner.

## PIÈGES
- `hasPermission` supporte le wildcard total `*` et les globs (`cloud.admin.*`) — un rôle avec `permissions:['*']` passe tout.
- seedRBAC et createAdmin sont idempotents (upsert) : sûrs à rappeler ; createAdmin sur un email existant renvoie l'utilisateur existant sans erreur.
- Le mode de données (ORM ou NET) est piloté par la variable d'environnement `MOSTA_DATA=orm|net` ; getRbacRepos résout le dialect en conséquence — ne pas instancier les Repository à la main si on veut le dual mode.
- Les handlers `./api/*` exigent une callback `checkPermission` (typiquement fournie par `@mostajs/auth` createAuthChecks) : le module ne gère pas la session lui-même.
- index.d.ts (`.`) est client-safe (schémas, composants, helpers) ; les repositories et le seed sont uniquement dans `./server` — ne pas importer `./server` côté client.
- `password` est optionnel dans UserDTO et ne doit pas transiter vers le client ; les méthodes `findAllSafe`/`findByIdSafe` retournent la version sans champs sensibles.

## RÉFÉRENCES
- README.md (racine du module) — exemples d'usage
- MULTI-TENANT.md — fonctionnement multi-tenant
- LICENSE (AGPL-3.0-or-later)
