Files
my2/docs/PRD.md
Bastian Masanek b372e2cf78 Implement shopping cart functionality with UI components and API integration
- Added CartItem, CartSummary, CartEmpty, CartSidebar, and CartSheet components for managing cart display and interactions.
- Integrated useCart and useCartUI composables for cart state management and UI control.
- Implemented API endpoints for cart operations, including fetching, adding, updating, and removing items.
- Enhanced user experience with loading states and notifications using vue-sonner for cart actions.
- Configured session management for guest and authenticated users, ensuring cart persistence across sessions.

This commit completes the shopping cart feature, enabling users to add items, view their cart, and proceed to checkout.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2025-11-03 12:43:13 +01:00

1114 lines
30 KiB
Markdown

# Product Requirements Document (PRD)
## my.experimenta.science E-Commerce App
**Version:** 1.0
**Datum:** 28. Oktober 2025
**Status:** Draft
**Autor:** experimenta Development Team
---
## 1. Executive Summary
### 1.1 Projektvision
Die **my.experimenta.science** App ist eine moderne, komponentenbasierte E-Commerce-Plattform für das experimenta Science Center. Sie soll den bestehenden Webshop zunächst ergänzen.
### 1.2 Ziele
**Primäre Ziele:**
- Vereinfachter Online-Verkauf von Makerspace-Jahreskarten
- Mobile-first Nutzererlebnis mit exzellenter Desktop-Kompatibilität
- Nahtlose Integration mit bestehenden Systemen (NAV ERP, Cidaas)
- Skalierbare Architektur für zukünftige Produkterweiterungen
**Geschäftsziele:**
- Steigerung der Online-Verkäufe durch verbesserte UX
- Reduzierung manueller Prozesse durch Automatisierung
- Erhöhung der Kundenzufriedenheit
- Grundlage für digitale Transformation des Ticketing-Systems
### 1.3 Erfolgsmetriken
- Erfolgreiche Verkäufe von Makerspace-Jahreskarten
- Conversion Rate > 3%
- Page Load Time < 2 Sekunden (mobile)
- Fehlerfreie Synchronisation mit NAV ERP
- Positive Nutzerfeedbacks
---
## 2. Produktübersicht
### 2.1 Was ist my.experimenta.science?
Eine spezialisierte E-Commerce-App, die es Besuchern des experimenta Science Centers ermöglicht, Produkte und Services online zu erwerben:
- Jahreskarten für den Makerspace
- Pädagogische Jahreskarten (Post-MVP)
- Experimenta-Tickets mit Platzreservierung (Post-MVP)
- Laborkurse für Schulen (Post-MVP)
### 2.2 Abgrenzung
**Im Scope (MVP):**
- Registrierung und Login
- Rollen-Datenstruktur (private, educator, company)
- Rollenbasierte Produktsichtbarkeit
- Anzeige von Makerspace-Jahreskarten
- Warenkorb-Funktionalität
- Checkout-Prozess
- PayPal-Bezahlung
- NAV ERP Push-Integration
**Out of Scope (MVP):**
- Rollen-Antrags-UI (Pädagogen, Unternehmen beantragen Rolle)
- Admin-Panel für Rollen-Genehmigung
- Pädagogische Jahreskarten
- Genehmigungsworkflows (UI)
- Platzreservierung
- Multi-Payment-Provider
- Laborkurse
---
## 3. Zielgruppen
### 3.1 Primäre Zielgruppe (MVP)
**Privatpersonen:**
- Besucher des experimenta Science Centers
- Interessenten am Makerspace
- Alter: 18-65 Jahre
- Technikaffinität: mittel bis hoch
- Gerät: überwiegend Smartphone, teilweise Desktop
### 3.2 Zukünftige Zielgruppen (Post-MVP)
**Pädagogen/Erzieher:**
- Lehrkräfte an Schulen
- Erzieher in Kindergärten
- Benötigen Genehmigungsprozess für vergünstigte Tickets
**Unternehmen:**
- Firmen mit Interesse an Gruppenbesuchen
- Corporate Events
- Teambuilding-Maßnahmen
### 3.3 Rollen & Berechtigungen
Das System nutzt ein rollenbasiertes Modell zur Steuerung der Produktsichtbarkeit.
#### 3.3.1 Verfügbare Rollen
**Private (Privatperson):**
- Code: `private`
- Beschreibung: Für private Besucher und Einzelpersonen
- Genehmigung: Keine Genehmigung erforderlich (auto-approved)
- Produkte: Makerspace-Jahreskarten, allgemeine Jahreskarten
**Educator (Pädagoge):**
- Code: `educator`
- Beschreibung: Für Lehrer, Erzieher und pädagogische Fachkräfte
- Genehmigung: Erforderlich (Phase 2/3)
- Produkte: Pädagogen-Jahreskarten, Makerspace-Jahreskarten
**Company (Unternehmen):**
- Code: `company`
- Beschreibung: Für Firmenkunden und B2B-Partner
- Genehmigung: Erforderlich (Phase 2/3)
- Produkte: Firmen-Jahreskarten (zukünftig)
#### 3.3.2 Produktsichtbarkeit (MVP)
**Grundprinzip:** Opt-in Sichtbarkeit
- Produkte sind NUR sichtbar, wenn explizit Rollen zugewiesen sind
- Produkte OHNE Rollenzuweisung sind für NIEMANDEN sichtbar
- User OHNE genehmigte Rolle sehen KEINE Produkte
- Unauthentifizierte User sehen KEINE Produkte
**Beispiele:**
- Makerspace-Jahreskarte → zugewiesen zu `private` + `educator` → sichtbar für beide Rollen
- Pädagogen-Jahreskarte → zugewiesen zu `educator` → nur für Pädagogen sichtbar
- Unzugewiesenes Produkt → für niemanden sichtbar
#### 3.3.3 Rollenzuweisung (MVP)
**Automatische Rollen-Zuweisung (MVP):**
- Neue User erhalten bei erster Anmeldung automatisch die Rolle `private` (Status: `approved`)
- Implementierung in `server/api/auth/login.post.ts`
- Falls ein bestehender User keine Rolle hat (z.B. Legacy-Daten), wird ebenfalls `private` zugewiesen
**Manuelle Zuweisung via Datenbank:**
- Weitere Rollen werden manuell via Drizzle Studio zugewiesen
- Status immer `approved` (keine Anträge im MVP)
**Automatische Produkt-Rollen-Zuweisung (ERP-Import):**
Beim Import von Produkten aus dem NAV ERP werden Rollen basierend auf der Kategorie automatisch zugewiesen:
| Kategorie | Zugewiesene Rollen |
|-----------|-------------------|
| `makerspace-annual-pass` | `private`, `educator` |
| `annual-pass` | `private` |
| `educator-annual-pass` | `educator` |
| `company-annual-pass` | `company` |
#### 3.3.4 Antrags-Workflow (Phase 2/3)
**Future Feature:** Benutzer können zusätzliche Rollen beantragen.
**Prozess (geplant):**
1. User navigiert zu "Profil" → "Rollen verwalten"
2. User wählt Rolle (z.B. "Pädagoge")
3. User gibt Schule/Organisation an (Freitext oder Dropdown)
4. System erstellt Antrag mit Status `pending`
5. Admin prüft Antrag im Admin-Panel
6. Admin genehmigt (`approved`) oder lehnt ab (`rejected`)
7. Bei Genehmigung: User sieht nun Produkte für diese Rolle
8. Bei Ablehnung: User kann mit korrigierten Daten erneut beantragen
**Datenbank-Vorbereitung (MVP):**
- Tabelle `user_roles` enthält bereits Felder für Antrags-Workflow:
- `status`: `pending` | `approved` | `rejected`
- `organizationName`: Name der Schule/Firma (Freitext)
- `adminNotes`: Admin-Kommentare zur Genehmigung/Ablehnung
- `statusHistory`: JSONB-Array mit Änderungshistorie
- Diese Felder sind vorbereitet, aber im MVP ungenutzt
---
## 4. User Stories & Use Cases
### 4.1 MVP User Stories
#### US-001: Benutzerregistrierung
**Als** Besucher
**möchte ich** mich mit meiner E-Mail-Adresse registrieren
**damit** ich Produkte kaufen kann
**Akzeptanzkriterien:**
- Registrierungsformular mit Feldern: E-Mail, Passwort, Vorname, Nachname
- Passwort-Anforderungen: mind. 8 Zeichen, Groß-/Kleinbuchstaben, Zahl
- Registrierung erfolgt über Cidaas Registration API
- Custom Registrierungs-Maske im experimenta Design (nicht Cidaas hosted)
- Bestätigungs-E-Mail wird von Cidaas versendet
- E-Mail muss bestätigt werden bevor Login möglich ist
- Nach erster Anmeldung wird User-Profil in lokaler DB angelegt (über OAuth2 Callback)
- **Automatische Rollen-Zuweisung**: Bei Erstellung des User-Profils wird automatisch die Rolle "Privatperson" (`private`) zugewiesen
- User erhält Fehlermeldung wenn E-Mail bereits registriert
- Validierung: Client-seitig (UX) + Server-seitig (Sicherheit)
- Übersetzung in Deutsch und Englisch
**Technische Details:**
- Custom Registrierungsseite: `/auth?tab=register`
- POST `/api/auth/register` → Cidaas Registration API
- Response: "Bitte bestätigen Sie Ihre E-Mail"
- User-Profil wird bei erstem Login erstellt (nicht bei Registrierung)
---
#### US-002: Benutzer-Login
**Als** registrierter Nutzer
**möchte ich** mich mit meinen Zugangsdaten anmelden
**damit** ich auf mein Profil und meine Bestellungen zugreifen kann
**Akzeptanzkriterien:**
- Custom Login-Maske im experimenta Design (nicht Cidaas hosted)
- Login erfolgt über OAuth2 Authorization Code Flow mit PKCE
- E-Mail-Adresse als Identifier (kein Benutzername)
- Weiterleitung zur Cidaas Login-Seite für Credential-Eingabe
- Nach erfolgreicher Authentifizierung: OAuth2 Callback
- User-Profil wird in lokaler DB erstellt (erste Anmeldung) oder aktualisiert
- Session wird erstellt (30 Tage Gültigkeit)
- Automatische Weiterleitung zur ursprünglich angeforderten Seite (oder Homepage)
- Bei fehlgeschlagenem Login: Klare Fehlermeldung
- Rate Limiting: Max. 5 Login-Versuche pro 15 Minuten
- "Passwort vergessen"-Link zu Cidaas Password Reset
**Technische Details:**
- Custom Login-Seite: `/auth?tab=login`
- OAuth2 Flow:
1. POST `/api/auth/login` → Redirect zu Cidaas
2. User authentifiziert sich bei Cidaas
3. Cidaas redirected zu `/api/auth/callback?code=xxx`
4. Server exchanged code für tokens
5. User-Profil wird aus Cidaas UserInfo geholt
6. User-Profil in DB erstellt/aktualisiert (via `experimenta_id`)
7. Encrypted session cookie gesetzt
8. Redirect zu Homepage
- Session: HTTP-only, Secure, SameSite=Lax, 30 Tage
---
#### US-002a: Benutzer-Logout
**Als** angemeldeter Nutzer
**möchte ich** mich sicher abmelden
**damit** meine Daten geschützt bleiben (besonders auf gemeinsam genutzten Geräten)
**Akzeptanzkriterien:**
- Logout-Button ist im Benutzerm enü prominent platziert
- Klick auf Logout löscht die Session sofort
- User wird zur Homepage weitergeleitet
- Session-Cookie wird vollständig entfernt
- Nach Logout ist kein Zugriff auf geschützte Bereiche mehr möglich
- Optional: Single Sign-Out bei Cidaas (Logout aus allen Apps)
**Technische Details:**
- POST `/api/auth/logout`
- `clearUserSession(event)` löscht Session-Cookie
- Redirect zu `/`
---
#### US-002b: Session-Management
**Als** angemeldeter Nutzer
**möchte ich** dass meine Session sicher verwaltet wird
**damit** ich nicht nach jeder Interaktion neu anmelden muss, aber dennoch geschützt bin
**Akzeptanzkriterien:**
- Session bleibt 30 Tage gültig (configurable)
- Session wird bei jeder Interaktion automatisch verlängert (sliding expiration)
- Session-Cookie ist verschlüsselt (AES-256-GCM)
- Session-Cookie ist HTTP-only (nicht via JavaScript auslesbar)
- Session-Cookie nur über HTTPS übertragen (Secure flag)
- CSRF-Schutz durch SameSite=Lax Cookie-Attribut
- Nach Ablauf der Session: Automatisches Logout + Weiterleitung zu `/auth`
- User sieht Meldung: "Ihre Sitzung ist abgelaufen. Bitte melden Sie sich erneut an."
**Technische Details:**
- Session Implementierung: `nuxt-auth-utils` Module
- Cookie Name: `experimenta-session`
- Verschlüsselung: AES-256-GCM via `nuxt-auth-utils`
- Max-Age: 2592000 Sekunden (30 Tage)
---
#### US-002c: Geschützte Bereiche
**Als** System
**möchte ich** dass bestimmte Bereiche nur für angemeldete Nutzer zugänglich sind
**damit** nicht-autorisierte Zugriffe verhindert werden
**Akzeptanzkriterien:**
- Geschützte Bereiche: Profil, Bestellhistorie, Checkout (teilweise)
- Unangemeldete User werden zu `/auth` weitergeleitet
- Nach erfolgreichem Login: Automatische Weiterleitung zur ursprünglich angeforderten Seite
- Ursprüngliche URL wird temporär gespeichert (max. 10 Minuten)
- API-Endpoints prüfen Session und geben 401 bei fehlender Authentifizierung
- Klare visuelle Kennzeichnung geschützter Bereiche (z.B. Schloss-Icon)
**Technische Details:**
- Middleware: `middleware/auth.ts`
- Usage: `definePageMeta({ middleware: 'auth' })`
- Redirect-Cookie: `redirect_after_login` (10min TTL)
- Protected API: `requireUserSession(event)` wirft 401
---
#### US-002d: Sicherheit & Rate Limiting
**Als** System
**möchte ich** dass Authentifizierungs-Endpoints vor Missbrauch geschützt sind
**damit** Brute-Force-Angriffe und Spam verhindert werden
**Akzeptanzkriterien:**
- Login: Max. 5 Versuche pro 15 Minuten pro IP-Adresse
- Registrierung: Max. 3 Versuche pro Stunde pro IP-Adresse
- Bei Überschreitung: HTTP 429 (Too Many Requests) mit Retry-After Header
- Klare Fehlermeldung: "Zu viele Versuche. Bitte versuchen Sie es in X Sekunden erneut."
- Rate Limit-Zähler wird bei erfolgreichem Login zurückgesetzt
- PKCE (Proof Key for Code Exchange) wird für OAuth2 verwendet
- State-Parameter schützt vor CSRF-Angriffen
- JWT-Tokens von Cidaas werden validiert (Signatur, Expiration, Issuer, Audience)
**Technische Details:**
- Rate Limiting Middleware: `server/middleware/rate-limit.ts`
- In-Memory Store für Rate Limits (Production: Redis empfohlen)
- PKCE: Code verifier (64 chars random) → SHA-256 Challenge
- State: 32 bytes random string, validiert im Callback
- JWT Validation: `jose` Library mit JWKS Caching
---
#### US-003: Makerspace-Jahreskarte ansehen
**Als** Nutzer
**möchte ich** Details zur Makerspace-Jahreskarte sehen
**damit** ich informiert eine Kaufentscheidung treffen kann
**Akzeptanzkriterien:**
- Produktseite zeigt: Name, Beschreibung, Preis, Bild
- Informationen kommen aus der lokalen DB (synchronisiert von NAV)
- Call-to-Action: "In den Warenkorb"
- Mobile-optimierte Darstellung
---
#### US-004: Produkt in den Warenkorb legen
**Als** Nutzer
**möchte ich** die Jahreskarte in den Warenkorb legen
**damit** ich sie später kaufen kann
**Akzeptanzkriterien:**
- Button "In den Warenkorb" ist prominent platziert
- Warenkorb-Icon zeigt Anzahl der Artikel
- Feedback nach Hinzufügen (z.B. Toast-Notification)
- Warenkorb ist persistent (auch nach Logout)
---
#### US-005: Warenkorb ansehen
**Als** Nutzer
**möchte ich** meinen Warenkorb einsehen und bearbeiten
**damit** ich meine Bestellung überprüfen kann
**Akzeptanzkriterien:**
- Warenkorb zeigt alle hinzugefügten Artikel
- Menge kann angepasst werden
- Artikel können entfernt werden
- Gesamtpreis wird angezeigt
- Button "Zur Kasse" führt zum Checkout
---
#### US-006: Checkout durchführen
**Als** Nutzer
**möchte ich** meine Bestellung abschließen
**damit** ich die Jahreskarte erhalte
**Akzeptanzkriterien:**
- Übersicht der Bestellung (Artikel, Preis)
- Eingabe/Bestätigung von Rechnungsdaten
- Auswahl der Zahlungsmethode (MVP: nur PayPal)
- Weiterleitung zu PayPal
- Nach erfolgreicher Zahlung: Bestätigungsseite
---
#### US-007: Bestellbestätigung erhalten
**Als** Nutzer
**möchte ich** eine Bestätigung meiner Bestellung sehen
**damit** ich weiß, dass der Kauf erfolgreich war
**Akzeptanzkriterien:**
- Bestätigungsseite mit Bestellnummer
- E-Mail mit Bestelldetails und Jahreskarte (PDF/Link)
- Bestellung wird in der Bestellhistorie angezeigt
- Daten werden an NAV ERP übermittelt
---
#### US-008: Gespeicherte Rechnungsadresse verwenden
**Als** wiederkehrender Nutzer
**möchte ich** meine Rechnungsadresse gespeichert haben
**damit** ich sie beim nächsten Kauf nicht erneut eingeben muss
**Akzeptanzkriterien:**
- Beim Checkout wird gespeicherte Adresse automatisch vorausgefüllt
- Option "Adresse für zukünftige Käufe speichern" ist beim ersten Kauf vorausgewählt
- Gespeicherte Adresse kann im Profil bearbeitet werden
- Adresse kann beim Checkout vor Abschluss editiert werden
- Im Profil unter `/profil/adresse` einsehbar und änderbar
---
### 4.2 Post-MVP User Stories
#### US-101: Rollenauswahl nach Registrierung
**Als** neuer Nutzer
**möchte ich** nach dem ersten Login meine Rolle auswählen
**damit** ich auf für mich relevante Produkte zugreifen kann
**Akzeptanzkriterien:**
- Modal/Seite zur Rollenauswahl nach erstem Login
- Optionen: Privatperson, Pädagoge/Erzieher, Unternehmen
- Auswahl wird im User-Profil gespeichert
- Pädagogen-Rolle löst Genehmigungsprozess aus
---
#### US-102: Pädagogische Jahreskarte beantragen
**Als** Pädagoge
**möchte ich** eine pädagogische Jahreskarte beantragen
**damit** ich die experimenta kostenlos besuchen kann
**Akzeptanzkriterien:**
- Antragsformular mit Nachweis (Schulnachweis, etc.)
- Status: "In Prüfung"
- Kann reservieren, aber nicht kaufen
- Benachrichtigung bei Genehmigung/Ablehnung
---
## 5. Funktionale Anforderungen
### 5.1 Authentifizierung & Benutzerverwaltung
#### F-001: Cidaas Integration
- Integration mit Cidaas über OIDC/OAuth2
- Custom Registrierungs- und Login-Masken im experimenta Design
- E-Mail-basierte Registrierung (minimal)
- Session Management
#### F-002: User-Profil Verwaltung
- User-Profile werden in lokaler PostgreSQL-DB gespeichert
- Cidaas dient nur zur Authentifizierung
- Verknüpfung über Cidaas User-ID
- Profildaten: E-Mail, Name, Adresse (für Rechnungen)
---
### 5.2 Produktverwaltung
#### F-003: Produkt-Synchronisation
- NAV ERP sendet Produktdaten per Push an Server-Endpunkt
- Endpunkt: `POST /api/erp/products`
- Produktdaten werden in lokaler DB gespeichert
- Felder: ID, Name, Beschreibung, Preis, Lagerbestand, Status
#### F-004: Produktanzeige
- Produktseite für Makerspace-Jahreskarten
- Responsives Layout (mobile-first)
- Bilder und Texte aus lokaler DB (synchronisiert via X-API)
- Preisanzeige in Euro
---
### 5.3 Warenkorb & Checkout
#### F-005: Warenkorb-Funktionalität
**Desktop Design:**
- Sidebar von rechts (400px breit)
- Kann durch Button im Header geöffnet/geschlossen werden
- Zeigt aktuelle Cart-Artikel mit Produktdetails
- Live-Summenberechnung
- Sticky Footer mit "Zur Kasse" Button
**Mobile Design:**
- FAB (Floating Action Button) mit Warenkorb-Icon
- FAB zeigt Artikelanzahl als Badge an
- Klick öffnet Bottom Sheet mit voller Cart-Anzeige
- Bottom Sheet scrollbar für lange Warenkörbe
- Bedingte FAB-Renderung: Nur auf Produktseiten wenn Cart nicht leer
**Funktionalität:**
- Session-basierter Warenkorb für nicht-angemeldete User
- DB-persistenter Warenkorb für angemeldete User
- CRUD-Operationen: Hinzufügen, Entfernen, Mengenänderung
- Warenkorb-Icon mit Badge (Artikelanzahl)
- Automatische Verfügbarkeitsprüfung
- Entfernung nicht verfügbarer Produkte
**Persistierung:**
- 30 Tage Persistierung für User-Carts (DB-gespeichert)
- 30 Tage Persistierung für Guest-Carts (session_id-basiert)
- Auto-Cleanup: Nicht verfügbare Produkte werden automatisch aus dem Warenkorb entfernt
**Rollenbasierte Sichtbarkeit:**
- Nur Produkte, die zur Rolle des Users passen, sind im Warenkorb sichtbar
- Bei Rollenwechsel werden inkompatible Produkte markiert/entfernt
**Session Management:**
- Warenkorb-ID wird in Session gespeichert
- Cart wird bei Session-Ablauf gelöscht
- Gast-Cart wird zu User-Cart migriert, wenn sich Gast anmeldet (optional)
#### F-006: Checkout-Prozess
- Schritt 1: Warenkorb-Übersicht
- Schritt 2: Rechnungsdaten
- Schritt 3: Zahlungsmethode (MVP: nur PayPal)
- Schritt 4: Bestellübersicht & Bestätigung
#### F-007: PayPal Integration
- PayPal Checkout Integration
- Redirect zu PayPal für Zahlung
- Webhook für Payment-Bestätigung
- Fehlerbehandlung bei fehlgeschlagener Zahlung
---
### 5.4 Bestellverwaltung
#### F-008: Bestellung speichern
- Bestellung wird nach erfolgreicher Zahlung in DB gespeichert
- Status: "Bezahlt", "In Bearbeitung", "Abgeschlossen"
- Bestellnummer generieren
- Timestamp & User-ID verknüpfen
#### F-009: Bestellbestätigung
- Bestätigungsseite nach erfolgreichem Kauf
- E-Mail mit Bestelldetails
- PDF-Ticket/Jahreskarte als Anhang oder Download-Link
#### F-010: Bestellhistorie
- User kann eigene Bestellungen einsehen
- Filtermöglichkeiten: Status, Datum
- Details-Ansicht pro Bestellung
---
### 5.5 ERP & API Integrationen
#### F-011: NAV ERP Push-Endpunkt
- REST-API Endpunkt: `POST /api/erp/products`
- Authentifizierung via API-Key oder OAuth
- Payload: Produktdaten (JSON)
- Validierung & Speicherung in DB
- Logging & Error Handling
#### F-012: X-API Integration
- Abruf von Veranstaltungstexten und Bildern
- Caching in lokaler DB
- Regelmäßige Synchronisation (Cronjob)
#### F-013: Bestellung an NAV senden (via X-API)
- Nach erfolgreichem Kauf: Bestellung an NAV übermitteln
- REST-API Call zu X-API Endpoint `/shopware/order`
- **Authentifizierung:** HTTP Basic Auth (Username + Password)
- X-API konvertiert JSON zu SOAP für NAV ERP
- Retry-Mechanismus bei Fehlern (exponentieller Backoff)
- Status-Tracking
- **Environments:**
- Development: `https://x-api-dev.experimenta.science`
- Staging: `https://x-api-stage.experimenta.science`
- Production: `https://x-api.experimenta.science`
---
## 6. Nicht-funktionale Anforderungen
### 6.1 Performance
- **Page Load Time:** < 2 Sekunden (mobile, 4G)
- **Time to Interactive:** < 3 Sekunden
- **API Response Time:** < 500ms (95th percentile)
- **Checkout Response:** < 1 Sekunde (nach PayPal Erfolg)
- **Concurrent Users:** 500+ gleichzeitige Nutzer
- **Queue Processing:** Order submission innerhalb 5 Minuten nach Payment
### 6.2 Skalierbarkeit
- Horizontal skalierbar (Docker Container)
- Stateless Server-Design
- DB Connection Pooling
- Redis für Caching-Strategie (Redis optional)
### 6.3 Sicherheit
- **HTTPS only** (TLS 1.3)
- **DSGVO-konform:** Datensparsamkeit, Einwilligungen, Löschkonzept
- **PCI-DSS-konform:** Keine Speicherung von Kreditkartendaten
- **Input Validation:** Alle User-Inputs validieren
- **Rate Limiting:** API-Endpunkte gegen Missbrauch schützen
- **Secrets Management:** Keine Secrets im Code (Environment Variables)
### 6.4 Verfügbarkeit
- **Uptime:** 99.5% (außer geplante Wartung)
- **Backup:** Tägliche DB-Backups
- **Disaster Recovery:** Wiederherstellung innerhalb 24h
### 6.5 Usability
- **Mobile-first Design:** Optimiert für Smartphones
- **Responsive:** Funktioniert auf allen Geräten (320px - 4K)
- **Accessibility:** WCAG 2.1 Level AA konform
- **Intuitive Navigation:** Maximal 3 Klicks zum Ziel
- **Corporate Design:** experimenta Styleguide (Farben, Fonts)
### 6.6 Wartbarkeit
- **Clean Code:** ESLint, Prettier
- **Dokumentation:** Inline-Kommentare, README
- **Testing:** Unit Tests (>80% Coverage), E2E Tests
- **CI/CD:** Automatisierte Builds & Deployments
- **Monitoring:** Logging, Error Tracking (Sentry optional)
---
## 7. User Experience & Design
### 7.1 Design-Prinzipien
- **Mobile-first:** Primär für Smartphones optimiert
- **Minimal:** Fokus auf Kernfunktionen, keine Ablenkungen
- **Schnell:** Kurze Ladezeiten, optimierte Assets
- **Konsistent:** Einheitliches Design im gesamten System
### 7.2 Corporate Design Integration
- Farben aus experimenta Styleguide
- Schriftarten aus experimenta Styleguide
- Logo-Nutzung gemäß Brand Guidelines
- Icons: Material Design Icons oder Heroicons
### 7.3 Key Screens (MVP)
#### Homepage
- Hero-Bereich mit Call-to-Action
- Makerspace-Jahreskarte prominent anzeigen
- Login/Registrierung Button (Header)
- Warenkorb-Icon (Header)
#### Produktseite
- Großes Produktbild
- Name, Beschreibung, Preis
- "In den Warenkorb" Button (sticky)
- Zusätzliche Informationen (Accordion)
#### Warenkorb
- Liste der Artikel
- Menge anpassen, entfernen
- Gesamtpreis
- "Zur Kasse" Button
#### Checkout
- Multi-Step Form (Progress Indicator)
- Rechnungsdaten (Formular)
- Zahlungsmethode (PayPal Button)
- Bestellübersicht
#### Bestätigung
- Erfolgs-Icon
- Bestellnummer
- Zusammenfassung
- Link zur Bestellhistorie
---
## 8. Technische Anforderungen
### 8.1 Tech Stack
Siehe [TECH_STACK.md](./TECH_STACK.md) für Details.
**Übersicht:**
- Frontend: Nuxt 4
- UI-Framework: Nuxt UI oder shadcn-vue
- Backend: Nuxt Server APIs
- Datenbank: PostgreSQL
- ORM: Drizzle
- Auth: Cidaas (OIDC/OAuth2)
- Payment: PayPal SDK
- Deployment: Docker, Hetzner Proxmox
- CI/CD: GitLab
### 8.2 Hosting & Infrastructure
- **Hosting:** Hetzner Dedicated Server / VPS
- **Virtualisierung:** Proxmox Container
- **Container Runtime:** Docker
- **Reverse Proxy:** Nginx oder Traefik
- **SSL:** Let's Encrypt (automatisch)
- **Domain:** my.experimenta.science
### 8.3 CI/CD Pipeline
- **Repository:** GitLab (intern gehostet)
- **Pipeline:** GitLab CI/CD
- **Deploy-Strategie:** Blue-Green oder Rolling Deployment
- **SSH-Zugang:** GitLab Runner mit SSH-Key oder Runner auf Server
- **Stages:** Build → Test → Deploy (Staging) → Deploy (Production)
---
## 9. Datenmodell (MVP)
### 9.1 Hauptentitäten
#### User
```typescript
{
id: string(UUID)
cidaas_user_id: string(unique)
email: string
first_name: string ? last_name : string ? phone : string ? created_at : timestamp
updated_at: timestamp
}
```
#### Product
```typescript
{
id: string (UUID)
nav_product_id: string (unique)
name: string
description: text
price: decimal
image_url: string?
stock: integer
status: enum (active, inactive)
created_at: timestamp
updated_at: timestamp
}
```
#### Cart
```typescript
{
id: string (UUID)
user_id: string? (FK to User, null for anonymous)
session_id: string? (for anonymous users)
created_at: timestamp
updated_at: timestamp
}
```
#### CartItem
```typescript
{
id: string (UUID)
cart_id: string (FK to Cart)
product_id: string (FK to Product)
quantity: integer
price_snapshot: decimal (Preis zum Zeitpunkt des Hinzufügens)
created_at: timestamp
}
```
#### Order
```typescript
{
id: string (UUID)
order_number: string (unique, z.B. "EXP-2025-00001")
user_id: string (FK to User)
status: enum (pending, paid, processing, completed, cancelled)
total_amount: decimal
payment_method: enum (paypal)
payment_id: string? (PayPal Transaction ID)
billing_address: jsonb
created_at: timestamp
updated_at: timestamp
}
```
#### OrderItem
```typescript
{
id: string (UUID)
order_id: string (FK to Order)
product_id: string (FK to Product)
quantity: integer
price: decimal
created_at: timestamp
}
```
---
## 10. API-Spezifikation
### 10.1 Public API Endpoints
#### Authentication
- `POST /api/auth/login` - Initiiert Cidaas Login
- `POST /api/auth/callback` - OAuth Callback von Cidaas
- `POST /api/auth/logout` - Beendet Session
#### Products
- `GET /api/products` - Liste aller aktiven Produkte
- `GET /api/products/:id` - Details zu einem Produkt
#### Cart
- `GET /api/cart` - Warenkorb abrufen
- `POST /api/cart/items` - Artikel hinzufügen
- `PATCH /api/cart/items/:id` - Menge ändern
- `DELETE /api/cart/items/:id` - Artikel entfernen
#### Orders
- `POST /api/orders` - Bestellung erstellen
- `GET /api/orders` - Bestellhistorie
- `GET /api/orders/:id` - Bestelldetails
#### Payment
- `POST /api/payment/paypal/create` - PayPal Order erstellen
- `POST /api/payment/paypal/capture` - PayPal Zahlung erfassen
- `POST /api/payment/paypal/webhook` - PayPal Webhook
---
### 10.2 Internal API Endpoints (ERP Integration)
#### NAV ERP Push
- `POST /api/erp/products` - Produkte von NAV empfangen
- `POST /api/erp/stock` - Lagerbestände aktualisieren
**Authentication:** API-Key oder OAuth Client Credentials
**Payload Example (Produkt):**
```json
{
"nav_product_id": "MS-JK-2025",
"name": "Makerspace Jahreskarte 2025",
"description": "Jahresticket für unbegrenzten Zugang zum Makerspace",
"price": 99.0,
"stock": 500,
"status": "active",
"image_url": "https://api.experimenta.science/images/ms-jk.jpg"
}
```
---
## 11. Abhängigkeiten & Risiken
### 11.1 Externe Abhängigkeiten
- **Cidaas:** Verfügbarkeit und Stabilität der Auth-Platform
- **NAV ERP:** Zuverlässigkeit der Push-Integration
- **X-API:** Verfügbarkeit der Veranstaltungsdaten
- **PayPal:** Uptime des Payment-Gateways
- **Hetzner:** Infrastruktur-Verfügbarkeit
### 11.2 Technische Risiken
- **Cidaas Integration:** Komplexität der Custom-UI Integration
- **ERP Synchronisation:** Dateninkonsistenzen, Timing-Probleme
- **Payment Failures:** Umgang mit fehlgeschlagenen Transaktionen
- **Skalierung:** Performance bei hohem Nutzeraufkommen
### 11.3 Mitigationsstrategien
- **Cidaas:** Ausführliches Testing, Fallback-Mechanismen
- **ERP:** Retry-Logik, Monitoring, manuelle Sync-Option
- **Payment:** Klare Error-Messages, Support-Kontakt prominent
- **Skalierung:** Load Testing, horizontale Skalierung vorbereiten
---
## 12. Zeitplan & Meilensteine
### 12.1 MVP (Phase 1) - 8-12 Wochen
**Sprint 1-2 (Woche 1-4): Foundation**
- Projekt-Setup (Nuxt 4, Drizzle, PostgreSQL)
- Datenbank-Schema erstellen
- Basic Layout & Routing
- Cidaas Integration (Auth)
**Sprint 3-4 (Woche 5-8): Core Features**
- Produktseite implementieren
- Warenkorb-Funktionalität
- NAV ERP Push-Endpunkt
- User-Profil
**Sprint 5-6 (Woche 9-12): Checkout & Payment**
- Checkout-Flow implementieren
- PayPal Integration
- Bestellbestätigung & E-Mail
- Testing & Bug Fixes
**Sprint 7 (Optional): Launch Preparation**
- UAT (User Acceptance Testing)
- Performance-Optimierung
- Dokumentation
- Production Deployment
---
### 12.2 Post-MVP Roadmap
**Phase 2 (Q2 2025): Pädagogen & Rollen**
- Rollen-System implementieren
- Pädagogische Jahreskarten
- Genehmigungsworkflow
- Admin-Panel (Basic)
**Phase 3 (Q3 2025): Experimenta-Tickets**
- Ticket-Varianten
- Science Dome Platzreservierung
- Kalender-Integration
- Multi-Payment-Provider
**Phase 4 (Q4 2025): Laborkurse**
- Kurs-Verwaltung
- Schulen-Accounts
- Gruppenbuchungen
- Erweiterte Reporting-Funktionen
---
## 13. Testing-Strategie
### 13.1 Test-Arten
**Unit Tests:**
- Nuxt Composables
- Utility Functions
- Drizzle Queries (Mocked)
- Ziel: >80% Coverage
**Integration Tests:**
- API Endpoints
- Database Operations
- Auth Flow
**E2E Tests:**
- User Flows (Registrierung bis Kauf)
- Payment Flow (mit Sandbox)
- Responsive Design
### 13.2 Test-Tools
- **Vitest:** Unit & Integration Tests
- **Playwright:** E2E Tests
- **MSW (Mock Service Worker):** API Mocking
- **Testing Library:** Component Tests
---
## 14. Monitoring & Support
### 14.1 Monitoring
- **Application Monitoring:** Error Tracking (Sentry optional)
- **Performance Monitoring:** Core Web Vitals
- **Uptime Monitoring:** Ping-Service
- **Logging:** Strukturiertes Logging (JSON)
### 14.2 Support
- **E-Mail-Support:** support@experimenta.science
- **FAQ-Seite:** Häufige Fragen & Antworten
- **Status-Page:** System-Status & geplante Wartungen
---
## 15. Open Questions
### 15.1 Zu klären
- [ ] Welches UI-Framework: Nuxt UI vs. shadcn-vue?
- [ ] Detailliertes Design der Custom Cidaas Login/Registrierungs-UI
- [ ] Exakte Struktur der NAV ERP Push-Payload
- [ ] X-API Dokumentation & Zugang
- [ ] E-Mail-Versand: Eigener SMTP oder Service (SendGrid, etc.)?
- [ ] Ticket-Format: PDF, QR-Code, oder anderes?
- [ ] Admin-Panel: Ab wann benötigt?
### 15.2 Entscheidungen treffen
- [ ] GitLab Runner: Auf Server oder SSH-Zugang?
- [ ] Caching-Strategie: Redis verwenden?
- [ ] Staging-Environment: Separate Instanz?
---
## 16. Glossar
| Begriff | Bedeutung |
| ---------------- | ---------------------------------------------------------- |
| **MVP** | Minimum Viable Product - Erste funktionsfähige Version |
| **NAV ERP** | Microsoft Dynamics NAV - ERP-System der experimenta |
| **X-API** | Externe API für Veranstaltungsdaten |
| **Cidaas** | Customer Identity and Access Management Platform von Widas |
| **OIDC** | OpenID Connect - Authentifizierungsprotokoll |
| **JK** | Jahreskarte |
| **MS** | Makerspace |
| **Päd. JK** | Pädagogische Jahreskarte |
| **Science Dome** | 150-Sitzer Kino/Planetarium der experimenta |
---
## 17. Anhang
### 17.1 Referenzen
- [Nuxt 4 Dokumentation](https://nuxt.com)
- [Drizzle ORM](https://orm.drizzle.team)
- [Cidaas Dokumentation](https://docs.cidaas.com)
- [PayPal Developer Docs](https://developer.paypal.com)
### 17.2 Änderungshistorie
| Version | Datum | Autor | Änderungen |
| ------- | ---------- | -------- | ---------------------- |
| 1.0 | 2025-10-28 | Dev Team | Initiales PRD erstellt |
---
**Ende des Dokuments**