Darstellung
eventVIA -- Event-Management
In Entwicklung
eventVIA ist geplant, läuft aber noch nicht produktiv. Diese Seite beschreibt das Soll-Bild des Moduls. Verfügbarkeit: TBA. Bei Interesse: Kontakt aufnehmen.
eventVIA ist das Event-Management-Modul von VIA. Es ermöglicht dir, Kurse, Veranstaltungen und Termine zu verwalten, inklusive Buchungen, Wartelisten und Zahlungsabwicklung über Stripe.
API Endpoints
Alle Endpoints erfordern Authentifizierung (authMiddleware). Basis-Pfad: /api/events.
| Method | Pfad | Funktion | Beschreibung |
|---|---|---|---|
POST | /api/events | createEvent | Event erstellen |
GET | /api/events | listEvents | Events auflisten (mit Filtern) |
GET | /api/events/:id | getEvent | Event-Detail mit Live-Stats |
PUT | /api/events/:id | updateEvent | Event aktualisieren |
DELETE | /api/events/:id | deleteEvent | Event löschen (nur draft/cancelled) |
PATCH | /api/events/:id/status | changeStatus | Event-Status ändern |
GET | /api/events/:id/bookings | listBookings | Buchungen eines Events auflisten |
POST | /api/events/:id/bookings | createBooking | Buchung erstellen |
DELETE | /api/events/:eventId/bookings/:bookingId | cancelBooking | Buchung stornieren |
PATCH | /api/events/:eventId/bookings/:bookingId/status | updateBookingStatus | Booking-Status ändern |
Filter für GET /api/events
| Parameter | Typ | Beschreibung |
|---|---|---|
status | string | Filtert nach Event-Status (draft, selling, waitlist, completed, cancelled) |
from_date | date | Events ab diesem Datum |
to_date | date | Events bis zu diesem Datum |
bot_id | uuid | Events eines bestimmten Bots |
Pflichtfelder für POST /api/events
title(string, max 200 Zeichen)event_date(date)capacity_total(integer)
Pflichtfelder für POST /api/events/:id/bookings
contact_id(uuid)
Optional: channel (default: manual), metadata (object).
Datenbank-Schema
Tabelle: events
26 Spalten mit CHECK Constraints für status und payment_model.
| Spalte | Typ | Nullable | Default | Beschreibung |
|---|---|---|---|---|
id | uuid | NOT NULL | gen_random_uuid() | Primaerschlüssel |
tenant_id | uuid | NOT NULL | -- | Mandanten-ID (FK tenants) |
bot_id | uuid | NULL | -- | Zugeordneter Bot (FK bots, ON DELETE SET NULL) |
created_by | uuid | NULL | -- | Ersteller (FK users, ON DELETE SET NULL) |
title | varchar(200) | NOT NULL | -- | Event-Titel |
description | text | NULL | -- | Beschreibung |
location | varchar(500) | NULL | -- | Veranstaltungsort |
image_url | varchar(1000) | NULL | -- | Bild-URL |
event_date | date | NOT NULL | -- | Veranstaltungsdatum |
event_time_start | time | NULL | -- | Startzeit |
event_time_end | time | NULL | -- | Endzeit |
booking_deadline | timestamptz | NULL | -- | Buchungsschluss |
capacity_total | integer | NOT NULL | 0 | Gesamtkapazitaet |
capacity_booked | integer | NOT NULL | 0 | Aktuell gebucht |
capacity_waitlist | integer | NOT NULL | 0 | Aktuell auf Warteliste |
waitlist_max | integer | NULL | -- | Maximale Wartelisten-Plaetze |
price | numeric(10,2) | NOT NULL | 0 | Preis |
currency | varchar(3) | NOT NULL | 'EUR' | Waehrung |
payment_model | text | NOT NULL | 'free' | Zahlungsmodell (CHECK) |
deposit_amount | numeric(10,2) | NULL | -- | Anzahlungsbetrag |
stripe_payment_link | varchar(500) | NULL | -- | Stripe Payment Link |
external_payment_url | varchar(1000) | NULL | -- | Externer Zahlungslink |
status | text | NOT NULL | 'draft' | Event-Status (CHECK) |
metadata | jsonb | NULL | '{}' | Zusaetzliche Metadaten |
created_at | timestamptz | NOT NULL | CURRENT_TIMESTAMP | Erstellungszeitpunkt |
updated_at | timestamptz | NOT NULL | CURRENT_TIMESTAMP | Letztes Update |
CHECK Constraint events_status_check:status IN ('draft', 'selling', 'waitlist', 'completed', 'cancelled')
CHECK Constraint events_payment_model_check:payment_model IN ('free', 'full_payment', 'deposit', 'external_link')
Indizes:
events_pkey-- PRIMARY KEY (id)idx_events_tenant_status-- btree (tenant_id, status)idx_events_date-- btree (event_date)idx_events_bot-- btree (bot_id)
Foreign Keys:
tenant_id-> tenants(id) ON DELETE CASCADEbot_id-> bots(id) ON DELETE SET NULLcreated_by-> users(id) ON DELETE SET NULL
Referenced by:
event_bookings.event_id-> events(id) ON DELETE CASCADEcampaigns.event_id-> events(id) ON DELETE SET NULLnewsletter_campaigns.event_id-> events(id) ON DELETE SET NULL
Tabelle: event_bookings
15 Spalten mit CHECK Constraints für status, payment_status und booking_channel.
| Spalte | Typ | Nullable | Default | Beschreibung |
|---|---|---|---|---|
id | uuid | NOT NULL | gen_random_uuid() | Primaerschlüssel |
event_id | uuid | NOT NULL | -- | Event (FK events) |
contact_id | uuid | NOT NULL | -- | Kontakt (FK contacts) |
tenant_id | uuid | NOT NULL | -- | Mandanten-ID (FK tenants) |
status | text | NOT NULL | 'confirmed' | Buchungsstatus (CHECK) |
waitlist_position | integer | NULL | -- | Position auf Warteliste |
payment_status | text | NOT NULL | 'not_required' | Zahlungsstatus (CHECK) |
payment_amount | numeric(10,2) | NULL | -- | Bezahlter Betrag |
stripe_payment_intent_id | varchar(255) | NULL | -- | Stripe PaymentIntent ID |
booking_channel | text | NOT NULL | 'manual' | Buchungskanal (CHECK) |
booked_at | timestamptz | NULL | CURRENT_TIMESTAMP | Buchungszeitpunkt |
cancelled_at | timestamptz | NULL | -- | Stornierungszeitpunkt |
metadata | jsonb | NULL | '{}' | Zusaetzliche Metadaten |
created_at | timestamptz | NOT NULL | CURRENT_TIMESTAMP | Erstellungszeitpunkt |
updated_at | timestamptz | NOT NULL | CURRENT_TIMESTAMP | Letztes Update |
CHECK Constraint event_bookings_status_check:status IN ('confirmed', 'waitlist', 'cancelled', 'attended', 'no_show')
CHECK Constraint event_bookings_payment_status_check:payment_status IN ('not_required', 'pending', 'paid', 'refunded')
CHECK Constraint event_bookings_booking_channel_check:booking_channel IN ('whatsapp', 'voice', 'email', 'manual', 'api')
Indizes:
event_bookings_pkey-- PRIMARY KEY (id)idx_event_bookings_event_status-- btree (event_id, status)idx_event_bookings_contact-- btree (contact_id)idx_event_bookings_tenant-- btree (tenant_id)idx_event_bookings_unique_contact-- UNIQUE (event_id, contact_id) WHERE status != 'cancelled'idx_event_bookings_waitlist-- btree (event_id, waitlist_position) WHERE status = 'waitlist'
Foreign Keys:
event_id-> events(id) ON DELETE CASCADEcontact_id-> contacts(id) ON DELETE CASCADEtenant_id-> tenants(id) ON DELETE CASCADE
Event-Status-Übergaenge
Events durchlaufen einen definierten Lebenszyklus. Nur bestimmte Übergaenge sind erlaubt:
draft ──────> selling ──────> completed
│ │
│ ├────> waitlist ──> completed
│ │ │
│ │ └──> selling (Plaetze frei geworden)
│ │
└──> cancelled <──────────────────┘| Von | Erlaubte Übergaenge |
|---|---|
draft | selling, cancelled |
selling | waitlist, completed, cancelled |
waitlist | selling (Plaetze frei), completed, cancelled |
completed | -- (Endstatus) |
cancelled | -- (Endstatus) |
Booking-Status-Übergaenge
| Von | Erlaubte Übergaenge |
|---|---|
confirmed | attended, no_show, cancelled |
waitlist | confirmed, cancelled |
cancelled | -- (Endstatus) |
attended | -- (Endstatus) |
no_show | -- (Endstatus) |
Warteliste-Logik
Die Warteliste wird über vier Spalten in der events-Tabelle gesteuert:
| Spalte | Beschreibung |
|---|---|
capacity_total | Gesamtkapazitaet des Events |
capacity_booked | Anzahl bestaetigter Buchungen |
capacity_waitlist | Anzahl Personen auf der Warteliste |
waitlist_max | Maximale Wartelisten-Plaetze (NULL = unbegrenzt) |
- Verfügbare Plaetze =
capacity_total - capacity_booked - Wenn keine Plaetze mehr frei sind und
waitlist_maxnoch nicht erreicht ist, wird die Buchung auf die Warteliste gesetzt - Nach einer Stornierung rückt der nächste Wartelisten-Kontakt automatisch nach (basierend auf
waitlist_position) - Der Event-Status wechselt automatisch zwischen
sellingundwaitlistje nach Kapazitaet
Delete-Schutz
Events können nur gelöscht werden, wenn sie den Status draft oder cancelled haben. Events mit dem Status selling, waitlist oder completed sind geschuetzt und müssen zuerst storniert werden.
Fehlermeldung bei geschuetztem Status:
Event im Status 'selling' kann nicht gelöscht werden
Stripe Integration
eventVIA unterstützt vier Zahlungsmodelle über das Feld payment_model:
| Modell | Beschreibung |
|---|---|
free | Keine Zahlung erforderlich |
full_payment | Voller Preis wird über Stripe abgewickelt |
deposit | Anzahlung über Stripe (deposit_amount), Rest vor Ort |
external_link | Externer Zahlungslink (external_payment_url) |
Wenn ein Event in den Status selling wechselt und das Zahlungsmodell full_payment oder deposit ist, wird automatisch ein Stripe Payment Link erstellt (via EventPaymentService). Der Link wird in stripe_payment_link gespeichert.
AI Booking Intent Tags
Bots können Buchungsabsichten per Intent-Tags erkennen und automatisch verarbeiten:
| Tag | Beschreibung |
|---|---|
[BOOK:event_id] | Buchung für ein Event auslösen |
[WAITLIST:event_id] | Wartelisten-Eintrag für ein Event auslösen |
Diese Tags werden vom Bot im AI-Response generiert und vom System als Buchungs-Aktionen interpretiert.
Quellcode-Referenz
| Datei | Beschreibung |
|---|---|
src/routes/eventRoutes.js | Route-Definitionen (10 Endpoints) |
src/controllers/eventController.js | Request-Handler |
src/services/EventService.js | Core-Logik (CRUD, Status, Kapazitaet) |
src/services/EventPaymentService.js | Stripe Payment Links |
src/services/EventNotificationService.js | Benachrichtigungen |
src/services/EventWebhookService.js | Webhook bei Status-Änderungen |