feat: Phase 8 – Modul-SDK (createModuleServer, Config, Logger, Platform-Client)
This commit is contained in:
111
packages/platform-module-sdk/README.md
Normal file
111
packages/platform-module-sdk/README.md
Normal file
@@ -0,0 +1,111 @@
|
||||
# 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)`
|
||||
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.
|
||||
Reference in New Issue
Block a user