# @mostajs/module-contract

**Auteur** : Dr Hamid MADANI <drmdh@msn.com> · **Licence** : AGPL-3.0-or-later
**Niveau** : N0 · **ZÉRO dépendance** · Types purs (aucun code exécutable).

Le **contrat** que tout module @mostajs remplit pour se déclarer au démarrage : la forme de
`ModuleRegistration`, `WireManifest`, `SocleConfig`, et tout le vocabulaire des contributions
(`SchemaDefinition`, `PermissionDefinition`, `RouteRegistration`, `PageRegistration`, `MenuContribution`…).

C'est une **interface**, pas une implémentation. Un module s'y **conforme** ; il ne dépend pas de
qui la consomme.

## Pourquoi ce paquet existe

Ces types vivaient dans **`@mostajs/socle`** (N1), l'orchestrateur d'amorçage. Conséquence : toute
primitive N0 qui voulait se déclarer — `orm`, `ui`, `themes` — devait importer depuis l'orchestrateur,
c'est-à-dire **dépendre vers le haut**.

`mostajs-layer-lint` (§5.bis) ne le signalait pas… parce que la règle elle-même avait dû inscrire
`socle` sur une **liste blanche** (`BASE`) pour les N0. **Une dérogation dans les règles est toujours
le symptôme d'une couche mal posée, jamais sa solution.**

En descendant le contrat en N0 :

- `orm`, `ui`, `themes` se conforment à une interface N0 — plus aucune dépendance vers le haut ;
- `socle` **implémente** ce contrat (il le ré-exporte pour compatibilité) ;
- `socle` **sort** de la liste blanche `BASE`, et l'exception `§5.bis.1` **disparaît des règles**.

> Le signe d'un bon correctif d'architecture : il **retire** un cas particulier. Vérifié — **240
> modules, 0 faute, sans l'exception**.

## Le flux (analogie BIOS)

```
   socle (BIOS)                    application (init OS)
   ├─ découvre les modules         ├─ dépend de socle  ── reçoit les déclarations
   ├─ collecte leurs déclarations  └─ dépend de orm    ── crée les schémas collectés
   └─ remet le tout à l'app
```

`orm` ne connaît pas `socle`. `socle` ne connaît pas `orm`. Leur **seul point commun est ce
contrat** — et il est sous les deux, en N0.

## Usage

```ts
import type { ModuleRegistration } from '@mostajs/module-contract'

// Un module qui CONTRIBUE se conforme au contrat :
export function register(registry: { register(r: ModuleRegistration): void }): void {
  registry.register({
    manifest: { name: 'rbac', package: '@mostajs/rbac', version: '2.7.0', type: 'functional', priority: 50, register: './dist/register.js' },
    schemas: [{ name: 'User', schema: UserSchema }],
    permissions: { permissions: {}, definitions: [], categories: [] },
  })
}
```

Un module d'**infrastructure** qui ne contribue rien (comme `orm`) n'importe même pas ce contrat :
son seul `wire.json` (présence) suffit.

## Contenu du contrat

`ModuleRegistration` · `WireManifest` · `ModuleType` · `SchemaDefinition` · `RepositoryFactory` ·
`PermissionDefinition` · `CategoryDefinition` · `RoleDefinition` · `MenuContribution` ·
`RouteRegistration` · `PageRegistration` · `ResolvedPage` · `SocleConfig` · `IModuleRegistry` · …

## Tests

```bash
npm test   # 14 tests — le contrat exporte bien chaque type, et ne dépend de RIEN
```
L'implémentation, elle, est prouvée par les **25 tests de `@mostajs/socle`**, qui consomme ce contrat.
