presseportale/dev/migration 2026/06-FEATURES-SCOPE.md
Kevin Adametz 5b8bdf4182
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (push) Waiting to run
12-05-2026 Frontend dev
2026-05-12 18:32:33 +02:00

244 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 06 Feature-Scope (IN / OUT / ANGEPASST)
Diese Matrix ist die **fachliche Scope-Grundlage**. **Stand: 2026-04-23 Entscheidungen vom Auftraggeber bestätigt.**
Legende: **IN** = wird migriert · **NEU** = wird neu gebaut (nicht aus Legacy portiert) · **OUT** = entfällt · **ANGEPASST** = kommt rein, aber in veränderter Form · **ARCHIV** = nur lesbar für Nachschau.
---
## 1. Authentifizierung
| Feature | Legacy | Scope | Anmerkung |
|---|---|---|---|
| Login/Logout | ✓ | **IN** | Fortify |
| Registrierung (neue User) | ✓ | **IN** | Fortify-View anpassen; User-Typ bei Anmeldung wählen |
| Passwort zurücksetzen | ✓ | **IN** | Fortify |
| E-Mail-Verifizierung | ✓ | **IN** | Fortify |
| 2FA (TOTP) | | **IN** (neu) | Fortify 2FA-Spalten liegen bereits in `users` |
| Remember-me | ✓ | **IN** | Laravel Standard |
| **Magic-Link Login** (Login per E-Mail-Link) | | **NEU** ⭐ | Für Companies ohne Passwort + als Alternative für alle; kurzlebige signed URLs |
| Legacy-Passwort-Hashes weiter gültig | sha1 | **OUT** | Go-Live-Mailing mit Reset-Link + Sicherheitshinweis |
| Legacy-API-Key-Kompatibilität | ✓ | **OUT** | Sauberer Cut-over auf Sanctum; Kunden werden über neue Tokens informiert |
| Captcha beim Login | sfCaptchaGDPlugin | **OUT** | Ersetzt durch Rate-Limiting + Honeypot |
---
## 2. Benutzer / Profile
| Feature | Legacy | Scope |
|---|---|---|
| User-CRUD im Admin | ✓ | **IN** |
| User-Rollen (Groups) | sfGuardGroup | **IN** (Spatie): `admin`, `editor`, `customer`, `api-only` |
| User-Permissions | sfGuardPermission | **IN** (Spatie) |
| User-Profile (Adresse, Tel, Tax-ID …) | ✓ | **IN** |
| Sanctum-Tokens verwalten (Self-Service) | | **NEU** | Customer verwaltet eigene Tokens unter `/account/tokens` |
| User-Profile `backlink_url` | ✓ | **IN** |
| User-Profile `show_stats` | ✓ | **IN** |
| User-Profile `disable_footer_code` | ✓ | **IN** | Footer-Code bleibt Feature |
| User-Profile `contract_date` | ✓ | **IN** |
| ApiUser als eigener Typ | ✓ | **ANGEPASST** | Als Rolle `api-only` (Spatie), keine eigene Tabelle |
---
## 3. Firmen & Kontakte
| Feature | Legacy | Scope |
|---|---|---|
| Company-CRUD | ✓ | **IN** |
| Agency als Subtyp | Inheritance | **IN** | Als `type`-Enum auf `companies` (entschieden in D-17/Q-10) |
| Mehrere verantwortliche User pro Company | `ResponsibleCompanyUser` | **IN** | Pivot mit `role` |
| Company-Login (eigenes Passwort) | ✓ | **OUT** | Stattdessen: User-Zugang pro Ansprechpartner; Company-E-Mail bekommt Magic-Link |
| **Company-Logo-Upload (verbessert)** | ✓ (minimal) | **ANGEPASST** ⭐ | Mehrere Varianten (sq / wide / darkmode), größere Auflösung, Drag-&-Drop |
| Footer-Code deaktivieren pro Company | ✓ | **IN** |
| Contact-CRUD | ✓ | **IN** |
| Contact-Autocomplete in PM-Formular | ✓ | **IN** |
---
## 4. Pressemitteilungen
| Feature | Legacy | Scope |
|---|---|---|
| CRUD (Admin) | ✓ | **IN** |
| **CRUD (Customer-Self-Service)** | ✓ | **IN** ⭐ | Customer-Portal: eigene PMs erstellen/bearbeiten |
| Multi-Kategorie? | Nein (1 Kategorie) | **IN** (1:1, N:M optional später) |
| Slugging per Titel+Sprache | ✓ | **IN** |
| Teaser-Range `teaser_begin`/`teaser_end` | ✓ | **IN** |
| Status (`draft`, `published`, `rejected`, `archived`) | lose Strings | **IN** | Enum |
| Publish/Reject-Workflow | ✓ | **IN** | Actions + Events |
| Automatische Blacklist-Prüfung | ✓ | **IN** |
| **Image-Upload mehrere pro PM (verbessert)** | ✓ | **ANGEPASST** ⭐ | Mehrere Bilder, größere Auflösungen, Varianten; Legacy war sehr minimalistisch |
| Preview-Bild | ✓ | **IN** |
| Hits-Zähler | ✓ | **IN** | Atomar `increment` |
| `no_export`-Flag | ✓ | **IN** |
| `portal`-Spalte (portal_type) | | **IN** ⭐ | Pflichtfeld für Portal-Zuordnung (presseecho / businessportal24) |
| SEO-Felder (Meta Title, Description) | teilw. | **ANGEPASST** | Explizite SEO-Spalten |
| Kontakte zu PMs zuordnen | ✓ | **IN** |
| **Öffentlicher Magic-Link zum Teilen / Vorschau** | | **NEU** | UUID-basierter Share-Link für noch unveröffentlichte PMs |
---
## 5. Kategorien
| Feature | Legacy | Scope |
|---|---|---|
| CRUD mit Slug | ✓ | **IN** |
| Mehrsprachigkeit (DE + EN) | ✓ | **IN** | `category_translations`, DE + EN direkt initialisiert |
| Hierarchie (Parent/Child) | ✗ | **IN** (neu, optional) | `parent_id` vorgesehen |
| Footer-Code pro Kategorie | ✓ | **IN** |
---
## 6. Newsletter
| Feature | Legacy | Scope |
|---|---|---|
| Subscribe mit Double-Opt-In | ✓ | **NEU** | Komplett neu gebaut |
| Unsubscribe-Link | ✓ | **NEU** |
| Admin: Subscriber-Liste | ✓ | **NEU** |
| Admin: Kampagnen (manuell versenden) | ✗ | **NEU** |
| CSV-Export / -Import | ✗ | **NEU** |
| Bestandssubscriber (aus Legacy) | ✓ | **IN** (Datenimport) | Nur Subscriber-Daten werden übernommen, kein Workflow-Code |
---
## 7. Billing / Payment / Invoicing
**Großer Umbau** (D-03, D-12, D-13): Komplett neuer Billing-Lauf, nur Stripe, alte Rechnungen → Archiv.
| Feature | Legacy | Scope |
|---|---|---|
| **PaymentOption-Verwaltung (neu definiert)** | ✓ | **NEU** | Neue Produkte, Stripe Prices als Quelle |
| **Grandfathering** (aktive Alt-User behalten Konditionen) | | **NEU** ⭐ | `grandfathered_until`-Feld, automatische Migration auf neue Produkte bei Ablauf |
| Recurring via Stripe Subscription | | **NEU** | Stripe Subscriptions |
| Onetime / Single-Purchase | ✓ | **NEU** | Stripe Checkout |
| Coupons | ✓ | **OUT** (vertagt, D-16) | Kein Model in Phase 1; evtl. Stripe-Coupons später. Aktuelle Coupon-Routen/Views gelten nur als UI-Skeleton ohne Priorisierung in P1. |
| Mehrfach-Buchung pro Company | ✓ | **IN** (neu modelliert) |
| Zahlungsart: SPK Berlin / Cortal Consors / Bar / Post / PayPal | ✓ | **OUT** |
| **Zahlungsart: Rechnung** | ✓ | **OUT** ⭐ | Entfällt komplett, nur noch Stripe |
| Zahlungsart: Stripe (Karte, SEPA, Klarna optional) | ✗ | **NEU** |
| Invoice-Generation (neu) | ✓ | **NEU** | Trigger: erfolgreicher Stripe-Charge oder periodische Subscription-Invoices |
| Invoice-PDF | ✓ (TCPDF) | **ANGEPASST** | DomPDF |
| Mahnwesen | ✓ (3 Stufen) | **NEU** | Vereinfacht, da nur noch Stripe-Zahlungsausfälle abzufangen sind |
| Abweichende Rechnungs-Adresse | ✓ | **IN** |
| Tax-Exempt / Reverse-Charge | ✓ | **IN** |
| VAT-Berechnung | ✓ | **IN** (aktuelle Sätze) |
| **Legacy-Rechnungen (PDFs)** | ✓ | **ARCHIV** ⭐ | Separate Tabelle `legacy_invoices` mit vollständigem DB-Import inkl. Status/User-Zuordnung; PDF wird read-only bei Abruf aus Legacy-Daten generiert |
---
## 8. REST-API
Details: [`07-API-MIGRATION.md`](./07-API-MIGRATION.md)
| Endpoint | Legacy | Scope |
|---|---|---|
| POST Pressrelease | ✓ | **IN** (neu implementiert, Sanctum-Auth) |
| GET Pressrelease-List | ✓ | **IN** |
| GET/PATCH Pressrelease | ✓ | **IN** |
| POST Image-Upload | ✓ | **IN** |
| GET Companies | ✓ | **IN** |
| GET Categories | ✓ | **IN** |
| POST Newsletter subscribe | ✓ | **IN** |
| **Auth: Legacy `api_key`-Query-Param** | ✓ | **OUT** ⭐ | Sanctum-Bearer-Token only; Kunden-Migration per E-Mail |
| (alles andere Undokumentierte) | ? | ❓ | Legacy-Log analysieren |
---
## 9. Marketing / Redaktion
| Feature | Legacy | Scope |
|---|---|---|
| **Promotion-Links** | ✓ | **OUT** ⭐ | Entfällt komplett (D-14) |
| Footer-Code pro Kategorie/Sprache | ✓ | **IN** |
| „page"-Modul (statische Seiten) | ✓ | **OUT** | Static Pages im Frontend-Repo als Blade |
---
## 10. Cron / Scheduler
| Job | Legacy | Scope |
|---|---|---|
| `sfp:user-payment-create` | ✓ | **OUT** | Abgelöst durch Stripe Subscriptions |
| `sfp:invoice-create` | ✓ | **NEU** | Stripe-Webhook-getrieben statt Cron |
| `sfp:invoice-reminder` | ✓ | **NEU** | Laravel-Scheduler-Job für unbezahlte Stripe-Invoices |
| `sfp:user-paymentoption-expire` | deaktiviert | **NEU** | Grandfather-Ablauf-Handler |
| **Magic-Link-Cleanup** | | **NEU** | Expired tokens löschen |
| Newsletter-Versand-Queue | | **NEU** |
| Log-Rotation / Prune Failed Jobs | | **NEU** |
---
## 11. Bilder / Media
| Feature | Legacy | Scope |
|---|---|---|
| Thumbnail-Generierung | sfImageTransformPlugin | **ANGEPASST** | Intervention Image, on-upload |
| Varianten (thumb_200, thumb_500, etc.) | ✓ | **IN** |
| Storage lokal | ✓ | **IN** (Dev + Prod initial) |
| Storage S3-kompatibel | ✗ | **IN** (optional später) |
| Alte Image-URLs (`/thumbnails/...`) | ✓ | **ANGEPASST** | Redirect-Middleware |
| **Company-Logo größer & mehrere Varianten** | ✓ (minimal) | **NEU** ⭐ |
| **Press-Release mehrere Bilder** | teils | **NEU** ⭐ |
---
## 12. Kundenbereich / Customer-Portal ⭐ NEU AUFGEWERTET
**Entscheidung D-11:** Das Backend ist **nicht nur Admin-UI**, sondern bedient auch Endkunden.
| Feature | Scope | Anmerkung |
|---|---|---|
| Customer-Login (Passwort oder Magic-Link) | **NEU** | Eigene Route-Gruppe `customer.*` |
| Eigenes Dashboard (Übersicht aktive Abos, letzte PMs, Rechnungen) | **NEU** |
| Eigene Pressemitteilungen: Liste / Erstellen / Bearbeiten | **NEU** |
| Eigene Rechnungen einsehen + PDF | **NEU** | Inkl. Legacy-Archivrechnungen |
| API-Tokens verwalten (Sanctum-PATs) | **NEU** |
| Company-/Contact-Profile pflegen | **NEU** |
| Zwei-Faktor-Auth aktivieren | **NEU** |
| Passwort ändern / Mail ändern | **NEU** |
---
## 13. Frontend-Integration
| Feature | Legacy | Scope |
|---|---|---|
| Altes Symfony-Frontend (presseecho/businessportal24.com) | ✓ | **OUT** |
| Neue Frontends (presseecho.test / businessportal24.test) | vorhanden | **IN** | Greifen künftig auf neue Models/API zu |
---
## 14. Offene Scope-Entscheidungen (Restliste)
| ID | Thema | Vorschlag / Status |
|---|---|---|
| S-01 | Multi-Kategorie pro PM | Bei 1:1 belassen; N:M-Ausbau nur auf Anfrage |
| S-02 | Coupons-Wiedereinführung | Vertagt (siehe D-16) |
| S-03 | E-Mail-Duplikate zwischen Portalen | Merge wenn gleiche E-Mail (siehe 05-DATABASE-MERGE §3.1) |
| S-04 | S3 für Medien in Prod | Optional, erst wenn Volumen es erfordert |
| S-05 | Definition der neuen Stripe-Produkte | Preisliste + Laufzeiten vom Auftraggeber noch zu liefern |
---
## 15. QA-Checkliste (manuell, vor Go-Live)
- [ ] Admin-Login (inkl. 2FA) funktioniert
- [ ] **Customer-Login via Magic-Link** funktioniert
- [ ] **Customer-Login via Passwort** funktioniert
- [ ] Passwort-Reset-Flow funktioniert (für Go-Live-Mailing kritisch)
- [ ] Portal-Scoping: Admin sieht mit Filter Presseecho-only, BP24-only, alle
- [ ] Press Release: Admin: Create → Save Draft → Publish → Mail → sichtbar im Frontend
- [ ] Press Release: **Customer**: Create → Save Draft → Submit → Admin sieht zur Prüfung
- [ ] Pressrelease Image-Upload, mehrere Bilder, Preview-Bild-Flag
- [ ] Company-Logo-Upload (mehrere Varianten)
- [ ] Blacklist-Wort blockiert Publish
- [ ] Newsletter Double-Opt-In End-to-End (**neu**)
- [ ] Stripe-Checkout End-to-End inkl. Webhook, Invoice-PDF wird erzeugt
- [ ] Grandfather-User: aktives Alt-Abo wird korrekt weiterberechnet/angezeigt
- [ ] Legacy-Rechnungen im Archiv sichtbar (Admin + Customer)
- [ ] API: `POST /v1/press-releases` mit Sanctum-Token
- [ ] API: Alter `api_key`-Parameter wird abgewiesen (Error-Hinweis mit Migrationslink)
- [ ] Alter `/thumbnails/...`-Link redirectet korrekt
- [ ] Scheduler-Jobs greifen (Runbook: `php artisan schedule:run` und `queue:work`)
- [ ] **Import-Rehearsal**: aktuelles Runbook aus `MIGRATION-STEPS.md` läuft auf frischer Ziel-DB gegen produktiven DB-Snapshot erfolgreich durch