From 226fb8131a0a2ff0246f8ea8d84fc0875e402719 Mon Sep 17 00:00:00 2001 From: Kevin Adametz Date: Fri, 18 Sep 2026 10:41:58 +0000 Subject: [PATCH] dev: Umsetzungsprotokoll und Live-Schritte zum Audit-Entwicklungsplan Co-Authored-By: Claude Fable 5.1 --- dev/2026-09-11-audit/ENTWICKLUNGSPLAN.md | 37 ++++++++++++++++++------ 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/dev/2026-09-11-audit/ENTWICKLUNGSPLAN.md b/dev/2026-09-11-audit/ENTWICKLUNGSPLAN.md index efc0c31a..8213633e 100644 --- a/dev/2026-09-11-audit/ENTWICKLUNGSPLAN.md +++ b/dev/2026-09-11-audit/ENTWICKLUNGSPLAN.md @@ -187,16 +187,26 @@ Beide latent. Aufnehmen, weil die Fixes klein sind und der Fehler beim ersten Da ## Reihenfolge und Deploys -| Schritt | Inhalt | Deploy | -|---|---|---| -| 1 | Block 1, Punkte 1.1, 1.2, 1.6, 1.8, 1.9, 1.10 (alles S, kein Schema) | Deploy A, Hotfix-Charakter | -| 2 | Block 2 komplett (Migration: ein Unique-Index auf kleiner Tabelle) | Deploy B, vor der nächsten Kampagne | -| 3 | Block 1, Punkte 1.3, 1.4, 1.5, 1.7 (Migration `granted_via`, Bestandsprüfung) | Deploy C | -| 4 | Block 3 | Deploy D (Migration: Index `contacts.email`) | -| 5 | Block 4 | Deploy E (Migration: `quota_period`, `ki_audits.content_hash`) | -| 6 | Block 5, Block 6 | Deploy F | +Tatsächlich umgesetzt am 18.09.2026 in fünf Commits auf `technik/betriebsfixes-2026-09`. Block 3 und 4 teilen sich Dateien (User-Modell, PressReleaseService) und wurden deshalb zusammen committet. -Migrationen in diesem Plan berühren `press_releases` nicht. `press_release_search` bleibt unangetastet. Für `users` (25 MB, FULLTEXT) ist die Spalte `quota_period` ein `ALGORITHM=COPY` von wenigen Sekunden; nach dem üblichen Fenster nachts einspielen. +| Deploy | Inhalt | Commit | Migrationen | +|---|---|---|---| +| A | Block 1, Punkte 1.1, 1.2, 1.6, 1.8, 1.9, 1.10 | `0ab53bf` | keine | +| B | Block 2 komplett | `a7f991f` | Unique-Index `newsletter_campaign_recipients` (räumt Doppelungen vorher weg) | +| C | Block 1, Punkte 1.3, 1.4, 1.5, 1.7 | `62202a4` | `company_user.granted_via` | +| D | Block 3 und Block 4 | `f235156` | `contacts_email_idx`; `ki_audits.content_hash/discarded_at`; `users.press_release_quota_period` (COPY, Sekunden) | +| E | Block 5 und Block 6 | `375f4df` | `user_payment_options.billing_hold_reason/-at` | + +Migrationen berühren `press_releases` und `press_release_search` nicht. + +### Live-Schritte nach dem Deploy + +1. `php artisan migrate --force` (sechs Migrationen, alle kurz; `users` als einziges COPY, nachts einspielen). +2. `php artisan company-memberships:audit` – Liste sichten (Tabelle: nicht erklärbare `responsible` seit Go-Live; CSV vollständig in `storage/app`). Danach `--classify`, damit erklärbare Rechte als `auto` gelten und der Login-Sync sie zurücknehmen kann. +3. `php artisan schedule:list` – neuer Task `billing:expire-grandfathering` um 04:15 muss erscheinen. +4. Queue-Worker neu starten (Job-Timeouts und `retry_after` 150 greifen erst dann). +5. Kunden mit aktiver 2FA sehen auf der Sicherheitsseite ein neues Code-Feld vor „Deaktivieren“ und „Neue Codes“; E-Mail-Änderung fragt nach Passwort oder Code. +6. Nächste Newsletter-Kampagne erst nach diesem Deploy starten. ## Entscheidungen @@ -215,3 +225,12 @@ Am 18.09.2026 alle sechs nach Empfehlung entschieden. Umsetzung ab demselben Tag | Datum | Punkte | Commit | Bemerkung | |---|---|---|---| +| 18.09.2026 | 1.1, 1.2, 1.6, 1.8, 1.9, 1.10 | `0ab53bf` | Fortify-Profilendpunkt aus, Sync verlangt verifiziertes aktives Konto, Google-2FA, `#[Locked]`, Gate nur für aktive Super-Admins, Route unter `can:users:manage` | +| 18.09.2026 | 2.1–2.6 | `a7f991f` | Auf der Dev-Kopie 470 doppelte Empfängerzeilen, die Migration räumt sie weg; Zusatzbefund: Sperrlisten-Adressen galten als „gesendet“; `newsletter:resume` | +| 18.09.2026 | 1.3, 1.4, 1.5, 1.7 | `62202a4` | `granted_via`, `company-memberships:audit`, Entzug beim Login, TOTP-/Recovery-Nachweis; passwortlose Konten (66.000 im Bestand) können die Adresse weiter ändern | +| 18.09.2026 | 3.1–3.7, 6.5 | `f235156` | 28 Dateien auf `withoutGlobalScope(PortalScope::class)`, 39 Ausnahmen per Architekturtest eingefroren; `EmailQuery` (MySQL direkt, SQLite LOWER); Firmen-Observer; `ReportedUrlResolver` | +| 18.09.2026 | 4.1–4.6 | `f235156` | Hash-Bindung in beiden Jobs und im Scheduler; Kontingentperiode; Exit-Code; Timeout 120 / retry_after 150; Aggregations-Lock | +| 18.09.2026 | 5.1–5.3 | `375f4df` | Vertragsende in Auswahl und Sperre; `billing:expire-grandfathering` mit Mail; Sperrvermerk und Seitenlauf | +| 18.09.2026 | 6.1–6.4 | `375f4df` | `pint --test`, `dev:all`, Doku-Einstieg, Fokusführung ohne neue Abhängigkeit | + +Offen aus dem Plan: 6.6 (MySQL-/Worker-Integrationstests) bleibt aufgeschoben. Beobachtung: `ManualInvoicePdfTest` (Anrede „Frau“) ist zufallsabhängig und schlägt allein gestartet in etwa drei von vier Läufen fehl, in der Gesamtsuite nicht – nicht durch diesen Plan verursacht, aber ein Kandidat für die nächste Session.