From 6b1d84fc01a163f876f1ebc4dce37c8447553570 Mon Sep 17 00:00:00 2001 From: Kevin Adametz Date: Thu, 2 Jul 2026 08:44:44 +0000 Subject: [PATCH] Doku: 5.4 abgeschlossen + 5.5 Teil-Stand im Entwicklungsplan 5.4 als erledigt markiert (page-header/empty-state/table-pagination; table- panel + searchable-select bewusst nicht gebaut). 5.5 Teil-erledigt (alert + session-status); password-input + rate-limit-trait mit Begruendung zurueck- gestellt. Wiedereinstieg-Abschnitt + Datum aktualisiert, Perf-Fix vermerkt. Co-Authored-By: Claude Opus 4.8 (1M context) --- dev/optimize/entwicklungsplan.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/dev/optimize/entwicklungsplan.md b/dev/optimize/entwicklungsplan.md index cc7f1b21..a40be7ff 100644 --- a/dev/optimize/entwicklungsplan.md +++ b/dev/optimize/entwicklungsplan.md @@ -5,18 +5,18 @@ --- -## Stand & Wiedereinstieg (zuletzt: 19.06.2026) +## Stand & Wiedereinstieg (zuletzt: 02.07.2026) -**Fertig:** Phasen **0, 1, 2, 3, 4** vollständig · **5.1** vollständig · **5.2 Teil 1** (Form-Rules-Concern) · **5.3 Teil 1+2** (`Contact::displayName()`, `Category::localizedName()`). -Gesamttest-Suite zuletzt grün (**818 passed, 1 skipped**), Pint sauber. Jeder Schritt ist ein eigener Commit (`git log` Präfix „Optimierung X.Y"). +**Fertig:** Phasen **0–4** vollständig · **5.1** · **5.2 Teil 1** (Form-Rules-Concern) · **5.3 Teil 1+2** (`Contact::displayName()`, `Category::localizedName()`) + `portalBadgeColor()`-Toter-Code entfernt · **5.4 vollständig** (page-header 33 Seiten, empty-state 5 States, table-pagination 13 Wrapper) · **5.5 Teil-erledigt** (``, ``). +Zusätzlich **Perf-Fix** auf `/admin/me/press-releases`: `User::accessibleCompanyIds()` hydratisierte ~107k Company-Models (jetzt `toBase()`-pluck + memoisiert), `accessibleBy()` nutzt company_id-Subquery, Status-Counts via UNION statt OR-GROUP-BY; neue `PressRelease::accessibleStatusCountsFor()`. Und Fix: fehlendes `.search-wrap`-CSS (Suchfeld /admin/me/firmen). +Pint sauber, betroffene Test-Filter grün. -**Hier geht es weiter** — der gesamte Rest ist **Blade-Component-Extraktion** und braucht **visuelle Kontrolle im Browser** (die automatischen Tests prüfen nur Text-Präsenz, keine Optik). Empfehlung: **eine Component pro Commit**, danach im Browser gegenchecken (`vendor/bin/sail npm run dev`). Reihenfolge des Wiedereinstiegs: +**Hier geht es weiter** — der Rest ist teils UI-Extraktion (visuelle/funktionale QA nötig), teils backend-testbar. Empfehlung weiterhin: **eine Component/ein Schritt pro Commit**, im Browser gegenchecken (`vendor/bin/sail npm run dev`). -1. **5.4 Seiten-Struktur-Components** (risikoärmster UI-Einstieg, rein additiv): ``, ``, `` usw. — je Component erst die Komponente bauen (Muster: bestehende ``), dann eine Admin-Seite umstellen und visuell prüfen, dann die übrigen. -2. **5.3 Rest** (Badges/Formatierung): `portalBadgeColor()` ist **erledigt** — die Helfer waren tot (kein Call-Site) und wurden entfernt, eine `Portal::badgeColor()`-Zentralisierung entfällt. Offen bleibt nur die UI-Extraktion: `PressReleaseStatus`-Badge-Methode + ``/``/``/``. -3. **5.2 Rest**: gemeinsamer `UserUpsertService`/`SaveUserAction` (Achtung: Anlegen vs. Bearbeiten divergieren stark — Bearbeiten trägt zusätzlich Profil/Kontakte/Passwort/2FA; nur den wirklich gemeinsamen Persistenz-Kern ziehen) + Blade-Feld-Components (`billing-fields`, `company-link-picker`, `role-checkboxes`, `contact-fields`). -4. **5.5 Flash/Auth-Components**. -5. **Phase 6** (Web-Frontend) — separat, dem User gehörend, vor jedem Löschen bestätigen lassen. +1. **5.5 Rest** (braucht **funktionale Auth-QA**): `` — 7 Felder über login/register/reset/confirm divergieren (Label-Zeile mit „vergessen?"-Link, `:placeholder`-Bindung, current-/new-password, Alpine-`showPassword` auf Form-Ebene). Rate-Limit-Trait bleibt zurückgestellt (login vs. magic-link divergieren zu stark). +2. **5.2 Rest**: gemeinsamer `UserUpsertService`/`SaveUserAction` (Achtung: Anlegen vs. Bearbeiten divergieren stark — Bearbeiten trägt zusätzlich Profil/Kontakte/Passwort/2FA; nur den wirklich gemeinsamen Persistenz-Kern ziehen) + Blade-Feld-Components (`billing-fields`, `company-link-picker`, `role-checkboxes`, `contact-fields`). +3. **5.3 Rest**: `PressReleaseStatus`-Badge-Methode + ``/``/`` (die Status-Badge-Call-Sites nutzen divergente Farb-Vokabulare — vor Zentralisierung klären). +4. **Phase 6** (Web-Frontend) — separat, dem User gehörend, vor jedem Löschen bestätigen lassen. **Wichtig beim Wiedereinstieg:** `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`). `resources/views/web/**` und `components/web/**` erst in Phase 6. @@ -103,8 +103,8 @@ Keine Fachlogik-Änderung. Reduziert erreichbare Demo-Komponenten und Altlasten. - [x] **5.1 Tabellen-Concerns** — `HasSortableTable::sort()` (5 byte-identische Kopien zentralisiert; `$sortBy`/`$sortDir`-Defaults bleiben in der Komponente, da sie divergieren) und `HasFullTextSearch::supportsFullTextSearch()` (9 byte-identische Kopien — 4 Index-Listen + 5 Firmen-Comboboxen; nicht mehr genutzte `DB`-Imports entfernt). `AdminPerformanceCache::activeInactiveStats(Builder)` bündelt den identischen `SUM(CASE WHEN is_active)`-Block der Benutzer- und Firmenliste. Tests: erweiterte `AdminPerformanceCacheTest`; abgesichert durch 99 `Admin/`-Tests. **Bewusst zurückgestellt:** `HasResettableFilters` (die `updatedXxxFilter()` divergieren — manche normalisieren zusätzlich Werte; ein generischer `updated()`-Hook wäre eine Verhaltensänderung) und eine gemeinsame `hydrateRelationCounts()` (Count-Hydration unterscheidet sich je Tabelle real). - [~] **5.2 User create/edit entdoppeln** — **Teil 1 erledigt:** `ProvidesUserFormRules`-Concern bündelt die zwischen Anlegen/Bearbeiten identischen Validierungsblöcke (`userIdentityRules(?int $ignore)`, `userRolesAndCompaniesRules()`, `userBillingRules()`); die nur im Bearbeiten genutzten Profil-/Kontakt-Regeln bleiben dort inline. Beide Formulare nutzen die Spreads, 31 User-Tests grün. **Offen (bewusst, mit User abzustimmen):** gemeinsamer `UserUpsertService`/`SaveUserAction` für die ~175-Zeilen-`save()` (Anlegen/Bearbeiten divergieren stark — Bearbeiten trägt zusätzlich Profil, Kontakte, Passwort, 2FA), sowie die Blade-Feld-Components (`billing-fields`, `company-link-picker`, `role-checkboxes`, `contact-fields`) — Markup-Extraktion braucht visuelle QA (analog zur zurückgestellten 2.8). - [~] **5.3 Formatierungs-Components/Enum** — **Erledigt (Model-Methoden, getestet):** `Contact::displayName()` (6 Relation-Stellen ersetzt; `ContactDisplayNameTest`) und `Category::localizedName()` (4 Stellen; `CategoryLocalizedNameTest`). **Geklärt & erledigt:** Die `portalBadgeColor()`-Helfer in `companies/index`, `companies/show`, `contacts/index` waren toter Code (kein Aufruf) und wurden entfernt — eine `Portal::badgeColor()`-Zentralisierung ist damit gegenstandslos. **Offen (UI-/Blade-lastig, mit User abzustimmen):** `PressReleaseStatus`-Badge-Methode sowie die Blade-Components ``, ``, ``, `` (Markup-Extraktion braucht visuelle QA). -- [ ] **5.4 Seiten-Struktur-Components** — ``, ``, ``, ``, ``, ``. (Muster: bestehende ``/`components.portal.pagination`.) -- [ ] **5.5 Flash/Auth-Components** — `` + `` app-weit; ``, ``/``; `ensureNotRateLimited()/throttleKey()`-Trait (login/magic-link divergieren); ``. +- [x] **5.4 Seiten-Struktur-Components** — **erledigt.** `` (Props size sm/md/lg + descriptionWidth, Slots :meta/:actions) über **33 Seiten** ausgerollt; `` (Icon-Slot, variant warm/err, Default-Slot für Onboarding) über **5 States**; `` (:paginator) über **13 Wrapper**. **Bewusst nicht gebaut:** `` (nur triviales `
`, keine wiederholte Innenstruktur → Over-Engineering) und `` (existiert nirgends — keine `flux:combobox`). **Bewusst bespoke:** companies/show + press-releases/show (Sonder-Header mit Logo/Untertitel). +- [~] **5.5 Flash/Auth-Components** — **Erledigt:** `` (6 Flash-Blöcke: categories/create+edit, footer-codes/index, presets/index) und `` (login, forgot-password, register, magic-link). **Bewusst bespoke:** companies/show (icon-loses Flash-Design + info-Variante), verify-email/settings-profile (eigene Status-Logik). **Offen (bewusst zurückgestellt, braucht funktionale Auth-QA):** `` — 7 Felder über login/register/reset/confirm divergieren (Label-Zeile mit „Passwort vergessen?"-Link vs. schlicht, statische vs. `:placeholder`-Bindung, current-/new-password, Alpine-`showPassword`-State auf Form-Ebene); Extraktion verlagert Alpine-State in die Component und muss die Login-/Registrier-/Reset-Flows funktional (nicht nur optisch) verifizieren. `ensureNotRateLimited()/throttleKey()`-Trait bleibt zurückgestellt (login: 1 Key/5 Versuche/Lockout-Event/clear-on-success vs. magic-link: 2 Keys/3+15 Versuche/Stunden-Decay/kein Event — zu wenig gemeinsame Fläche). ``/``/`` optional, geringer Hebel. ---