Skip to content

Test-Protokoll: Modul-Architektur

Systematisches Testprotokoll zur Validierung aller Komponenten der Modul-Architektur. Jeder Abschnitt kann unabhängig getestet und abgesegnet werden.

Stand: März 2026

Voraussetzungen

Bevor du startest, müssen folgende Dienste laufen:

bash
# 1. Infrastruktur starten
cd prilog-infra
docker compose -f docker-compose.dev.yml up -d

# 2. Prüfen dass alles läuft
docker exec prilog-infra-postgres-1 pg_isready -U prilog    # → accepting connections
docker exec prilog-infra-redis-1 redis-cli ping              # → PONG
docker exec prilog-infra-minio-1 mc ls local                 # → prilog-files/

# 3. Backend starten
cd prilog-backend-api
npx prisma migrate deploy     # Alle 29 Migrationen anwenden
npx prisma generate           # Prisma Client generieren
npm run dev                   # Server auf Port 3001

# 4. Seed-Script ausführen (falls noch nicht geschehen)
npx tsx prisma/seed-module-registry.ts

Benötigte Ports: 3001 (Backend), 5432 (PostgreSQL), 6379 (Redis), 9000/9001 (MinIO)


1. Datenbank-Schema

Ziel: Alle neuen Tabellen existieren und sind korrekt strukturiert.

Tests

  • [ ] 1.1 Prisma-Migrationen vollständig angewandt

    bash
    npx prisma migrate deploy
    # Erwartung: "No pending migrations to apply." oder alle applied
  • [ ] 1.2 Neue Tabellen existieren

    bash
    docker exec prilog-infra-postgres-1 psql -U prilog -c "\dt" | grep -E "module_|store_|developer_|cron_"

    Erwartete Tabellen:

    • module_registrations
    • tenant_module_installations
    • module_events
    • module_configs
    • module_usage_events
    • developer_accounts
    • store_submissions
    • store_ratings
    • cron_job_runs
  • [ ] 1.3 Seed-Daten vorhanden

    bash
    docker exec prilog-infra-postgres-1 psql -U prilog -c "SELECT module_id, name, version, status FROM module_registrations;"

    Erwartung: prilog-project mit Status active

  • [ ] 1.4 Tenant-Installation vorhanden

    bash
    docker exec prilog-infra-postgres-1 psql -U prilog -c "SELECT tenant_id, module_id, status FROM tenant_module_installations;"

    Erwartung: Mindestens 1 Eintrag mit prilog-project und Status active


2. Unit-Tests

Ziel: Alle automatisierten Tests laufen grün.

Tests

  • [ ] 2.1 Backend-Tests

    bash
    cd prilog-backend-api
    npx vitest run

    Erwartung: 18 passed (18), 296 passed (296)

  • [ ] 2.2 TypeScript-Kompilierung (Backend)

    bash
    npx tsc --noEmit

    Erwartung: Keine Fehler

  • [ ] 2.3 TypeScript-Kompilierung (Web-Client)

    bash
    cd prilog-web-client
    npx tsc --noEmit

    Erwartung: Keine Fehler

  • [ ] 2.4 TypeScript-Kompilierung (Portal)

    bash
    cd prilog-portal
    npx tsc --noEmit

    Erwartung: Keine Fehler

  • [ ] 2.5 TypeScript-Kompilierung (Admin)

    bash
    cd prilog-admin
    npx tsc --noEmit

    Erwartung: Keine Fehler

  • [ ] 2.6 SDK-Build

    bash
    cd prilog-sdk
    npm run build

    Erwartung: Alle 4 Pakete bauen fehlerfrei


3. Event-Bus

Ziel: Events werden emittiert, persistiert und an Handler weitergeleitet.

