Setup-Anleitung, Architektur und API-Referenz fuer die eforms.cloud-Plattform
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.
php, composer, node (falls lokal ohne Docker gearbeitet wird)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:
| Service | URL / Port | Beschreibung |
|---|---|---|
api | http://localhost:8000 | Laravel Backend (API) |
frontend | http://localhost:3000 | Nuxt 3 Frontend |
db | localhost:5432 | PostgreSQL Datenbank |
docker compose -f docker compose.dev.yml exec api php artisan migrate
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
Der AdminSeeder erstellt automatisch einen Standard-Admin-Account:
docker compose -f docker compose.dev.yml exec api php artisan db:seed --class=AdminSeeder
| Feld | Wert |
|---|---|
admin@eforms.cloud | |
| Passwort | password |
Öffne http://localhost:3000/admin/login und melde dich mit den obigen Zugangsdaten an.
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')
]);
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
Basis-URL (Entwicklung): http://localhost:8000/api
| Methode | Endpunkt | Beschreibung |
|---|---|---|
| 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) |
| Methode | Endpunkt | Beschreibung |
|---|---|---|
| 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 |
| Methode | Endpunkt | Beschreibung |
|---|---|---|
| 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) |
| Methode | Endpunkt | Beschreibung |
|---|---|---|
| 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) |
| Methode | Endpunkt | Beschreibung |
|---|---|---|
| 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:read Berechtigung)| Methode | Endpunkt | Beschreibung |
|---|---|---|
| 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
Die API nutzt Laravel Sanctum mit Token-basierter Authentifizierung.
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" }
}
curl http://localhost:8000/api/meldungen \ -H "Authorization: Bearer 1|abc123..."
curl -X POST http://localhost:8000/api/auth/logout \ -H "Authorization: Bearer 1|abc123..."
Das System unterstuetzt TOTP-basierte Zwei-Faktor-Authentifizierung fuer alle Admin-Benutzer. Die Implementierung nutzt pragmarx/google2fa und bacon/bacon-qr-code.
POST /api/auth/two-factor/enable – Generiert Secret, QR-Code (SVG) und 8 Recovery Codes (Format: XXXX-XXXX)POST /api/auth/two-factor/confirm – Verifiziert TOTP-Code aus Authenticator-Apptwo_factor: true zurueck → Client sendet Code an POST /api/auth/two-factor-challengecurl -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", ...]
}
curl -X DELETE http://localhost:8000/api/auth/two-factor \
-H "Authorization: Bearer 1|abc123..." \
-H "Content-Type: application/json" \
-d '{"password": "mein-passwort"}'
Das System bietet einen mathematischen CAPTCHA-Schutz mit SVG-Rendering und visueller Rausch-Ueberlagerung.
| Stufe | Bereich | Operationen | Beispiel |
|---|---|---|---|
easy | 1–10 | Addition | 3 + 7 = ? |
medium | 10–50 | Addition, Subtraktion | 34 - 12 = ? |
hard | 2–99 | Addition, Subtraktion, Multiplikation | 8 * 7 = ? |
CAPTCHA kann separat fuer verschiedene Kontexte aktiviert werden:
forms – Meldungsformulare (Standard: aktiviert)login – Admin-Login (Standard: deaktiviert)curl http://localhost:8000/api/captcha
Antwort:
{
"token": "abc123...",
"image_svg": "<svg ...>",
"accessible_text": "Was ergibt 3 plus 7?"
}
Das System verwendet vier Rollen mit hierarchischen Berechtigungen:
| Rolle | Zugriff |
|---|---|
user | Dashboard, Meldungen ansehen, eigenes Profil |
editor | Alles von user + eingeschraenkter Admin-Zugang zu Templates |
admin | Alles von editor + Benutzerverwaltung, Einstellungen, Wartungsmodus, Tokens, Testdaten, Uebersetzungen |
developer | Alles von admin + Formular-Template-Editor, Block-Editor, Import/Export |
Hierarchie-Regel: Admins koennen keine Developer bearbeiten oder loeschen. Benutzer koennen sich nicht selbst loeschen.
Formulare werden ueber ein Template-Block-System definiert, das ohne Code-Aenderungen neue Formular-Layouts ermoeglicht.
| Kategorie | Typen |
|---|---|
| Auswahl (Einzel) | select, radio-group |
| Auswahl (Mehrfach) | multi-select, checkbox-group |
| Text | text, email, tel, url, textarea |
| Numerisch | number, range |
| Temporal | date, time |
| Sonstige | toggle, file-upload, hidden |
| Anzeige | heading, paragraph |
dbField – Datenbank-Schluessel fuer JSONB-Speicherungrequired, min, max, step – Validierungoptions – Auswahlliste fuer Select-/Checkbox-FeldershowAsChart – Feld wird als Chart im Dashboard angezeigtshowAsTopCard – Feld wird als Top-Wert-Karte im Dashboard angezeigtanonymize – Feld wird bei Einreichung anonymisiertdetailedOnly – Feld nur im ausfuehrlichen Modus sichtbardependsOn – Abhaengigkeiten (z.B. Landkreis abhaengig von Bundesland)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.
Der AnonymisierungsService entfernt automatisch personenbezogene Daten aus allen Freitextfeldern bei der Einreichung einer Meldung.
Alle _sonstiges-Freitextfelder sowie: beschreibung_vorfall, beschreibung_verletzung, auswirkung, konflikt_hintergrund, zusatz_intervention, wahrnehmung, umstaende.
| Muster | Ersetzung |
|---|---|
| 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.
eforms.cloud unterstuetzt vollstaendige Zweisprachigkeit (Deutsch und Englisch) auf allen Ebenen:
translations-Tabelle| Methode | Endpunkt | Beschreibung |
|---|---|---|
| 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 |
Das System verfügt über einen konfigurierbaren Wartungsmodus, der über die app_settings-Tabelle gesteuert wird.
curl http://localhost:8000/api/maintenance/status
Antwort:
{
"enabled": true,
"message": "Dieses Projekt dient als Demonstrationsversion...",
"contact": ""
}
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"}'
| Parameter | Wert |
|---|---|
| Host | localhost |
| Port | 5432 |
| Datenbank | eforms_db |
| Benutzer | eopel |
| Passwort | devpassword123 |
docker compose -f docker compose.dev.yml exec db psql -U eopel eforms_db
users – Benutzer (E-Mail, Passwort-Hash, Rolle, 2FA-Secret/-Recovery-Codes)submissions – Formular-Einreichungen (JSONB-Daten, Template-Slug)form_templates – Formular-Templates (Slug, Titel, aktiv, Detailmodus)form_blocks – Formular-Bloecke (Slug, Legende, Felddefinitionen als JSON)form_template_blocks – Verknuepfung Template-Block (Sortierung, Feld-Overrides)personal_access_tokens – Sanctum-Tokens (API-Zugang)app_settings – Schluessel-Wert-Konfiguration (Wartung, CAPTCHA, Layout)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
| Pfad | Beschreibung |
|---|---|
/ | Startseite |
/meldung/:slug | Dynamische Formularseite per Template-Slug (z.B. /meldung/schnell, /meldung/ausfuehrlich) |
/schnell | Redirect auf /meldung/schnell |
/ausfuehrlich | Redirect auf /meldung/ausfuehrlich |
/danke | Bestätigungsseite nach Absenden |
/maintenance | Wartungsmodus-Anzeige |
/admin/login | Admin-Anmeldung (mit 2FA-Unterstuetzung) |
/admin | Admin-Dashboard mit Statistiken |
/admin/meldungen | Liste aller Meldungen |
/admin/meldungen/:id | Detailansicht einer Meldung |
/admin/profil | Benutzerprofil, Passwort & 2FA-Verwaltung |
/admin/benutzer | Benutzerverwaltung (Erstellen, Bearbeiten, Loeschen) |
/admin/templates | Formular-Templates verwalten (CRUD, Import/Export, Duplizieren) |
/admin/blockeditor | Formular-Bloecke und Felder bearbeiten (Developer) |
/admin/einstellungen | Anwendungseinstellungen (Wartung, CAPTCHA, Layout, Testdaten) |
/admin/seiten | Oeffentliche Seiten verwalten |
/admin/tokens | API-Token-Verwaltung |
useApi – API-Kommunikation mit Bearer-TokenuseApiLocale – Locale-aware API-Aufrufe (sendet aktuelle Sprache mit)useAuth – Authentifizierungsstatus, Login, Logout, 2FA-VerifizierunguseCaptcha – CAPTCHA-Generierung, Validierung und Honeypot-VerwaltunguseTemplates – FormTemplate-CRUD, Import/Export, DuplizierenuseBlocks – FormBlock-CRUD mit Suche und PaginierunguseTranslations – Uebersetzungsverwaltung (CRUD, Import/Export)useLayoutSettings – Layout-Konfiguration (Header, Footer, Logos, Content)useLandkreise – Landkreis-Daten für FormulareuseFeiertage – Deutsche Feiertage (fest, beweglich, landesspezifisch)Die CI/CD-Pipeline ist in drei GitHub Actions Workflows aufgeteilt:
deploy.yml)Wird bei jedem Push und Pull Request auf main ausgeführt:
| Schritt | Tool | Beschreibung |
|---|---|---|
| PHP Syntax | php -l | Syntax-Check aller PHP-Dateien |
| Code-Style | Laravel Pint | Code-Formatierung prüfen |
| Config-Check | Artisan | Laravel-Konfiguration und Routen validieren |
| Migrationen | Artisan | Datenbank-Schema gegen PostgreSQL 15 testen |
| Backend-Tests | PHPUnit | Tests mit min. 40% Code-Coverage |
| Frontend-Build | npm run build | TypeScript-Kompilierung prüfen |
| Frontend-Lint | ESLint | Code-Qualität prüfen |
Bei erfolgreichem Merge auf main wird automatisch auf den Produktionsserver deployed.
pages.yml)Automatisches Deployment der docs/-Inhalte bei Änderungen auf main.
version-bump.yml)Automatische semantische Versionierung nach PR-Merge basierend auf Labels:
breaking → Major-Versionfeature / enhancement → Minor-VersionDas Produktions-Deployment nutzt docker compose.yml mit Nginx, SSL via Let's Encrypt und automatischer Zertifikatserneuerung.
.env-Datei im Root erstellen (basierend auf .env.example)APP_KEY, DB_PASSWORD und Domain setzendocker compose up -d --build ausführendocker-entrypoint.sh führt automatisch Migrationen aus| Variable | Beschreibung |
|---|---|
APP_KEY | Laravel-Verschlüsselungsschlüssel |
DB_PASSWORD | PostgreSQL-Passwort |
SANCTUM_STATEFUL_DOMAINS | Frontend-Domain(s) |
APP_URL | Öffentliche Backend-URL |