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