Technische Dokumentation

Setup-Anleitung, Architektur und API-Referenz fuer die eforms.cloud-Plattform

Inhaltsverzeichnis

  1. Architektur & Tech-Stack
  2. Voraussetzungen
  3. Entwicklungsumgebung starten
  4. Backend-Zugang & Admin-User
  5. API-Referenz
  6. Authentifizierung (Sanctum)
  7. Zwei-Faktor-Authentifizierung (2FA)
  8. CAPTCHA-System
  9. Rollensystem & Berechtigungen
  10. Dynamisches Formularsystem
  11. Anonymisierung
  12. Mehrsprachigkeit (i18n)
  13. Wartungsmodus
  14. Datenbank
  15. Projektstruktur
  16. Frontend-Seiten & Komponenten
  17. CI/CD-Pipeline
  18. Deployment (Produktion)

1. Architektur & Tech-Stack

Frontend Nuxt 3 (Vue 3)
TypeScript, Tailwind CSS
Backend (API) Laravel 13 (PHP 8.4)
Laravel Sanctum
Datenbank PostgreSQL 15
Docker Volume

Die Anwendung folgt einer klassischen Client-Server-Architektur. Das Nuxt-3-Frontend kommuniziert per REST-API mit dem Laravel-Backend. In Produktion sitzt ein Nginx-Reverse-Proxy davor, der SSL-Terminierung und Routing übernimmt.

2. Voraussetzungen

3. Entwicklungsumgebung starten

Repository klonen und starten

git clone https://github.com/calhelp/eforms-cloud.git
cd eforms-cloud
docker compose -f docker compose.dev.yml up --build

Das startet drei Container:

ServiceURL / PortBeschreibung
apihttp://localhost:8000Laravel Backend (API)
frontendhttp://localhost:3000Nuxt 3 Frontend
dblocalhost:5432PostgreSQL Datenbank

Datenbank-Migrationen ausführen

docker compose -f docker compose.dev.yml exec api php artisan migrate

Container stoppen

docker compose -f docker compose.dev.yml down

Zum vollständigen Zurücksetzen inkl. Datenbank-Volume:

docker compose -f docker compose.dev.yml down -v

4. Backend-Zugang & Admin-User

Admin-User per Seeder anlegen

Der AdminSeeder erstellt automatisch einen Standard-Admin-Account:

docker compose -f docker compose.dev.yml exec api php artisan db:seed --class=AdminSeeder
FeldWert
E-Mailadmin@eforms.cloud
Passwortpassword

Admin-Login im Frontend

Öffne http://localhost:3000/admin/login und melde dich mit den obigen Zugangsdaten an.

Eigenen Admin-User per Tinker anlegen

docker compose -f docker compose.dev.yml exec api php artisan tinker

# In Tinker:
User::create([
    'name' => 'Dein Name',
    'email' => 'deine@email.de',
    'password' => Hash::make('deinSicheresPasswort')
]);

Direkt in den Backend-Container

docker compose -f docker compose.dev.yml exec api bash

# Nützliche Artisan-Befehle:
php artisan migrate         # Migrationen ausführen
php artisan migrate:fresh   # DB zurücksetzen & neu migrieren
php artisan tinker           # Laravel REPL
php artisan route:list       # Alle API-Routen anzeigen

5. API-Referenz

Basis-URL (Entwicklung): http://localhost:8000/api

Öffentliche Endpunkte (kein Token nötig)

MethodeEndpunktBeschreibung
POST /api/meldungen Anonyme Meldung abgeben (mit CAPTCHA/Honeypot-Validierung)
POST /api/auth/login Admin-Login (gibt Bearer-Token zurück, optional CAPTCHA)
POST /api/auth/two-factor-challenge 2FA-Code oder Recovery-Code verifizieren
GET /api/maintenance/status Wartungsstatus abfragen
GET /api/captcha CAPTCHA-Challenge generieren (Rate-Limited)
GET /api/captcha/settings CAPTCHA-Einstellungen (aktiviert/deaktiviert)
GET /api/layout/settings Header-/Footer-/Seiten-Layout-Konfiguration
GET /api/geo/bundeslaender Liste aller Bundeslaender (OpenPLZ API, 24h Cache)
GET /api/geo/landkreise/{bundesland} Landkreise eines Bundeslandes
GET /api/app-name Anwendungsname abrufen (fuer Layout und Login-Seite)
GET /api/form-templates/{slug} Formular-Template mit aufgeloesten Bloecken (fuer Rendering)

