presseportale/docs/weiteres/Detailplan Umsetzung Launch-Slice (Magic-Link, Compliance, Bestandsschutz, Auth).md
Kevin Adametz ce5d6c98e1 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>
2026-06-15 10:03:05 +00:00

11 KiB
Raw Blame History

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.

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.