Tests

  • [ ] 3.1 Event-Bus wird beim Server-Start initialisiert

    Server starten → Log prüfen
    Erwartung: "EventBus initialized" in der Konsolenausgabe
  • [ ] 3.2 Space-Created Event wird emittiert

    Über die Platform-API einen neuen Space erstellen:
    POST /api/platform/v1/spaces
    {
      "name": "Test-Space",
      "type": "CLASSROOM",
      "visibility": "PRIVATE"
    }
    
    Dann in der DB prüfen:
    SELECT * FROM module_events WHERE event_type = 'space.created' ORDER BY created_at DESC LIMIT 1;

    Erwartung: Ein Eintrag mit source = 'core' und payload mit spaceId und name

  • [ ] 3.3 Space-Deleted Event wird emittiert

    Space löschen → DB prüfen:
    SELECT * FROM module_events WHERE event_type = 'space.deleted' ORDER BY created_at DESC LIMIT 1;

    Erwartung: Ein Eintrag mit dem gelöschten spaceId

  • [ ] 3.4 User-Joined Event bei Membership-Erstellung

    Mitglied zu einem Space hinzufügen →
    SELECT * FROM module_events WHERE event_type = 'user.joined' ORDER BY created_at DESC LIMIT 1;

    Erwartung: Eintrag mit userId und spaceId

  • [ ] 3.5 User-Left Event bei Membership-Löschung

    Mitglied aus Space entfernen →
    SELECT * FROM module_events WHERE event_type = 'user.left' ORDER BY created_at DESC LIMIT 1;
  • [ ] 3.6 Module-Activated / Module-Deactivated Events

    Wird in Test 5 (Lifecycle) mitgetestet

4. Modul-Registry & Bootstrap

Ziel: Registrierte Module erscheinen im Bootstrap-Response mit Feature-Flags.

Tests

  • [ ] 4.1 Registry-Endpunkt liefert Module

    GET /api/platform/v1/modules/registry

    Erwartung: prilog-project mit type: "B", featureFlag: "project", und installation.status: "active"

  • [ ] 4.2 Installed-Endpunkt liefert aktive Installationen

    GET /api/platform/v1/modules/installed

    Erwartung: prilog-project mit status: "active"

  • [ ] 4.3 Bootstrap enthält Feature-Flags

    GET /api/platform/v1/bootstrap

    Erwartung:

    • featureFlags.project === true
    • modules Array enthält einen Eintrag mit key: "project" und enabled: true
  • [ ] 4.4 Einzelnes Modul-Detail

    GET /api/platform/v1/modules/installed/prilog-project

    Erwartung: Vollständige Installation-Details inkl. permissions, featureFlag, activatedAt


5. Modul-Lifecycle

Ziel: Module können installiert, aktiviert, deaktiviert und deinstalliert werden.

Vorbereitung

Falls prilog-project bereits aktiv ist, erst deaktivieren:

POST /api/platform/v1/modules/installed/prilog-project/deactivate

Tests

  • [ ] 5.1 Modul installieren

    POST /api/platform/v1/modules/install
    {
      "moduleId": "prilog-project",
      "approvedPermissions": ["spaces:read", "files:read", "files:write", "events:publish", "events:subscribe"]
    }

    Erwartung: { success: true, status: "installed" }

  • [ ] 5.2 Modul aktivieren

    POST /api/platform/v1/modules/installed/prilog-project/activate

    Erwartung:

    • { success: true, status: "active" }
    • module_events hat module.activated Eintrag
    • tenant_events hat Audit-Eintrag module.activated
    • Bootstrap liefert jetzt featureFlags.project: true
  • [ ] 5.3 Modul deaktivieren

    POST /api/platform/v1/modules/installed/prilog-project/deactivate

    Erwartung:

    • { success: true, status: "deactivated" }
    • tenant_module_installations.data_delete_at ist 30 Tage in der Zukunft
    • module_events hat module.deactivated Eintrag
    • Bootstrap liefert featureFlags.project NICHT mehr (oder false)
  • [ ] 5.4 Modul reaktivieren (innerhalb 30 Tage)

    POST /api/platform/v1/modules/installed/prilog-project/activate

    Erwartung: Modul ist wieder aktiv, data_delete_at ist null

  • [ ] 5.5 Modul deinstallieren

    DELETE /api/platform/v1/modules/installed/prilog-project

    Erwartung:

    • { success: true, status: "pending_deletion" }
    • data_delete_at ist 30 Tage in der Zukunft
  • [ ] 5.6 Ungültiges Modul installieren (Negativtest)

    POST /api/platform/v1/modules/install
    { "moduleId": "prilog-gibts-nicht", "approvedPermissions": [] }

    Erwartung: HTTP 400

  • [ ] 5.7 Ungültige Berechtigung (Negativtest)

    POST /api/platform/v1/modules/install
    { "moduleId": "prilog-project", "approvedPermissions": ["admin:alles"] }

    Erwartung: HTTP 400 — Berechtigung nicht im Manifest

Nach dem Lifecycle-Test

Stelle sicher dass prilog-project wieder aktiv ist bevor du weitertestest:

POST /api/platform/v1/modules/install
{ "moduleId": "prilog-project", "approvedPermissions": ["spaces:read", "files:read", "files:write", "events:publish", "events:subscribe"] }
POST /api/platform/v1/modules/installed/prilog-project/activate