Geschützte Endpunkte (Bearer-Token erforderlich)

MethodeEndpunktBeschreibung
POST /api/auth/logout Logout & Token widerrufen
GET /api/auth/me Aktuellen User abrufen (inkl. 2FA-Status)
PUT /api/auth/profile Name, E-Mail und Passwort aktualisieren
GET /api/meldungen Alle Meldungen auflisten (paginiert, Template-Filter)
GET /api/meldungen/{id} Einzelne Meldung anzeigen
GET /api/dashboard/stats Dashboard-Statistiken
GET /api/dashboard/templates Verfuegbare Templates fuer Dashboard-Auswahl
GET /api/dashboard/stats/{templateSlug} Dashboard-Statistiken fuer ein bestimmtes Template

Zwei-Faktor-Authentifizierung (Bearer-Token erforderlich)

MethodeEndpunktBeschreibung
POST /api/auth/two-factor/enable 2FA aktivieren (Secret + QR-Code + Recovery Codes)
POST /api/auth/two-factor/confirm 2FA-Einrichtung mit TOTP-Code bestaetigen
DELETE /api/auth/two-factor 2FA deaktivieren (Passwort erforderlich)
POST /api/auth/two-factor/recovery-codes Neue Recovery Codes generieren (8 Stueck, XXXX-XXXX)

Admin-Endpunkte (Admin-Rolle erforderlich)

MethodeEndpunktBeschreibung
GET /api/admin/users Alle Benutzer auflisten
POST /api/admin/users Neuen Benutzer erstellen (Name, E-Mail, Passwort, Rolle)
PUT /api/admin/users/{user} Benutzer aktualisieren (Rollen-Hierarchie beachten)
DELETE /api/admin/users/{user} Benutzer loeschen (Selbstloeschung verhindert)
POST /api/admin/maintenance Wartungsmodus umschalten
POST /api/admin/layout Layout-Einstellungen speichern (Header, Footer, Seiten)
POST /api/admin/layout/upload-logo Logo-Bild hochladen
GET /api/admin/captcha CAPTCHA-Einstellungen abrufen
POST /api/admin/captcha CAPTCHA-Einstellungen speichern (Schwierigkeit, Kontext, Rate Limit)
GET /api/admin/testdata/status Anzahl geseedeter Testdaten abfragen
POST /api/admin/testdata/prompt LLM-Prompt fuer realistische Testdaten generieren
POST /api/admin/testdata/import Testdaten aus JSON importieren
POST /api/admin/testdata/clear Alle Testmeldungen loeschen
GET /api/admin/meldungen/count Gesamtanzahl aller Meldungen
POST /api/admin/meldungen/clear-all Alle Meldungen unwiderruflich loeschen
POST /api/admin/meldungen/clear-by-template Meldungen eines bestimmten Templates loeschen
POST /api/admin/app-name Anwendungsname speichern
GET /api/admin/translations Alle Uebersetzungen abrufen
PUT /api/admin/translations Uebersetzung erstellen oder aktualisieren
DELETE /api/admin/translations/{id} Uebersetzung loeschen
GET /api/admin/translations/export Alle Uebersetzungen als JSON exportieren
POST /api/admin/translations/import Uebersetzungen aus JSON importieren
GET /api/admin/tokens Alle API-Tokens des Benutzers auflisten
POST /api/admin/tokens Neuen API-Token erstellen (optionales Ablaufdatum)
DELETE /api/admin/tokens/{id} API-Token widerrufen
GET /api/admin/bi/felder BI-Feld-Metadaten (fuer Endpunkt-Anzeige in Token-Verwaltung)

Developer-Endpunkte (Developer-Rolle erforderlich)

MethodeEndpunktBeschreibung
GET /api/admin/form-blocks Formular-Bloecke auflisten (Suche, Feldtyp-Filter, paginiert)
POST /api/admin/form-blocks Neuen Formular-Block erstellen
GET /api/admin/form-blocks/{id} Einzelnen Block abrufen
PUT /api/admin/form-blocks/{id} Block aktualisieren
DELETE /api/admin/form-blocks/{id} Block loeschen (Verwendung wird geprueft)
GET /api/admin/form-templates Alle Formular-Templates auflisten
POST /api/admin/form-templates Neues Template erstellen
GET /api/admin/form-templates/{id} Template mit Bloecken abrufen
PUT /api/admin/form-templates/{id} Template aktualisieren
DELETE /api/admin/form-templates/{id} Template loeschen
POST /api/admin/form-templates/{id}/duplicate Template duplizieren (inaktive Kopie)
GET /api/admin/form-templates/{id}/export Template als JSON-Bundle exportieren
POST /api/admin/form-templates/import Template aus JSON-Bundle importieren

