Detailplan Umsetzungsphase: Launch-Slice aus Decision-Updates + Merkliste
Bündelt die Launch-Anteile der beiden Decision-Updates (Phase-2/Magic-Link, Duplicate-Content) mit den Merkliste-Notizen zu einem Plan (WS-1 bis WS-8) inkl. empfohlener Reihenfolge und Anti-Zombie-Check. Verbindliche Entscheidungen (15.06.): Legacy-Posten bleiben ungemappt, Pflicht-E-Mail-Verifizierung bei Registrierung (Ausnahme Magic-Link/Google), Laravel Socialite freigegeben. README-Index um den Plan ergänzt; Merkliste (Wochenend-Notizen) als Quelle mit aufgenommen. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
ad741331ee
commit
ec4aa1dc3d
3 changed files with 146 additions and 0 deletions
|
|
@ -0,0 +1,129 @@
|
|||
**Version:** Juni 2026 · **Datum:** 15.06.2026 · **Status:** Abgestimmt – in Umsetzung
|
||||
**Scope:** Detaillierter Umsetzungsplan für die nächste Phase. Bündelt die Launch-Anteile der beiden Decision-Updates (Phase-2/Magic-Link, Duplicate-Content) mit den offenen Punkten aus `weiteres/Merkliste.md` sowie den Rest-Zweigen Login-Flow und Code-Optimierung.
|
||||
|
||||
---
|
||||
|
||||
## 0. Ausgangslage – was bereits im Code existiert
|
||||
|
||||
Die Kartierung der betroffenen Subsysteme hat ergeben, dass einiges bereits halb gebaut ist. Der reale Restaufwand ist dadurch kleiner als die Konzept-Dokumente vermuten lassen – vieles ist „verifizieren + scharf schalten + UI" statt „von null bauen".
|
||||
|
||||
| Thema | Ist-Stand |
|
||||
|---|---|
|
||||
| Magic-Link | Basis vorhanden (`app/Models/MagicLink.php`, `MagicLinkGenerator`, `MagicLinkConsumeController`) – aber nur **Login registrierter User** + **Read-only-PM-Vorschau**. Pressekontakt-per-E-Mail-Zugang fehlt. |
|
||||
| Abo-/Bestandsschutz-Gate | **Bereits implementiert:** `User::hasActiveBooking()` zählt `grandfathered` mit; `app/Services/PressRelease/PressReleaseService.php` wirft `BookingRequiredException`. Aber hinter Launch-Schalter `billing.enforce_booking=false` deaktiviert. |
|
||||
| Bestandsschutz | Abgebildet als `UserPaymentOption.status='grandfathered'` + `legacy_conditions` (JSON). Einmal-Import `GrandfatherLegacySubscriptions` + täglicher MAN-Worker `GenerateManualInvoices` (04:30) existieren. |
|
||||
| Boost / Proof-PDF / Extra-PM | Enum-Cases existieren (`SinglePurchaseType`), aber **keine Credit-Wallet** → bleibt Phase 2. |
|
||||
| Canonical-Tags | Fehlen in `resources/views/web/layouts/web-master.blade.php` (`<head>` hat nur `meta_description`). |
|
||||
| „Melden"-Button | Platzhalter (`href="#"`) in `resources/views/web/release-detail.blade.php`, kein Backend. |
|
||||
| Google-Login / Socialite | **Nicht installiert** – Greenfield (hiermit freigegeben). |
|
||||
| E-Mail-Verifizierung | Fortify-Feature `emailVerification()` aktuell **nicht aktiv**; Registrierung setzt weder `is_active` noch Rolle. |
|
||||
|
||||
---
|
||||
|
||||
## 1. Verbindliche Entscheidungen (15.06.2026)
|
||||
|
||||
1. **Legacy-Posten bleiben unverändert.** Bestandsschutz-Posten werden **nicht** auf ein Tarif-Abo (z. B. Agentur) gemappt. Die Positionen bleiben als eigene Legacy-Konditionen erhalten, so wie sie sind.
|
||||
2. **Registrierung mit Pflicht-Verifizierung.** Neu registrierte Benutzer müssen sich **einmalig per E-Mail verifizieren**. Erst nach Verifizierung: `customer`-Rolle + `is_active=true`. **Ausnahme:** Magic-Link, Google-Login & vergleichbare Wege – dort findet die Verifizierung über den Login-Kanal selbst statt (keine zusätzliche E-Mail-Verifizierung nötig).
|
||||
3. **Laravel Socialite freigegeben** als neue Abhängigkeit (für Google-Login, später ggf. weitere Provider).
|
||||
|
||||
---
|
||||
|
||||
## 2. Bewusst NICHT in dieser Phase (Phase 2, credit-abhängig)
|
||||
|
||||
Der Großteil des Phase-2/Magic-Link-Dokuments hängt an der **Credit-Wallet**, die noch nicht existiert. Diese Punkte werden bewusst zurückgestellt, bis die Wallet gebaut ist:
|
||||
|
||||
- Pfade **C** (Inhaltliche Korrektur), **D** (Update/Ergänzung), **G** (Depublizieren)
|
||||
- **Boost** (Platzierung), **Veröffentlichungsnachweis/PDF**, **Extra-PM** (Kontingent-Nachkauf)
|
||||
- **Prüfzähler** & höheres Prüfkontingent, Vorab-Prüfung/Redigieren
|
||||
|
||||
Vom **Duplicate-Content-Dokument** ist die Entscheidung ohnehin „nichts bauen"; einziger umsetzbarer Launch-Punkt dort: **Canonical-Tags** (siehe WS-1). Hash-/Shingle-Vergleich bleibt Phase-3-Option.
|
||||
|
||||
---
|
||||
|
||||
## 3. Arbeitspakete
|
||||
|
||||
### WS-1 — SEO Canonical-Tags (Duplicate-Doc §5) · klein, isoliert
|
||||
**Scope:** Jede öffentliche PM bekommt ihre kanonische URL; pro Portal getrennt (kein Cross-Portal → kein System-Duplicate).
|
||||
- `<link rel="canonical">` + OpenGraph-Tags (og:title/description/image) in `web-master.blade.php` via `@yield`/`@stack`.
|
||||
- `release-detail.blade.php` setzt die kanonische URL der PM; Listen-/Übersichtsseiten Self-Canonical.
|
||||
- **Tests:** Feature-Test prüft `rel="canonical"` mit korrekter URL auf veröffentlichter PM.
|
||||
- **Aufwand:** ~½ Tag. Keine Migration, kein Risiko.
|
||||
|
||||
### WS-2 — Magic-Link-Pressekontaktzugang (Phase-2-Doc §3.1) · Fundament
|
||||
**Scope:** Zugangsbrücke „eine Verwaltung, zwei Eintrittswege" für unregistrierte Pressekontakte.
|
||||
- Neuer Magic-Link-`purpose` = `contact_access` im bestehenden `MagicLinkGenerator` (TTL 30 Min).
|
||||
- Dezenter Link auf jeder öffentlichen PM: „Sie sind als Pressekontakt hinterlegt? → verwalten".
|
||||
- E-Mail-Eingabe + Captcha; **enumeration-sichere identische Antwort** unabhängig vom Match.
|
||||
- Bei Match → Mail mit Token → authentifizierte Session, die alle PMs zu dieser E-Mail listet (`Contact::where('email',…)->pressReleases()`, firmen-/jahresübergreifend).
|
||||
- Rate-Limit pro E-Mail/IP; Audit-Log (IP/User-Agent) je Aktion.
|
||||
- **Account-Konvertierung:** „Permanenten Account anlegen" aus der Magic-Link-Session (Passwort vergeben) → Verifizierung gilt über den Magic-Link-Kanal als erfolgt (siehe Entscheidung 2).
|
||||
- **Tests:** Token-Lifecycle, Enumeration-Sicherheit, abgelaufener/verbrauchter Token, PM-Liste nur eigene E-Mail.
|
||||
- **Aufwand:** ~2–3 Tage. **Fundament für WS-3.**
|
||||
|
||||
### WS-3 — Änderungs-/Lösch-Pfade A · B · E · F (Phase-2-Doc §3.2/3.3) · Launch-Pflicht
|
||||
Alle hinter WS-2 **oder** regulärem Login.
|
||||
- **B — Kontaktdaten ändern** (einfachster Pfad zuerst): Formular, direkt übernommen, Versionierung im Hintergrund. Kostenfrei.
|
||||
- **A — Tippfehler/Grammatik:** Inline-Editor mit **Levenshtein-Diff** (kein KI-Call). Kleine Änderung ohne Zahlen/Namen → automatisch; Graubereich → Hinweis „bitte als Korrektur (Pfad C, Phase 2) einreichen". Bremse: 1 Einreichung/PM/24 h + Account-Tages-Cap.
|
||||
- **E — DSGVO-Anonymisierung** & **F — Persönlichkeitsrecht:** **rechtlich zwingend ab Launch.** Formular → Eintrag in neuer Tabelle `legal_requests` → **Admin-Queue** (keine KI). Bremse: „1 offene Anfrage pro PM" (nicht hart gesperrt).
|
||||
- **Öffentlicher „Melden"-Button** (§3.5) verdrahten → speist dieselbe Queue wie F.
|
||||
- **Neuer Admin-Bereich „Recht & Compliance":** Nav in `components/layouts/app/sidebar.blade.php`, Routen in `routes/admin.php`, Volt-Komponenten unter `livewire/admin/legal-requests/` nach Muster `admin/contacts/index`.
|
||||
- **Migration:** `legal_requests` (press_release_id, type[dsgvo/personal_rights/report], status, payload, requester_email, resolved_at, …).
|
||||
- **Tests:** je Pfad ein Feature-Test; „1 offene Anfrage/PM"-Bremse; Admin-Queue-Sichtbarkeit; Melden→F-Queue.
|
||||
- **Aufwand:** ~4–5 Tage (E/F + Queue der Großteil).
|
||||
|
||||
### WS-4 — Bestandsschutz-Abrechnung & -Übersicht (Merkliste 1·2·3·5)
|
||||
**Scope:** Vorhandene Mechanik (`GrandfatherLegacySubscriptions`, `GenerateManualInvoices`) verifizieren + Lücken schließen. **Legacy-Posten bleiben unverändert (Entscheidung 1) – kein Tarif-Mapping.**
|
||||
- **M1 — Beide Portale ohne Unterscheidung:** Bestandsschutz gilt portalübergreifend, auch wenn nur für ein Portal gebucht → sicherstellen, dass `legacy_portal` im Import **kein** Filter ist.
|
||||
- **M2 — Zwei Posten zusammen abrechnen, nicht einzeln kündbar:** Zwei Legacy-Posten desselben Kunden (je Portal, z. B. connektar 2×1000 € netto) werden gemeinsam abgerechnet und gelten zusammen (Gesamtsumme 2000 € netto bleibt). Die einzelnen Positionen bleiben als eigene Legacy-Konditionen erhalten – **keine** Zusammenführung zu einem Tarif, **keine** Einzelkündigung.
|
||||
- **M5 — Einmal-Import + täglicher Worker:** Verifizieren, dass alle aktiven Abrechnungen erfasst werden und der 04:30-Worker fällige Rechnungen korrekt erzeugt; ggf. Gesamtübersicht ergänzen.
|
||||
- **M3 — Ansicht deutlicher:** Im Admin-Payments-Bereich Bestandsschutz-Posten optisch klar kennzeichnen/zuordnen (Badge „Bestandsschutz", Portal-Zuordnung, gebündelte Posten sichtbar).
|
||||
- **Tests:** gemeinsame Abrechnung zweier Posten; portalübergreifende Geltung; Worker erzeugt Rechnung zum Periodenende.
|
||||
- **Aufwand:** ~2–3 Tage. Parallel zu WS-1/2 möglich.
|
||||
|
||||
### WS-5 — Abo-/Bestandsschutz-Gate scharf schalten (Merkliste 6)
|
||||
**Scope:** „User ohne aktives Abo oder Bestandsschutz dürfen keine PM schreiben."
|
||||
- Mechanik existiert (`hasActiveBooking()` inkl. `grandfathered`, `BookingRequiredException`). Nötig: `billing.enforce_booking` für Launch auf `true`, Block-UX prüfen, Bestandsschutz-Fall absichern.
|
||||
- **Tests:** User ohne Buchung → blockiert; grandfathered → erlaubt; aktives Abo → erlaubt.
|
||||
- **Aufwand:** ~½–1 Tag. **Abhängigkeit:** WS-4.
|
||||
|
||||
### WS-6 — Login/Registrierung: Flow + E-Mail-Verifizierung + Google-Login (Merkliste 7 + Zweig 3)
|
||||
**Scope nach Entscheidung 2 & 3:**
|
||||
- **E-Mail-Verifizierung aktivieren:** Fortify `emailVerification()` bzw. Volt-Flow scharf schalten. Bei Registrierung: User wird angelegt, aber **erst nach Bestätigung** `customer`-Rolle + `is_active=true` (heute fehlt beides in `CreateNewUser`/Register-Volt). Bis dahin kein Zugriff auf geschützte Bereiche.
|
||||
- **Ausnahme-Kanäle:** Magic-Link & Google-Login gelten als verifiziert (keine zusätzliche E-Mail-Verifizierung) → dort direkt `is_active=true` + Rolle.
|
||||
- **Google-Login:** Laravel Socialite installieren, `config/services.php` + Redirect/Callback-Controller, Provider-Verknüpfung (`provider`/`provider_id`-Spalten an `users`), Rollen-/`is_active`-Logik.
|
||||
- **Flow-Audit:** Login, Passwort-Reset, Verify-Email, 2FA, Magic-Link-Login durchtesten und korrigieren.
|
||||
- **Tests:** Registrierung→Verifizierung→Aktivierung; unverifizierter User blockiert; Socialite gemockt; Account-Verknüpfung; Magic-Link/Google ohne E-Mail-Verifizierung aktiv.
|
||||
- **Aufwand:** ~2–3 Tage.
|
||||
|
||||
### WS-7 — Live-Deployment-Checkliste (Merkliste 4)
|
||||
- Kompakte Liste nötiger Commands & Live-Settings: `migrate`, `enforce_booking=true`, Stripe-Live-Keys, `BILLING_OWN_VAT_ID`, Asset-Build, Scheduler/Worker, Favicons, Domain-Config, Socialite-Keys – damit nicht aus langen Dokumenten gesucht werden muss.
|
||||
- **Aufwand:** ~½ Tag (reine Doku).
|
||||
|
||||
### WS-8 — Code-Optimierung (Zweig 4)
|
||||
- Nach Abschluss der Features: gezielte Optimierung (N+1 in Listen, doppelte Query-Logik, Service-Extraktion). Bewusst zuletzt, wenn der Funktionsumfang steht.
|
||||
|
||||
---
|
||||
|
||||
## 4. Empfohlene Reihenfolge
|
||||
|
||||
```
|
||||
1. WS-1 Canonical-Tags (Quick-Win, isoliert)
|
||||
2. WS-2 Magic-Link-Kontaktzugang (Fundament)
|
||||
3. WS-3 Pfade B → A → E/F + Queue (Launch-Pflicht, auf WS-2)
|
||||
4. WS-4 Bestandsschutz-Abrechnung (parallel möglich)
|
||||
5. WS-5 Abo-Gate scharf schalten (nach WS-4)
|
||||
6. WS-6 Login-Flow + E-Mail-Verifizierung + Google
|
||||
7. WS-7 Deployment-Checkliste
|
||||
8. WS-8 Code-Optimierung (zuletzt)
|
||||
── Phase 2 (später): Wallet, C/D/G, Boost, Proof-PDF, Extra-PM, Prüfzähler ──
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Anti-Zombie-Check
|
||||
|
||||
- ✅ Phase-2-Funktionen (Wallet-abhängig) bewusst zurückgestellt – nichts auf Vorrat gebaut.
|
||||
- ✅ Legacy-Posten bleiben unangetastet – kein riskantes Tarif-Mapping bestehender Konditionen.
|
||||
- ✅ Rechtlich zwingende Pfade E/F ab Launch erreichbar, kostenfrei, nie hart gesperrt.
|
||||
- ✅ Vorhandene Mechanik (Abo-Gate, Bestandsschutz-Worker, Magic-Link-Basis) wird verifiziert/erweitert statt neu gebaut.
|
||||
- ✅ Duplicate-Checking nicht gebaut – nur Canonical-Hygiene, wie im Decision-Update entschieden.
|
||||
16
docs/weiteres/Merkliste.md
Normal file
16
docs/weiteres/Merkliste.md
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
Bestandsschutz gilt für beide Portale Auch wenn es nur für ein Portal gebucht ist, hier machen wir in der Migration keine Unterscheidung.
|
||||
|
||||
Hinweis, wer für jeweils ein Portal ein Bestandsschutz hat, d.h. zwei laufende Posten, Werden diese im Bestandsschutz auch zusammen abgerechnet und sind nicht einzeln kündbar. Heißt zum Beispiel bei connektar Gibt es zwei Bestandschutz mit 1000 € netto jeweils für ein Portal diese fallen zusammen und gelten als Bestandsschutz für beide Portale. Heißt die Gesamtrechnungsumme von 2000 € netto bleibt erhalten. Das entspricht in etwa dem Agentur Abo dass es noch mal zu prüfen.
|
||||
|
||||
In der Ansicht muss noch mal deutlich zugeordnet werden und optisch besser erkennbar werden. Ist sehr einfach Gehalten.
|
||||
|
||||
Wir brauchen eine Live Deployment Liste, welche wichtigen Command und Dinge für die Live Einstellung beachtet werden müssen, damit diese nicht aus den Langen Dokumenten gesucht werden müssen.
|
||||
|
||||
Für den Bestandsschutz muss einmalig alle aktiven Abrechnungen in die Tabelle übernommen werden, damit wir eine Gesamtübersicht haben, was noch aktiv ist. Hier drauf läuft im Hintergrund der Worker, der täglich schaut, ob eine Rechnung erstellt werden muss für einen Bestandsschutz.
|
||||
|
||||
Es ist zu prüfen, dass User ohne aktives Abo oder Bestandsschutz keine Pressemitteilung schreiben dürfen.
|
||||
|
||||
Login und Registrierung
|
||||
Zusätzlich Integration von Google Login, gegebenenfalls weitere.
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue