huge documentaton restructure for docusaurus
This commit is contained in:
40
docs/archive/Paketbeschreibungen.txt
Normal file
40
docs/archive/Paketbeschreibungen.txt
Normal file
@@ -0,0 +1,40 @@
|
||||
🟡 Starter – Der kleine Spaßmacher
|
||||
|
||||
Ideal für Geburtstage, Gartenpartys oder Polterabende!
|
||||
Bis zu 50 Gäste teilen ihre besten Schnappschüsse, lösen 30 spannende Aufgaben und haben 14 Tage lang Zugriff auf die Online-Galerie. 300 Bilder sind inklusive – genug Platz für jede Menge Lieblingsmomente. Dein Event bekommt sein eigenes Fotospiel mit persönlicher Note!
|
||||
|
||||
🟠 Standard – Für das große Fest
|
||||
|
||||
Das Rundum-Sorglos-Paket für Hochzeiten, Firmenfeiern oder Jubiläen.
|
||||
1.000 Bilder, 150 Gäste, 100 Fotoaufgaben – und eine Galerie, die 1 Monat online bleibt.
|
||||
Du kannst sogar dein eigenes Logo oder Wasserzeichen integrieren. So bleibt jedes Bild unverwechselbar und dein Event bekommt ein individuelles Branding.
|
||||
|
||||
🔴 Premium – Für unvergessliche Events
|
||||
|
||||
Das volle Erlebnis für alle, die keine Kompromisse machen wollen.
|
||||
3.000 Bilder, bis zu 500 Gäste, 6 Monate Galerie-Zugang, 200 Aufgaben, kein Wasserzeichen und exklusive Zusatz-Features wie eine Live-Slideshow.
|
||||
Ideal für große Hochzeiten, Firmen-Events oder Festivals. Hier wird jedes Foto zum Highlight – und dein Event unvergesslich.
|
||||
|
||||
|
||||
🤝 Reseller- / Agentur-Pakete (Jahresmodell)
|
||||
|
||||
🧩 Reseller S – Für den Einstieg ins Eventgeschäft
|
||||
|
||||
Das perfekte Paket für Fotografen oder Planer, die erste Erfahrungen mit Fotospiel sammeln wollen.
|
||||
Bis zu 5 Events pro Jahr sind inklusive, jeweils mit Standard-Leistung. Einfach, flexibel und mit Branding-Optionen, die zu deinem Stil passen.
|
||||
|
||||
🎯 Reseller M – Für Profis mit regelmäßigem Einsatz
|
||||
|
||||
Wenn du regelmäßig Hochzeiten, Firmenfeste oder private Events betreust, ist dieses Paket wie für dich gemacht.
|
||||
Bis zu 15 Events pro Jahr mit Branding-Optionen, längerer Galerie-Laufzeit und vollem Zugriff auf Standard-Features. So kannst du deinen Kunden jedes Mal ein professionelles Erlebnis bieten – ohne dich um Lizenzen oder Abrechnung zu kümmern.
|
||||
|
||||
🚀 Reseller L – Für die Vielnutzer und Markenmacher
|
||||
|
||||
Ideal für Agenturen, Fotografen oder Eventdienstleister mit vielen Veranstaltungen im Jahr.
|
||||
Bis zu 40 Events inklusive, mit Premium-Leistung, White-Label-Branding und allen Funktionen. Dein Branding steht im Mittelpunkt – Fotospiel arbeitet im Hintergrund. So stärkst du deine Marke und bietest gleichzeitig ein erstklassiges digitales Erlebnis.
|
||||
|
||||
🏆 Enterprise / Unlimited – Für Marken und Großveranstalter
|
||||
|
||||
Das Rundum-Paket für Unternehmen und Agenturen, die maximale Flexibilität brauchen.
|
||||
Unbegrenzte Events, volles White-Label-Branding, eigene Subdomain oder App-Branding – ganz nach deinen Vorstellungen.
|
||||
Dieses Paket ist individuell anpassbar und bietet alle Premium-Features plus persönliche Betreuung. Perfekt für Corporate-Events, Festivals oder Franchise-Konzepte.
|
||||
12
docs/archive/README.md
Normal file
12
docs/archive/README.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Archive
|
||||
|
||||
Legacy documents that are no longer part of the active Fotospiel specification live here to keep the primary `/docs` tree focused. Nothing inside this folder should be referenced by the Docusaurus site unless explicitly linked.
|
||||
|
||||
Current contents came from the repository root and include:
|
||||
|
||||
- `fotospiel_prp.md` — monolithic pre-split PRP kept for historical reference.
|
||||
- Miscellaneous planning notes (`Paketbeschreibungen.txt`, `packages-business-model-plan.md`, `checkout wizard flow.txt`, `capacitor-tenant-app.txt`).
|
||||
- Deprecated implementation details, e.g., the `piwik-trackingcode.txt` snippet.
|
||||
- `implementation-roadmap.md` — pre-split backend roadmap kept for historical context; superseded by `docs/process/roadmap.md`.
|
||||
|
||||
Feel free to move additional legacy files here, but document them in this README when you do so future contributors understand why they’re retained.
|
||||
64
docs/archive/capacitor-tenant-app.txt
Normal file
64
docs/archive/capacitor-tenant-app.txt
Normal file
@@ -0,0 +1,64 @@
|
||||
Yes: with Capacitor you can sell one/off event packs and subscriptions inside the tenant app, but you
|
||||
must follow Apple/Google in-app purchase rules. For iOS in the U.S., digital content/services bought in-app must use
|
||||
Apple IAP; for Android on Play you must use Google Play Billing (with limited “User Choice Billing” alternatives in
|
||||
some regions). Capacitor itself is fine; you’ll integrate store billing via a plugin.
|
||||
|
||||
Policy Reality
|
||||
|
||||
- iOS: Digital content/services consumed in the app must use In‑App Purchase. Apple now documents an entitlement to
|
||||
link to your website for purchases, but usage is constrained and varies by app category/region; the safe default in
|
||||
the U.S. is native IAP for in-app purchase flows. (developer.apple.com (https://developer.apple.com/app-store/review/
|
||||
guidelines/?utm_source=openai))
|
||||
- EU nuance: Apple has been loosening anti‑steering restrictions under the DMA; in the EU developers can direct
|
||||
users to external payment with different fees, pending evolving terms. Don’t rely on this outside the EU. (apnews.com
|
||||
(https://apnews.com/article/f68dbd203284ecab38860d8da2140899?utm_source=openai), reuters.com (https://www.reuters.com/
|
||||
sustainability/boards-policy-regulation/apple-set-stave-off-daily-fines-eu-accept-app-store-changes-sources-say-2025-
|
||||
07-22/?utm_source=openai))
|
||||
- Android: Apps on Google Play that sell digital goods must use Play Billing. Google’s “User Choice Billing” allows
|
||||
an alternative in select countries (e.g., U.K.) with a 4% fee reduction; you still owe Play service fees. (blog.google
|
||||
(https://blog.google/intl/en-in/products/platforms/answering-your-faqs-about-google-play/?utm_source=openai),
|
||||
play.google.com (https://play.google.com/console/about/programs/userchoicepilot/?utm_source=openai), techcrunch.com
|
||||
(https://techcrunch.com/2025/03/28/google-rolls-out-user-choice-billing-on-google-play-in-the-uk/?utm_source=openai))
|
||||
|
||||
Is It A Good Idea?
|
||||
|
||||
- For self-serve planners: Yes—native IAP lowers friction and can lift conversion; you’ll pay store fees but get
|
||||
instant recovery, tax handling, and easy restore on new devices.
|
||||
- For photobooth operators (B2B): Often better to keep web/Invoice/Stripe as the primary channel. In the app, let them
|
||||
sign in and use existing entitlements; only expose IAP if you want true self‑serve on mobile and accept fees.
|
||||
|
||||
How To Implement With Capacitor
|
||||
|
||||
- Billing layer: Use RevenueCat’s Capacitor SDK to unify StoreKit + Play Billing, handle receipts, entitlements,
|
||||
webhooks, and “restore purchases.” This keeps your Laravel backend authoritative via webhooks. (github.com (https://
|
||||
github.com/RevenueCat/purchases-capacitor?utm_source=openai), revenuecat.com (https://www.revenuecat.com/docs/getting-
|
||||
started/installation/capacitor?utm_source=openai))
|
||||
- Product model:
|
||||
- Subscriptions: “Pro Operator” monthly/annual tiers (unlimited or quota per month).
|
||||
- Consumables: “Event Packs” (e.g., 1, 5, 20 events) as consumables on both stores.
|
||||
- Map SKUs → backend entitlements (events_remaining, max_guests, features).
|
||||
- Web checkout coexistence:
|
||||
- Web (PWA/desktop): Stripe for subscriptions and invoices.
|
||||
- Native iOS (US): Do not show external purchase links; show “Manage Subscription” (opens App Store subscription
|
||||
management) and use IAP for in‑app purchase. (developer.apple.com (https://developer.apple.com/app-store/review/
|
||||
guidelines/?utm_source=openai))
|
||||
- Native Android: Offer Play Billing; optionally add User Choice Billing where allowed. (play.google.com (https://
|
||||
play.google.com/console/about/programs/userchoicepilot/?utm_source=openai))
|
||||
|
||||
Auth and Tenancy
|
||||
|
||||
- Use token-based auth for the native app.
|
||||
- On first run, select/confirm tenant (scan domain QR), then fetch entitlements from your API after successful
|
||||
purchase webhook.
|
||||
|
||||
- Add Capacitor shell for resources/js/admin.
|
||||
- Configure RevenueCat projects and products (iOS/Android), wire webhooks to Laravel to credit entitlements.
|
||||
- Implement Purchase UI: list offerings, purchase/restore, show current plan/credits.
|
||||
- Add “Event Packs” and “Operator Pro” subscription SKUs; gate features by entitlements.
|
||||
- Compliance UX: iOS (US) avoid external pay links; Android optionally implement UCB where eligible.
|
||||
|
||||
If you want, I can draft:
|
||||
|
||||
- A SKU/entitlement map (subscriptions + event packs).
|
||||
- A Capacitor + RevenueCat integration skeleton (purchase + restore + webhook controller in Laravel).
|
||||
- A rollout plan covering EU vs US behavior and QA checklist.
|
||||
31
docs/archive/checkout wizard flow.txt
Normal file
31
docs/archive/checkout wizard flow.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
die webseite benötigt einen modernen checkout, der die seite nicht neu lädt, sondern immer nur den jeweiligen schritt anzeigt. Er soll wir ein Multi-Step Wizard aufgebaut sein. Er startet von der Paket-Auswahlseite kommend mit der bestätigung des Pakets anhand der package_id.
|
||||
Schritt 1: gewähltes Paket
|
||||
|
||||
Anzeige des ausgewählten pakets mit allen details. möglichkeit, ein anderes paket (aber nur gleichartig, also wenn das paket vom typ "endcustomer" ist, nur solche andere pakete anzeigen, wenn das Paket vom Typ "reseller" ist, nur solche pakete anzeigen).
|
||||
|
||||
schritt 2: "login" und "registrierung"
|
||||
nahtlose integration beider formular mit umschalter. Loginformular: fehleingaben sollen direkt am formular und per toast sichtbar sein. Der erfolgreiche Login sollte das sichtbare formular ersetzen mit "Sie sind nun eingeloggt" => weiter zum nächsten schritt. toast-benachrichtigung. Fehler bei der registrierung sollen im formular widergespiegelt werden. ist der nutzer angemeldet, soll beides nicht mehr sichtbar sein, sondern "Sie sind bereits eingeloggt". Eine erfolgreiche Registrierung loggt den nutzer mit status "purchase_pending" ein und leitet zu schritt 3.
|
||||
Frage klären: kann man den login oder die registrierung ersetzen durch daten von paypal/strip registrierung (callback)?
|
||||
|
||||
schritt 3: Zahlung
|
||||
pakettyp "endcustomer":
|
||||
auswahl paypal / Stripe. Buttons für "Mit Paddle bezahlen" und "Mit Stripe bezahlen" anzeigen. Der Benutzer klickt einen aus.
|
||||
Zahlungsinitierung:
|
||||
Paddle: Umleitung zu Paddle's Express Checkout (via API-Call in Laravel-Controller, z. B. create_order). Der Benutzer loggt sich bei Paddle ein, bestätigt den Einmalkauf (keine Subscription-Option). Rückleitung mit Token zur Bestätigung (Webhook oder Redirect-Handler).
|
||||
Stripe: Client-seitige Integration mit Stripe Elements (React-Komponente in Ihrer PWA). Der Benutzer gibt Kartendaten ein (ohne Umleitung), oder nutzt Stripe Checkout (hosted Page). Backend-Call zu Stripe API für PaymentIntent erstellen und bestätigen.
|
||||
Bestätigung: Nach Zahlung (z. B. 29,99 €) wird der Kauf im Backend gespeichert (z. B. TenantPackage::createPurchase()), Zugang freigeschaltet (z. B. Event-Zugriff via EventController), und der Benutzer sieht eine Erfolgsseite.
|
||||
Fehlerbehandlung: Abbruch → Zurück zur Bestellübersicht mit Fehlermeldung (z. B. "Zahlung fehlgeschlagen").
|
||||
|
||||
pakettyp "reseller":
|
||||
Paddle:
|
||||
Nutzung von Paddle Subscriptions API (in Laravel via SDK). Erstellen eines Subscription-Plans (z. B. create_subscription), Umleitung zu Paddle für Autorisierung. Der Benutzer stimmt wiederkehrenden Abbuchungen zu. Rückleitung mit Subscription-ID, die im Backend (z. B. PackagePurchases) gespeichert wird. Webhooks für Updates (z. B. Kündigung).
|
||||
Stripe:
|
||||
Erstellen eines Subscription-Plans via Stripe Dashboard/API (z. B. stripe.subscriptions.create()). Client-seitig: Stripe Elements für SetupIntent (Kartenspeicherung), dann Subscription aktivieren. Keine Umleitung nötig, wenn Sie benutzerdefinierte UI bauen. Backend-Handling für Billing-Cycles, Invoices und Webhooks (z. B. für invoice.paid).
|
||||
Bestätigung: Erste Zahlung erfolgt sofort, Subscription startet. Backend-Update: Reseller-Status aktivieren (z. B. in Tenants-Tabelle), Willkommens-E-Mail.
|
||||
Für Kündigungen: Link im profil und in der Admin-PWA (z. B. via Filament).
|
||||
Fehlerbehandlung: Bei Kartenablehnung → Retry-Option oder Wechsel zu anderem Anbieter. Proration bei Paket-Wechsel (z. B. via Stripe's Proration-Feature).
|
||||
|
||||
Schritt 4: Abschluss und bestätigen der bestellung, falls noch erforderlich.
|
||||
Bestätigungsseite mit link zum tenant-admin bereich. Ergänzen des profilmenüs um den link zum tenant-admin.
|
||||
|
||||
bei allem die lokalisierung beachten
|
||||
176
docs/archive/implementation-roadmap.md
Normal file
176
docs/archive/implementation-roadmap.md
Normal file
@@ -0,0 +1,176 @@
|
||||
### Update 2025-10-21
|
||||
- Phase 3 credit scope delivered: tenant event creation now honours package allowances *and* credit balances (middleware + ledger logging), RevenueCat webhook signature checks ship with queue/backoff + env config, idempotency covered via unit tests.
|
||||
- Follow-up (separate): evaluate photo upload quota enforcement + SuperAdmin ledger visualisations once package analytics stabilise.
|
||||
|
||||
### Upcoming (Next Weeks — Security Hardening)
|
||||
- Week 1
|
||||
- `SEC-IO-01` dual-key rollout playbook.
|
||||
- `SEC-GT-01` hashed join tokens migration.
|
||||
- `SEC-API-01` signed asset URLs.
|
||||
- `SEC-MS-01` AV/EXIF worker integration.
|
||||
- `SEC-BILL-01` checkout session linkage.
|
||||
- `SEC-FE-01` CSP nonce utility.
|
||||
- Week 2
|
||||
- `SEC-IO-02` refresh-token management UI. *(delivered 2025-10-23)*
|
||||
- `SEC-GT-02` token analytics dashboards.
|
||||
- `SEC-API-02` incident response playbook.
|
||||
- `SEC-MS-02` streaming upload refactor.
|
||||
- `SEC-BILL-02` webhook signature freshness.
|
||||
- `SEC-FE-02` consent-gated analytics loader.
|
||||
- Week 3
|
||||
- `SEC-IO-03` subnet/device configuration.
|
||||
- `SEC-GT-03` gallery rate-limit alerts.
|
||||
- `SEC-API-03` synthetic monitoring.
|
||||
- `SEC-MS-03` checksum validation alerts.
|
||||
- `SEC-BILL-03` failed capture notifications.
|
||||
- `SEC-FE-03` cookie banner localisation refresh.
|
||||
- Week 4
|
||||
- `SEC-MS-04` storage health dashboard widget (Media Services).
|
||||
|
||||
# Backend-Erweiterung Implementation Roadmap (Aktualisiert: 2025-09-15 - Fortschritt)
|
||||
|
||||
## Implementierungsstand (Aktualisiert: 2025-09-15)
|
||||
Basierend auf aktueller Code-Analyse und Implementierung:
|
||||
- **Phase 1 (Foundation)**: ✅ Vollständig abgeschlossen – Migrationen ausgeführt, Sanctum konfiguriert, OAuthController (PKCE-Flow, JWT), Middleware (TenantTokenGuard, TenantIsolation) implementiert und registriert.
|
||||
- **Phase 2 (Core API)**: ✅ 100% abgeschlossen – EventController (CRUD, Credit-Check, Search, Bulk), PhotoController (Upload, Moderation, Stats, Presigned Upload), **TaskController (CRUD, Event-Assignment, Bulk-Operations, Search)**, **SettingsController (Branding, Features, Custom Domain, Domain-Validation)**, Request/Response Models (EventStoreRequest, PhotoStoreRequest, **TaskStoreRequest, TaskUpdateRequest, SettingsStoreRequest**), Resources (**TaskResource, EventTypeResource**), File Upload Pipeline (local Storage, Thumbnails via ImageHelper), API-Routen erweitert, **Feature-Tests (21 Tests, 100% Coverage)**, **TenantModelTest (11 Unit-Tests)**.
|
||||
- **Phase 3 (Business Logic)**: 60% implementiert – event_credits_balance Feld vorhanden, Endpunkt/Controller stehen, Credit-Middleware aktiv, RevenueCat Webhook inkl. Queue/Retries produktionsreif; Token-Rotation folgt.
|
||||
- **Phase 4 (Admin & Monitoring)**: 45% implementiert – **TenantResource erweitert (credits, features, activeSubscription)**, PurchaseHistory/OAuthClient-Management sowie Dashboard-Widgets fertig; verbleibend sind Advanced Actions (subscription_tier) und erweiterte Monitoring-Policies.
|
||||
|
||||
**Gesamtaufwand reduziert**: Von 2-3 Wochen auf **4-5 Tage**, da Phase 2 vollständig abgeschlossen und Tests implementiert.
|
||||
|
||||
## Phasenübersicht
|
||||
|
||||
| Phase | Fokus | Dauer | Dependencies | Status | Milestone |
|
||||
|-------|-------|-------|--------------|--------|-----------|
|
||||
| **Phase 1: Foundation** | Database & Authentication | 0 Tage | Laravel Sanctum/Passport | Vollständig abgeschlossen | OAuth-Flow funktioniert, Tokens validierbar |
|
||||
| **Phase 2: Core API** | Tenant-spezifische Endpunkte | 0 Tage | Phase 1 | ✅ 100% abgeschlossen | CRUD für Events/Photos/Tasks, Settings, Upload, Tests (100% Coverage) |
|
||||
| **Phase 3: Business Logic** | Freemium & Security | 3-4 Tage | Phase 2 | 30% implementiert | Credit-System aktiv, Rate Limiting implementiert |
|
||||
| **Phase 4: Admin & Monitoring** | SuperAdmin & Analytics | 4-5 Tage | Phase 3 | In Arbeit | Filament-Resources erweitert, Dashboard funktioniert |
|
||||
|
||||
## Phase 1: Foundation (Abgeschlossen)
|
||||
### Status: Vollständig implementiert
|
||||
- [x] DB-Migrationen ausgeführt (OAuth, PurchaseHistory, Subscriptions)
|
||||
- [x] Models erstellt (OAuthClient, RefreshToken, TenantToken, PurchaseHistory)
|
||||
- [x] Sanctum konfiguriert (api guard, HasApiTokens Trait)
|
||||
- [x] OAuthController implementiert (authorize, token, me mit PKCE/JWT)
|
||||
- [x] Middleware implementiert (TenantTokenGuard, TenantIsolation)
|
||||
- [x] API-Routen mit Middleware geschützt
|
||||
- **Testbar**: OAuth-Flow funktioniert mit Postman
|
||||
|
||||
## Phase 2: Core API (80% abgeschlossen, 2-3 Tage verbleibend)
|
||||
### Ziele
|
||||
- Vollständige tenant-spezifische API mit CRUD für Events, Photos, Tasks
|
||||
- File Upload Pipeline mit Moderation
|
||||
|
||||
### Implementierter Fortschritt
|
||||
- [x] EventController: CRUD, Credit-Check, Search, Bulk-Update
|
||||
- [x] PhotoController: Upload, Moderation (bulk approve/reject), Stats, Presigned Upload
|
||||
- [x] **TaskController**: CRUD, Event-Assignment, Bulk-Operations, Search/Filter
|
||||
- [x] **SettingsController**: Branding, Features, Custom Domain, Domain-Validation, Reset
|
||||
- [x] Request Models: EventStoreRequest, PhotoStoreRequest, **TaskStoreRequest, TaskUpdateRequest, SettingsStoreRequest**
|
||||
- [x] Response Resources: EventResource, PhotoResource, **TaskResource, EventTypeResource**
|
||||
- [x] File Upload: Local Storage, Thumbnail-Generation (ImageHelper)
|
||||
- [x] API-Routen: Events/Photos/Tasks/Settings (tenant-scoped, slug-basiert)
|
||||
- [x] Pagination, Filtering, Search, Error-Handling
|
||||
- [x] **Feature-Tests**: 21 Tests (SettingsApiTest: 8, TaskApiTest: 13, 100% Coverage)
|
||||
- [x] **Unit-Tests**: TenantModelTest (11 Tests für Beziehungen, Attribute, Methoden)
|
||||
|
||||
### Verbleibende Tasks
|
||||
- Phase 2 vollständig abgeschlossen
|
||||
|
||||
### Milestones
|
||||
- [x] Events/Photos Endpunkte funktionieren
|
||||
- [x] Photo-Upload und Moderation testbar
|
||||
- [x] Task/Settings implementiert (CRUD, Assignment, Branding, Custom Domain)
|
||||
- [x] Vollständige Testabdeckung (>90%)
|
||||
|
||||
## Phase 3: Business Logic (30% implementiert, 3-4 Tage)
|
||||
### Ziele
|
||||
- Freemium-Modell vollständig aktivieren
|
||||
- Credit-Management, Webhooks, Security
|
||||
|
||||
### Implementierter Fortschritt
|
||||
- [x] Credit-Feld in Tenant-Model mit `event_credits_balance`
|
||||
- [x] **Tenant::decrementCredits()/incrementCredits() Methoden** inkl. Logging implementiert
|
||||
- [x] Credit-Middleware & Route-Alias greifen vor Event-Create; `Tenant::consumeEventAllowance()` nutzt zuerst Reseller-Pakete, sonst Credits
|
||||
- [x] RevenueCat-Webhook: Signatur-Validierung, Queue-Konfiguration, Retry (`tries/backoff`) + Produkt-Mapping
|
||||
|
||||
### Verbleibende Tasks
|
||||
1. **Security Implementation (1 Tag)**
|
||||
- Rate Limiting: 100/min tenant API, 20/min tenant-auth login/exchange *(aktiv)*
|
||||
- Token issuance handled by Sanctum PAT endpoints; rotation via PAT revocation *(aktiv)*
|
||||
- IP-Binding für Refresh Tokens *(konfigurierbar, Subnetzrelax optional)*
|
||||
|
||||
### Milestones
|
||||
- [x] Credit-Check funktioniert (Event-Create scheitert bei 0)
|
||||
- [x] Webhooks verarbeiten Purchases
|
||||
- [x] Rate Limiting aktiv
|
||||
- [x] Token-Rotation implementiert
|
||||
|
||||
## Phase 4: Admin & Monitoring (In Arbeit, 4-5 Tage)
|
||||
### Ziele
|
||||
- SuperAdmin-Funktionen erweitern
|
||||
- Analytics Dashboard, Testing
|
||||
|
||||
### Implementierter Fortschritt
|
||||
- [x] **TenantResource erweitert**: credits, features, activeSubscription Attribute
|
||||
- [x] **TenantModelTest**: 11 Unit-Tests für Beziehungen (events, photos, purchases), Attribute, Methoden
|
||||
- [x] PurchaseHistoryResource, OAuthClientResource, Widgets, Policies
|
||||
|
||||
### Verbleibende Tasks
|
||||
1. **Filament Resources erweitern (2 Tage)**
|
||||
- TenantResource: subscription_tier, Actions (add_credits, suspend), RelationsManager *(Credits-Aktion fertig; subscription_tier-Actions noch offen)*
|
||||
- PurchaseHistoryResource: CRUD, Filter, Export, Refund *(CRUD & Export umgesetzt; Refund via UI noch offen)*
|
||||
- OAuthClientResource: Client-Management *(implementiert)*
|
||||
- TenantPolicy mit superadmin before() *(implementiert)*
|
||||
|
||||
2. **Dashboard Widgets (1 Tag)**
|
||||
- RevenueChart, TopTenantsByRevenue, CreditAlerts
|
||||
|
||||
3. **Admin Actions & Middleware (1 Tag)**
|
||||
- SuperAdminMiddleware, manuelle Credit-Zuweisung
|
||||
- Bulk-Export, Token-Revoke
|
||||
|
||||
4. **Testing & Deployment (1 Tag)**
|
||||
- Unit/Feature-Tests für alle Phasen
|
||||
- Deployment-Skript, Monitoring-Setup
|
||||
|
||||
### Milestones
|
||||
- [x] TenantResource basis erweitert
|
||||
- [x] PurchaseHistoryResource funktioniert
|
||||
- [x] Widgets zeigen Stats
|
||||
- [x] Policies schützen SuperAdmin
|
||||
- [ ] >80% Testabdeckung
|
||||
|
||||
## Gesamter Zeitplan
|
||||
|
||||
| Woche | Phase | Status |
|
||||
|-------|-------|--------|
|
||||
| **1** | Foundation | ✅ Abgeschlossen |
|
||||
| **1** | Core API | ✅ Abgeschlossen |
|
||||
| **2** | Business Logic | 40% â³ In Arbeit |
|
||||
| **2** | Admin & Monitoring | 45% ✅ In Arbeit |
|
||||
|
||||
**Gesamtdauer:** **4-5 Tage** - Phase 2 vollständig abgeschlossen, Tests implementiert
|
||||
**Kritische Pfade:** Phase 3 (Business Logic) kann sofort starten
|
||||
**Parallelisierbarkeit:** Phase 4 (Admin) parallel zu Phase 3 (Webhooks/Credits) möglich
|
||||
|
||||
## Risiken & Mitigation
|
||||
|
||||
| Risiko | Wahrscheinlichkeit | Impact | Mitigation |
|
||||
|--------|--------------------|--------|------------|
|
||||
| File Upload Performance | Mittel | Mittel | Local Storage optimieren, später S3 migrieren |
|
||||
| OAuth Security | Niedrig | Hoch | JWT Keys rotieren, Security-Review |
|
||||
| Credit-Logik-Fehler | Niedrig | Hoch | Unit-Tests, Manual Testing mit Credits |
|
||||
| Testing-Abdeckung | Mittel | Mittel | Priorisiere Feature-Tests für Core API |
|
||||
|
||||
## Nächste Schritte
|
||||
1. **Phase 3 Business Logic (2-3 Tage)**: CreditMiddleware, CreditController, Webhooks
|
||||
2. **Phase 4 Admin & Monitoring (2 Tage)**: PurchaseHistoryResource, Widgets, Policies
|
||||
3. **Stakeholder-Review**: OAuth-Flow, Upload, Task/Settings testen
|
||||
4. **Development Setup**: Postman Collection für API, Redis/S3 testen
|
||||
5. **Final Testing**: 100% Coverage, Integration Tests
|
||||
6. **Deployment**: Staging-Environment, Monitoring-Setup
|
||||
|
||||
**Gesamtkosten:** Ca. 60-100 Stunden (weit reduziert durch bestehende Basis).
|
||||
**Erwartete Ergebnisse:** Voll funktionsfähige Multi-Tenant API mit Events/Photos, Freemium-Modell bereit für SuperAdmin-Management.
|
||||
244
docs/archive/packages-business-model-plan.md
Normal file
244
docs/archive/packages-business-model-plan.md
Normal file
@@ -0,0 +1,244 @@
|
||||
# Fotospiel: Umstellung auf Package-basiertes Business Model – Detaillierter Plan
|
||||
|
||||
**Datum:** 2025-09-26
|
||||
**Version:** 1.0
|
||||
**Autor:** Kilo Code (Architect Mode)
|
||||
**Status:** Finaler Plan für Review und Implementation in Code-Mode.
|
||||
**Ziel:** Ersetze das aktuelle Credits-basierte Freemium-Modell (One-off-Käufe via Stripe/RevenueCat, Balance-Checks) durch ein package-basiertes Modell mit vordefinierten Bündeln (Einmalkäufe pro Event für Endkunden, jährliche Subscriptions für Reseller/Agenturen). Der Plan deckt Analyse, Design, Änderungen in DB/Code/UI/Billing, Lücken und Rollout ab. Alle Details basieren auf User-Feedback und Best Practices für Laravel 12, Filament 4, React/Vite PWA.
|
||||
|
||||
## 1. Analyse des Aktuellen Modells
|
||||
Das bestehende Modell ist Credits-basiert (Freemium mit 1 Free-Credit, One-off-Käufen für Events). Subscriptions sind deferred (nicht implementiert).
|
||||
|
||||
### Betroffene Komponenten:
|
||||
- **DB:**
|
||||
- Felder: `event_credits_balance` (in `tenants`, default 1), `subscription_tier`/`subscription_expires_at` (in `tenants`).
|
||||
- Tabellen: `event_purchases` (Käufe), `event_credits_ledger` (Transaktionen), `purchase_history` (IAP-Historie).
|
||||
- **Code (Backend):**
|
||||
- Models: `Tenant::decrementCredits()`/`incrementCredits()`.
|
||||
- Controllers: `EventController` (Credit-Check bei Create), `CreditController` (Balance/Purchase).
|
||||
- Middleware: `CreditMiddleware` (prüft Balance >=1 für Events).
|
||||
- Filament: `TenantResource` (credits-Column, add_credits-Action), `PurchaseHistoryResource` (CRUD/Refund).
|
||||
- **API:** Endpunkte `/api/v1/tenant/credits/balance`, `/credits/ledger`, `/credits/purchase`, `/credits/sync`, `/purchases/intent`.
|
||||
- **Frontend (Admin PWA):** Dashboard-Cards für Balance, Kauf-Integration (RevenueCat).
|
||||
- **Guest PWA:** Keine direkten Checks (Backend-handhabt).
|
||||
- **Billing:** Stripe (Checkout/Webhooks), RevenueCat (IAP), PaddleWebhookController (teilweise).
|
||||
- **Tests:** `RevenueCatWebhookTest`, Credit-Unit-Tests.
|
||||
- **Docs:** PRP 08-billing.md (Credits-MVP), 14-freemium-business-model.md (IAP-Struktur), API-Specs (credits-Endpunkte).
|
||||
- **Lücken im Aktuellen:** Keine Package-Limits (nur Balance), Subscriptions nicht live, Paddle untergenutzt.
|
||||
|
||||
**Auswirkungen:** Vollständige Ersetzung, um Flexibilität (Limits/Features pro Package) zu ermöglichen.
|
||||
|
||||
## 2. Neues Package-basiertes Modell
|
||||
Packages ersetzen Credits: Vordefinierte Bündel mit Limits/Features. Kauf bei Event-Create (Endkunden) oder Tenant-Upgrade (Reseller). Freemium: Free/Test-Paket für Einstieg.
|
||||
|
||||
### Endkunden-Pakete (Einmalkäufe pro Event)
|
||||
| Paket | Preis | max_photos | max_guests | gallery_days | max_tasks | watermark | branding | Features |
|
||||
|-----------|-------|------------|------------|--------------|-----------|-----------|----------|----------|
|
||||
| Free/Test | 0 € | 30 | 10 | 3 | 1 | Standard | Nein | - |
|
||||
| Starter | 19 € | 300 | 50 | 14 | 5 | Standard | Nein | - |
|
||||
| Standard | 39 € | 1000 | 150 | 30 | 10 | Custom | Ja | Logo |
|
||||
| Premium | 79 € | 3000 | 500 | 180 | 20 | Kein | Ja | Live-Slideshow, Analytics |
|
||||
|
||||
### Reseller/Agentur-Pakete (Jährliche Subscriptions)
|
||||
| Paket | Preis/Jahr | max_events/year | Per-Event Limits | Branding | Extra |
|
||||
|------------|------------|-----------------|------------------|----------|-------|
|
||||
| Reseller S | 149 € | 5 | Standard | Eingeschränkt | - |
|
||||
| Reseller M | 299 € | 15 | Standard | Eigene Logos | 3 Monate Galerie |
|
||||
| Reseller L | 599 € | 40 | Premium | White-Label | - |
|
||||
| Enterprise | ab 999 € | Unlimited | Premium | Voll | Custom Domain, Support |
|
||||
|
||||
**Flow:** Event-Create: Package wählen → Kauf (Free: direkt; Paid: Checkout) → Limits für Event setzen. Reseller: Tenant-Package limitiert Events/Features global.
|
||||
|
||||
## 3. DB-Schema & Migrationen
|
||||
### Neue Tabellen (Migration: create_packages_tables.php)
|
||||
#### packages (global)
|
||||
```php
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->enum('type', ['endcustomer', 'reseller']);
|
||||
$table->decimal('price', 8, 2);
|
||||
$table->integer('max_photos')->nullable();
|
||||
$table->integer('max_guests')->nullable();
|
||||
$table->integer('gallery_days')->nullable();
|
||||
$table->integer('max_tasks')->nullable();
|
||||
$table->boolean('watermark_allowed')->default(true);
|
||||
$table->boolean('branding_allowed')->default(false);
|
||||
$table->integer('max_events_per_year')->nullable();
|
||||
$table->timestamp('expires_after')->nullable(); // Für Subscriptions
|
||||
$table->json('features')->nullable(); // ['live_slideshow', 'analytics']
|
||||
$table->timestamps();
|
||||
$table->index(['type', 'price']); // Für Queries
|
||||
```
|
||||
|
||||
#### event_packages (pro Event)
|
||||
```php
|
||||
$table->id();
|
||||
$table->foreignId('event_id')->constrained()->cascadeOnDelete();
|
||||
$table->foreignId('package_id')->constrained()->cascadeOnDelete();
|
||||
$table->decimal('purchased_price', 8, 2);
|
||||
$table->timestamp('purchased_at');
|
||||
$table->integer('used_photos')->default(0); // Counter
|
||||
$table->timestamps();
|
||||
$table->index('event_id');
|
||||
```
|
||||
|
||||
#### tenant_packages (Reseller)
|
||||
```php
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->constrained()->cascadeOnDelete();
|
||||
$table->foreignId('package_id')->constrained()->cascadeOnDelete();
|
||||
$table->decimal('price', 8, 2);
|
||||
$table->timestamp('purchased_at');
|
||||
$table->timestamp('expires_at');
|
||||
$table->integer('used_events')->default(0);
|
||||
$table->boolean('active')->default(true);
|
||||
$table->timestamps();
|
||||
$table->index(['tenant_id', 'active']);
|
||||
```
|
||||
|
||||
#### package_purchases (Ledger)
|
||||
```php
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->nullable()->constrained();
|
||||
$table->foreignId('event_id')->nullable()->constrained();
|
||||
$table->foreignId('package_id')->constrained();
|
||||
$table->string('provider_id'); // Paddle ID
|
||||
$table->decimal('price', 8, 2);
|
||||
$table->enum('type', ['endcustomer_event', 'reseller_subscription']);
|
||||
$table->json('metadata'); // {event_id, ip_address}
|
||||
$table->string('ip_address')->nullable();
|
||||
$table->string('user_agent')->nullable();
|
||||
$table->boolean('refunded')->default(false);
|
||||
$table->timestamps();
|
||||
$table->index(['tenant_id', 'purchased_at']);
|
||||
```
|
||||
|
||||
### Migration-Strategie (php artisan make:migration migrate_to_packages)
|
||||
- **Schritt 1:** Neue Tabellen erstellen + Seeder für Standard-Packages (php artisan make:seeder PackageSeeder).
|
||||
- **Schritt 2:** Daten-Transfer (Artisan-Command packages:migrate):
|
||||
- Tenants: if event_credits_balance > 0 → Zuweisen zu Free-Paket (insert tenant_packages mit expires_at = now() + 30 days); alte Balance zu used_events konvertieren (z.B. balance / 100 = initial events).
|
||||
- Events: Bestehende Events zu Test-Paket migrieren (insert event_packages).
|
||||
- Ledger: Transfer event_purchases zu package_purchases (map credits_added zu package_id = 'free').
|
||||
- **Schritt 3:** Alte Felder/Tabellen droppen (in separater Migration, nach Backup).
|
||||
- **Rollback:** php artisan migrate:rollback --step=3; Restore aus Backup.
|
||||
- **Performance:** Transactions für Migration; Cache::flush() nach.
|
||||
|
||||
## 4. Filament 4 Resources (Backend-Logik, Todo 6)
|
||||
- **PackageResource (app/Filament/Resources/PackageResource.php, SuperAdmin):**
|
||||
- Form: TextInput('name'), Select('type'), MoneyInput('price'), NumericInputs für Limits, Toggles für watermark/branding, Repeater('features'), Numeric('max_events_per_year').
|
||||
- Table: TextColumn('name'), BadgeColumn('type'), MoneyColumn('price'), IconColumn('limits' – z.B. CameraIcon für max_photos), Actions (Edit/Delete/Duplicate).
|
||||
- Pages: ListPackages, CreatePackage, EditPackage.
|
||||
- Policy: SuperAdmin only.
|
||||
|
||||
- **TenantPackageResource (SuperAdmin/TenantAdmin):**
|
||||
- Form: Select('tenant_id'), Select('package_id'), DateTimePicker('purchased_at'), DateTimePicker('expires_at'), TextInput('used_events', readOnly), Toggle('active').
|
||||
- Table: TextColumn('tenant.name'), BadgeColumn('package.name'), DateColumn('expires_at', color: expired → danger), ProgressColumn('used_events' / max_events), Actions (Renew: set expires_at +1 year, Cancel: active=false + Paddle cancel).
|
||||
- Relations: BelongsTo Tenant/Package, HasMany Events (RelationManager mit Event-List).
|
||||
- Bulk-Actions: Renew Selected.
|
||||
|
||||
- **PurchaseResource (SuperAdmin/TenantAdmin):**
|
||||
- Form: Select('tenant_id/event_id'), Select('package_id'), TextInput('provider_id'), MoneyInput('price'), Select('type'), JSONEditor('metadata'), Toggle('refunded').
|
||||
- Table: BadgeColumn('type'), LinkColumn('tenant' or 'event'), TextColumn('package.name/price'), DateColumn('purchased_at'), BadgeColumn('status' – paid/refunded), Actions (View, Refund: Call Paddle API, decrement counters, log).
|
||||
- Filters: SelectFilter('type'), DateRangeFilter('purchased_at'), TenantFilter.
|
||||
- Widgets: StatsOverview (Total Revenue, Monthly Purchases, Top Package), ChartWidget (Revenue over Time via Laravel Charts).
|
||||
- Export: CSV (für Buchhaltung: tenant, package, price, date).
|
||||
|
||||
**Integration:** Ersetze add_credits in TenantResource durch 'Assign Package'-Action (modal mit Select + Intent-Call). Policies: Role-based (superadmin full, tenant_admin own).
|
||||
|
||||
## 5. Marketing- und Legal-Anpassungen (Todo 4)
|
||||
- **Webfrontend (Blade, resources/views/marketing/):**
|
||||
- **packages.blade.php (neu, Route /packages):** Hero ("Entdecken Sie unsere Packages"), Tabs (Endkunden/Reseller), Tabelle/Accordion mit Details (Preis, Limits als Icons, Features-Bullets, i18n-Übersetzungen). CTA: "Kaufen" → /checkout/{id}. Dynamisch: @foreach(Package::where('type', 'endcustomer')->get() as $package).
|
||||
- **checkout.blade.php (neu, Route /checkout/{package_id}):** Summary-Box (Package-Details), Form (Name, E-Mail, Adresse für Reseller), Zahlungsoptionen (Radio: Paddle), Stripe-Element/Paddle-Button. Submit: POST /purchases/intent → Redirect. Tailwind: Secure-Design mit Badges.
|
||||
- **success.blade.php:** "Vielen Dank! Package {name} gekauft." Details (Limits, Event-Link), Upsell ("Upgrade zu Reseller?"), Rechnung-Download (PDF via Dompdf), Onboarding-Tour-Link.
|
||||
- **marketing.blade.php:** Teaser-Section mit Package-Icons/Preisen, Link zu /packages.
|
||||
- **occasions.blade.php/blog*.blade.php:** Kontextuelle Erwähnungen (z.B. "Ideal für Partys: Starter-Paket"), Blog-Post "Neues Package-Modell" mit FAQ.
|
||||
|
||||
- **Legal (resources/views/legal/):**
|
||||
- **datenschutz.blade.php:** Abschnitt "Zahlungen" (Paddle: Keine Karten-Speicherung, GDPR: Löschung nach 10 Jahren; Consent für E-Mails). "Package-Daten (Limits) sind anonymisiert."
|
||||
- **impressum.blade.php:** "Monetarisierung: Packages via Paddle; USt-ID: ...; Support: support@fotospiel.de".
|
||||
- **Allgemein:** Datum "Aktualisiert: 2025-09-26 – Package-Modell"; Links zu Provider-Datenschutz.
|
||||
|
||||
**i18n:** Translations in lang/de/en (z.B. 'package.starter' → 'Starter-Paket').
|
||||
|
||||
## 6. Backend-Logik & API (Todo 6/7)
|
||||
- **Controllers:**
|
||||
- `PackagesController` (index: Liste mit Cache, show: Details, store: Intent für Kauf).
|
||||
- `PurchasesController` (intent: Erstelle Stripe-Session oder Paddle-Order basierend auf method; store: Nach Webhook).
|
||||
- **Middleware:** `PackageMiddleware` (für Events: Check event_packages.used_photos < max_photos; für Tenant: used_events < max_events_per_year).
|
||||
- **Models:** `Package` (Relationships: hasMany EventPackage/TenantPackage), `EventPackage` (incrementUsedPhotos-Method), `TenantPackage` (isActive-Scope, Observer für Expiry: E-Mail + active=false).
|
||||
- **API-Endpunkte (routes/api.php, tenant-group):**
|
||||
- GET /packages (Liste, filter by type).
|
||||
- GET /packages/{id} (Details).
|
||||
- POST /packages/purchase (Body: package_id, type, event_id?; Response: {checkout_url, provider}).
|
||||
- GET /tenant/packages (Active Package, Purchases-List).
|
||||
- POST /tenant/packages/assign (Free-Zuweisung).
|
||||
- DELETE /credits/* (entfernen, 404-redirect).
|
||||
- Tokens: Füge 'package_info' (JSON: active_package_id) zu JWT-Claims hinzu (via Sanctum).
|
||||
- **Jobs:** `ProcessPackagePurchase` (nach Webhook: Zuweisen, E-Mail, Analytics-Event).
|
||||
|
||||
## 7. Frontend-Anpassungen (Todo 8/9)
|
||||
- **Admin PWA (resources/js/admin/):**
|
||||
- EventFormPage.tsx: Select('package_id') mit Details-Modal (Limits/Preis), Button 'Kaufen' → Paddle-Integration (stripe.elements oder Paddle-Button).
|
||||
- Dashboard: Card 'Aktuelles Package' (Limits, Expiry, Upgrade-Button).
|
||||
- SettingsPage.tsx: Reseller-Übersicht (used_events/Progress, Renew-Button).
|
||||
- Hooks: usePackageLimits (fetch /packages, check used_photos).
|
||||
- **Guest PWA (resources/js/guest/):**
|
||||
- EventDetailPage.tsx: Header "Package: Premium – {used_photos}/{max_photos} Fotos, Galerie bis {date}".
|
||||
- Upload-Component: If used_photos >= max_photos → Disable + Message "Limit erreicht – Upgrade via Admin".
|
||||
- Features: Watermark-Overlay if watermark_allowed; Branding-Logo if branding_allowed.
|
||||
- Router: Guard für Limits (z.B. /upload → Check API).
|
||||
|
||||
**Tech:** React Query für API-Calls, Stripe.js/Paddle-SDK in Components, i18n mit react-i18next.
|
||||
|
||||
## 8. Billing-Integration (Todo 10)
|
||||
- **Provider:** Stripe (Primär: Einmalkäufe/Subscriptions) + Paddle (Alternative: PHP SDK für Orders/Subscriptions).
|
||||
- **Flow:** Auswahl → Intent (Controller: if 'stripe' → Stripe::checkout()->sessions->create([...]); if 'paypal' → Paddle::orders()->create([...]) ) → Redirect → Webhook (verifiziert, insert package_purchases, assign Package, E-Mail).
|
||||
- **Webhooks:** StripeWebhookController (neue Events: checkout.session.completed → ProcessPurchase), PaddleWebhookController (erweitert: PAYMENT.CAPTURE.COMPLETED → ProcessPurchase).
|
||||
- **SDKs:** composer require stripe/stripe-php ^10.0, paypal/rest-api-sdk-php ^1.14; NPM: @stripe/stripe-js, @paypal/react-paypal-js.
|
||||
- **Free:** Kein Provider – direkt assign via API.
|
||||
- **Refunds:** Action in PurchaseResource: Call Stripe::refunds->create oder Paddle::refunds, decrement Counters.
|
||||
- **Env:** STRIPE_KEY/SECRET, PAYPAL_CLIENT_ID/SECRET, SANDBOX-Flags.
|
||||
|
||||
## 9. Tests (Todo 11)
|
||||
- **Unit/Feature:** Pest/PHPUnit: Test PackageSeeder, Migration (assert Tables exist), Controllers (mock Paddle SDKs mit Stripe::mock(), test Intent/Webhook), Models (Package::find(1)->limits, TenantPackage::isActive), Middleware (assert denies if limit exceeded).
|
||||
- **E2E (Playwright):** Test Kauf-Flow (navigate /packages, select Starter, choose Paddle, complete sandbox, assert success.blade.php), Limits (upload photo, assert counter +1, deny at max).
|
||||
- **Anpassungen:** RevenueCatWebhookTest → PaddleWebhookTest; Add PackageValidationTest (e.g. EventCreate without Package → 422).
|
||||
- **Coverage:** 80% für Billing/DB; Mock Providers für Isolation.
|
||||
|
||||
## 10. Deployment & Rollout (Todo 12)
|
||||
- **Vorbereitung:** Backup DB (php artisan db:backup), Staging-Env (duplicate prod, test Migration).
|
||||
- **Schritte:**
|
||||
1. Deploy Migration/Seeder (php artisan migrate, db:seed --class=PackageSeeder).
|
||||
2. Run packages:migrate (Command: Transfer Daten, log Errors).
|
||||
3. Update Code (Controllers/Middleware/Resources, API-Routes).
|
||||
4. Frontend-Build (npm run build for PWAs).
|
||||
5. Smoke-Tests (Kauf-Flow, Limits, Webhooks mit Sandbox).
|
||||
6. Go-Live: Feature-Flag (config/packages.enabled = true), Monitor mit Telescope/Sentry.
|
||||
- **Rollback:** migrate:rollback, restore Backup.
|
||||
- **Post-Deployment:** Update TODO.md (neue Tasks: Monitor Conversions), Gogs-Issues (z.B. "Implement Package Analytics"), E-Mail an Users ("Neues Package-Modell – Ihr Free-Paket ist aktiv").
|
||||
- **Monitoring:** Scheduled Job (daily: Check expired Packages, notify), Revenue-Dashboard in Filament.
|
||||
|
||||
## 11. Identifizierte Lücken & Best Practices
|
||||
- **Sicherheit:** PCI-Compliance (Provider-handhabt), Audit-Logs (payments-channel), Rate-Limiting (/checkout: 5/min), GDPR (Lösch-Job, Consent in Checkout).
|
||||
- **i18n:** Package-Features als translatable JSON, Locale in Checkout (Stripe metadata).
|
||||
- **Analytics:** GA-Events in Frontend, Telescope für Backend-Käufe, ARPU-Tracking in Widgets.
|
||||
- **Support:** E-Mail-Templates (PurchaseMailable), FAQ in /support/packages, Onboarding-Tour post-Kauf.
|
||||
- **Performance:** Caching (Packages-Liste), Indexing (purchased_at), Queues für Webhooks (ProcessPurchaseJob).
|
||||
- **Edge-Cases:** Upgrade (prorate Preis, transfer Limits), Expiry (Observer + E-Mail), Offline-PWA (queued Käufe sync).
|
||||
- **Dependencies:** Paddle SDKs, Dompdf (Rechnungen), Laravel Cashier (optional für Stripe).
|
||||
- **Kosten:** Env für Sandbox/Prod-Keys; Test mit Paddle Test-Accounts.
|
||||
|
||||
## 12. Todo-List (Status: Alle Planung completed)
|
||||
- [x] Analyse.
|
||||
- [x] Design (15-packages-design.md).
|
||||
- [x] PRP-Updates.
|
||||
- [x] Marketing/Legal (Blades mit Checkout).
|
||||
- [x] DB-Migrationen.
|
||||
- [ ] Backend (Resources/Controllers).
|
||||
- [ ] API.
|
||||
- [ ] PWAs.
|
||||
- [ ] Billing (SDKs/Webhooks).
|
||||
- [ ] Tests.
|
||||
- [ ] Deployment.
|
||||
|
||||
**Nächster Schritt:** Wechsel zu Code-Mode für Implementation (start with DB-Migrationen). Kontaktieren Sie für Änderungen.
|
||||
15
docs/archive/piwik-trackingcode.txt
Normal file
15
docs/archive/piwik-trackingcode.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
<!-- Matomo -->
|
||||
<script>
|
||||
var _paq = window._paq = window._paq || [];
|
||||
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
|
||||
_paq.push(['trackPageView']);
|
||||
_paq.push(['enableLinkTracking']);
|
||||
(function() {
|
||||
var u="//piwik.sebfoto.de/";
|
||||
_paq.push(['setTrackerUrl', u+'matomo.php']);
|
||||
_paq.push(['setSiteId', '6']);
|
||||
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
||||
})();
|
||||
</script>
|
||||
<!-- End Matomo Code -->
|
||||
39
docs/archive/process/todo/event-join-token-hardening.md
Normal file
39
docs/archive/process/todo/event-join-token-hardening.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Event Join Token Hardening TODO
|
||||
|
||||
## Goal
|
||||
Replace slug-based guest access with opaque, revocable join tokens and provide printable QR layouts tied to those tokens.
|
||||
|
||||
## Status (Stand 12.10.2025)
|
||||
- **Phase 1 – Data & Backend:** vollständig abgeschlossen.
|
||||
- **Phase 2 – Guest PWA:** Aufgaben zu Fehlerzuständen und Regressionstests noch offen.
|
||||
- **Phase 3 – Tenant Admin UX:** Layout-Downloads und Abschaltung des alten Slug-QR-Flows noch offen.
|
||||
- **Phase 4 – Migration & Cleanup:** alle Aufgaben offen.
|
||||
|
||||
## Phase 1 – Data & Backend
|
||||
- [x] Create `event_join_tokens` table (token, event_id, usage_limit/count, expires_at, revoked_at, created_by).
|
||||
- [x] Add Eloquent model + relations (`Event::joinTokens()`), factory, and seed helper.
|
||||
- [x] Implement service for token generation/rotation (secure RNG, audit logging).
|
||||
- [x] Expose tenant API endpoints for listing/creating/revoking tokens.
|
||||
- [x] Introduce middleware/controller updates so guest API resolves `/e/{token}` → event.
|
||||
- [x] Add rate limiting + logging for invalid token attempts.
|
||||
|
||||
## Phase 2 – Guest PWA
|
||||
- [x] Update router and data loaders to use `:token` paths.
|
||||
- [x] Adjust storage/cache keys to use token identifiers.
|
||||
- [x] Display friendly error states for expired/invalid tokens.
|
||||
- [x] Regression-test photo upload, likes, and stats flows via token.
|
||||
|
||||
## Phase 3 – Tenant Admin UX
|
||||
- [x] Build “QR & Invites” management UI (list tokens, usage stats, rotate/revoke).
|
||||
- [x] Hook Filament action + PWA screens to call new token endpoints.
|
||||
- [x] Generate five print-ready layouts (PDF/SVG) per token with download options.
|
||||
- [x] Deprecate slug-based QR view; link tenants to new flow.
|
||||
|
||||
## Phase 4 – Migration & Cleanup
|
||||
- [x] Remove slug parameters from public endpoints (legacy slug URLs now return invalid_token).
|
||||
- [x] Update documentation (PRP, onboarding guides, runbooks) to reflect token process.
|
||||
- [x] Add feature/integration tests covering expiry, rotation, and guest flows.
|
||||
|
||||
## Open Questions
|
||||
- Decide on default token lifetime and rotation cadence.
|
||||
- Confirm whether guest tokens should embed locale or package metadata.
|
||||
@@ -0,0 +1,67 @@
|
||||
# Package Limit Experience Overhaul
|
||||
|
||||
**Status:** Planned
|
||||
**Owner:** Codegen Agent
|
||||
**Related Areas:** Packages, Tenant Admin PWA, Guest PWA, Notifications
|
||||
|
||||
## Motivation
|
||||
- Uneinheitliche Limit-Prüfungen (Public Upload vs. Admin Upload vs. Event-Erstellung).
|
||||
- Fehlende, generische oder kryptische Fehlermeldungen im Admin-Frontend.
|
||||
- Keine Frühwarnungen bei 80 %/95 % Auslastung, kein Countdown für Galerien.
|
||||
- Fehlende Automatisierung für E-Mail-/In-App-Warnungen bei kritischen Zuständen.
|
||||
|
||||
## High-Level Goals
|
||||
1. Konsistente Limit-Prüfungen & Fehlercodes im Backend.
|
||||
2. Verbesserte UX in Guest & Tenant Admin PWA (Warnungen, klare Fehlermeldungen).
|
||||
3. Proaktive Benachrichtigungen (E-Mail, In-App) bei bevorstehenden Grenzwerten / Ablauf.
|
||||
4. Monitoring, Dokumentation, Tests für alle neuen Abläufe.
|
||||
|
||||
## Work Breakdown
|
||||
|
||||
### 1. Backend Unification
|
||||
- [x] Paket-Limit-Service erstellen (Fotos, Gäste, Aufgaben, Events/Jahr, Galerie-Laufzeit). *(Initial evaluator + Middleware Integration für Events/Fotos)*
|
||||
- [x] Public Uploads um Paketlimit-Prüfung erweitern (inkl. Events ohne Aktivpaket blockieren). *(Guest Upload prüft & erhöht Zähler)*
|
||||
- [x] Konsistentes Fehler-Response-Schema (`code`, `title`, `message`, `meta`) implementieren.
|
||||
- [x] Domain-Events für Grenzwerte & Ablaufzustände emitten.
|
||||
- [x] Feature-/Unit-Tests für neue Services & Events.
|
||||
|
||||
### 2. Threshold Detection & Storage
|
||||
- [x] Schwellenwerte konfigurieren (Fotos/Gäste, Gallery D-7/D-1).
|
||||
- [x] Scheduler/Jobs für regelmäßige Galerie-Checks.
|
||||
- [x] Persistenz für Galerie-Benachrichtigungen (warning/expired timestamps).
|
||||
|
||||
### 3. Guest PWA Improvements
|
||||
- [x] Limit-Status im Upload-Flow anzeigen (Warnbanner + Sperrzustände).
|
||||
- [x] Upload-Fehlercodes auswerten und freundliche Dialoge zeigen.
|
||||
- [x] Galerie-Countdown/Badge für Ablaufdatum + Call-to-Action.
|
||||
- [x] E2E-Tests für Limitwarnungen & abgelaufene Galerie aktualisieren.
|
||||
|
||||
### 4. Tenant Admin PWA Improvements
|
||||
- [x] Dashboard-Karten & Event-Header mit Ampelsystem für Limitfortschritt.
|
||||
- [x] Event-Formular: Warnhinweise bei 80 %/95 % + Upgrade-CTA.
|
||||
- [x] Globale Fehlerzustände aus Fehlerkontrakt (Toast/Dialog).
|
||||
- [x] Übersetzungen für alle neuen Messages hinzufügen.
|
||||
|
||||
- [x] E-Mail-Schablonen & Notifications für Foto- und Gäste-Schwellen/Limits.
|
||||
- [x] Galerie-Warnungen (D-7/D-1) & Ablauf-Mails + Cron Task.
|
||||
- [x] Weitere Benachrichtigungen (Paket-Ablauf, Reseller-Eventlimit, Credits fast leer).
|
||||
- [x] Opt-in/Opt-out-Konfiguration pro Tenant implementieren.
|
||||
- [x] In-App/Toast-Benachrichtigungen für Admin UI (und optional Push/Slack intern).
|
||||
- [x] Audit-Log & Retry-Logik für gesendete Mails.
|
||||
|
||||
### 6. Monitoring, Docs & Support
|
||||
- [x] Prometheus/Grafana-Metriken für Paketnutzung & Warns triggern. *(`PackageLimitMetrics` + `php artisan metrics:package-limits` Snapshot)*
|
||||
- [x] PRP & API-Doku mit neuem Fehlerschema & Limitverhalten aktualisieren.
|
||||
- [x] Support-Playbook & FAQ für Limitwarnungen erweitern. *(docs/prp/06 Tenant Admin Playbook Abschnitt)*
|
||||
|
||||
## Dependencies & Notes
|
||||
- Bestehende Credit-Logik parallel weiter unterstützen (Legacy-Kunden).
|
||||
- Paddle/E-Mail-Dienste müssen auf Sandbox getestet werden.
|
||||
- Mehrsprachigkeit (de/en) sicherstellen.
|
||||
|
||||
## Definition of Done
|
||||
- Alle relevanten Grenzwerte serverseitig validiert und getestet.
|
||||
- Frontends zeigen spezifische Warnungen + Handlungsanweisungen.
|
||||
- Benachrichtigungssystem verschickt Mails bei konfigurierten Schwellen.
|
||||
- Monitoring & Dokumentation sind aktualisiert.
|
||||
- Regressionstests und neue Tests laufen grün.
|
||||
50
docs/archive/process/todo/tenant-admin-onboarding-fusion.md
Normal file
50
docs/archive/process/todo/tenant-admin-onboarding-fusion.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# Tenant Admin Onboarding Fusion TODO
|
||||
Created: 2025-10-10
|
||||
Owner: Codex (handoff)
|
||||
|
||||
## Context
|
||||
- Blend the immersive welcome + ordering journey from fotospiel-tenant-app/tenant-admin-app with the new management modules under /event-admin.
|
||||
- Align with the detailed PRP (docs/prp/tenant-app-specs/*.md) and onboarding plan notes (docs/process/changes/2025-10-10-tenant-admin-onboarding-plan.md).
|
||||
- Preserve existing dashboard/events/tasks/billing screens while introducing a guided first-run experience and mobile-first polish.
|
||||
|
||||
## References
|
||||
- docs/prp/tenant-app-specs/README.md
|
||||
- docs/prp/tenant-app-specs/pages-ui.md
|
||||
- docs/prp/tenant-app-specs/functional-specs.md
|
||||
- docs/process/changes/2025-10-10-tenant-admin-onboarding-plan.md
|
||||
- resources/js/admin/router.tsx
|
||||
- resources/js/admin/components/AdminLayout.tsx
|
||||
- resources/js/admin/pages/DashboardPage.tsx
|
||||
- fotospiel-tenant-app/tenant-admin-app/src/App.tsx (legacy welcome flow)
|
||||
|
||||
## Priority: Now ( unblock design + scope )
|
||||
- [x] Audit the legacy Capacitor app assets (intro carousel, package picker, CTA cards, animation helpers) and list what should be ported or rebuilt in Tailwind/React. Capture findings in docs/process/changes/2025-10-10-tenant-admin-onboarding-plan.md with component parity notes. See "Component Audit - 2025-10-10".
|
||||
- [x] Define shared onboarding design primitives inside Laravel PWA (e.g. gradient backgrounds, full-height hero layout, swipeable stepper). Propose implementation sketch for new components such as TenantWelcomeLayout and WelcomeStepCard. Documented under "Proposed Laravel PWA Welcome Primitives".
|
||||
|
||||
## Priority: Next ( build the welcome flow )
|
||||
- [x] Introduce /event-admin/welcome/* routes and constants, plus a lightweight layout distinct from AdminLayout. Update resources/js/admin/router.tsx and resources/js/admin/constants.ts accordingly.
|
||||
- [x] Implement onboarding steps (Hero, HowItWorks, PackageSelection, OrderSummary, FirstEventSetup) that reuse existing APIs (getTenantPackagesOverview, createEvent, checkout helpers). Landing, package, summary, and setup screens are live; summary links to Billing for payments, direct in-flow checkout still TBD.
|
||||
- [x] Persist onboarding progress (e.g. useOnboardingProgress in auth context or dedicated store) and add guard logic so tenants without active events land on the welcome flow after login. Provide a way to resume the flow from the dashboard CTA.
|
||||
- [x] Refresh DashboardPage.tsx to surface the new welcome CTA ("Plan your first event") and quick links back into the guided flow without breaking existing management cards. Guided setup card and header action now link to `/event-admin/welcome`.
|
||||
|
||||
## Priority: Later ( polish + delivery )
|
||||
- [x] Align theming, typography, and transitions with the legacy mobile look (consider porting key styles from fotospiel-tenant-app/tenant-admin-app/src/styles). Tenant admin layout now reuses marketing brand palette, fonts, and gradient utilities; Tailwind variables capture the shared tokens.
|
||||
- [x] Review PWA manifest/offline setup so die kombinierte Welcome+Management-Experience TWA-/Capacitor-ready ist (Manifest + `admin-sw.js` dokumentiert).
|
||||
- [x] Extend docs: PRP-Onboarding-Abschnitte aktualisiert, Screenshots unter `docs/screenshots/tenant-admin-onboarding/` ergänzt, Testscope notiert.
|
||||
- [x] Add automated coverage: Vitest + Testing Library für Welcome Landing, Dashboard-Guard und Checkout-Komponenten; `npm run test:unit` führt Suite aus.
|
||||
- [x] Finalise direct checkout: Paddle-Flows markieren Fortschritt, API-Mocks + Unit-Tests decken Erfolgs- und Fehlerpfade ab.
|
||||
- [x] Lokalisierung ausbauen: Landing-, Packages-, Summary- und Event-Setup-Screens sind nun DE/EN übersetzt; Copy-Review für weitere Module (Tasks/Billing/Members) bleibt offen.
|
||||
|
||||
## Risks & Open Questions
|
||||
- Confirm checkout UX expectations (Stripe vs Paddle) before wiring package purchase into onboarding.
|
||||
- Validate whether onboarding flow must be localized at launch; coordinate mit den neuen i18n JSONs und fehlenden Übersetzungen.
|
||||
- Determine deprecation plan for fotospiel-tenant-app/tenant-admin-app once the merged flow ships.
|
||||
|
||||
## Priority: Immediate (Tenant admin refresh 2025-10-18)
|
||||
- [x] Replace the `/event-admin/login` landing with a public welcome screen that explains Fotospiel for non-technical couples, keeps the login button, and updates `resources/js/admin/router.tsx`, `constants.ts`, and new `WelcomeTeaserPage`.
|
||||
- [x] Align authentication by migrating the tenant-admin flow to Sanctum PATs, dropping `VITE_OAUTH_CLIENT_ID`, updating the exchange endpoints, and documenting the env expectations in `docs/prp/tenant-app-specs/api-usage.md` / `13-backend-authentication.md`.
|
||||
- [x] Rebrand the Filament tenant panel away from “Admin” by adjusting `AdminPanelProvider` (brand name, home URL, navigation visibility) and registering a new onboarding home page.
|
||||
- [x] Build the Filament onboarding wizard (welcome → task package selection → event name → color palette → QR layout) with persisted progress on the tenant record and guards that hide legacy resource menus until completion.
|
||||
- [x] Expose QR invite generation in Filament via a dedicated page/component that reuses the join-token flow from `EventDetailPage.tsx`, ensuring tokens stay in sync between PWA and Filament.
|
||||
- [x] Update PRP/docs to cover die neue Welcome Journey, OAuth-Ausrichtung, Filament-Onboarding und QR-Tooling; Regression Notes + Tests dokumentiert.
|
||||
|
||||
Reference in New Issue
Block a user