docs: State-Management-Ist-Analyse + Umbauplan (M2), ROADMAP-Punkt annotiert

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Bernd Steckmeister
2026-07-06 17:50:05 +02:00
parent 41bcaf2a88
commit 6b0ae21f2b
4 changed files with 125 additions and 0 deletions
+3
View File
@@ -1424,3 +1424,6 @@
2026-07-06 17:44 [Edit] C:\Users\nordm\pyramid - Kopie\ROADMAP.md 2026-07-06 17:44 [Edit] C:\Users\nordm\pyramid - Kopie\ROADMAP.md
2026-07-06 17:45 [Edit] C:\Users\nordm\pyramid - Kopie\PROGRESS.md 2026-07-06 17:45 [Edit] C:\Users\nordm\pyramid - Kopie\PROGRESS.md
2026-07-06 17:47 [Edit] C:\Users\nordm\pyramid - Kopie\lib\core\app_state.dart 2026-07-06 17:47 [Edit] C:\Users\nordm\pyramid - Kopie\lib\core\app_state.dart
2026-07-06 17:49 [Write] C:\Users\nordm\pyramid - Kopie\docs\M2_STATE_MANAGEMENT.md
2026-07-06 17:49 [Edit] C:\Users\nordm\pyramid - Kopie\ROADMAP.md
2026-07-06 17:49 [Edit] C:\Users\nordm\pyramid - Kopie\PROGRESS.md
+28
View File
@@ -13,6 +13,34 @@ Schritt (und beim Abbruch mitten im Schritt den Zwischenstand). Format:
--- ---
## 2026-07-06 State-Management-Ist-Analyse (docs/M2_STATE_MANAGEMENT.md) + toter incomingCallProvider entfernt
**Erledigt:** Nächster offener M2-Punkt „Einheitliches State-Management"
nach dem erprobten Vorgehen erst die Analyse, Umsetzung folgt gestaffelt:
- **`docs/M2_STATE_MANAGEMENT.md` geschrieben:** Repo-weite Bestandsaufnahme
(Riverpod schon dominant, ~50 Provider, keine ValueNotifier/eigenen
StreamController). 4 Misch-Patterns identifiziert und gewichtet:
(1) Call-Singletons + ChangeNotifier hinter den Pilot-Fassaden mit
UI-Zustand IN den Managern, (2) `activeVoiceRoomIdProvider`/
`voiceParticipantsProvider` liegen in app_state.dart statt im
voice_channel-Modul, (3) `MediaCache.instance`, (4) Push-Globals
(bewusst so, Isolate-Zwang KEIN Umbau-Kandidat). Zielbild +
Schrittfolge mit klarem Gating: Schritte 12 (Call-Pfad) GESPERRT bis
Bernds Klick-Test des Piloten; frei ist nur MediaCache-hinter-Provider.
- **Toter `incomingCallProvider` entfernt (41bcaf2):** einzige Fundstelle
repo-weit war die Definition in app_state.dart Überbleibsel des
Call-Piloten (Provider ersatzlos in die Module verlegt). analyze sauber,
29 Tests grün.
**Offen/Nächster Schritt:** auth_log-Check (Einträge seit 2026-07-06
17:43). Umsetzbar ohne Bernd wäre noch Schritt 3 aus dem neuen Doc
(MediaCache hinter Provider); Schritte 12 erst nach dem Klick-Test.
**Stolperfallen:** Keine Analyse + risikofreie Leichen-Entfernung.
---
## 2026-07-06 auth_log-Check 17:14-Fenster sauber + settings_encryption.dart in 4 part-Dateien geteilt (6128953) ## 2026-07-06 auth_log-Check 17:14-Fenster sauber + settings_encryption.dart in 4 part-Dateien geteilt (6128953)
**Erledigt:** Dritte PC-Session des Tages. Zuerst der von der Vorsession **Erledigt:** Dritte PC-Session des Tages. Zuerst der von der Vorsession
+7
View File
@@ -197,6 +197,13 @@ lassen, ohne dass andere Module angefasst werden müssen.
herauslösen kein zweiter ungetesteter Logik-Umbau auf dem heiligen herauslösen kein zweiter ungetesteter Logik-Umbau auf dem heiligen
Call-Pfad. Call-Pfad.
- [ ] Einheitliches State-Management (Riverpod konsequent, keine Misch-Patterns) - [ ] Einheitliches State-Management (Riverpod konsequent, keine Misch-Patterns)
**Ist-Analyse + Umbauplan liegen in `docs/M2_STATE_MANAGEMENT.md`**
(2026-07-06): Riverpod ist schon dominant (~50 Provider); 4
Misch-Patterns identifiziert, Schrittfolge definiert. Schritte 12
(Call-Manager-UI-State, Voice-Provider-Umzug) GESPERRT bis Bernds
Klick-Test (PC_TESTPLAN Abschnitt 8); frei: MediaCache hinter
Provider. Push bleibt bewusst wie er ist (Isolate-Zwang). Toter
`incomingCallProvider` bereits entfernt (41bcaf2).
- [x] Toten Code & Duplikate entfernen, Ordnerstruktur vereinheitlichen - [x] Toten Code & Duplikate entfernen, Ordnerstruktur vereinheitlichen
(PROGRESS.md 2026-07-03: `message_bubble.dart` tot entfernt, doppelte (PROGRESS.md 2026-07-03: `message_bubble.dart` tot entfernt, doppelte
`_formatTime` in `message_group.dart` zusammengeführt; alle 6 in der `_formatTime` in `message_group.dart` zusammengeführt; alle 6 in der
+87
View File
@@ -0,0 +1,87 @@
# M2 Einheitliches State-Management: Ist-Analyse + Umbauplan
> **STATUS 2026-07-06: reine Analyse, noch KEIN Umbau.** Grundlage für den
> ROADMAP-M2-Punkt „Einheitliches State-Management (Riverpod konsequent,
> keine Misch-Patterns)". Die Schritte 12 unten betreffen den heiligen
> Call-Pfad und sind GESPERRT, bis Bernds Klick-Test des Call-Piloten
> (`docs/PC_TESTPLAN.md` Abschnitt 8) grün ist vorher nur Schritt 3.
## Ist-Stand (repo-weit erhoben, 2026-07-06)
Riverpod ist bereits das dominante Muster: rund 50 Provider
`StateProvider` für UI-Zustand, `StreamProvider` auf `client.onSync`,
`FutureProvider` (Client, Update-Info), `StateNotifierProvider` für die
Prefs-Notifier (`BoolPref`/`StringSetPref` in `core/settings_prefs.dart`).
`ValueNotifier`/eigene `StreamController` gibt es NICHT. Lokales
`setState` in Widgets für rein ephemeren Zustand (Hover, Dialog-Schritte,
Textfelder) ist normales Flutter und zählt hier bewusst NICHT als
Misch-Pattern.
Gefundene Misch-Patterns, nach Gewicht:
1. **Call-Schicht: Singletons + ChangeNotifier hinter den Fassaden.**
`LiveKitCallManager.instance` (static final Singleton,
`features/voice_channel/livekit_call_manager.dart:17`) und
`PyramidVoipManager._instance` (nullable static,
`features/call_signaling/voip_manager.dart:17`; konstruiert im
Kompositions-Punkt `core/matrix_client.dart:6671`). Die Modul-Provider
(`voiceChannelProvider`/`callSignalingProvider`) geben nur die
Singletons zurück. Das ist die im Pilot BEWUSST gewählte Zwischenform
(Verhaltensgleichheit vor Schönheit). Eigentliches Problem: UI-Zustand
(Mute-Flags, Teilnehmer, Renderer, Qualitätswahl) lebt mutierbar IN den
Managern und wird per `notifyListeners()` grob-granular publiziert.
2. **Voice-UI-Zustand außerhalb des Moduls:** `activeVoiceRoomIdProvider`
und `voiceParticipantsProvider` liegen in `core/app_state.dart`
(Kopplungspunkt laut Ist-Analyse), werden aber von Rooms-Panel und
Mini-Call-Widget gesetzt/gelesen und gehören fachlich ins
`voice_channel`-Modul (Join-Zustand + Presence sind Modulsache).
3. **`MediaCache.instance`** (`core/media_cache.dart:19`): reines
Singleton, direkt von `widgets/mxc_image.dart` benutzt. Kein
UI-Zustand, nur Cache geringer Schaden, leicht hinter einen
`Provider<MediaCache>` zu legen.
4. **Push/Notifications:** modul-globale Mutable-Zustände in
`core/notification_service.dart` (`_windowsNotifs`-Map, Plugin-Globals)
und direkte `SharedPreferences`-Zugriffe in `background_push.dart`/
`fcm_push_service.dart`. Das ist dem Background-Isolate-Zwang
geschuldet (siehe Schnitt-Doc Punkt 8 + Memory „Pyramid Push")
**bewusst KEIN Umbau-Kandidat**, nur hier dokumentiert.
Bereits erledigt im Zuge dieser Analyse: der seit dem Call-Piloten tote
`incomingCallProvider` ist aus `app_state.dart` entfernt (41bcaf2).
## Zielbild
- `core/app_state.dart` enthält nur noch ECHTEN App-weiten UI-Zustand
(Theme, Layout/Panels, Navigation, Toast, Space-Auswahl) kein
Feature-Fachzustand.
- Feature-Zustand lebt im jeweiligen Modul hinter dessen Provider;
andere Module lesen ihn NUR über die öffentliche Schnittstelle.
- Kein `.instance`-Zugriff über Modulgrenzen; Konstruktion ausschließlich
im Kompositions-Punkt bzw. im Provider des Moduls.
- ChangeNotifier ist als Übergangsform ok; Endzustand der Call-Module ist
ein immutables Zustandsobjekt (z. B. `VoiceChannelState`) pro Modul,
das der Provider publiziert, plus Kommando-Methoden auf dem Service
(entspricht dem Schnitt-Doc-Entwurf, dort als Stream skizziert).
## Schrittfolge (Reihenfolge = Priorität)
1. **[GESPERRT bis Klick-Test] UI-State aus den Managern herauslösen:**
je Call-Modul ein immutables Zustandsobjekt + `Notifier`/
`StateNotifier`, Manager wird interne Implementierung ohne
UI-Zustand. Das ist der bereits in PROGRESS.md zurückgestellte
Logik-Umbau NICHT vorher anfangen (heiliger Call-Pfad, ein
ungetesteter Umbau liegt schon auf dem Stapel).
2. **[GESPERRT bis Klick-Test] `activeVoiceRoomIdProvider` +
`voiceParticipantsProvider` ins `voice_channel`-Modul umziehen**
(zusammen mit `kVoicePresenceType`). Mechanisch klein, aber
Call-Pfad-nah sinnvoll im selben Zug wie Schritt 1.
3. **[frei] `MediaCache` hinter `Provider<MediaCache>`** und die
`.instance`-Zugriffe in `mxc_image.dart` auf `ref` umstellen
risikoarm, jederzeit möglich, guter Lückenfüller.
4. **[kein Umbau] Push/Notifications:** bleibt wie es ist
(Isolate-Zwang); nur bei ohnehin anstehenden Push-Arbeiten die
Prefs-Zugriffe auf die `Prefs`-Fassade ziehen (Schnitt-Doc Punkt 6).
Abhak-Kriterium für den ROADMAP-Punkt: Schritte 13 umgesetzt und die
Kernflows (Login, Raum, Nachricht, Voice-Join) nach jedem Schritt
praktisch geprüft; Punkt 4 braucht nur den Doku-Vermerk (steht hiermit).