6. Store-API

Ziel: Module können eingereicht, gescannt, reviewed und im Katalog angezeigt werden.

Vorbereitung

Erstelle einen Developer-Account:

sql
INSERT INTO developer_accounts (id, email, name, organization, verified, updated_at)
VALUES ('dev-test-1', 'dev@test.com', 'Test Developer', 'TestOrg', true, NOW());

Tests

  • [ ] 6.1 Store-Katalog

    GET /api/platform/v1/store/modules

    Erwartung: prilog-project erscheint mit Rating-Daten und Installationszahl

  • [ ] 6.2 Store-Kategorien

    GET /api/platform/v1/store/categories

    Erwartung: 6 Kategorien (communication, organization, analytics, integration, security, other)

  • [ ] 6.3 Modul-Detail

    GET /api/platform/v1/store/modules/prilog-project

    Erwartung: Vollständiges Manifest, Rating, Installationszahl

  • [ ] 6.4 Modul einreichen (JSON)

    POST /api/platform/v1/store/developer/submit
    Header: X-Developer-Id: dev-test-1
    {
      "manifest": {
        "id": "prilog-test-scan",
        "name": "Scan Test",
        "version": "0.1.0",
        "type": "A",
        "prilogCoreVersion": ">=1.0.0",
        "description": "Test-Modul für Security-Scan",
        "author": { "name": "Test", "email": "test@test.com" },
        "license": "MIT",
        "permissions": ["events:subscribe"],
        "featureFlag": "test-scan"
      },
      "artifactPath": "test/path"
    }

    Erwartung: { submissionId: "...", status: "in_review" }

  • [ ] 6.5 Security-Scan blockiert gefährlichen Code

    POST /api/platform/v1/store/developer/submit
    Header: X-Developer-Id: dev-test-1
    {
      "manifest": { ... wie oben, aber id: "prilog-test-evil" ... },
      "artifactPath": "test/path",
      "sourceFiles": {
        "src/index.ts": "import { exec } from 'child_process';\nexport async function register() { eval('dangerous'); }"
      }
    }

    Erwartung: HTTP 422 mit Violations (child_process + eval)

  • [ ] 6.6 Meine Einreichungen

    GET /api/platform/v1/store/developer/submissions
    Header: X-Developer-Id: dev-test-1

    Erwartung: Die soeben erstellte Submission

  • [ ] 6.7 Admin: Offene Reviews

    GET /api/platform/v1/store/admin/reviews

    Erwartung: Submission mit Status in_review

  • [ ] 6.8 Admin: Einreichung genehmigen

    POST /api/platform/v1/store/admin/reviews/{submissionId}
    { "action": "approve", "notes": "Sieht gut aus" }

    Erwartung:

    • { success: true, status: "approved" }
    • Modul erscheint jetzt in module_registrations
    • Modul erscheint im Store-Katalog
  • [ ] 6.9 Bewertung abgeben

    POST /api/platform/v1/store/modules/prilog-project/ratings
    { "rating": 4, "comment": "Funktioniert gut" }

    Erwartung: HTTP 201

  • [ ] 6.10 Bewertung nicht möglich ohne Installation (Negativtest)

    POST /api/platform/v1/store/modules/prilog-test-scan/ratings
    { "rating": 5 }

    Erwartung: HTTP 403 (Modul nicht installiert)


7. Artifact-Upload (MinIO/S3)

Ziel: Module können als Datei hochgeladen und heruntergeladen werden.

Tests

  • [ ] 7.1 Multipart-Upload

    bash
    curl -X POST http://localhost:3001/api/platform/v1/store/developer/upload \
      -H "X-Developer-Id: dev-test-1" \
      -F "artifact=@/home/lee/prilog-sdk/dist/prilog-types-1.0.0.tgz" \
      -F 'manifest={"id":"prilog-upload-test","name":"Upload Test","version":"0.1.0","type":"A","prilogCoreVersion":">=1.0.0","description":"Test Upload","author":{"name":"Test","email":"t@t.com"},"license":"MIT","permissions":["events:subscribe"],"featureFlag":"upload-test"}'

    Erwartung:

    • HTTP 201 mit artifactPath, checksum, submissionId
    • Datei liegt in MinIO unter store/modules/prilog-upload-test/0.1.0/
  • [ ] 7.2 MinIO-Prüfung

    bash
    docker exec prilog-infra-minio-1 mc ls local/prilog-files/store/modules/ --recursive

    Erwartung: Hochgeladene Datei sichtbar

  • [ ] 7.3 Download-URL

    GET /api/platform/v1/store/developer/download/{submissionId}
    Header: X-Developer-Id: dev-test-1

    Erwartung: { downloadUrl: "http://...", expiresInSeconds: 900 }

  • [ ] 7.4 Upload zu groß (Negativtest)

    Eine Datei > 50 MB hochladen

    Erwartung: HTTP 413