BI-API Endpunkte (Bearer-Token mit bi:read Berechtigung)

MethodeEndpunktBeschreibung
GET /api/bi/felder Metadaten: verfuegbare Templates, abfragbare Felder, Filter
GET /api/bi/daten Alle Meldungen (paginiert, dynamisch filterbar)
GET /api/bi/stats/uebersicht Gesamtstatistiken mit Top-Werten
GET /api/bi/stats/zeitverlauf Monatliche Zeitreihe (konfigurierbarer Zeitraum)
GET /api/bi/stats/feld/{feldSlug} Statistik pro Feld (dynamisch, GROUP BY auf jedes abfragbare Feld)

Detaillierte Dokumentation: BI-API Dokumentation

6. Authentifizierung (Sanctum)

Die API nutzt Laravel Sanctum mit Token-basierter Authentifizierung.

Login (Token erhalten)

curl -X POST http://localhost:8000/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "admin@eforms.cloud", "password": "password"}'

Antwort:

{
  "token": "1|abc123...",
  "user": { "id": 1, "name": "Admin", "email": "admin@eforms.cloud" }
}

Geschützte Route aufrufen

curl http://localhost:8000/api/meldungen \
  -H "Authorization: Bearer 1|abc123..."

Logout

curl -X POST http://localhost:8000/api/auth/logout \
  -H "Authorization: Bearer 1|abc123..."

7. Zwei-Faktor-Authentifizierung (2FA)

Das System unterstuetzt TOTP-basierte Zwei-Faktor-Authentifizierung fuer alle Admin-Benutzer. Die Implementierung nutzt pragmarx/google2fa und bacon/bacon-qr-code.

Ablauf

  1. Aktivierung: POST /api/auth/two-factor/enable – Generiert Secret, QR-Code (SVG) und 8 Recovery Codes (Format: XXXX-XXXX)
  2. Bestaetigung: POST /api/auth/two-factor/confirm – Verifiziert TOTP-Code aus Authenticator-App
  3. Login mit 2FA: Login gibt two_factor: true zurueck → Client sendet Code an POST /api/auth/two-factor-challenge
  4. Recovery: Falls kein Zugriff auf Authenticator, kann ein Recovery Code statt TOTP-Code verwendet werden

Beispiel: 2FA aktivieren

curl -X POST http://localhost:8000/api/auth/two-factor/enable \
  -H "Authorization: Bearer 1|abc123..." \
  -H "Content-Type: application/json" \
  -d '{"password": "mein-passwort"}'

Antwort:

{
  "secret": "JBSWY3DPEHPK3PXP",
  "qr_code_svg": "<svg ...>",
  "recovery_codes": ["ABCD-EFGH", "IJKL-MNOP", ...]
}

Deaktivierung

curl -X DELETE http://localhost:8000/api/auth/two-factor \
  -H "Authorization: Bearer 1|abc123..." \
  -H "Content-Type: application/json" \
  -d '{"password": "mein-passwort"}'

8. CAPTCHA-System

Das System bietet einen mathematischen CAPTCHA-Schutz mit SVG-Rendering und visueller Rausch-Ueberlagerung.

Schwierigkeitsstufen

StufeBereichOperationenBeispiel
easy1–10Addition3 + 7 = ?
medium10–50Addition, Subtraktion34 - 12 = ?
hard2–99Addition, Subtraktion, Multiplikation8 * 7 = ?

Kontext-Steuerung

CAPTCHA kann separat fuer verschiedene Kontexte aktiviert werden:

Zusaetzlicher Schutz

Beispiel: CAPTCHA generieren

curl http://localhost:8000/api/captcha

Antwort:

{
  "token": "abc123...",
  "image_svg": "<svg ...>",
  "accessible_text": "Was ergibt 3 plus 7?"
}

9. Rollensystem & Berechtigungen

Das System verwendet vier Rollen mit hierarchischen Berechtigungen:

RolleZugriff
userDashboard, Meldungen ansehen, eigenes Profil
editorAlles von user + eingeschraenkter Admin-Zugang zu Templates
adminAlles von editor + Benutzerverwaltung, Einstellungen, Wartungsmodus, Tokens, Testdaten, Uebersetzungen
developerAlles von admin + Formular-Template-Editor, Block-Editor, Import/Export

