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>
11 KiB
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)
- 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.
- 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). - 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) inweb-master.blade.phpvia@yield/@stack.release-detail.blade.phpsetzt 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_accessim bestehendenMagicLinkGenerator(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 inroutes/admin.php, Volt-Komponenten unterlivewire/admin/legal-requests/nach Musteradmin/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_portalim 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_bookingfür Launch auftrue, 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ätigungcustomer-Rolle +is_active=true(heute fehlt beides inCreateNewUser/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 anusers), 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.