8. Billing-Hooks

Ziel: Nutzungs-Events werden korrekt erfasst.

Tests

  • [ ] 8.1 reportActive() wird gespeichert

    sql
    -- Manuell ein Usage-Event einfügen (simuliert ctx.billing.reportActive())
    INSERT INTO module_usage_events (id, tenant_id, module_id, event_type, quantity, billing_period, created_at)
    VALUES ('test-1', '<tenant-id>', 'prilog-project', 'active', 1, '2026-03', NOW());
    
    SELECT * FROM module_usage_events WHERE module_id = 'prilog-project';

    Erwartung: Eintrag vorhanden

  • [ ] 8.2 Billing-Hooks sind non-blocking

    Modul aktivieren/deaktivieren → Server darf NICHT abstürzen wenn Stripe nicht konfiguriert ist

    Erwartung: Lifecycle funktioniert, Log zeigt "Stripe is not configured — module billing disabled"


9. Monitoring & Audit

Ziel: Performance-Metriken werden erfasst, Audit-Log wird geschrieben.

Tests

  • [ ] 9.1 Modul-Health Dashboard

    GET /api/admin/modules/health

    Erwartung: prilog-project mit activeInstallations, performance Daten

  • [ ] 9.2 Audit-Log

    GET /api/admin/modules/audit/{tenantId}

    Erwartung: Einträge für module.installed, module.activated, module.deactivated (aus Test 5)

  • [ ] 9.3 Metriken nach API-Aufrufen

    Mehrere Requests an Projekt-Modul-Endpunkte machen:
    GET /api/platform/v1/spaces/{spaceId}/files/folders
    GET /api/platform/v1/spaces/{spaceId}/activity
    
    Dann:
    GET /api/admin/modules/health/prilog-project

    Erwartung: p95Ms und p99Ms sind befüllt (nicht null)


10. Cron-Jobs

Ziel: Alle Cron-Jobs sind registriert, können manuell ausgelöst werden, und deren Status ist sichtbar.

Tests

  • [ ] 10.1 Cron-Jobs sind registriert

    GET /api/admin/crons

    Erwartung: 6 Jobs:

    • module-data-cleanup (Täglich 03:00)
    • file-cleanup (Täglich 03:30)
    • billing-usage-aggregation (Monatlich 1., 02:00)
    • billing-developer-payouts (Monatlich 3., 04:00)
    • admin-password-cleanup (Täglich 04:00)
    • billing-period-end-warning (Monatlich 24., 09:00)
  • [ ] 10.2 Job manuell auslösen

    POST /api/admin/crons/file-cleanup/trigger

    Erwartung: { success: true, message: "0 expired files cleaned up" }

  • [ ] 10.3 Run-History

    GET /api/admin/crons/file-cleanup/history

    Erwartung: Mindestens 1 Eintrag mit status: "success" vom manuellen Trigger

  • [ ] 10.4 Cron-Job-Tracking in DB

    sql
    SELECT * FROM cron_job_runs ORDER BY started_at DESC LIMIT 5;

    Erwartung: Einträge mit job_key, status, duration_ms, started_at, finished_at


11. Frontend: Dynamisches Module Loading

Ziel: Web-Client zeigt nur aktivierte Module als Tabs an.

Vorbereitung

bash
cd prilog-web-client
npm run dev    # Port 5173

Tests

  • [ ] 11.1 Bootstrap lädt Module

    Browser DevTools → Network → /bootstrap Antwort prüfen

    Erwartung: modules Array enthält project mit enabled: true, featureFlags.project: true

  • [ ] 11.2 Space-View zeigt Tabs

    Einen Space öffnen → Tabs prüfen

    Erwartung: Tabs für Dateien, Aufgaben, Kalender sind sichtbar (wenn project-Modul aktiv)

  • [ ] 11.3 Tabs verschwinden bei Deaktivierung

    Projekt-Modul deaktivieren (API) → Seite neu laden

    Erwartung: Dateien/Aufgaben/Kalender-Tabs verschwinden

  • [ ] 11.4 Lazy Loading funktioniert

    Browser DevTools → Network → beim ersten Klick auf einen Tab

    Erwartung: Separater Chunk wird geladen (lazy import)


