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 Freitextfeldern bei der Einreichung einer Meldung. Welche Felder anonymisiert werden, wird dynamisch aus den FormBlock-Definitionen ermittelt.
Der Service liest zur Laufzeit alle Felder, die in den zugehoerigen FormBlocks mit anonymize: true markiert sind. Zusaetzlich werden alle otherDbField-Eintraege (Sonstiges-Freitextfelder) automatisch einbezogen. Neue Felder koennen im Block-Editor (/admin/blockeditor) per Checkbox "Anonymisieren" aktiviert werden — ohne Code-Aenderung.
| 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, Geo, AuditLog, │ │ │ # EmailNotification, Health, StripeWebhook, │ │ │ # Organization, OrganizationInvitation, Plan, │ │ │ # ScheduledReport, SsoAuth, SsoProvider, │ │ │ # Translation, UpdateController │ │ ├── Http/Middleware/ # Admin, Developer, ValidateCaptcha, CheckPlanFeature, │ │ │ # DemoMode, EnsureTenant, SetLocale │ │ ├── Models/ # User, Submission, FormTemplate, FormBlock, │ │ │ # FormTemplateBlock, AppSetting, AuditLog, │ │ │ # EmailNotification, InstancePlan, Organization, │ │ │ # OrganizationInvitation, ScheduledReport, │ │ │ # ScheduledReportRun, SsoProvider, Translation, UpdateLog │ │ └── Services/ # AnonymisierungsService, CaptchaService, │ │ # BiFieldRegistry, GeoService, TestDataSeederService, │ │ # AuditService, StripeService, PlanService, │ │ # SsoService, TenantContext, UpdateService │ ├── database/ │ │ ├── migrations/ # Datenbank-Schema │ │ └── seeders/ # AdminSeeder, FormBlockSeeder, FormTemplateSeeder, │ │ # EnglishTranslationSeeder, DatabaseSeeder │ ├── tests/ # PHPUnit-Tests │ ├── routes/api.php # API-Routen │ ├── Dockerfile # Produktion │ └── Dockerfile.dev # Entwicklung ├── frontend/ # Nuxt 3 Frontend │ ├── pages/ # 19 Seiten (Meldung, Admin, Login, …) │ ├── components/ # 19 Vue-Komponenten │ ├── composables/ # 15 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 |
/admin/email-notifications | E-Mail-Benachrichtigungen verwalten |
/admin/organization | Organisationsverwaltung |
/admin/sso | SSO-Konfiguration |
/admin/updates | Update-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)useEmailNotifications – E-Mail-Benachrichtigungs-CRUDuseOrganization – OrganisationsverwaltunguseSso – SSO-Provider-VerwaltunguseTranslationKeys – Uebersetzungsschluessel-VerwaltunguseUpdates – Update-VerwaltungDie Code-Qualitaet wird durch ein mehrstufiges System aus lokalen Git-Hooks, Makefile-Befehlen und CI-Pipeline sichergestellt. Jede Aenderung durchlaeuft automatisch mehrere Pruefungen, bevor sie auf main gelangt.
| Check | Tool | Pre-Commit | Pre-Push | CI |
|---|---|---|---|---|
| PHP Code-Style | Laravel Pint | ✓ | — | ✓ |
| PHP Syntax | php -l | ✓ | — | ✓ |
| PHP Statische Analyse | PHPStan + Larastan | — | ✓ | ✓ |
| PHP Unit-Tests | PHPUnit | — | ✓ | ✓ (min. 40%) |
| JS/TS Lint | ESLint | ✓ | — | ✓ |
| JS/TS Formatierung | Prettier | ✓ | — | ✓ |
| TypeScript Typecheck | nuxi typecheck | — | ✓ | ✓ |
| JS Unit-Tests | Vitest | — | ✓ | ✓ |
Die Git-Hooks werden mit bash scripts/setup-hooks.sh (bzw. make setup) aktiviert. Sie liegen unter .githooks/ und werden automatisch bei jedem Commit bzw. Push ausgefuehrt.
Schnelle Checks, die bei jedem git commit laufen (unter 5 Sekunden):
Umfassendere Checks, die vor jedem git push laufen (30–120 Sekunden):
nuxi typecheck (vue-tsc) ausfuehrenFalls ein Check fehlschlaegt, wird der Push abgelehnt. In Ausnahmefaellen: git push --no-verify (nicht empfohlen).
PHPStan analysiert den PHP-Code statisch auf Typfehler, undefinierte Variablen und falsche Methodenaufrufe. Die Konfiguration:
backend/phpstan.neonbackend/phpstan-baseline.neon – erfasst bestehende Fehler, sodass neue Fehler sofort auffallen# PHPStan ausfuehren cd backend && vendor/bin/phpstan analyse # Baseline aktualisieren (nach dem Fixen von Fehlern) cd backend && vendor/bin/phpstan analyse --generate-baseline
Alle Checks koennen auch manuell ueber das Makefile ausgefuehrt werden:
| Befehl | Beschreibung |
|---|---|
make test | Backend- und Frontend-Tests ausfuehren |
make test-backend | PHPUnit-Tests |
make test-frontend | Vitest-Tests |
make lint | Laravel Pint (PHP Code-Style pruefen) |
make lint-frontend | ESLint + Prettier (Frontend pruefen) |
make format | Laravel Pint (PHP automatisch formatieren) |
make phpstan | PHPStan statische Analyse |
make typecheck | TypeScript Typecheck (nuxi typecheck) |
make check-all | Alle Checks auf einmal ausfuehren |
Bei der Entwicklung mit Claude Code (.claude/settings.json) werden Pint, ESLint und Prettier automatisch vor jedem Commit ausgefuehrt und Aenderungen gestaged.
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 Code-Style | Laravel Pint | Code-Formatierung prüfen |
| PHP Statische Analyse | PHPStan + Larastan | Typfehler und Bugs erkennen (Level 5) |
| PHP Syntax | php -l | Syntax-Check aller PHP-Dateien |
| 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 |
| Frontend-Formatierung | Prettier | Code-Formatierung prüfen |
| TypeScript Typecheck | nuxi typecheck | TypeScript-Typen prüfen |
| Frontend-Tests | Vitest | Unit-Tests ausführen |
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-VersionAutomatisierte Screenshots der Anwendung werden mit Playwright erstellt und in docs/assets/screenshots/ abgelegt, wo sie direkt in der Dokumentation referenziert werden können.
Das System liegt im Verzeichnis screenshots/ und ist als eigenständiges Node.js-Projekt aufgebaut. Playwright steuert einen Chromium-Browser, meldet sich an der Anwendung an, navigiert zu den relevanten Seiten und erstellt PNG-Screenshots.
screenshots/
playwright.config.ts # Projekte, Viewports, Auth
package.json # Playwright als Dependency
.env.example # Credential-Template (nur für lokale Nutzung)
lib/helpers.ts # Shared Utilities
scripts/
eforms/
login.setup.ts # Auth-Flow
dashboard.spec.ts # Screenshot-Scripts
formulare.spec.ts
admin.spec.ts
calserver/ # Placeholder
edocs/ # Placeholder
quizrace/ # Placeholder
docs/assets/screenshots/ # Zielordner (wird committet)
eforms/
calserver/
edocs/
quizrace/
Der Workflow .github/workflows/screenshots.yml wird automatisch jeden Montag um 6:00 UTC ausgeführt oder kann manuell gestartet werden.
| Parameter | Optionen | Standard |
|---|---|---|
| Tool | all, eforms, calserver, edocs, quizrace | all |
| Viewport | desktop (1280×800), full-hd (1920×1080), tablet (768×1024) | desktop |
Geänderte Screenshots werden automatisch committet und gepusht.
Die Credentials müssen im Repository unter Settings → Secrets and variables → Actions konfiguriert werden:
| Secret | Beschreibung | Beispiel |
|---|---|---|
EFORMS_URL | URL der eforms-Instanz | https://demo.eforms.cloud |
EFORMS_USER | E-Mail des Admin-Accounts | admin@example.de |
EFORMS_PASS | Passwort des Admin-Accounts | – |
CALSERVER_URL | URL der calServer-Instanz | https://demo.calserver.com |
CALSERVER_USER | Benutzername calServer | – |
CALSERVER_PASS | Passwort calServer | – |
EDOCS_URL | URL der eDocs-Instanz | https://calhelp.edocs.cloud |
EDOCS_USER | E-Mail eDocs | – |
EDOCS_PASS | Passwort eDocs | – |
QUIZRACE_URL | URL der QuizRace-Instanz | https://demo.quizrace.app |
QUIZRACE_USER | E-Mail QuizRace | – |
QUIZRACE_PASS | Passwort QuizRace | – |
Hinweis: Nur die Secrets der Tools konfigurieren, die tatsächlich verwendet werden. Fehlende Credentials führen dazu, dass das jeweilige Login-Setup mit einer Fehlermeldung abbricht — andere Tools sind davon nicht betroffen.
Die erzeugten Bilder liegen unter docs/assets/screenshots/<tool>/ und können direkt referenziert werden:
<img src="assets/screenshots/eforms/dashboard-uebersicht.png" alt="Dashboard">
Eine neue .spec.ts-Datei im passenden Tool-Ordner anlegen. Jeder test()-Block erzeugt einen Screenshot:
import { test } from '@playwright/test';
import { prepareCleanState, hideVolatileElements, waitForIdle } from '../../lib/helpers';
test('neue-seite', async ({ page }) => {
await page.goto('/admin/neue-seite');
await prepareCleanState(page);
await hideVolatileElements(page);
await waitForIdle(page);
await page.screenshot({
path: 'docs/assets/screenshots/eforms/neue-seite.png',
});
});
Das 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 |
eforms.cloud unterstuetzt die Synchronisation von Terminen mit externen Kalendern (Google Calendar, Microsoft 365/Outlook und CalDAV). Die Integration erfolgt ueber OAuth 2.0 — Admins verbinden ihren Kalender mit einem Klick, ohne selbst OAuth-Credentials konfigurieren zu muessen.
Der Betreiber der eforms.cloud-Instanz muss einmalig eine OAuth-App bei Google und/oder Microsoft registrieren und die Credentials in der .env-Datei hinterlegen. Danach funktioniert die Kalender-Verbindung fuer alle Admins und Mandanten automatisch.
| Variable | Beschreibung |
|---|---|
GOOGLE_CALENDAR_CLIENT_ID | OAuth Client-ID aus der Google Cloud Console |
GOOGLE_CALENDAR_CLIENT_SECRET | OAuth Client-Secret aus der Google Cloud Console |
MICROSOFT_CALENDAR_CLIENT_ID | Application (Client) ID aus dem Azure Portal |
MICROSOFT_CALENDAR_CLIENT_SECRET | Client Secret aus dem Azure Portal |
MICROSOFT_CALENDAR_TENANT_ID | Tenant-ID (Standard: common fuer Multi-Tenant) |
Hinweis: Die Redirect-URI wird automatisch aus APP_URL abgeleitet (z.B. https://ihre-instanz.eforms.cloud/admin/calendars/google-callback). Eine manuelle Konfiguration ist nicht noetig.
console.cloud.google.com)https://[IHRE-DOMAIN]/admin/calendars/google-callback.env-Dateiportal.azure.com) und navigieren Sie zu App-Registrierungenhttps://[IHRE-DOMAIN]/admin/calendars/microsoft-callback.env-Datei:
common fuer mandantenuebergreifenden ZugriffSobald der Systembetreiber die OAuth-Credentials konfiguriert hat, koennen Admins ihre Kalender verbinden:
/admin/calendars)Die Kalender-Synchronisation ist DSGVO-konform: Es werden keine personenbezogenen Daten in den externen Kalender geschrieben. Stattdessen wird lediglich ein neutraler Eintrag "Terminbuchung" als Platzhalter eingetragen. Fuer die Verfuegbarkeitspruefung wird die FreeBusy-API verwendet, die keine Eventdetails preisgibt.