Hierarchie-Regel: Admins koennen keine Developer bearbeiten oder loeschen. Benutzer koennen sich nicht selbst loeschen.

10. Dynamisches Formularsystem

Formulare werden ueber ein Template-Block-System definiert, das ohne Code-Aenderungen neue Formular-Layouts ermoeglicht.

Architektur

Unterstuetzte Feldtypen (18)

KategorieTypen
Auswahl (Einzel)select, radio-group
Auswahl (Mehrfach)multi-select, checkbox-group
Texttext, email, tel, url, textarea
Numerischnumber, range
Temporaldate, time
Sonstigetoggle, file-upload, hidden
Anzeigeheading, paragraph

Feld-Eigenschaften

Import / Export

Templates koennen als JSON-Bundle exportiert und importiert werden. Beim Import werden bestehende Bloecke wiederverwendet oder automatisch erstellt. So lassen sich Formulare zwischen verschiedenen eforms.cloud-Instanzen portieren.

11. Anonymisierung

Der AnonymisierungsService entfernt automatisch personenbezogene Daten aus allen Freitextfeldern bei der Einreichung einer Meldung.

Anonymisierte Felder (18 Stück)

Alle _sonstiges-Freitextfelder sowie: beschreibung_vorfall, beschreibung_verletzung, auswirkung, konflikt_hintergrund, zusatz_intervention, wahrnehmung, umstaende.

Erkannte Muster

MusterErsetzung
Namen (Herr/Frau/Dr./Prof. + Name)[NAME ANONYMISIERT]
E-Mail-Adressen[E-MAIL ANONYMISIERT]
Telefonnummern (deutsche Formate)[TELEFON ANONYMISIERT]
Raum-/Stationsangaben (Zimmer/Station/Raum + Nr.)[RAUM ANONYMISIERT]
Datumsangaben (TT.MM.JJJJ)[DATUM ANONYMISIERT]

Zusätzlich werden technische Metadaten (ip, user_agent, session_id, debug_info) aus der Anfrage entfernt.

12. Mehrsprachigkeit (i18n)

eforms.cloud unterstuetzt vollstaendige Zweisprachigkeit (Deutsch und Englisch) auf allen Ebenen:

Frontend

Backend

API-Endpunkte (Admin-Rolle erforderlich)

MethodeEndpunktBeschreibung
GET /api/admin/translations Alle Uebersetzungen abrufen
PUT /api/admin/translations Uebersetzung erstellen oder aktualisieren
DELETE /api/admin/translations/{id} Uebersetzung loeschen
GET /api/admin/translations/export Alle Uebersetzungen als JSON exportieren
POST /api/admin/translations/import Uebersetzungen aus JSON importieren

13. Wartungsmodus

Das System verfügt über einen konfigurierbaren Wartungsmodus, der über die app_settings-Tabelle gesteuert wird.

Status abfragen (öffentlich)

curl http://localhost:8000/api/maintenance/status

Antwort:

{
  "enabled": true,
  "message": "Dieses Projekt dient als Demonstrationsversion...",
  "contact": ""
}

Wartungsmodus umschalten (Admin)

curl -X POST http://localhost:8000/api/admin/maintenance \
  -H "Authorization: Bearer 1|abc123..." \
  -H "Content-Type: application/json" \
  -d '{"enabled": true, "message": "Wartungsarbeiten bis 18 Uhr", "contact": "admin@example.de"}'

14. Datenbank

Entwicklungs-Zugangsdaten

ParameterWert
Hostlocalhost
Port5432
Datenbankeforms_db
Benutzereopel
Passwortdevpassword123

Direkte Verbindung per psql

docker compose -f docker compose.dev.yml exec db psql -U eopel eforms_db

Wichtige Tabellen

15. Projektstruktur

