presseportale/dev/release/entwicklungsplan-release.md
2026-07-03 16:18:56 +00:00

137 lines
22 KiB
Markdown
Raw 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.

# Entwicklungsplan: Release-Fertigstellung Pressekonto
> Konsolidiert aus vier Analysen vom **03.07.2026** (dev-Doku-Abgleich, Web-Frontend-Bestandsaufnahme, Backend-Baustellen, Deploy-Readiness).
> Reihenfolge nach **Risiko/Nutzen**: erst Korrektheit & kaputte Pfade, dann Release-Entscheidungen (Billing), dann Frontend-Fertigstellung, dann Aufräumen, dann Deploy/QA.
> Ergänzt `dev/optimize/entwicklungsplan.md` (Phasen 0–5 dort abgeschlossen; dessen Phase 6 ist hier als R4 aufgenommen).
---
## Stand & Wiedereinstieg (zuletzt: 03.07.2026)
**Phase R0 komplett; R1 bis auf [EXTERN] fertig; R2.1 erledigt.** Erledigt: R0.1–R0.5 (Variant-Routen raus, gdpr_consent_at in allen drei Registrierungspfaden, Newsletter-Binding config-aware + fail-fast, Seeder produktionssicher inkl. PlanSeeder + Dev-User-Guard, Fehlerseiten 403/404/419/500/503 self-contained) · R1.1 (Gate safe-by-default `true`, Legacy-/Grandfathered-Pfade per Test festgeschrieben, Scope-Logik war korrekt) · R1.3 (Quota-Reset als finales Tarif-Modell-Verhalten dokumentiert).
Offen in R1 (alle [EXTERN]): R1.2 Stripe-Live-Sync, R1.4 Preisfreigabe, R1.5 Refund-Entscheidung.
R2.1 Kontaktformular komplett (Backend + Web-Form, Brand-Empfaenger via CONTACT_EMAIL_*-Keys [EXTERN: echte Adressen]). Bonus-Fix: legal-request-Honeypot nickt Bots wieder still ab (size:0-Regel verriet die Falle).
**03.07. nachmittags (User-Vorgaben):** Preise/Limits der Buchungsseite sind die abgestimmte Wahrheit; Pipeline verifiziert: admin/payments/plans pflegt Plan-DB (inkl. Vorteile zeilenweise) -> erscheint auf Buchungsseite, oeffentlicher Preise-Seite, pricing-teaser UND (neu) Hub. **Vorteilstexte selbst sind noch nicht final [EXTERN: User passt sie im Admin-UI an — schlaegt automatisch ueberall durch].**
R2.2+R2.3 erledigt: Hub-Landing komplett ueberarbeitet (datengetriebenes Tarif-Grid aus Plan::active() via neuem `HubPageData`, echte Plattform-Kennzahlen statt erfundener, Fake-Kundenliste raus, alle toten Links beseitigt, unhaltbare Claims entschaerft, Footer-Rechtslinks auf /de/*-Seiten der Hub-Domain). Hub-Rechtsseiten sind erreichbar, brauchen aber weiterhin finale Texte (R3.1).
**Naechste Schritte:** R2.4 (Sitemap/robots/meta) ohne User-Input machbar; R3 Inhalte + R1.2 Stripe-Live [EXTERN].
**03.07. abends — Hub-Inhalts-Audit + Rechtstexte (Entscheidung E2: B2B-only!):** Alle Hub-/Web-Inhalte gegen den echten Funktionsstand geprueft und korrigiert (Startseiten-Claims, FAQ, Hilfe, Veroeffentlichen, API-Doku inkl. OpenAPI); kontakt/ueber-uns zurueckgebaut; Rechtstexte aus docs/legal eingebaut (Impressum echt, AGB v0.6, /richtlinien, /melden); Widerrufs-UI raus (E2), Submit-Modal auf Archiv-Hinweis (T2neu); Preise nach Leistungsbeschreibung v0.2. Details in R3.0–R3.2. **Wichtigste offene Folgepunkte:** T1neu Unternehmer-Checkbox im Checkout, Datenschutz-/Cookie-Texte fehlen noch in docs/legal, legal_documents-Versionierung (E3), anwaltliche Freigabe AGB v0.6 [EXTERN].
---
## Ausgangslage (Stand 03.07.2026)
- **Testsuite komplett grün:** 838 passed, 1 skipped (3.678 Assertions, ~70 s).
- **Branch:** `fix/zeitzone-europe-berlin`, **73 Commits vor `main`**, 62 davon ungepusht. `main` hat nichts Neues → Merge/Push ist Teil des Release (R6.5).
- **Keine Debug-Reste** (`dd`/`dump`/Test-Routen) im Backend; Mailables vollständig mit Views; Scheduler (5 Tasks) angeschlossen.
- **Wichtig:** `dev/migration 2026/12-NAECHSTE-SCHRITTE.md` ist teilweise **veraltet** — Stripe/Billing (dort „Phase 8 komplett offen") ist laut `dev/frontend/hub-flux/PROGRESS.md` seit 12.06. umgesetzt (Checkout, Webhooks, Tarif-Admin, Grandfathering). Restaufwand-Schätzungen von dort nicht übernehmen.
- **Nachgelagert (User-Entscheidung 03.07.):** kompletter getesteter Flow fürs User-Panel — bewusst NICHT Teil dieses Plans.
---
## Arbeitsregeln (für jeden Schritt)
- **Test-First bei Korrektheits-/Verhaltensänderungen** (R0–R2): erst Pest-Test, dann ändern.
- Tests gezielt laufen: `php artisan test --compact --filter=<Name>` (wir sind bereits im Sail-Container).
- Nach PHP-Änderungen: Pint (`--dirty`).
- **Web-Frontend** (`resources/views/web/**`, `components/web/**`) gehört dem User → separat committen, **vor jedem Löschen bestätigen lassen**.
- `resources/views/components/layouts/app/sidebar.blade.php` gehört dem User und bleibt aus allen Commits ausgeschlossen (`git reset -q -- …` vor jedem `git add`).
- Jeder Schritt = ein eigener, fokussierter Commit.
- Punkte mit **[EXTERN]** brauchen Input vom User/Auftraggeber (Texte, Entscheidungen, Zugänge) — früh anstoßen, parallel weiterarbeiten.
---
## Phase R0 — Korrektheit & kaputte Pfade (klein, sofort, Test-First)
- [x] **R0.1 Variant-Routen reparieren** — `routes/web.php:211-227`: `/variant-1` + `/variant-2` verweisen für die Businessportal-Domain auf `web.businessportal24-variant-float-glow` / `-glass-gradient` — **diese Views existieren nicht** → 500. Entscheidung: Routen entfernen (Design-Experimente sind abgeschlossen) oder auf `web.businessportal24` zurückfallen. Regressionstest.
- [x] **R0.2 `gdpr_consent_at` im Registrierungsflow befüllen** — Feld existiert (Model-Cast + Migration), wird aber **nirgends geschrieben** (verifiziert 03.07.). Bei Registrierung (Fortify `CreateNewUser`), Magic-Link-/Social-Provisioning (`CustomerAccountProvisioner`) setzen. DSGVO-relevant. Test-First. *(= rev-1 aus migration-Doku)*
- [x] **R0.3 Newsletter-Sync-Binding ehrlich machen** — `AppServiceProvider.php:47` bindet `NewsletterSyncClient` **unconditional** an `NullNewsletterSyncClient`; `NEWSLETter_SYNC_ENABLED=true` bewirkt nichts, das Admin-UI (`admin/newsletter/sync`) suggeriert aber eine funktionierende Sync. Fürs Release: No-Op bleibt (echte Sync ist nachgelagert), aber Binding config-aware machen und im Admin-UI den Placeholder-Status sichtbar ausweisen. Test.
- [x] **R0.4 Seeder produktionssicher machen** —
- `PlanSeeder` (Starter/Business/Pro/Agency) wird von `DatabaseSeeder` **nicht** aufgerufen → in den Produktions-Seed-Pfad aufnehmen (eigener `ProductionSeeder` oder Aufnahme + Guard).
- `PaymentOptionSeeder` schreibt Platzhalter (`prod_placeholder_monthly`, `price_placeholder_monthly`, …) → echte IDs via `billing:sync-stripe-plans` bzw. Seed anpassen (R1.2-Abhängigkeit).
- Test-User (`admin@pressekonto.test`, `test@example.com`, Passwort `password`) in `DatabaseSeeder` nur noch in `local`/`testing` anlegen.
- [x] **R0.5 Fehlerseiten erstellen** — `resources/views/errors/` existiert nicht → 404/500/503 (mind. 404 + 503 theme-/domain-aware fürs Web, neutrale Variante fürs Portal). Render-Tests.
---
## Phase R1 — Backend-Release-Entscheidungen (Billing/Gates)
- [x] **R1.1 Buchungs-/Tarif-Gate prüfen & bereinigen (User-Vorgabe 03.07.)** — Das Gate muss vollständig geprüft und bereinigt werden; **Legacy-Buchungen müssen funktionieren** (Bestandskunden mit Alt-Abo/Grandfathering dürfen veröffentlichen). Ist-Stand beim Testen: ohne gebuchtes Paket keine Veröffentlichung möglich (Gate lokal scharf via `.env`: `BILLING_ENFORCE_BOOKING=true`) — Soll-Verhalten bestätigt. Teilschritte:
- Alle Gate-Pfade durchgehen: `User::hasActiveBooking()`, `hasUnlimitedPressReleaseQuota`, `openSinglePurchaseCount()`, `UserPaymentOption::scopeActiveNow()`/`scopeGrandfatheredNow()`, Submit-Gate im `PressReleaseService`.
- **Legacy-Buchungen end-to-end testen:** migrierter User mit Alt-Abo (grandfathered, gültiges `grandfathered_until`) kann einreichen/veröffentlichen; abgelaufener Bestandsschutz wird korrekt geblockt (`NULL = abgelaufen`, Entscheidung 19.06.).
- Config-Default absichern: `config/billing.php` default `false` — bei vergessenem Prod-Env-Key liefert `hasActiveBooking()` für **alle** `true` → Default auf `true` drehen oder Runbook-Pflichtkey; `.env.example` korrigieren.
- Suite + manueller Submit-Flow (mit/ohne Buchung, mit Legacy-Buchung) gegengetestet.
- [ ] **R1.2 Stripe produktiv vorbereiten** — `billing:sync-stripe-plans` gegen **Live-Mode** ausführen (bislang nur Test-Mode); `STRIPE_PRICE_SINGLE_PM` setzen (sonst ist Einzel-PM-Checkout stumm deaktiviert, `CheckoutController.php:58`); Plan-`stripe_price_id_monthly/_yearly` gepflegt (sonst Abo-Checkout deaktiviert). Danach Checkout-Smoke-Test inkl. Webhook. **[EXTERN: Live-Stripe-Zugang]**
- [x] **R1.3 Quota-Reset-Provisorium festschreiben** — `ResetMonthlyPressReleaseQuota` ist als „temporärer Stub bis zum echten Tarif-/Credit-Modul" markiert, läuft aber monatlich per Scheduler. Prüfen ob das Verhalten fürs Release korrekt ist (Zusammenspiel mit Credit-Wallet/Add-ons); Doc-Kommentar aktualisieren oder Logik ersetzen.
- [ ] **R1.4 Preise/Lineup final abstimmen** — `PreisePageData.php:44` TODO („Lineup/Preise hängen am Bookings-/Magic-Link-Rework"): öffentliche Preisseite (correction/update/depublish-Pfade) gegen finale Preisliste prüfen. **[EXTERN: Preisfreigabe]**
- [ ] **R1.5 Refund-Workflow: Entscheidung** — laut hub-flux offen. Empfehlung: nachgelagert (Refunds initial direkt im Stripe-Dashboard), Entscheidung dokumentieren.
---
## Phase R2 — Web-Frontend funktional fertigstellen
- [x] **R2.1 Kontaktformular anbinden** — `kontakt.blade.php:52` TODO: aktuell nur `mailto:`, kein Form/Handler; Telefon/Adresse sind Fake-Daten. Umsetzung analog `LegalRequestController` (POST-Controller + Validierung + Honeypot + `throttle` + Mailversand an konfigurierbare Adresse). Feature-Tests. Echte Kontaktdaten **[EXTERN]**.
- [x] **R2.2 Hub-Pricing datengetrieben** — `pressekonto.blade.php:401/469/538`: 3 hartcodierte Pricing-`<article>`s (0 €/49 €/149 €) → `<x-web.pricing-teaser>` (iteriert `Plan::active()`, wird von beiden Spokes schon genutzt). Beseitigt Drift-Risiko zum Plan-Katalog. *(= alt Phase 6.1)*
- [x] **R2.3 Tote `href="#"`-Links in Live-Seiten fixen** — pressekonto (16×, u. a. Kundenlogos + Support-/Datenschutz-Links), release-detail (3×, Share-Aktionen), `hub/top-utility-bar` (3×), `events-week`/`highlight-card`. Echte Ziele setzen oder Elemente entfernen.
- [x] **R2.4 SEO-Basics** — Erledigt 03.07.: Host-aware `sitemap.xml` (Hub: Landing + Rechts-/Info-Seiten; Spokes: zusätzlich Kategorien, öffentliche Newsrooms, alle im Archiv sichtbaren PMs des Portals; 1h-Cache pro Host). `robots.txt` jetzt dynamische Route mit Sitemap-Verweis + Disallow (/admin, /login, /register, Suche) — die statische `public/robots.txt` wurde entfernt (**Deploy-Hinweis:** nicht wieder anlegen, sie würde die Route verschatten). karriere/partner/presse/team: Brand pro Request via `WebPortalContext` (statt hartcodiert „Business Portal 24") + Meta-Descriptions; bp24-Home auf config-getriebenes meta_title/meta_description-Muster vereinheitlicht. Sitemap listet bewusst nur die de-Edition (en-Entscheidung offen, s. Rechtstexte-Doku O3) und lässt Suche + Marketing-Platzhalterseiten (R3.2) draußen. Tests: `SitemapRobotsTest`.
- [ ] **R2.5 legal-request-Hinweistexte finalisieren** — `legal-request.blade.php:8/65`: Texte je Anfragetyp als „ENTWURF" markiert. **[EXTERN: finale Texte]**
---
## Phase R3 — Inhalte [EXTERN, früh anstoßen, parallelisierbar]
- [x] **R3.0 Online-Widerruf (gesetzlicher Widerrufsbutton)** — Umgesetzt 03.07., **danach per Entscheidung E2 (B2B-only, `docs/legal/Entscheidung.md` v2.0) zurückgebaut:** Das Angebot richtet sich ausschließlich an Unternehmer (§ 14 BGB), ein Widerrufsrecht besteht nicht — Button + Modal aus Hub-Footer/Static-Shell entfernt, Widerrufsbelehrung archiviert. Backend (`POST /widerruf`, `withdrawal_requests`, Mails, Admin-Queue) bleibt schlafend erhalten und ist bei B2C-Öffnung reaktivierbar.
- [x] **R3.0b Kündigungsbutton** — Erledigt 03.07.: „Verträge hier kündigen"-Button (Hub-Footer + jetzt auch Spoke-Footer) → öffentliche Bestätigungsseite `/de/kuendigung` ohne Login → persistiert `termination_requests` + sofortige Zugangsbestätigung per Mail + Betreiber-Mail; Admin-Queue mit K-Vorgängen. **Einordnung nach E2:** § 312k ist im B2B keine Pflicht — der Selfservice bleibt bewusst als Anti-Zombie-Standard (T3neu).
- [x] **R3.0c Erlöschens-Checkbox → Archiv-Hinweis (T2neu)** — Die § 356-Erlöschens-Bestätigung entfiel mit E2 (B2B-only); an ihrer Stelle verlangt das Einreichungs-Modal jetzt die von AGB § 13 Abs. 1 geforderte Bestätigung der dauerhaften Archivierung (Depublikation nur als kostenpflichtiger Service, gesetzliche Ansprüche unberührt). Zeitpunkt wird weiter als `withdrawal_waiver_consented_at` protokolliert (Spaltenname historisch — Umbenennung optional). Index-Schnell-Submit (wire:confirm) bleibt durch das gemeinsame Modal ersetzt.
- [~] **R3.1 Rechtstexte final** — **Inhalte eingebaut 03.07. (Quelle: `docs/legal/*`, untracked):** Impressum (echte Anbieterdaten adametz.media/Bielefeld, DDG, MStV, DSA-Kontaktpunkt via neuer `REPORT_EMAIL_*`-Keys), AGB v0.6 (B2B-Fassung, §§ 1–16, interne Anwalts-Anmerkungen entfernt, Version zentral in `config/legal.php`), **Datenschutzerklärung v0.3** (host-aware Bausteine: Hub Kundenkonto/Login/Stripe, Spokes Medienprivileg/Newsroom/Änderungslinks; Magic-Link-TTL 15 Min. aus dem Code, Logs 14 Tage, Stripe Payments Europe), neue Seiten `/richtlinien` (Rahmentext + K1–K6 statisch) und `/melden` (DSA/DSGVO/Änderung/Depublikation, verdrahtet mit den bestehenden Melde-Links je PM); **Cookie-Seite zurückgebaut** (User-Entscheidung: Cookies in Datenschutz Abschnitt 4, kein Banner; 301 auf /datenschutz). **T1neu erledigt:** Unternehmer-Pflicht-Checkbox im Buchungs-Modal, protokolliert in `booking_confirmations` (Timestamp, IP, AGB-Version); CheckoutController verlangt serverseitig eine zeitnahe Bestätigung (30 Min.) für Abo/Einzel-PM/Topup. Footer + Sitemap ergänzt; Preise-Seite nach Leistungsbeschreibung v0.2 (B2B-Satz, T9-Credit-Anker, Slots/Credits/Boost/Partner-Blöcke, T16-Wording inkl. PlanSeeder). **Noch offen:** (a) legal_documents-Versionierung + `agb_version_id` an Buchungen (E3, config/legal.php ist die Übergangslösung) und rejection_categories-DB; (b) T10 DSA-Meldeformulare mit URL-Feld + Vorgangsnummer, T12 Depublikations-Checkout, T13 „Inhalt melden"-Button prominenter an PM; (c) Umami ist in der Datenschutzerklärung beschrieben, aber noch nicht installiert [EXTERN: Ploi]; Log-Frist 14 Tage + Backups 4 Wochen mit Server-Konfig abgleichen; REPORT_EMAIL_* (melden@/legal@) vergeben; (d) AGB v0.6 anwaltsreif, finale anwaltliche Freigabe [EXTERN].
- [x] **R3.2 Marketing-Seiten: Inhalt oder Rückbau** — Entschieden + umgesetzt 03.07. (User: Rückbau): `presse`, `team`, `karriere`, `partner` und (2. Runde) `kontakt`, `ueber-uns` samt Routen entfernt (erfundene Adresse/Telefon/Anfahrt bzw. Team/Kennzahlen/Timeline); GET-Alt-Pfade → 301 Startseite, `kontakt.store`-POST bleibt fürs Hub-Modal, Spoke-Footer-Kontakt als mailto (Fallback Betreiber-Postfach bis R2.1). `hilfe` und `faq` inhaltlich auf den echten Funktionsstand gebracht (tote #-Links raus, echte Limits/Features), `veroeffentlichen` vom Fantasie-Preismodell („ab 89 €", Credits je PM, Cross-Publishing separat) auf echte Konditionen umgestellt (datengetrieben via `VeroeffentlichenPageData`). `api`-Seite komplett neu als echte Referenz + OpenAPI `docs/api/v1.yml` (Route lief vorher auf nie existierende Datei → 500 aus Hub-Footer/FAQ).
---
## Phase R4 — Web-Frontend aufräumen (= alt Phase 6; vor jedem Löschen bestätigen)
> Kontext (User, 03.07.): Bei der Frontend-Entwicklung gab es eine **alte Version** — es können noch **Fragmentseiten aus dieser Version** herumliegen. Die Funde unten (examples/, altes engl. Header/Footer-Layout, welcome, brand-mark, Variant-Views) passen dazu; beim Aufräumen gezielt nach weiteren Alt-Fragmenten suchen (auch in `components/web/**` und ungerouteten Blades).
- [x] **R4.1 Tote Dateien entfernen** — Erledigt 03.07. (User-Freigabe): `web/examples/` (4 Demo-Views), `welcome`, `home` („B2IN"-Fragment), `brand-mark`-View (die gleichnamige, viel genutzte *Komponente* bleibt), `layouts/web-master-test`, altes engl. `layouts/header`+`footer` — alle per grep verifiziert (inkl. dynamischer Auflösung).
- [x] **R4.2 Tote Komponenten entfernt** — Erledigt 03.07.: die 12 gelisteten `x-web`-Komponenten + 7 zusätzlich gefundene Chain-Dead-Komponenten (`main-navigation`, `breadcrumb`, `page-header`, `content-layout`, `article-card`, `section-header`, `sidebar-widget` — nur von examples/ bzw. anderen toten Kandidaten referenziert). Verwaiste `.highlights-slider`-CSS-Regeln mit entfernt, Web-Build gegengeprüft. Suite grün.
- [ ] **R4.3 Dedup (optional, nice-to-have)** — Release-Card-Vereinheitlichung, Industrie-Icon-Map → Config, Inline-SVGs → Icon-Set, `<x-web.container>` (alt 6.2/6.3). Nur wenn Zeit; kein Release-Blocker.
---
## Phase R5 — Deploy-Readiness
- [x] **R5.1 `.env.example` vervollständigen** — Erledigt 03.07.: alle projektspezifischen Keys ergänzt und dokumentiert (Multi-Domain `APP_PORTAL_*`/`APP_PRESSEECHO_*`/`APP_BUSINESSPORTAL_*`/`APP_PROTOCOL`, `SANCTUM_STATEFUL_DOMAINS`, Legacy-DBs, Stripe/Cashier/Billing inkl. `STRIPE_PRICE_SINGLE_PM` + `BILLING_OWN_VAT_ID`, KI `OPENAI_*`/`CLASSIFICATION_*`/`CONTENT_SCORE_*`, `NEWSLETTER_SYNC_*`, `VITE_DEV_SERVER_URL`, `SESSION_SECURE_COOKIE`-Prod-Hinweis). Werte selbst (Live-Keys, Adressen) bleiben [EXTERN].
- [x] **R5.2 Deploy-Runbook schreiben** — Erledigt 03.07.: `dev/release/deploy-runbook.md` — Server-Voraussetzungen, Prod-`.env`-Solltabelle, Build-/Release-Schritte (composer, `npm run build`, storage:link, migrate --force, Stammdaten-Seeder, Caches, queue:restart), Queue-Worker (Queue `classification`, systemd-Beispiel), Cron/Scheduler (5 Tasks mit Ausfall-Folgen), Stripe-Webhook, Erst-Einrichtung (Legacy-Import-Reihenfolge), Smoke-Test-Checkliste, Rollback. Enthält den robots.txt-Deploy-Hinweis aus R2.4.
- [ ] **R5.3 Monitoring/Alerting entscheiden** — kein Sentry o. ä. installiert; Scheduler-/Queue-Failure-Alerting fehlt. Minimalvorschlag: `schedule`-`onFailure`-Mail + Log-Rotation; optional Sentry. **[EXTERN: Entscheidung]**
- [ ] **R5.4 Favicons je Domain** — `domains:generate-favicons` erzeugt bewusst leere Platzhalter-Dateien; echte Favicons für pressekonto/presseecho/businessportal24 deployen. **[EXTERN: Assets]**
---
## Phase R6 — QA & Go-Live (teils extern/Ops)
- [ ] **R6.1 Manuelle QA-Checkliste durcharbeiten** — `dev/migration 2026/06-FEATURES-SCOPE.md` §15 (komplett offen): Logins inkl. 2FA + Magic-Link, Portal-Scoping, PM-Workflow Admin+Customer, Image-Upload, Blacklist, Stripe-Checkout inkl. Webhook + Invoice-PDF, Grandfathering, Legacy-Rechnungen, API (Sanctum + Abweisung alter api_key), Thumbnail-Redirect, Scheduler. Dabei auch verifizieren, was die (veraltete) Frontend-Konzept-Doku noch als offen führt (Branchen-/Kategorieseite, Veröffentlichen-Landing — im Code existieren `KategorieController`/`VeroeffentlichenController` bereits → visuell abnehmen statt neu bauen).
- [x] **R6.2 Security-Review** — Audit + Härtung erledigt 03.07. **Solide befunden:** CSRF (Stripe-Webhook via Signatur, keine Ausnahmen), Magic-Link-Krypto (64-Zeichen-Token, sha256-gehasht, atomare Einmalverwendung), HTMLPurifier-Sanitizing der PM-Texte, Raw-Queries durchgängig mit Bindings, IDOR-Schutz doppelt (Scope + Policy), BasicAuth timing-sicher, Session host-only korrekt fürs Hub-and-Spoke-Setup. **Gefixt:** Security-Header-Middleware (app-seitig), Logo-Upload im Company-Create über ImageService (vorher SVG/XSS möglich), Rate-Limits für Passwort-Reset/Registrierung/Consume-Routen, `EnsureUserIsCustomer` als persistente Livewire-Middleware. Tests: `SecurityHardeningTest`. **Offen/bewusst:** CSP separat einführen (Livewire/Alpine-Inline-Strategie nötig); Token-Abilities werden auf API-Routen nicht feingranular geprüft (ein Scope für alles — ok, solange keine eingeschränkten Tokens ausgegeben werden); Draft-PM-Anhänge nur per URL-Obscurity (dokumentierter MVP-Tradeoff); HSTS am Proxy setzen; **[USER-ENTSCHEIDUNG] Legacy-SQL-Dumps (`dev/migration 2026/sql/*.sql`, Produktivdaten!) sind im Git getrackt — enttracken + ggf. History bereinigen.**
- [ ] **R6.3 Staging-Import-Rehearsal** — Datenimport gegen produktiven Legacy-Snapshot auf Staging (mehrfach als der offene Vollständigkeitsnachweis referenziert, P6.10/P11.3). Achtung: `mysql_businessportal`-Verbindung lokal ist nur ein ~April-Snapshot — fürs Rehearsal echten aktuellen Dump ziehen. **[EXTERN: Server/Snapshot]**
- [ ] **R6.4 Go-Live-Kette** — Go-Live-Mailing (Passwort-Reset) + API-Kunden-Mailing: Code fertig, **finale Texte + Freigabeliste [EXTERN]**; DNS-Cutover `pressekonto.de`; Legacy-System read-only während Final-Import; alte Symfony-Server abschalten. *(= P11.x)*
- [ ] **R6.5 Git-Hygiene** — Branch `fix/zeitzone-europe-berlin` (73 Commits vor `main`) pushen und nach `main` mergen; danach Release-Tag. Die drei `user_filter_presets`-Migrations zusammenführen (rev-5, „Hygiene vor Go-Live") optional davor.
- [x] **R6.6 Doku-Sync** — Erledigt 03.07.: `12-NAECHSTE-SCHRITTE.md` + `08-PROGRESS.md` tragen deutliche Verweis-Banner auf den aktiven Release-Plan (Phase 8/Stripe als erledigt markiert, Test-Stand korrigiert).
---
## Bewusst NACHGELAGERT (kein Teil dieses Release-Plans)
- **Kompletter getesteter User-Panel-Flow** (User-Entscheidung 03.07.2026).
- Echte Newsletter-Sync-Implementierung (No-Op bleibt, R0.3 macht es nur ehrlich); Newsletter-Subscriber-Admin/CSV (P3.7, vertagt).
- Coupons (UI-Skeleton, D-16 vertagt), Google-Login (Socialite), Regionen-Übersichten `/region/{slug}` (301-Redirect bleibt), Blacklist-Admin-UI (Config reicht), PM-Nice-to-haves (Inline-Edit, Bulk, In-App-Notifications, Permission-Granularität).
- Legacy-Logging/-Performance-Deployments (betreffen nur das Alt-System als Überbrückung bis zum Cutover).
- Performance-Polishing aus `11-NOCH-ZU-TUN-OPTIMIERUNGEN.md` (Slow-Query-Auswertung braucht echte Live-Daten).
- Coverage-Ziel 70 % / arch()-Tests / `test --parallel` (P10.1–10.3) — Suite ist grün, Ausbau nachgelagert.
---
## Reihenfolge-Empfehlung (TL;DR)
1. **R0** sofort — kaputte Pfade, DSGVO, Seeder, Fehlerseiten (alles klein, Test-First).
2. **[EXTERN]-Punkte parallel anstoßen** — Rechtstexte (R3.1), Stripe-Live-Zugang (R1.2), Enforce-Booking-Entscheidung (R1.1), Kontaktdaten (R2.1), Mailing-Texte (R6.4). Das sind die längsten Wartezeiten.
3. **R1 + R2** — Billing scharf + Frontend funktional (Kern der Fertigstellung).
4. **R4 + R5** — Aufräumen + Deploy-Runbook, sobald R1/R2 stehen.
5. **R6** — QA, Security, Rehearsal, Cutover.