Init
This commit is contained in:
996
docs/PRD.md
Normal file
996
docs/PRD.md
Normal file
@@ -0,0 +1,996 @@
|
||||
# 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
|
||||
- Anzeige von Makerspace-Jahreskarten
|
||||
- Warenkorb-Funktionalität
|
||||
- Checkout-Prozess
|
||||
- PayPal-Bezahlung
|
||||
- NAV ERP Push-Integration
|
||||
|
||||
**Out of Scope (MVP):**
|
||||
|
||||
- Rollen-System (Pädagogen, Unternehmen)
|
||||
- Pädagogische Jahreskarten
|
||||
- Genehmigungsworkflows
|
||||
- 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
|
||||
|
||||
---
|
||||
|
||||
## 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)
|
||||
- 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
|
||||
|
||||
- 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)
|
||||
|
||||
#### 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**
|
||||
Reference in New Issue
Block a user