eforms.cloud/
├── backend/                        # Laravel 13 API
│   ├── app/
│   │   ├── Http/Controllers/Api/   # Auth, Meldung, Dashboard, Settings, User,
│   │   │                           # FormTemplate, FormBlock, BiStats, TwoFactor,
│   │   │                           # Captcha, ApiToken, GeoController
│   │   ├── Http/Middleware/         # AdminMiddleware, DeveloperMiddleware, ValidateCaptcha
│   │   ├── Models/                 # User, Submission, FormTemplate, FormBlock,
│   │   │                           # FormTemplateBlock, AppSetting
│   │   └── Services/               # AnonymisierungsService, CaptchaService,
│   │                               # BiFieldRegistry, GeoService, TestDataSeederService
│   ├── database/
│   │   ├── migrations/             # Datenbank-Schema
│   │   └── seeders/                # AdminSeeder
│   ├── tests/                      # PHPUnit-Tests
│   ├── routes/api.php              # API-Routen
│   ├── Dockerfile                  # Produktion
│   └── Dockerfile.dev              # Entwicklung
├── frontend/                       # Nuxt 3 Frontend
│   ├── pages/                      # 17 Seiten (Meldung, Admin, Login, …)
│   ├── components/                 # 25 Vue-Komponenten
│   ├── composables/                # 8 Composables (useApi, useAuth, useCaptcha, …)
│   ├── tests/                      # Vitest-Tests
│   ├── Dockerfile                  # Produktion
│   └── Dockerfile.dev              # Entwicklung
├── nginx/                          # Reverse-Proxy-Konfiguration
├── docs/                           # GitHub Pages Dokumentation
├── .github/workflows/
│   ├── deploy.yml                  # Build, Test & Deploy
│   ├── pages.yml                   # GitHub Pages Deploy
│   └── version-bump.yml            # Semantische Versionierung
├── docker-compose.yml              # Produktion
└── docker-compose.dev.yml          # Entwicklung

16. Frontend-Seiten & Komponenten

Seiten (17)

PfadBeschreibung
/Startseite
/meldung/:slugDynamische Formularseite per Template-Slug (z.B. /meldung/schnell, /meldung/ausfuehrlich)
/schnellRedirect auf /meldung/schnell
/ausfuehrlichRedirect auf /meldung/ausfuehrlich
/dankeBestätigungsseite nach Absenden
/maintenanceWartungsmodus-Anzeige
/admin/loginAdmin-Anmeldung (mit 2FA-Unterstuetzung)
/adminAdmin-Dashboard mit Statistiken
/admin/meldungenListe aller Meldungen
/admin/meldungen/:idDetailansicht einer Meldung
/admin/profilBenutzerprofil, Passwort & 2FA-Verwaltung
/admin/benutzerBenutzerverwaltung (Erstellen, Bearbeiten, Loeschen)
/admin/templatesFormular-Templates verwalten (CRUD, Import/Export, Duplizieren)
/admin/blockeditorFormular-Bloecke und Felder bearbeiten (Developer)
/admin/einstellungenAnwendungseinstellungen (Wartung, CAPTCHA, Layout, Testdaten)
/admin/seitenOeffentliche Seiten verwalten
/admin/tokensAPI-Token-Verwaltung

Wichtige Komponenten

Composables (10)

17. CI/CD-Pipeline

Die CI/CD-Pipeline ist in drei GitHub Actions Workflows aufgeteilt:

Build, Test & Deploy (deploy.yml)

Wird bei jedem Push und Pull Request auf main ausgeführt:

SchrittToolBeschreibung
PHP Syntaxphp -lSyntax-Check aller PHP-Dateien
Code-StyleLaravel PintCode-Formatierung prüfen
Config-CheckArtisanLaravel-Konfiguration und Routen validieren
MigrationenArtisanDatenbank-Schema gegen PostgreSQL 15 testen
Backend-TestsPHPUnitTests mit min. 40% Code-Coverage
Frontend-Buildnpm run buildTypeScript-Kompilierung prüfen
Frontend-LintESLintCode-Qualität prüfen

Bei erfolgreichem Merge auf main wird automatisch auf den Produktionsserver deployed.

GitHub Pages (pages.yml)

Automatisches Deployment der docs/-Inhalte bei Änderungen auf main.

Versionierung (version-bump.yml)

Automatische semantische Versionierung nach PR-Merge basierend auf Labels:

18. Deployment (Produktion)

Das Produktions-Deployment nutzt docker compose.yml mit Nginx, SSL via Let's Encrypt und automatischer Zertifikatserneuerung.

Schritte

  1. .env-Datei im Root erstellen (basierend auf .env.example)
  2. Sichere Werte für APP_KEY, DB_PASSWORD und Domain setzen
  3. docker compose up -d --build ausführen
  4. Der docker-entrypoint.sh führt automatisch Migrationen aus

Wichtige Umgebungsvariablen (.env)

VariableBeschreibung
APP_KEYLaravel-Verschlüsselungsschlüssel
DB_PASSWORDPostgreSQL-Passwort
SANCTUM_STATEFUL_DOMAINSFrontend-Domain(s)
APP_URLÖffentliche Backend-URL