# API-Dokumentation
Die SeminarPlan API ist eine Fastify-basierte REST-API mit zwei Generationen von Endpunkten: V1 und V2.
# Übersicht
Die API stellt zwei parallele Endpunkt-Familien bereit:
| V1 | V2 | |
|---|---|---|
| Basis-Pfad | /v1/{entity} bzw. /api/{entity} | /api/v2/{entity} |
| Architektur | Mongoose Model + AbstractController | Factory-Routen + LookupService |
| Daten | Roh-Dokumente aus MongoDB | Denormalisiert, paginiert, optimiert |
| Verwendung | V1-Frontend, Webseite (CMS-Plugins), Externe | V2-Frontend (Desktop-Shell) |
Beide Versionen sind gleichzeitig aktiv. V2-Endpunkte sind für das moderne Frontend optimiert und liefern fertig aufbereitete Daten.
# Authentifizierung
Die API verwendet JSON Web Tokens (JWT) zur Authentifizierung.
# Login
POST /v1/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "..."
}
Antwort:
{
"token": "eyJhbG...",
"user": { "_id": "...", "name": "...", "group": "user" }
}
# Token verwenden
Das Token wird bei jedem Request als Header mitgeschickt:
token: eyJhbG...
# Öffentliche Routen
Folgende Routen benötigen kein Token:
| Route | Zweck |
|---|---|
POST /v1/login | Login |
POST /v1/register/* | Registrierung |
GET /v1/public/* | Öffentliche Daten (Feedbacks, Organisation) |
POST /v1/orders/place | Bestellung aufgeben (Website) |
POST /v1/inquiries/place | Anfrage aufgeben (Website) |
GET /v1/ics/* | Kalender-Download (ICS) |
GET /v1/api-docs/* | Swagger-Dokumentation |
GET /v2/api-docs/* | Swagger-Dokumentation (V2) |
GET /v1/coupons/validate/* | Gutschein validieren |
Swagger UI
Die API-Dokumentation ist auch interaktiv verfügbar:
- V1:
/v1/api-docs - V2:
/v2/api-docs
Dort kannst du alle Endpunkte durchsuchen, Parameter sehen und direkt testen.
# V1 Endpunkte
V1-Endpunkte folgen dem klassischen CRUD-Muster:
| Methode | Route | Beschreibung |
|---|---|---|
GET | /api/{entity} | Alle Einträge laden |
GET | /api/{entity}/:id | Einzelnen Eintrag laden |
POST | /api/{entity} | Neuen Eintrag erstellen |
PUT | /api/{entity}/:id | Eintrag aktualisieren |
DELETE | /api/{entity}/:id | Eintrag löschen (Soft Delete) |
# V1 Response-Formate
Liste:
{
"items": [{ "_id": "...", "title": "..." }, ...]
}
Erstellen / Aktualisieren:
{
"count": 1,
"item": { "_id": "...", "title": "..." }
}
# Verfügbare V1-Entitäten
Kontakte, Buchungen, Angebote, Bestellungen, Anfragen, Rechnungen, Gutschriften, Seminare, Feste Termine, Standorte, Räume, Kategorien, Hersteller, Tags, E-Mails, Briefe, Aufgaben, Gesprächsnotizen, Feedbacks, Lernpfade, Gutscheine, Kursunterlagen, Portale, Statische Seiten, Menüs, Förderungen, Wartelisten, Kontaktformularnachrichten, Preisgruppen und weitere.
# V2 Endpunkte
V2-Endpunkte werden über zwei Factory-Funktionen erzeugt:
# createV2ResourceRoutes (Vollständiges CRUD)
Für Entitäten mit Schreibzugriff (Kontakte, Buchungen, Angebote, ...):
| Methode | Route | Beschreibung |
|---|---|---|
GET | /api/v2/{entity} | Paginierte Liste |
GET | /api/v2/{entity}/:id | Detail-Ansicht (deep populate) |
POST | /api/v2/{entity} | Neuen Eintrag erstellen |
PATCH | /api/v2/{entity}/:id | Eintrag aktualisieren (partial) |
DELETE | /api/v2/{entity}/:id | Eintrag löschen |
POST | /api/v2/{entity}/search | Erweiterte Suche |
POST | /api/v2/{entity}/resolve | Eintrag per Kriterium finden |
# createV2LookupRoutes (Nur Lesen)
Für denormalisierte Lesezugriffe (z.B. Feste Termine, Kalender):
| Methode | Route | Beschreibung |
|---|---|---|
GET | /api/v2/{entity} | Paginierte Liste |
GET | /api/v2/{entity}/:id | Detail-Ansicht |
# V2 Response-Formate
Liste:
{
"items": [{ "_id": "...", "title": "..." }],
"meta": {
"total": 142,
"limit": 20,
"offset": 0,
"hasMore": true
}
}
Detail:
{
"item": { "_id": "...", "title": "...", "customer": { "name": "..." } }
}
Mutation (Create/Update):
{
"count": 1,
"item": { "_id": "...", "title": "..." }
}
Resolve:
{
"found": true,
"item": { "_id": "...", "title": "..." }
}
# Standard-Query-Parameter (V2)
| Parameter | Typ | Beschreibung |
|---|---|---|
q | string | Freitextsuche |
limit | integer | Max. Ergebnisse (Standard: 20, Max: 100) |
offset | integer | Offset für Pagination |
statuses | string/array | Nach Status filtern |
sortBy | string | Sortierfeld |
sortType | asc / desc | Sortierrichtung |
ids | string/array | Bestimmte IDs laden |
employeeId | string | Nach Mitarbeiter filtern |
relationKey / relationValue | string | Nach Beziehung filtern |
group | string | Nach Gruppe filtern |
tag | string | Nach Tag filtern |
countOnly | boolean | Nur Anzahl zurückgeben |
# Erweiterte Filter (V2)
V2 unterstützt serialisierte Filter als JSON-Array im Query-Parameter filters:
[
{ "field": "title", "operator": "contains", "value": "Excel" },
{ "field": "createdAt", "operator": "greaterThan", "value": "2025-01-01" }
]
Verfügbare Operatoren:
| Operator | Beschreibung |
|---|---|
contains | Enthält (Regex) |
containsNot | Enthält nicht |
isEmpty | Feld ist leer |
startsWith | Beginnt mit |
endsWith | Endet mit |
equals | Exakte Übereinstimmung |
notEquals | Nicht gleich |
greaterThan | Größer als |
lessThan | Kleiner als |
greaterThanOrEqual | Größer oder gleich |
lessThanOrEqual | Kleiner oder gleich |
# V2 Spezial-Endpunkte
Neben den Standard-CRUD-Routen gibt es spezielle Endpunkte:
| Endpunkt | Beschreibung |
|---|---|
GET /api/v2/fixed-dates/schedule | Denormalisierte Terminplanung (Kalender, Wochenplan, Raumbelegung) |
GET /api/v2/bootstrap | Bootstrap-Daten (User, Organisation, ACL) beim Login |
GET /api/v2/dashboard/* | Dashboard-Statistiken und Widgets |
POST /api/v2/search/global | Globale Suche über alle Entitäten |
GET /api/v2/chat/* | Chat-Nachrichten |
POST /api/v2/assistant/* | KI-Assistent |
# LookupService-Pattern
Jede V2-Entität hat einen zugehörigen LookupService (z.B. ContactLookupService, BookingLookupService). Diese Services erben von BaseLookupService und bieten:
| Methode | Beschreibung |
|---|---|
listPage(args) | Paginierte Liste mit Suche, Sortierung, Populate |
getDetailItem(args) | Einzelner Eintrag mit Deep Populate |
toListItem(item, stats) | Rohdaten → denormalisiertes Listenformat |
Jeder LookupService definiert statische Konstanten:
*_LIST_SELECT-- Welche Felder in der Liste geladen werden*_LIST_SORT_FIELDS-- Erlaubte Sortierfelder
Beispiel: FixedDateLookupService
Der Schedule-Endpunkt ist ein gutes Beispiel für erweiterte Denormalisierung:
GET /api/v2/fixed-dates/schedule?begin=2026-01-01&end=2026-01-31&statuses=published
Dieser Endpunkt:
- Fragt Feste Termine im Datumsbereich ab
- Lädt Buchungsstatistiken in einem Batch
- Löst Kundennamen auf (für Firmenseminare)
- Berechnet Teilnehmerzahlen, Uhrzeiten und Farben
- Liefert fertig aufbereitete
ScheduleItemszurück
So müssen Kalender, Wochenplan und Raumbelegung keine kompletten Stores laden.
# ACL-System (Berechtigungen)
Die API verwendet ein rollenbasiertes Berechtigungssystem:
| Gruppe | Beschreibung |
|---|---|
guest | Nur Lesezugriff auf ausgewählte Bereiche |
user | Standard-Benutzer mit Lese- und Schreibzugriff |
manager | Erweiterte Rechte (alle Benutzeraktionen) |
admin | Vollzugriff inkl. Systemeinstellungen |
root | Superadmin (nur für Entwickler) |
Pro Entität und Gruppe werden Rechte definiert:
| Recht | Beschreibung |
|---|---|
create | Neue Einträge erstellen |
read | Einträge lesen |
edit | Alle Einträge bearbeiten |
editOwn | Eigene Einträge bearbeiten |
editState | Status ändern |
delete | Einträge löschen |
Im Frontend prüfst du Rechte mit:
const { can, isAdmin } = useAcl();
if (can('Booking', 'edit')) { ... }
# WebSocket
Die API stellt eine WebSocket-Verbindung für Echtzeit-Updates bereit:
| Event | Beschreibung |
|---|---|
change | Ein Datensatz wurde erstellt, aktualisiert oder gelöscht |
lock / unlock | Optimistisches Locking (Bearbeitung durch anderen Benutzer) |
notification | Benachrichtigung an einen Benutzer |
task | V2-spezifische Aufgabe (z.B. KI-Antwort) |
Änderungen werden über das modelToStoreKeys-Mapping in storeHelper.ts an die richtigen Stores weitergeleitet.
# Siehe auch
- Extensions -- API mit eigenen Plugins erweitern
- Neuen Store anlegen
- Berechtigungen -- Benutzergruppen im Detail