Files
mpm/packages/platform-module-sdk/README.md

113 lines
4.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# platform-module-sdk
Offizielles SDK für MPM-Module (Phase 8). Es verdrahtet den verbindlichen
Modul-API-Vertrag und stellt Authentifizierung, Konfiguration, Logging und
einen Plattform-API-Client bereit.
## Installation (Vendor-Pattern)
Module sind selbstständige ZIP-Pakete. Das SDK wird als **eine Datei**
(`index.js`) in das Modul-Paket kopiert (z. B. `backend/platform-module-sdk.js`)
und per `require` geladen. Dadurch bleiben Module ohne npm-Registry lauffähig.
```text
mein-modul/
├── module.json
├── backend/
│ ├── server.js # Einstiegspunkt (Manifest: entrypoint)
│ └── platform-module-sdk.js # vendored SDK (Kopie von index.js)
└── README.md
```
## Schnellstart
```js
'use strict';
const path = require('node:path');
const {
createModuleServer,
loadManifest,
createLogger,
} = require('./platform-module-sdk');
const manifest = loadManifest(path.join(__dirname, '..', 'module.json'));
const logger = createLogger({ moduleId: manifest.id });
const port = Number(process.env.PORT ?? manifest.port);
const server = createModuleServer({
manifest,
logger,
permissions: ['meinmodul.read'],
routes: (request, response, context) => {
// context.identity → { userId, username, displayName, role }
// context.path → URL-Pfad
if (request.method === 'GET' && context.path === '/aufgaben') {
response.writeHead(200, { 'Content-Type': 'application/json' });
response.end(JSON.stringify({ aufgaben: [] }));
return;
}
response.writeHead(404, { 'Content-Type': 'application/json' });
response.end(JSON.stringify({ statusCode: 404, message: 'Nicht gefunden' }));
},
});
server.listen(port, '127.0.0.1', () => {
logger.info(`Modul gestartet`, { port });
});
```
Der Server verdrahtet automatisch den Vertrag:
| Endpunkt | Verhalten |
|---|---|
| `GET /health` | 200 `{ moduleId, version, status: "healthy" }` |
| `GET /api/manifest` | 200 Manifest + Status |
| `GET /api/me` | 200 Identität vom Gateway (401 ohne Identität) |
| fachliche Routen | `options.routes(...)`; ohne Identität 401 (`identityRequired`) |
## API
### `extractIdentity(headers)`
> This helper only parses untrusted header values. Do not use it as an authorization check. `createModuleServer` verifies the request-bound, per-module signature before exposing the identity to `/api/me` or route handlers. In production it requires the key injected as `MPM_MODULE_IDENTITY_KEY`.
Liest die Benutzer-Identität aus den Gateway-Headern (`x-user-id`,
`x-user-username`, `x-user-display-name`, `x-user-role`). Case-insensitive;
`null`, wenn der Request nicht über den Gateway kam.
### `loadManifest(manifestPath)`
Lädt und validiert `module.json` (Pflichtfelder, Runtime `node`, apiVersion `v1`).
### `loadModuleConfig(env?)`
Laufzeit-Konfiguration: `port` (ENV `PORT`), `nodeEnv`, `platformBaseUrl`
(ENV `PLATFORM_INTERNAL_URL`, Default `http://127.0.0.1:3000`), `serviceToken`.
### `createLogger({ moduleId, level })`
Strukturierte JSON-Logs (`debug/info/warn/error`). Sensible Schlüssel
(Passwort, Token, Secret, Cookie, …) werden automatisch geschwärzt.
### `createPlatformClient({ baseUrl, serviceToken, timeoutMs }))`
HTTP-Client für interne Aufrufe zur Plattform (`get/post/patch/delete`).
Wirft bei Nicht-2xx einen Fehler mit Statuscode.
### `createModuleServer(options)`
Siehe Schnellstart. Optionen: `manifest`, `routes`, `permissions`,
`logger`, `identityRequired` (Default `true` – sicherer Default).
## Tests
Die SDK-Tests laufen im Backend-Test-Suite
(`apps/platform-backend/test/platform-module-sdk.spec.ts`):
```bash
cd apps/platform-backend && npm test
```
## Sicherheitsregeln für Modul-Autoren
- Nur auf `127.0.0.1` lauschen (der Gateway ist der einzige Zugang).
- Identität ausschließlich über `extractIdentity` beziehen – niemals aus
URL, Body oder eigenen Headern vertrauen.
- Keine Plattform-Secrets erwarten: Der Prozess-Manager übergibt nur
`PATH`, `NODE_ENV` und `PORT`.
- Logs niemals Passwörter/Tokens/personenbezogene Daten schreiben lassen.