Admin-UI /admin/booking-partners: Affiliate-ID-Feld pro Partner, Radio-Toggle (nur einer gleichzeitig aktiv), Klick-Zähler-Badge, "Gespeichert!"-Feedback; atomare Transaktion beim Aktivieren (alle anderen werden deaktiviert)
AccommodationBlock Server Component auf Event-Detailseite: Unsplash-Stadtbild (30+ europäische Städte gemappt), dunkler Gradient-Overlay links für Lesebarkeit, Partner-farbiger CTA-Button
Intro-Text "Buche über unseren Partner X:" über dem Block; erscheint nur wenn aktiver Partner + affiliateId + event.city + Event in der Zukunft
Click-Tracking: /api/booking-partners/[id]/click — atomares clickCount++ (fire-and-forget), 302-Redirect zur Partner-URL mit Stadt + Check-in/Checkout vorbelegt
i18n in allen 11 Sprachen: events.accommodation-Namespace (label, title, intro, subtitle, cta) — alle 11 locales/*.json-Dateien aktualisiert
Genre-Chips auf /events: TagChips-Client-Komponente — Häufigkeits-Sortierung via Map-Counter (meistgenutzte zuerst), max. 20 Chips sichtbar
"Mehr anzeigen"-Modal: pendingTags-State, "Alle abwählen"-Button, "Anwenden"-Button mit router.push — aktive versteckte Tags als "+X aktiv"-Badge in Primary-Color
Bug-Fix /admin/featured: vergangene Events werden nicht mehr in der Auswahlliste angezeigt (endDate: { gte: new Date() })
CheckinForecastSection im Analytics-Dashboard: historische checkedInAt-Zeitstempel aller vergangenen Events aggregiert, normalisiert auf Minuten ab Event-Startzeit, 8 Zeitbuckets (-60 bis +300 Min), Peak-Bucket-Hervorhebung
API GET /api/organizer/events/[id]/checkin-forecast — Mindest-3-Events-Guard, gibt Prognose-Daten zurück
Venue-Bibliothek: Venue + VenueSeatingTemplate-Prisma-Modelle. private (Standard) oder public (erfordert Admin-Freigabe)
POST /api/organizer/events/[id]/message mit ticketTypeIds-Filter — segmentierte Direktnachricht an ausgewählte Ticket-Typ-Inhaber (z.B. nur VIP, nur Stehplatz)
Rate-Limit: 3 Massen-E-Mails pro Event/Tag. Audit-Log-Eintrag bei jedem Versand
"Erinnere mich"-Button auf Event-Detailseite: EventInterest-Modell speichert E-Mail + Event-ID
E-Mail-Benachrichtigung wenn Tickets für ein gewünschtes Event live gehen — Cron-Check bei Event-Veröffentlichung
/admin/languages: Aktivieren/Deaktivieren der 11 i18n-Sprachen (DE/EN/FR/NL/PL/ES/DA/IT/SV/FI/NO)
disabledLocales als String-Array in AdminSettings (DB via prisma db push); /api/locales liefert nur aktive Locales
LocalePicker zeigt ausschließlich aktivierte Sprachen — deaktivierte Sprachen verschwinden sofort aus der Sprachauswahl
Deckungsbeitrag-Kalkulator als eigenständiger zweiter Tab in /organizer/fee-calculator: Fixkosten (dynamisch hinzufügbar), variable Kosten pro Ticket
Automatische Plattform- + Zahlungsgebühren aus DB via GET /api/organizer/fee-config (respektiert platformFeeOverride pro Organizer + kioskFeeExtra), Kiosk-Toggle
Break-Even-Punkt-Anzeige, Auslastungs-%-Visualisierung, Szenarien-Tabelle. Sidebar-Redesign: identisches Layout-Muster wie /organizer/profile
39
Mai 2026
Sprint 39 — Mail Retry, API-Keys, Finance-Presets, Flex-Ticket, Scanner-Gate
Mail Retry: fehlgeschlagene E-Mails direkt aus /admin/emails per Button erneut senden — rawBody in EmailLog gespeichert, neuer Log-Eintrag bei Retry
API-Keys nach Veranstalter: /admin/api-keys zeigt System-Keys und Veranstalter-API-Keys in getrennten Sektionen
Finance-Presets: Q1/Q2/Q3/Q4, aktuelles Jahr, Vorjahr als Preset-Buttons im Finance-Dashboard — ein Klick statt manueller Datumseingabe
Flex-Ticket: isFlexTicket Flag pro Ticket-Typ — Käufer wählt aus allen Terminen einer Event-Serie, flexSelectedEventId in DB gespeichert
Öffentliche API /api/events/[slug]/series-dates liefert Live-Verfügbarkeit aller Serientage
Scanner-Gate: aktive Bestätigung bei personalisierten Tickets ("Ausweis geprüft"), Doppelscan, gesperrtem Ticket — normaler grüner Einlass ohne Unterbrechung
Sprint B: Custom Domain per CNAME — Veranstalter binden eigene Domain (z.B. tickets.meinveranstaltung.de) an. Organizer-Logo auf Event-Seiten + eigene Primärfarbe
"Powered by tl-tickets"-Badge konfigurierbar (optional ausblendbar). DNS-Anleitung im Organizer-Portal. Admin-UI für Domain-Verwaltung
Sprint D: Custom Favicon pro Organizer. Custom OG-Bild (1200×630) für Social-Media-Sharing
Vercel-API Auto-Domain-Registrierung: neue CNAME-Einträge automatisch über Vercel-API registriert
DNS-Check mit Echtzeit-Statusanzeige via Cloudflare DoH. Admin-Übersicht /admin/white-label für alle registrierten Domains
generateMetadata-Middleware: dynamische og:title, og:image, og:description, favicon pro Organizer
A
Mai 2026
Sprint A — Internationalisierung — 11 Sprachen
11 Sprachen live: DE, EN, FR, NL, PL, ES, DA, IT, SV, FI, NO — vollständig abgeschlossen
next-intl 4.12.0: Cookie-basiertes Locale-Routing (tl_locale Cookie, 1 Jahr), kein URL-Prefix
LocalePicker-Modal: beim ersten Besuch, jederzeit änderbar, Geolocation-Vorschlag via Vercel-Header (x-vercel-ip-country)
LoyaltyBadge-Komponente: kompaktes ⭐ N Pill auf Event-Cards (featured + grid), Tooltip via createPortal (nicht durch overflow-hidden abgeschnitten)
LoyaltyHint auf Event-Detailseite: Infobox unterhalb der Ticket-Auswahl
LoyaltyCheckModal auf /events: "Mein Punktestand ansehen"-Button öffnet Modal — Auswahl Login oder E-Mail-Lookup, Punktestand + Euro-Wert direkt im Modal (via createPortal)
/events-Seite: fetchEvents() + fetchFeaturedSlots() um Loyalty-Felder erweitert (Prisma-select + mapping) — Badge auch für Featured- und Grid-Cards
1 Punkt = 0,10 € Rabatt beim Checkout
AP1
Mai 2026
Sprint AP1 — Addon-PDF-Integration & Checkout-UX
Addons auf PDF-Tickets: gebuchte Extras ("GEBUCHTE EXTRAS") erscheinen auf dem Ticket-PDF direkt unter dem Sitzplatz-Block — Name linksbündig, Preis rechtsbündig, "inkl." bei Preis 0
TicketPDFParams erweitert: addons-Feld (Array mit name + price) — beide PDF-Routen (by-id + by-code) befüllen es aus TicketOrderAddon.unitPrice (Preis zum Kaufzeitpunkt)
Ticket-Design-Editor (/organizer/ticket-design): JSX-Canvas-Vorschau zeigt Addon-Block mit zwei Demo-Einträgen (Sektempfang + Artist Meet & Greet)
PDF-Vorschau (/api/organizer/ticket-design/preview): Demo-Addons in der generierten Vorschau-PDF
Checkout-Addon-Beschreibungen: von truncate auf line-clamp-2 + leading-relaxed umgestellt — Beschreibungen bis zu zwei Zeilen lesbar, kein hartes Abschneiden mehr
Seed-Demo-Daten: 3 neue Events für The Legends Entertainment GmbH — Galerie Nacht, Symphonie unter Sternen, Theater-Gala — je 4 Addons (Garderobe, Parkplatz, Getränk, Custom)
Demo-Events im Seed-Skript idempotent — Addons werden nur angelegt wenn Event neu erstellt wird, keine Duplikate bei erneutem Seeden
Unassigned-Queue im Supporter-Dashboard: Live-Liste aller offenen, nicht zugewiesenen Tickets — sortiert nach Priorität und Eingangszeit
"Mir zuweisen" Button pro Ticket: 1-Click-Claim setzt assignedSupporterId + Status → in_progress, Erfolgs-Feedback mit Checkmark, Row verschwindet nach 1,2s
API GET /api/tls-support/tickets/unassigned: bis zu 30 Tickets ohne assignedSupporterId (status: open | unassigned) — zugänglich für tl_supporter + admin
API POST /api/tls-support/tickets/customers/[id]/claim: atomare Zuweisung des aufrufenden Supporters — 409 wenn bereits vergeben
UnassignedQueue-Komponente auch im Admin-Dashboard sichtbar — Admins können ebenfalls Tickets direkt übernehmen
Ticket-Link in der Queue direkt klickbar — Supporter können Ticket-Detail öffnen ohne zu claimen
Organizer-eigener Kiosk: Jeder Veranstalter erhält eine eigene Kiosk-URL (/kiosk/[slug]) mit individuellem Namen und PIN-Schutz
Kiosk-Einstellungen im Organizer-Dashboard: Slug, Name, PIN setzen/ändern/entfernen, Anzeige-Modus (alle Events / ein Event)
Anzeige-Modus "Nur ein Event": Organizer pinnt ein Event — Kiosk springt direkt zum Ticket-Kauf, kein Auswahlscreen
kioskEventId auf OrganizerProfile (Prisma): pinned Event — Kiosk-Events-API liefert mode: single | all
Gerät-lokaler Event-Override: Jedes Tablet kann im Settings-Panel ein eigenes Event auswählen (localEventId, localStorage) — eine Kiosk-URL, mehrere Tablets mit unterschiedlichen Events
Erweiterte Gerät-Einstellungen (localStorage, kein Reload): forceFullscreen, inactivityTimeout (Auto-Redirect), language (de/en), forcePayMethod (all/cash/card), autoPrint, receiptCopies (1/2), kioskLabel, localEventId
forcePayMethod: Kartenzahlung oder Barzahlung am Gerät erzwingen — andere Option verschwindet im Checkout, Badge "von Kiosk vorgegeben"
Inaktivitäts-Timer: Nach konfigurierten Sekunden Inaktivität automatisch zur Kiosk-Startseite zurück — Reset bei Maus/Touch/Tastatur
Bluetooth-Drucker-Suche: Web Bluetooth API scannt nach EPSON-, Bixolon-, TM-*, SRP-*-Geräten — Gerätename wird übernommen
Drucker-Modell als Serie: TM-T20 Serie, TM-T82 Serie, TM-T88 Serie, TM-m30 Serie, Bixolon SRP-350 Serie etc. statt Einzelmodelle
Kiosk-Nav im Organizer-Dashboard: "Kiosk" unter Technik-Gruppe in der Sidebar ergänzt
Addons im Kiosk: Wenn das Event Add-ons konfiguriert hat, werden diese nach der Ticket-Auswahl angezeigt (+/- Stepper, Kategorie-Badge, Verfügbarkeit)
Footer zeigt "X Tickets + Y Extras" und Gesamtpreis — Addons fließen in den Betrag ein
Neue Checkout-Seite [slug]/[eventSlug]/checkout: Routing-Fix (war falscher Pfad), liest Addons aus URL-Params, zeigt separate Extras-Sektion
bar-order API: multi-item (items[]) + addons[] — backward-kompatibel, atomare Transaktion mit TicketOrderAddon-Einträgen, sold-Decrement für Addons
Debug-Modus: Bon-Druckvorschau — Quittung mit QR-Code, jetzt auch Addon-Zeilen auf dem Bon
PIN-Schutz: SHA-256-gehashter PIN in DB, 10 Fehlversuche / 15 Min Brute-Force-Schutz, 8h Cookie je Organizer-Slug
35
Mai 2026
Sprint 35 — Multi-Provider vollständig — PayPal + Mollie in allen Flows
PayPal + Mollie vollständig in allen Checkout-Flows gleichgestellt mit Stripe: Online-Checkout, POS, Kiosk, Season Pass, Bundle
117 Bugs behoben — umfassender Provider-Bugfix-Zyklus aller Zahlungspfade
Session-Invalidierung bei Passwort-Änderung: passwordChangedAt-Check in staffHandler ergänzt (war bisher fehlend — Staff-Tokens blieben nach Passwort-Reset gültig)
Sitzplan-TOCTOU-Race-Condition: seatReservation nun via $transaction atomisch — deleteMany expired → updateMany own → createMany new, P2002 gibt 409 zurück
Admin-Audit Runde 1 (8 Bugs): Inventar-Restore-Quantity, /100-Division auf Decimal-Feldern in 7 Dateien (Preise in Euro, nicht Cent!), audit-log FK-Fehler, 2FA-Gate für Activity-Radar