# 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**
