feat: Phase 3 – Modul-System (Manifest, ZIP-Installation, Lifecycle, Prozess-Manager)
This commit is contained in:
@@ -142,8 +142,17 @@ Security Hardening (Penetrationstests, Dependency/Container-Scans, HSTS, Backup/
|
||||
| DELETE | `/api/v1/users/:id` | Admin | Benutzer löschen |
|
||||
| GET | `/api/v1/profile` | Session | Eigenes Profil |
|
||||
| PATCH | `/api/v1/profile/password` | Session | Eigenes Passwort ändern |
|
||||
| GET | `/api/v1/modules` | Admin | Alle Module |
|
||||
| POST | `/api/v1/modules/install` | Admin | ZIP-Paket installieren (multipart, Feld `package`) |
|
||||
| GET | `/api/v1/modules/:id` | Admin | Einzelnes Modul |
|
||||
| POST | `/api/v1/modules/:id/start` | Admin | Modul starten |
|
||||
| POST | `/api/v1/modules/:id/stop` | Admin | Modul stoppen |
|
||||
| POST | `/api/v1/modules/:id/restart` | Admin | Modul neu starten |
|
||||
| PATCH | `/api/v1/modules/:id/enabled` | Admin | Modul aktivieren/deaktivieren |
|
||||
| GET | `/api/v1/modules/:id/health` | Admin | Healthcheck ausführen |
|
||||
| DELETE | `/api/v1/modules/:id` | Admin | Modul entfernen |
|
||||
|
||||
OpenAPI/Swagger UI: `/api/docs` · Ab Phase 3: `/api/v1/modules/*`, `/api/v1/permissions/*`, `/api/v1/audit/*`.
|
||||
OpenAPI/Swagger UI: `/api/docs` · Ab Phase 4: dynamisches Routing `/slug`.
|
||||
|
||||
### Schutzregeln der Benutzerverwaltung
|
||||
|
||||
@@ -153,9 +162,11 @@ OpenAPI/Swagger UI: `/api/docs` · Ab Phase 3: `/api/v1/modules/*`, `/api/v1/per
|
||||
- Passwort-Reset (Admin) meldet den Benutzer von allen Sessions ab
|
||||
- Eigenes Passwort ändern meldet alle übrigen Sessions ab (aktuelle bleibt aktiv)
|
||||
|
||||
## 9. Modul-Vertrag (Ausblick Phase 3+)
|
||||
## 9. Modul-System (Phase 3)
|
||||
|
||||
Jedes Modul liefert ein Manifest (`module.json`) und einen minimalen API-Vertrag:
|
||||
### Manifest-Vertrag
|
||||
|
||||
Jedes Modul-Paket (ZIP, max. 10 MB) enthält ein `module.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -164,6 +175,7 @@ Jedes Modul liefert ein Manifest (`module.json`) und einen minimalen API-Vertrag
|
||||
"version": "1.0.0",
|
||||
"slug": "kalender-tool",
|
||||
"description": "Kalenderverwaltung",
|
||||
"author": "…",
|
||||
"runtime": "node",
|
||||
"entrypoint": "server.js",
|
||||
"port": 41001,
|
||||
@@ -172,7 +184,27 @@ Jedes Modul liefert ein Manifest (`module.json`) und einen minimalen API-Vertrag
|
||||
}
|
||||
```
|
||||
|
||||
Minimal-API je Modul: `GET /health`, `GET /api/manifest`, `GET /api/me`. Installation als ZIP-Paket mit Validierung, Dependency-Installation, Migrationen und Healthcheck. Details: [`modules/README.md`](../modules/README.md).
|
||||
Validierung per Zod: ID/Slug-Muster, SemVer, Port 41000–41999, kein Pfad-Traversal im Entrypoint, Runtime `node`, apiVersion `v1`.
|
||||
|
||||
### Lifecycle
|
||||
|
||||
```
|
||||
INSTALLED → STARTING → RUNNING → STOPPING → STOPPED
|
||||
↓ ↓
|
||||
ERROR ERROR DISABLED (via Enable/Disable)
|
||||
```
|
||||
|
||||
### Sicherheitsmaßnahmen
|
||||
|
||||
- **Zip-Slip-Schutz**: Alle ZIP-Einträge müssen im Zielverzeichnis bleiben
|
||||
- **Minimale Prozess-ENV**: Module erhalten nur `PATH`, `NODE_ENV`, `PORT` – keine Plattform-Secrets
|
||||
- **Spawn ohne Shell**: keine Command-Injection möglich
|
||||
- **Eigene Log-Dateien** pro Modul (`/app/data/logs/module-<id>.log`)
|
||||
- **Startup-Grace**: Healthcheck mit 10 Retries, bevor ein Modul als ERROR gilt
|
||||
- **Isolation**: Ein abgestürztes Modul (ERROR) beeinträchtigt weder Plattform noch andere Module
|
||||
- Persistente Volumes: Modul-Dateien und Logs überleben Container-Updates
|
||||
|
||||
Minimal-API je Modul (Phase 6): `GET /health`, `GET /api/manifest`, `GET /api/me`. Details zum Paketformat: [`modules/README.md`](../modules/README.md).
|
||||
|
||||
## 10. Architektur-Entscheidungen (ADR-Kurzform)
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ Der Arbeitsplan sieht zehn inkrementelle Phasen vor. Nach jeder Phase muss das S
|
||||
|---|---|---|
|
||||
| 1 | Grundgerüst (Docker, DB, Login, Rollen) | ✅ Abgeschlossen |
|
||||
| 2 | Benutzerverwaltung | ✅ Abgeschlossen |
|
||||
| 3 | Modul-System (Manifest, Installation, Lifecycle) | ⏳ Geplant |
|
||||
| 3 | Modul-System (Manifest, Installation, Lifecycle) | ✅ Abgeschlossen |
|
||||
| 4 | Gateway & dynamisches Routing (`/slug`) | ⏳ Geplant |
|
||||
| 5 | Berechtigungssystem (User ↔ Module) | ⏳ Geplant |
|
||||
| 6 | Modul-API (`/health`, `/api/manifest`, `/api/me`) | ⏳ Geplant |
|
||||
@@ -51,10 +51,26 @@ Definition of Done: Admin kann Benutzer vollständig verwalten.
|
||||
- [x] Backend-Tests: 49 bestanden (inkl. UsersService, ProfileService)
|
||||
- [x] E2E verifiziert: CRUD, RBAC (User → 403), Login-Sperre nach Deaktivierung, Passwort-Flows
|
||||
|
||||
## Nächste Schritte (Phase 3 – Modul-System)
|
||||
## Phase 3 – Modul-System (abgeschlossen)
|
||||
|
||||
- Modul-Datenmodell (`modules`-Tabelle) und Manifest-Vertrag (`module.json`)
|
||||
- Modul-Installation als ZIP-Paket (Validierung, Dateien, Registrierung)
|
||||
- Modul-Lifecycle (INSTALLED/STARTING/RUNNING/STOPPING/STOPPED/ERROR/DISABLED)
|
||||
- Prozessverwaltung der Modul-Prozesse über Supervisor
|
||||
- Healthchecks und Statusanzeige im Admin-Bereich
|
||||
Definition of Done: Modul-Datenmodell, Manifest, Installation, Registrierung, Status, Start/Stop/Restart, Healthcheck.
|
||||
|
||||
- [x] `modules`-Tabelle (Migration 002) mit Lifecycle-Status und eindeutigen Ports/Slugs
|
||||
- [x] Manifest-Vertrag `module.json` (Zod: ID, Name, Version, Slug, Runtime, Entrypoint, Port 41000–41999, Healthcheck, apiVersion)
|
||||
- [x] ZIP-Installer mit Manifest-Validierung, Größenlimit (10 MB) und **Zip-Slip-Schutz**
|
||||
- [x] Modul-Prozess-Manager: Start/Stop (SIGTERM→SIGKILL) als Kindprozesse, minimale ENV (keine Plattform-Secrets), eigene Log-Dateien
|
||||
- [x] Healthcheck-Service mit Startup-Grace (10 Retries × 500 ms)
|
||||
- [x] Lifecycle: INSTALLED → STARTING → RUNNING → STOPPING → STOPPED, ERROR, DISABLED
|
||||
- [x] `GET/POST /api/v1/modules`, `POST :id/start|stop|restart`, `PATCH :id/enabled`, `GET :id/health`, `DELETE :id` (nur ADMIN)
|
||||
- [x] Duplikat-Schutz: Modul-ID, Slug und Port müssen eindeutig sein (409)
|
||||
- [x] Frontend: Modulverwaltungs-Seite (ZIP-Upload, Tabelle mit Status-Badges, Lifecycle-Buttons, Health-Anzeige, Remove-Dialog)
|
||||
- [x] Persistente Volumes für Modul-Dateien und Logs (`modules-data`, `module-logs`)
|
||||
- [x] Demo-Modul (`modules/demo`) als Referenzimplementierung
|
||||
- [x] Backend-Tests: 72 bestanden (inkl. ModulesService-Lifecycle, Manifest-Validierung, Installer)
|
||||
- [x] E2E verifiziert: Installation (201), Start → RUNNING, Healthcheck (healthy, 2 ms), Stop, Restart, Disable (stoppt Prozess), Start-Sperre bei Disable (400), Remove, RBAC (USER → 403)
|
||||
|
||||
## Nächste Schritte (Phase 4 – Gateway & Routing)
|
||||
|
||||
- Dynamisches Routing: `/slug` → Modul-Prozess (Nginx-Konfiguration zur Laufzeit)
|
||||
- Zugriffskontrolle beim Routing (Session → Permission Check → 403/Proxy)
|
||||
- Modul-Gateway mit sicherer Identitätsübergabe an das Modul
|
||||
Reference in New Issue
Block a user