Docs: fahrschuldesk Plan erweitert - Billing, Messenger, DKS, Audit-Log, Branding, Self-Hosted
This commit is contained in:
@@ -22,8 +22,14 @@
|
|||||||
- **Frontend:** Vue 3 + Vite (SPA)
|
- **Frontend:** Vue 3 + Vite (SPA)
|
||||||
- **Backend:** PHP (Laravel oder Slim Framework)
|
- **Backend:** PHP (Laravel oder Slim Framework)
|
||||||
- **Datenbank:** PostgreSQL (fahrschuldesk DB, Host: 10.255.30.11:5433)
|
- **Datenbank:** PostgreSQL (fahrschuldesk DB, Host: 10.255.30.11:5433)
|
||||||
- **Auth:** JWT-basiert
|
- **WebSockets:** Für Messenger (Socket.io oder native WebSockets)
|
||||||
- **Deploy:** Git → Server via rsync
|
- **Dateien:** Lokaler Storage + S3-kompatibel (für Self-Hosted einfach lokaler Ordner)
|
||||||
|
- **Auth:** JWT-basiert mit Refresh-Token
|
||||||
|
- **CI/CD:** GitHub Actions / GitLab CI
|
||||||
|
|
||||||
|
### 2.3 Kalender-Integration
|
||||||
|
|
||||||
|
Der Kalender wird über die fahrschultermin.de API gesteuert (spätere Integration). Die fahrschuldesk-API dient als Schnittstelle.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -41,7 +47,7 @@ Plattform-Admins (intern)
|
|||||||
#### Plattform-Admins (interne Verwaltung)
|
#### Plattform-Admins (interne Verwaltung)
|
||||||
```
|
```
|
||||||
platform_admins
|
platform_admins
|
||||||
- id
|
- id (uuid)
|
||||||
- email (unique)
|
- email (unique)
|
||||||
- password_hash
|
- password_hash
|
||||||
- name
|
- name
|
||||||
@@ -54,28 +60,39 @@ platform_admins
|
|||||||
#### Fahrschulen (Mandanten)
|
#### Fahrschulen (Mandanten)
|
||||||
```
|
```
|
||||||
tenants
|
tenants
|
||||||
- id
|
- id (uuid)
|
||||||
- name
|
- name
|
||||||
- slug (unique, für Subdomain?)
|
- slug (unique, für Subdomain?)
|
||||||
- email (Rechnungs-Kontakt)
|
- email (Rechnungs-Kontakt)
|
||||||
- phone
|
- phone
|
||||||
- address
|
- address
|
||||||
- status (active | suspended | trial)
|
- status (pending_approval | active | suspended | trial)
|
||||||
- trial_ends_at
|
- trial_ends_at
|
||||||
- created_at
|
- created_at
|
||||||
- updated_at
|
- updated_at
|
||||||
|
|
||||||
|
# Branding
|
||||||
|
- logo_url
|
||||||
|
- primary_color
|
||||||
|
- secondary_color
|
||||||
|
- custom_css (optional)
|
||||||
|
|
||||||
|
# Self-Hosted
|
||||||
|
- is_self_hosted (bool)
|
||||||
|
- self_hosted_license_key
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Filialen
|
#### Filialen
|
||||||
```
|
```
|
||||||
branches
|
branches
|
||||||
- id
|
- id (uuid)
|
||||||
- tenant_id (FK)
|
- tenant_id (FK)
|
||||||
- name
|
- name
|
||||||
- address
|
- address
|
||||||
- phone
|
- phone
|
||||||
- email
|
- email
|
||||||
- opening_hours (JSON)
|
- opening_hours (JSON)
|
||||||
|
- is_headquarters (bool)
|
||||||
- created_at
|
- created_at
|
||||||
- updated_at
|
- updated_at
|
||||||
```
|
```
|
||||||
@@ -83,15 +100,17 @@ branches
|
|||||||
#### Benutzer
|
#### Benutzer
|
||||||
```
|
```
|
||||||
users
|
users
|
||||||
- id
|
- id (uuid)
|
||||||
- tenant_id (FK)
|
- tenant_id (FK)
|
||||||
- branch_id (FK, nullable)
|
- branch_id (FK, nullable)
|
||||||
- email (unique pro Tenant)
|
- email (unique pro Tenant)
|
||||||
- password_hash
|
- password_hash
|
||||||
- first_name
|
- first_name
|
||||||
- last_name
|
- last_name
|
||||||
- user_type (office | instructor | lecturer | student | admin)
|
- user_type (admin | office | instructor | lecturer | student)
|
||||||
- status (active | inactive)
|
- status (active | inactive | pending)
|
||||||
|
- avatar_url
|
||||||
|
- phone
|
||||||
- created_at
|
- created_at
|
||||||
- updated_at
|
- updated_at
|
||||||
- last_login_at
|
- last_login_at
|
||||||
@@ -100,26 +119,49 @@ users
|
|||||||
#### Module (pro Fahrschule zuweisbar)
|
#### Module (pro Fahrschule zuweisbar)
|
||||||
```
|
```
|
||||||
modules
|
modules
|
||||||
- id
|
- id (uuid)
|
||||||
- key (office | calendar | messenger | learning_blank | learning_premium)
|
- key (office | calendar | messenger | learning_blank | learning_premium)
|
||||||
- name
|
- name
|
||||||
- description
|
- description
|
||||||
- monthly_price
|
- monthly_price (cent)
|
||||||
- is_active (Plattform-global)
|
- is_active (Plattform-global)
|
||||||
|
- created_at
|
||||||
|
|
||||||
tenant_modules
|
tenant_modules
|
||||||
- id
|
- id (uuid)
|
||||||
- tenant_id (FK)
|
- tenant_id (FK)
|
||||||
- module_id (FK)
|
- module_id (FK)
|
||||||
- status (enabled | disabled)
|
- status (enabled | disabled)
|
||||||
- enabled_at
|
- enabled_at
|
||||||
- expires_at (nullable)
|
- expires_at (nullable)
|
||||||
|
- trial_ends_at (nullable)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Pakete (Preismodelle)
|
||||||
|
```
|
||||||
|
packages
|
||||||
|
- id (uuid)
|
||||||
|
- key (starter | professional | enterprise)
|
||||||
|
- name
|
||||||
|
- description
|
||||||
|
- monthly_price (cent)
|
||||||
|
- modules_included (JSON array von module_keys)
|
||||||
|
- max_users
|
||||||
|
- max_branches
|
||||||
|
- created_at
|
||||||
|
|
||||||
|
tenant_packages
|
||||||
|
- id (uuid)
|
||||||
|
- tenant_id (FK)
|
||||||
|
- package_id (FK)
|
||||||
|
- started_at
|
||||||
|
- expires_at
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Lerninhalte (Premium-Modul)
|
#### Lerninhalte (Premium-Modul)
|
||||||
```
|
```
|
||||||
learning_contents
|
learning_contents
|
||||||
- id
|
- id (uuid)
|
||||||
- tenant_id (FK, nullable — null = Plattform-global)
|
- tenant_id (FK, nullable — null = Plattform-global)
|
||||||
- category
|
- category
|
||||||
- title
|
- title
|
||||||
@@ -127,7 +169,8 @@ learning_contents
|
|||||||
- content_type (video | document | quiz | exercise)
|
- content_type (video | document | quiz | exercise)
|
||||||
- content_url
|
- content_url
|
||||||
- thumbnail_url
|
- thumbnail_url
|
||||||
- is_premium (nur mit Premium-Modul)
|
- duration_minutes
|
||||||
|
- is_premium
|
||||||
- created_at
|
- created_at
|
||||||
- updated_at
|
- updated_at
|
||||||
```
|
```
|
||||||
@@ -135,7 +178,7 @@ learning_contents
|
|||||||
#### Fahrschüler-Fortschritt
|
#### Fahrschüler-Fortschritt
|
||||||
```
|
```
|
||||||
student_progress
|
student_progress
|
||||||
- id
|
- id (uuid)
|
||||||
- user_id (FK, student)
|
- user_id (FK, student)
|
||||||
- content_id (FK)
|
- content_id (FK)
|
||||||
- status (not_started | in_progress | completed)
|
- status (not_started | in_progress | completed)
|
||||||
@@ -145,18 +188,150 @@ student_progress
|
|||||||
- updated_at
|
- updated_at
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Audit-Log
|
||||||
|
```
|
||||||
|
audit_logs
|
||||||
|
- id (uuid)
|
||||||
|
- tenant_id (FK, nullable — null für Plattform-Admin-Aktionen)
|
||||||
|
- user_id (FK, nullable)
|
||||||
|
- action (created | updated | deleted | login | logout | etc.)
|
||||||
|
- entity_type (tenant | user | branch | module | etc.)
|
||||||
|
- entity_id (UUID des betroffenen Datensatzes)
|
||||||
|
- old_values (JSON, nullable)
|
||||||
|
- new_values (JSON, nullable)
|
||||||
|
- ip_address
|
||||||
|
- user_agent
|
||||||
|
- created_at
|
||||||
|
|
||||||
|
# Index auf tenant_id + created_at für schnelle Abfragen
|
||||||
|
# Index auf entity_type + entity_id
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Rechnungen
|
||||||
|
```
|
||||||
|
invoices
|
||||||
|
- id (uuid)
|
||||||
|
- tenant_id (FK)
|
||||||
|
- invoice_number (unique)
|
||||||
|
- amount (cent)
|
||||||
|
- vat_amount (cent)
|
||||||
|
- total_amount (cent)
|
||||||
|
- currency (EUR)
|
||||||
|
- status (draft | pending | paid | overdue | cancelled)
|
||||||
|
- billing_period_start
|
||||||
|
- billing_period_end
|
||||||
|
- due_date
|
||||||
|
- paid_at (nullable)
|
||||||
|
- created_at
|
||||||
|
- updated_at
|
||||||
|
|
||||||
|
invoice_items
|
||||||
|
- id (uuid)
|
||||||
|
- invoice_id (FK)
|
||||||
|
- description
|
||||||
|
- quantity
|
||||||
|
- unit_price (cent)
|
||||||
|
- total_price (cent)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### E-Mail / Notifications
|
||||||
|
```
|
||||||
|
notification_templates
|
||||||
|
- id (uuid)
|
||||||
|
- key (welcome | password_reset | invoice | trial_expiring | etc.)
|
||||||
|
- subject
|
||||||
|
- body_html
|
||||||
|
- body_text
|
||||||
|
- variables (JSON)
|
||||||
|
- created_at
|
||||||
|
- updated_at
|
||||||
|
|
||||||
|
notifications
|
||||||
|
- id (uuid)
|
||||||
|
- user_id (FK)
|
||||||
|
- tenant_id (FK, nullable)
|
||||||
|
- template_key
|
||||||
|
- subject
|
||||||
|
- body
|
||||||
|
- status (pending | sent | failed)
|
||||||
|
- sent_at
|
||||||
|
- created_at
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Dateien / Uploads / DKS (Dokumenten-Klasse-System)
|
||||||
|
```
|
||||||
|
files
|
||||||
|
- id (uuid)
|
||||||
|
- tenant_id (FK)
|
||||||
|
- user_id (FK, nullable — wer hochgeladen hat)
|
||||||
|
- entity_type (vehicle | student | instructor | branch | etc.)
|
||||||
|
- entity_id (UUID)
|
||||||
|
- file_type (insurance | tuv | logo | avatar | document | etc.)
|
||||||
|
- original_filename
|
||||||
|
- storage_path
|
||||||
|
- mime_type
|
||||||
|
- size_bytes
|
||||||
|
- created_at
|
||||||
|
|
||||||
|
# Dateien werden im Storage abgelegt:
|
||||||
|
# SaaS: /storage/tenants/{tenant_id}/files/
|
||||||
|
# Self-Hosted: /var/www/fahrschuldesk/storage/files/
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Messenger (DSGVO-konform)
|
||||||
|
```
|
||||||
|
conversations
|
||||||
|
- id (uuid)
|
||||||
|
- tenant_id (FK)
|
||||||
|
- type (direct | group)
|
||||||
|
- name (nullable, nur für groups)
|
||||||
|
- created_at
|
||||||
|
- updated_at
|
||||||
|
|
||||||
|
conversation_participants
|
||||||
|
- id (uuid)
|
||||||
|
- conversation_id (FK)
|
||||||
|
- user_id (FK)
|
||||||
|
- joined_at
|
||||||
|
- last_read_at
|
||||||
|
|
||||||
|
messages
|
||||||
|
- id (uuid)
|
||||||
|
- conversation_id (FK)
|
||||||
|
- user_id (FK)
|
||||||
|
- body (Verschlüsselt auf DB-Ebene)
|
||||||
|
- is_edited (bool)
|
||||||
|
- is_deleted (bool)
|
||||||
|
- created_at
|
||||||
|
- updated_at
|
||||||
|
|
||||||
|
# Keine Ende-zu-Ende Verschlüsselung (Plattform hat Zugriff für Support/Audit)
|
||||||
|
# DSGVO: Keine externen Dienste, alles auf eigenen Servern
|
||||||
|
# Nachrichten können auf Anfrage exportiert/gelöscht werden (DSGVO-Compliance)
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 4. API-Struktur
|
## 4. API-Struktur
|
||||||
|
|
||||||
### 4.1 Auth
|
### 4.1 Auth
|
||||||
```
|
```
|
||||||
POST /api/auth/login (Admin/Login)
|
POST /api/auth/login (JWT Token)
|
||||||
POST /api/auth/logout
|
POST /api/auth/logout
|
||||||
|
POST /api/auth/refresh (Refresh Token)
|
||||||
GET /api/auth/me
|
GET /api/auth/me
|
||||||
|
|
||||||
|
POST /api/auth/forgot-password
|
||||||
|
POST /api/auth/reset-password
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4.2 Plattform-Admin (nur Admins)
|
### 4.2 Registration (Self-Service)
|
||||||
|
```
|
||||||
|
POST /api/auth/register (Fahrschule registrieren)
|
||||||
|
GET /api/auth/register/verify/:token (E-Mail verifizieren)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.3 Plattform-Admin (nur Admins)
|
||||||
```
|
```
|
||||||
GET /api/admin/tenants
|
GET /api/admin/tenants
|
||||||
POST /api/admin/tenants
|
POST /api/admin/tenants
|
||||||
@@ -164,15 +339,30 @@ GET /api/admin/tenants/:id
|
|||||||
PUT /api/admin/tenants/:id
|
PUT /api/admin/tenants/:id
|
||||||
DELETE /api/admin/tenants/:id
|
DELETE /api/admin/tenants/:id
|
||||||
|
|
||||||
|
POST /api/admin/tenants/:id/approve (Freigabe nach Registration)
|
||||||
|
POST /api/admin/tenants/:id/suspend
|
||||||
|
|
||||||
GET /api/admin/tenants/:id/modules
|
GET /api/admin/tenants/:id/modules
|
||||||
POST /api/admin/tenants/:id/modules
|
POST /api/admin/tenants/:id/modules
|
||||||
DELETE /api/admin/tenants/:id/modules/:moduleId
|
DELETE /api/admin/tenants/:id/modules/:moduleId
|
||||||
|
|
||||||
GET /api/admin/platform-modules
|
GET /api/admin/platform-modules
|
||||||
GET /api/admin/platform-modules/:id
|
GET /api/admin/platform-modules/:id
|
||||||
|
|
||||||
|
GET /api/admin/invoices
|
||||||
|
GET /api/admin/invoices/:id
|
||||||
|
PUT /api/admin/invoices/:id/mark-paid
|
||||||
|
|
||||||
|
GET /api/admin/audit-logs (Plattform-weit)
|
||||||
|
GET /api/admin/audit-logs/:id
|
||||||
|
|
||||||
|
GET /api/admin/platform-admins
|
||||||
|
POST /api/admin/platform-admins
|
||||||
|
PUT /api/admin/platform-admins/:id
|
||||||
|
DELETE /api/admin/platform-admins/:id
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4.3 Tenant-Admin (Fahrschule)
|
### 4.4 Tenant-Admin (Fahrschule)
|
||||||
```
|
```
|
||||||
GET /api/branches
|
GET /api/branches
|
||||||
POST /api/branches
|
POST /api/branches
|
||||||
@@ -186,27 +376,69 @@ PUT /api/users/:id
|
|||||||
DELETE /api/users/:id
|
DELETE /api/users/:id
|
||||||
|
|
||||||
GET /api/my-modules
|
GET /api/my-modules
|
||||||
|
GET /api/my-profile
|
||||||
|
PUT /api/my-profile
|
||||||
|
|
||||||
|
GET /api/audit-logs (Tenant-spezifisch)
|
||||||
|
GET /api/audit-logs/:id
|
||||||
|
|
||||||
|
# Branding
|
||||||
|
PUT /api/tenant/branding
|
||||||
|
GET /api/tenant/branding
|
||||||
|
|
||||||
|
# Pakete
|
||||||
|
GET /api/my-package
|
||||||
|
PUT /api/tenant/logo
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4.4 Users (allgemein pro Tenant)
|
### 4.5 Kalender (Integration fahrschultermin.de)
|
||||||
```
|
```
|
||||||
GET /api/calendar/events
|
GET /api/calendar/events (weiterleiten an fahrschultermin.de API)
|
||||||
POST /api/calendar/events
|
POST /api/calendar/events
|
||||||
PUT /api/calendar/events/:id
|
PUT /api/calendar/events/:id
|
||||||
DELETE /api/calendar/events/:id
|
DELETE /api/calendar/events/:id
|
||||||
|
GET /api/calendar/availability (Abfrage freier Slots)
|
||||||
GET /api/messages
|
|
||||||
POST /api/messages
|
|
||||||
GET /api/messages/conversations
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4.5 Lernsoftware
|
### 4.6 Messenger
|
||||||
|
```
|
||||||
|
GET /api/messenger/conversations
|
||||||
|
POST /api/messenger/conversations
|
||||||
|
GET /api/messenger/conversations/:id
|
||||||
|
POST /api/messenger/conversations/:id/messages
|
||||||
|
GET /api/messenger/conversations/:id/messages
|
||||||
|
PUT /api/messenger/messages/:id (editieren)
|
||||||
|
DELETE /api/messenger/messages/:id (soft delete)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.7 Lernsoftware
|
||||||
```
|
```
|
||||||
GET /api/learning/contents
|
GET /api/learning/contents
|
||||||
GET /api/learning/contents/:id
|
GET /api/learning/contents/:id
|
||||||
GET /api/learning/my-progress
|
GET /api/learning/my-progress
|
||||||
POST /api/learning/my-progress
|
POST /api/learning/my-progress
|
||||||
PUT /api/learning/my-progress/:contentId
|
PUT /api/learning/my-progress/:contentId
|
||||||
|
|
||||||
|
# Nur für Admin / Dozenten
|
||||||
|
POST /api/learning/contents (Blanko: eigene Inhalte erstellen)
|
||||||
|
PUT /api/learning/contents/:id
|
||||||
|
DELETE /api/learning/contents/:id
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.8 Dateien / DKS
|
||||||
|
```
|
||||||
|
GET /api/files (Liste, gefiltert nach entity)
|
||||||
|
POST /api/files (Upload)
|
||||||
|
GET /api/files/:id
|
||||||
|
DELETE /api/files/:id
|
||||||
|
GET /api/files/:id/download
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.9 Rechnungen (Tenant)
|
||||||
|
```
|
||||||
|
GET /api/billing/invoices
|
||||||
|
GET /api/billing/invoices/:id
|
||||||
|
GET /api/billing/current-package
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -216,18 +448,28 @@ PUT /api/learning/my-progress/:contentId
|
|||||||
### Plattform-Admins (intern)
|
### Plattform-Admins (intern)
|
||||||
| Rolle | Rechte |
|
| Rolle | Rechte |
|
||||||
|---|---|
|
|---|---|
|
||||||
| super_admin | Alles: Tenants, Admins, Module, Settings |
|
| super_admin | Alles: Tenants, Admins, Module, Settings, Invoices, Audit |
|
||||||
| support | Tenants einsehen/verwalten, keine Admins |
|
| support | Tenants einsehen/verwalten, keine Admins ändern, keine Settings |
|
||||||
| sales | Tenants anlegen, keine Settings |
|
| sales | Tenants anlegen, keine Settings, keine Admin-Verwaltung |
|
||||||
|
|
||||||
### Fahrschul-Benutzer
|
### Fahrschul-Benutzer
|
||||||
| Typ | Beschreibung |
|
| Typ | Beschreibung |
|
||||||
|---|---|
|
|---|---|
|
||||||
| admin | Voller Zugriff auf eigene Fahrschule |
|
| admin | Voller Zugriff auf eigene Fahrschule |
|
||||||
| office | Büromitarbeiter: Kunden, Kalender, Berichte |
|
| office | Büromitarbeiter: Kunden, Kalender, Berichte |
|
||||||
| instructor | Fahrlehrer: Kalender, eigene Fahrschüler |
|
| instructor | Fahrlehrer: Kalender, eigene Fahrschüler, DKS |
|
||||||
| lecturer | Dozent: Kalender, eigene Unterrichtseinheiten |
|
| lecturer | Dozent: Kalender, eigene Unterrichtseinheiten |
|
||||||
| student | Fahrschüler: Lernsoftware, eigener Fortschritt |
|
| student | Fahrschüler: Lernsoftware, eigener Fortschritt, Messenger |
|
||||||
|
|
||||||
|
### Rechte-Matrix (pro Modul)
|
||||||
|
```
|
||||||
|
user_types:
|
||||||
|
admin: [office:rw, calendar:rw, messenger:rw, learning:rw, files:rw]
|
||||||
|
office: [office:rw, calendar:r, messenger:rw, learning:r, files:r]
|
||||||
|
instructor:[office:r, calendar:rw, messenger:rw, learning:r, files:rw]
|
||||||
|
lecturer: [calendar:rw, messenger:rw, learning:rw, files:r]
|
||||||
|
student: [calendar:r, messenger:rw, learning:rw, files:r]
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -238,92 +480,333 @@ PUT /api/learning/my-progress/:contentId
|
|||||||
| Key | Name | Beschreibung |
|
| Key | Name | Beschreibung |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `office` | Office | Kundenverwaltung, Fahrzeugverwaltung, Berichte |
|
| `office` | Office | Kundenverwaltung, Fahrzeugverwaltung, Berichte |
|
||||||
| `calendar` | Kalender | Terminplanung, Unterrichtszeiten |
|
| `calendar` | Kalender | Terminplanung (Integration fahrschultermin.de) |
|
||||||
| `messenger` | Messenger | Interne Kommunikation |
|
| `messenger` | Messenger | WhatsApp-ähnlich, DSGVO-konform |
|
||||||
| `learning_blank` | Lernsoftware (Blanko) | Eigene Inhalte erstellen, keine Premium-Inhalte |
|
| `learning_blank` | Lernsoftware (Blanko) | Eigene Inhalte erstellen |
|
||||||
| `learning_premium` | Lernsoftware (Premium) | Inkl. vorgefertigter Lerninhalte |
|
| `learning_premium` | Lernsoftware (Premium) | Inkl. vorgefertigter Lerninhalte |
|
||||||
|
|
||||||
### 6.2 Modul-Zuordnung
|
### 6.2 Modul-Zuordnung
|
||||||
|
|
||||||
- Jede Fahrschule kann Module einzeln aktivieren/deaktivieren
|
- Jede Fahrschule kann Module einzeln aktivieren/deaktivieren
|
||||||
- Preise werden pro Modul hinterlegt (für Abrechnung)
|
- Preise werden pro Modul hinterlegt
|
||||||
- Das Modul `learning_blank` und `learning_premium` schließen sich gegenseitig aus
|
- `learning_blank` und `learning_premium` schließen sich gegenseitig aus
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 7. Frontend-Struktur (fahrschuldesk.de)
|
## 7. Billing & Pakete
|
||||||
|
|
||||||
|
### 7.1 Pakete (Beispiel)
|
||||||
|
| Paket | Preis/Monat | Module | Max Users | Max Filialen |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| Starter | 49€ | Office + Kalender + Messenger | 5 | 1 |
|
||||||
|
| Professional | 99€ | Alle Module (Blanko) | 20 | 3 |
|
||||||
|
| Premium | 149€ | Alle Module (Premium) | Unlimited | Unlimited |
|
||||||
|
|
||||||
|
### 7.2 Trial
|
||||||
|
- 14 Tage kostenlos testen
|
||||||
|
- Danach: Admin-Freigabe nötig
|
||||||
|
- Trial-End: E-Mail-Erinnerung 3 Tage vorher
|
||||||
|
|
||||||
|
### 7.3 Bezahlung
|
||||||
|
- PayPal (monatlich/jährlich)
|
||||||
|
- Rechnung (auf Anfrage für Enterprise)
|
||||||
|
- Automatische Mahnung bei Überfälligkeit
|
||||||
|
|
||||||
|
### 7.4 Self-Hosted
|
||||||
|
- License-Key nötig
|
||||||
|
- Keine weiteren Mandanten anlegbar (nur Filialen)
|
||||||
|
- Update-Management via License-Key
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Registration & Freigabe
|
||||||
|
|
||||||
|
### 8.1 Self-Service Flow
|
||||||
|
```
|
||||||
|
1. Fahrschule registriert sich (Name, E-Mail, Password)
|
||||||
|
2. E-Mail-Verifizierung (Token)
|
||||||
|
3. Status: "pending_approval"
|
||||||
|
4. Admin erhält E-Mail: "Neue Registrierung"
|
||||||
|
5. Admin prüft und genehmigt (oder ablehnen)
|
||||||
|
6. Status: "active" → Fahrschule kann Login
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8.2 Multi-Admin pro Fahrschule
|
||||||
|
- Erster Admin = der Registrierer
|
||||||
|
- Weitere Admin-Accounts können durch den ersten Admin angelegt werden
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Branding & Design
|
||||||
|
|
||||||
|
### 9.1 Plattform-Defaults
|
||||||
|
- Logo, Farben, Fonts werden durch Plattform vorgegeben
|
||||||
|
- Template: Default-Theme für alle neuen Fahrschulen
|
||||||
|
|
||||||
|
### 9.2 Tenant-Branding
|
||||||
|
Jede Fahrschule kann anpassen:
|
||||||
|
- Logo (Header, E-Mails, Rechnungen)
|
||||||
|
- Primärfarbe (Buttons, Links, Akzente)
|
||||||
|
- Sekundärfarbe
|
||||||
|
- Custom CSS (optional, für fortgeschrittene Nutzer)
|
||||||
|
|
||||||
|
### 9.3 E-Mail-Branding
|
||||||
|
- Rechnungs-E-Mails mit Logo der Fahrschule
|
||||||
|
- E-Mail-Templates pro Tenant individuell
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Audit-Log
|
||||||
|
|
||||||
|
### 10.1 Plattform-Admin Audit
|
||||||
|
- Alle Aktionen aller Tenants einsehbar
|
||||||
|
- Filterbar nach Tenant, Aktionstyp, Zeitraum
|
||||||
|
|
||||||
|
### 10.2 Tenant-Admin Audit
|
||||||
|
- Nur eigene Fahrschule
|
||||||
|
- Alle User-Aktionen geloggt
|
||||||
|
- Erfüllt DSGVO-Anforderungen
|
||||||
|
|
||||||
|
### 10.3 Was geloggt wird
|
||||||
|
- Login / Logout
|
||||||
|
- CRUD-Operationen auf alle Entitäten
|
||||||
|
- Änderungen an Benutzern, Modulen, Rechten
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. Messenger (WhatsApp-like)
|
||||||
|
|
||||||
|
### 11.1 Features
|
||||||
|
- 1:1 Chat
|
||||||
|
- Gruppen-Chat
|
||||||
|
- Nachrichten editieren/löschen
|
||||||
|
- Timestamps, Read-Receipts
|
||||||
|
- Online-Status
|
||||||
|
|
||||||
|
### 11.2 DSGVO
|
||||||
|
- Alle Daten auf eigenen Servern
|
||||||
|
- Keine externen Dienste (kein Twilio, keine Cloud-Dienste)
|
||||||
|
- Export aller Daten möglich (DSGVO-Art. 15)
|
||||||
|
- Löschen auf Anfrage (DSGVO-Art. 17)
|
||||||
|
|
||||||
|
### 11.3 Technisch
|
||||||
|
- WebSockets für Echtzeit
|
||||||
|
- Polling-Fallback wenn WebSockets nicht verfügbar
|
||||||
|
- Messages in DB verschlüsselt (für Backend-Zugriff)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12. DKS (Dokumenten-Klasse-System)
|
||||||
|
|
||||||
|
### 12.1 Dateitypen
|
||||||
|
- Fahrzeug: Versicherungsunterlagen, TÜV-Berichte, Kennzeichen
|
||||||
|
- Fahrschüler: Personalausweis, Sehtest, Erste-Hilfe-Nachweis
|
||||||
|
- Fahrlehrer: Führerschein, Lehrberechtigung
|
||||||
|
- Filiale: Mietverträge, Gewerbeanmeldung
|
||||||
|
|
||||||
|
### 12.2 Features
|
||||||
|
- Upload mit Drag & Drop
|
||||||
|
- Dateityp-Kategorisierung
|
||||||
|
- Ablage nach Entity (Fahrzeug, Student, etc.)
|
||||||
|
- Download
|
||||||
|
- Versionierung (neue Datei ersetzt alte, alte bleibt)
|
||||||
|
- Ablaufdatum-Erinnerungen (z.B. TÜV)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 13. Self-Hosted Option
|
||||||
|
|
||||||
|
### 13.1 Anforderungen
|
||||||
|
- PHP 8.2+
|
||||||
|
- PostgreSQL 15+
|
||||||
|
- 4GB RAM minimum
|
||||||
|
- Ubuntu/Debian/CentOS
|
||||||
|
|
||||||
|
### 13.2 Einschränkungen
|
||||||
|
- **Keine Mandanten** anlegbar (nur die eigene Fahrschule)
|
||||||
|
- Filialen: Ja (unbegrenzt)
|
||||||
|
- User: Ja (gemäß Paket)
|
||||||
|
- Updates: Manuell via License-Key
|
||||||
|
|
||||||
|
### 13.3 Installation
|
||||||
|
- Docker-Compose für einfache Installation
|
||||||
|
- Oder klassisch via Composer + Migration
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 14. Frontend-Struktur (fahrschuldesk.de)
|
||||||
|
|
||||||
```
|
```
|
||||||
src/
|
src/
|
||||||
├── views/
|
├── views/
|
||||||
│ ├── auth/
|
│ ├── auth/
|
||||||
│ │ ├── Login.vue
|
│ │ ├── Login.vue
|
||||||
│ │ └── Logout.vue
|
│ │ ├── Register.vue
|
||||||
│ ├── admin/ (Plattform-Admin-Bereich)
|
│ │ ├── ForgotPassword.vue
|
||||||
|
│ │ └── VerifyEmail.vue
|
||||||
|
│ ├── admin/ (Plattform-Admin)
|
||||||
│ │ ├── Dashboard.vue
|
│ │ ├── Dashboard.vue
|
||||||
│ │ ├── Tenants.vue
|
│ │ ├── Tenants.vue
|
||||||
│ │ ├── TenantEdit.vue
|
│ │ ├── TenantEdit.vue
|
||||||
│ │ └── Modules.vue
|
│ │ ├── Modules.vue
|
||||||
│ ├── tenant/ (Fahrschule-Bereich)
|
│ │ ├── Invoices.vue
|
||||||
|
│ │ ├── AuditLog.vue
|
||||||
|
│ │ └── PlatformAdmins.vue
|
||||||
|
│ ├── tenant/ (Fahrschule)
|
||||||
│ │ ├── Dashboard.vue
|
│ │ ├── Dashboard.vue
|
||||||
│ │ ├── Users.vue
|
│ │ ├── Users.vue
|
||||||
│ │ ├── Branches.vue
|
│ │ ├── Branches.vue
|
||||||
│ │ ├── Office.vue
|
│ │ ├── Office.vue (Kunden, Fahrzeuge)
|
||||||
│ │ ├── Calendar.vue
|
│ │ ├── Calendar.vue (→ fahrschultermin.de)
|
||||||
│ │ ├── Messenger.vue
|
│ │ ├── Messenger.vue
|
||||||
│ │ └── Learning.vue
|
│ │ ├── Learning.vue
|
||||||
│ └── student/ (Fahrschüler-Bereich)
|
│ │ ├── Files.vue (DKS)
|
||||||
|
│ │ ├── Branding.vue
|
||||||
|
│ │ └── Billing.vue
|
||||||
|
│ └── student/ (Fahrschüler)
|
||||||
│ ├── Dashboard.vue
|
│ ├── Dashboard.vue
|
||||||
│ └── Learning.vue
|
│ ├── Learning.vue
|
||||||
|
│ └── Messenger.vue
|
||||||
├── components/
|
├── components/
|
||||||
|
│ ├── common/
|
||||||
|
│ │ ├── AppHeader.vue
|
||||||
|
│ │ ├── AppSidebar.vue
|
||||||
|
│ │ └── ModuleCard.vue
|
||||||
|
│ ├── messenger/
|
||||||
|
│ │ ├── ChatWindow.vue
|
||||||
|
│ │ ├── ConversationList.vue
|
||||||
|
│ │ └── MessageBubble.vue
|
||||||
|
│ ├── files/
|
||||||
|
│ │ ├── FileUploader.vue
|
||||||
|
│ │ └── FileList.vue
|
||||||
|
│ └── branding/
|
||||||
|
│ └── ColorPicker.vue
|
||||||
├── stores/ (Pinia)
|
├── stores/ (Pinia)
|
||||||
|
│ ├── auth.js
|
||||||
|
│ ├── tenant.js
|
||||||
|
│ ├── modules.js
|
||||||
|
│ └── messenger.js
|
||||||
├── router/
|
├── router/
|
||||||
└── api/ (API-Client)
|
│ └── index.js
|
||||||
|
├── api/ (Axios Client)
|
||||||
|
│ ├── client.js
|
||||||
|
│ ├── auth.js
|
||||||
|
│ ├── admin.js
|
||||||
|
│ └── tenant.js
|
||||||
|
└── styles/
|
||||||
|
├── variables.css
|
||||||
|
└── theme.css
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 8. Deployment-Workflow
|
## 15. CI/CD Pipeline
|
||||||
|
|
||||||
```
|
```yaml
|
||||||
Lokal (~/drivetimeplaner/www/fahrschuldesk.de/)
|
# .github/workflows/deploy.yml
|
||||||
└── git commit + push
|
|
||||||
↓
|
|
||||||
Git (https://git.shadow-land.de/madgerm/drivetimeplaner)
|
|
||||||
↓ git push (oder rsync via CI/CD)
|
|
||||||
Server (/srv/web/fahrschuldesk/domains/fahrschuldesk.de/public/)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Sync-Befehle
|
name: Deploy
|
||||||
```bash
|
|
||||||
# Server → Lokal (Daten holen)
|
|
||||||
rsync -az --exclude='storage/sessions/' --exclude='storage/database/' \
|
|
||||||
-e "ssh -p 2225" fahrschuldesk@fahrschuldesk.de:/srv/web/fahrschuldesk/domains/ www/
|
|
||||||
|
|
||||||
# Lokal → Server (deployen)
|
on:
|
||||||
rsync -az --exclude='storage/sessions/' --exclude='storage/database/' \
|
push:
|
||||||
-e "ssh -p 2225" www/fahrschuldesk.de/public/ \
|
branches: [main]
|
||||||
fahrschuldesk@fahrschuldesk.de:/srv/web/fahrschuldesk/domains/fahrschuldesk.de/public/
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: PHP Setup
|
||||||
|
uses: shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
php-version: '8.2'
|
||||||
|
extensions: pgsql, curl
|
||||||
|
- name: Run Tests
|
||||||
|
run: composer test
|
||||||
|
|
||||||
|
deploy-api:
|
||||||
|
needs: test
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Sync to Server
|
||||||
|
uses: appleboy/scp-action@master
|
||||||
|
with:
|
||||||
|
host: fahrschuldesk.de
|
||||||
|
port: 2225
|
||||||
|
username: fahrschuldesk
|
||||||
|
key: ${{ secrets.SSH_KEY }}
|
||||||
|
source: "api/*"
|
||||||
|
target: "/srv/web/fahrschuldesk/domains/api.fahrschuldesk.de/public/"
|
||||||
|
|
||||||
|
deploy-frontend:
|
||||||
|
needs: test
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Build Vue
|
||||||
|
run: |
|
||||||
|
npm ci
|
||||||
|
npm run build
|
||||||
|
- name: Sync to Server
|
||||||
|
uses: appleboy/scp-action@master
|
||||||
|
with:
|
||||||
|
host: fahrschuldesk.de
|
||||||
|
port: 2225
|
||||||
|
username: fahrschuldesk
|
||||||
|
key: ${{ secrets.SSH_KEY }}
|
||||||
|
source: "dist/*"
|
||||||
|
target: "/srv/web/fahrschuldesk/domains/fahrschuldesk.de/public/"
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 9. Offene Fragen / Next Steps
|
## 16. Offene Fragen / Next Steps
|
||||||
|
|
||||||
- [ ] Tech-Stack final abstimmen (Laravel vs. Slim vs. anderes?)
|
- [ ] Tech-Stack final abstimmen (Laravel vs. Slim vs. anderes?)
|
||||||
- [ ] Auth-Flow: Login-Seite designen
|
- [ ] PayPal Integration: API Keys besorgen
|
||||||
- [ ] Erste Migration: Plattform-Admins + Tenants + Users
|
- [ ] Design-System erstellen (Default-Theme)
|
||||||
- [ ] Mockups/UI-Design für Dashboard
|
- [ ] OpenAPI Spec schreiben
|
||||||
- [ ] Premium-Lerninhalte: woher kommen? Eigene Erstellung oder Drittanbieter?
|
- [ ] Erste Migration: Alle Tabellen
|
||||||
|
- [ ] Auth-Flow: Login + Registration + E-Mail-Verifizierung
|
||||||
|
- [ ] Messenger: WebSocket-Integration planen
|
||||||
|
- [ ] Self-Hosted: Docker-Compose vorbereiten
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 10. Phase 1 — Erste Schritte
|
## 17. Phase 1 — Erste Schritte
|
||||||
|
|
||||||
### Ziel: Grundgerüst stehen
|
### Ziel: Grundgerüst stehen
|
||||||
|
|
||||||
1. **DB-Schema:** Migrationen schreiben für alle Tabellen
|
1. **DB-Schema:** Migrationen schreiben für alle Tabellen
|
||||||
2. **API-Skelett:** Auth + Tenant-CRUD + Module-CRUD
|
2. **API-Skelett:** Auth + Tenant-Registration + Admin-CRUD + Module-CRUD
|
||||||
3. **Frontend-Skelett:** Vue 3 + Vite + Router + Pinia
|
3. **Frontend-Skelett:** Vue 3 + Vite + Router + Pinia + TailwindCSS
|
||||||
4. **Login-Seite:** Plattform-Admin Login
|
4. **Login-Seite:** Plattform-Admin Login
|
||||||
5. **Admin-Dashboard:** Tenants auflisten, anlegen, Module zuweisen
|
5. **Registration:** Self-Service + Admin-Freigabe
|
||||||
|
6. **Admin-Dashboard:** Tenants auflisten, anlegen, Module zuweisen
|
||||||
|
7. **Branding:** Logo-Upload, Farben wählen
|
||||||
|
8. **Audit-Log:** Basis-Implementierung
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 18. Datei-Ablage (Storage)
|
||||||
|
|
||||||
|
### SaaS
|
||||||
|
```
|
||||||
|
/srv/web/fahrschuldesk/storage/
|
||||||
|
├── tenants/{tenant_id}/
|
||||||
|
│ ├── files/
|
||||||
|
│ │ ├── vehicles/
|
||||||
|
│ │ ├── students/
|
||||||
|
│ │ └── ...
|
||||||
|
│ ├── avatars/
|
||||||
|
│ └── logos/
|
||||||
|
└── backups/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Self-Hosted
|
||||||
|
```
|
||||||
|
/var/www/fahrschuldesk/storage/
|
||||||
|
├── files/
|
||||||
|
├── avatars/
|
||||||
|
├── logos/
|
||||||
|
└── backups/
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user