12. Portal: Store-UI

Ziel: Store-Seite im Portal funktioniert.

Vorbereitung

bash
cd prilog-portal
npm run dev    # Port 3003

Tests

  • [ ] 12.1 Store-Seite erreichbar

    /modules/store öffnen

    Erwartung: Modul-Katalog wird angezeigt

  • [ ] 12.2 Kategorien-Filter

    Auf eine Kategorie klicken (z.B. "Organisation")

    Erwartung: Liste filtert sich

  • [ ] 12.3 Suche

    "Projekt" in die Suche eingeben → Enter

    Erwartung: Projekt-Modul wird angezeigt

  • [ ] 12.4 Modul-Card

    Prüfe ob die Card zeigt: Name, Typ-Badge, Beschreibung, Autor, Version, Rating, Installationszahl

13. Admin: Cron-Jobs UI

Ziel: Cron-Dashboard im Admin-Panel funktioniert.

Vorbereitung

bash
cd prilog-admin
npm run dev    # Port 3004

Tests

  • [ ] 13.1 Cron-Seite erreichbar

    /crons öffnen

    Erwartung: 6 Job-Cards werden angezeigt

  • [ ] 13.2 Job-Details

    Jede Card prüfen

    Erwartung: Name, Beschreibung, Schedule-Label, letzter Status

  • [ ] 13.3 Manuell auslösen

    "Auslösen" Button bei "Gelöschte Dateien bereinigen" klicken

    Erwartung: Spinner → Erfolgsmeldung → Status aktualisiert

  • [ ] 13.4 Verlauf aufklappen

    Pfeil-Button bei einem Job klicken

    Erwartung: Historie mit Zeitstempel, Dauer, Ergebnis


14. SDK & Tooling

Ziel: Modul-Generator und Validator funktionieren.

Tests

  • [ ] 14.1 Modul erstellen

    bash
    cd /tmp
    node /home/lee/prilog-sdk/packages/create-module/dist/index.js test-validierung --type=B

    Erwartung: Verzeichnis test-validierung/ mit prilog-module.json, src/index.ts, package.json, etc.

  • [ ] 14.2 Modul validieren (valide)

    bash
    node /home/lee/prilog-sdk/packages/module-validator/dist/cli.js /tmp/test-validierung

    Erwartung: ✓ Module is valid

  • [ ] 14.3 Modul validieren (invalide)

    bash
    rm /tmp/test-validierung/src/index.ts
    node /home/lee/prilog-sdk/packages/module-validator/dist/cli.js /tmp/test-validierung

    Erwartung: ✗ Module validation failed mit Fehler für fehlende src/index.ts

  • [ ] 14.4 Manifest-Validierung

    bash
    # Ungültige ID testen
    echo '{"id":"INVALID","name":"X"}' > /tmp/bad-manifest.json
    # Im Code oder via API testen
  • [ ] 14.5 Aufräumen

    bash
    rm -rf /tmp/test-validierung

15. Dokumentation

Ziel: Docs sind deployed und korrekt.

Tests

  • [ ] 15.1 GitHub Pages erreichbar

    https://brasilspace.github.io/prilog_docs/ öffnen

    Erwartung: VitePress-Seite mit Startseite

  • [ ] 15.2 Navigation prüfen

    • [ ] Guide → Einführung
    • [ ] Guide → Modul entwickeln
    • [ ] Architektur → Modul-Architektur-Handbuch
    • [ ] Referenz → SDK API
    • [ ] Referenz → Platform API
    • [ ] Referenz → Infrastruktur
    • [ ] Umsetzung → Umsetzungsbericht
  • [ ] 15.3 Suche funktioniert

    Suchfeld öffnen → "tenantId" eingeben

    Erwartung: Treffer in mehreren Seiten

  • [ ] 15.4 Code-Blöcke korrekt gerendert

    Referenz → SDK API → Code-Beispiele prüfen

    Erwartung: Syntax-Highlighting, keine Artefakte


Zusammenfassung

#BereichTestsStatus
1Datenbank-Schema4
2Unit-Tests6
3Event-Bus6
4Registry & Bootstrap4
5Modul-Lifecycle7
6Store-API10
7Artifact-Upload4
8Billing-Hooks2
9Monitoring & Audit3
10Cron-Jobs4
11Frontend Module Loading4
12Portal Store-UI4
13Admin Cron-UI4
14SDK & Tooling5
15Dokumentation4
Total71

Wenn alle 71 Tests bestanden sind, ist die Modul-Architektur validiert und abgesegnet.