mirror of
https://github.com/complexcaresolutions/dak.c2s.git
synced 2026-03-17 16:03:41 +00:00
docs: add state management refactoring design (TanStack Query)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
99767fe6fe
commit
d4420500e5
1 changed files with 101 additions and 0 deletions
101
docs/plans/2026-02-26-state-management-design.md
Normal file
101
docs/plans/2026-02-26-state-management-design.md
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
# State Management Refactoring — Design
|
||||
|
||||
## Ziel
|
||||
|
||||
Boilerplate reduzieren und Zukunftssicherheit schaffen durch Einführung von TanStack Query für Server-State-Management. UI-State bleibt bei useState/Context.
|
||||
|
||||
## Ansatz
|
||||
|
||||
TanStack Query (`@tanstack/react-query`) übernimmt alles was mit API-Daten zu tun hat: Fetching, Caching, Refetch, Mutations mit automatischer Cache-Invalidierung.
|
||||
|
||||
## Architektur
|
||||
|
||||
### Provider-Hierarchie
|
||||
|
||||
```
|
||||
App.tsx
|
||||
└── QueryClientProvider (NEU)
|
||||
└── AuthProvider (bleibt)
|
||||
└── BrowserRouter
|
||||
└── Routes...
|
||||
```
|
||||
|
||||
### Globale Query-Konfiguration
|
||||
|
||||
- `staleTime: 30s` — Daten gelten 30 Sekunden als frisch
|
||||
- `retry: 1` — Einmal wiederholen bei Fehler
|
||||
- `refetchOnWindowFocus: false` — Kein automatischer Refetch bei Tab-Wechsel
|
||||
|
||||
### Was migriert wird
|
||||
|
||||
Alle `useEffect(() => api.get(...), [deps])` Patterns → `useQuery()`
|
||||
Alle `api.put/post` in Save-Handlern → `useMutation()` mit Cache-Invalidierung
|
||||
useNotifications Polling → `useQuery()` mit `refetchInterval: 60000`
|
||||
|
||||
### Was bleibt
|
||||
|
||||
- AuthContext (Token + User)
|
||||
- useTheme
|
||||
- UI-State (Modals, Sidebar-Toggle, Filter-Inputs) — useState
|
||||
- useInlineEdit — bleibt als Hook, nutzt aber TanStack Mutations intern
|
||||
|
||||
## Custom Query-Hooks
|
||||
|
||||
Domänenspezifische Hooks in `frontend/src/hooks/`:
|
||||
|
||||
| Hook | Ersetzt | Datei |
|
||||
|------|---------|-------|
|
||||
| `useCases(filters)` | useState+useEffect in CasesPage | `hooks/useCases.ts` |
|
||||
| `useCase(id)` | Einzelfall-Fetch in CaseDetail | `hooks/useCases.ts` |
|
||||
| `useCaseMutation()` | api.put in useInlineEdit | `hooks/useCases.ts` |
|
||||
| `useDashboard(jahr)` | useState+useEffect in DashboardPage | `hooks/useDashboard.ts` |
|
||||
| `useNotifications()` | Bestehender Polling-Hook | `hooks/useNotifications.ts` |
|
||||
| `useUsers()` | useState+useEffect in AdminUsersPage | `hooks/useUsers.ts` |
|
||||
| `useDisclosures(status)` | useState+useEffect in DisclosuresPage | `hooks/useDisclosures.ts` |
|
||||
| `useAuditLog(filters)` | useState+useEffect in AdminAuditPage | `hooks/useAuditLog.ts` |
|
||||
| `useImportLogs(page)` | useState+useEffect in ImportLogTab | `hooks/useImportLogs.ts` |
|
||||
|
||||
### Query Key Konvention
|
||||
|
||||
- `['cases']` — alle Fälle
|
||||
- `['cases', { page, search, jahr, fallgruppe }]` — gefilterte Liste
|
||||
- `['cases', id]` — Einzelfall
|
||||
- `['dashboard', jahr]` — Dashboard-KPIs
|
||||
- `['notifications']` — Benachrichtigungen
|
||||
- `['users']` — Admin-Benutzerliste
|
||||
- `['disclosures', status]` — Disclosure-Anfragen
|
||||
- `['audit-log', filters]` — Audit-Log
|
||||
- `['import-logs', page]` — Import-Logs
|
||||
|
||||
## Mutations & Cache-Invalidierung
|
||||
|
||||
| Mutation | Invalidiert |
|
||||
|----------|-------------|
|
||||
| Case updaten | `['cases']` |
|
||||
| KVNR setzen | `['cases']` |
|
||||
| ICD setzen | `['cases']`, `['dashboard']` |
|
||||
| Coding setzen | `['cases']`, `['dashboard']` |
|
||||
| Disclosure genehmigen/ablehnen | `['disclosures']`, `['notifications']` |
|
||||
| Notification lesen | `['notifications']` |
|
||||
| User anlegen/bearbeiten | `['users']` |
|
||||
|
||||
useInlineEdit nutzt intern `useMutation()` statt direkter `api.put()`. Der `onCaseSaved`-Callback durch den Komponentenbaum entfällt komplett.
|
||||
|
||||
## Migrations-Strategie
|
||||
|
||||
Schrittweise Migration, Page für Page:
|
||||
|
||||
### Phase 1: Setup
|
||||
- `pnpm add @tanstack/react-query @tanstack/react-query-devtools`
|
||||
- `QueryClientProvider` in App.tsx
|
||||
|
||||
### Phase 2: Einfache Pages
|
||||
- DashboardPage, ReportsPage, AdminAuditPage, DisclosuresPage
|
||||
|
||||
### Phase 3: Mittlere Komplexität
|
||||
- AdminUsersPage, ImportLogTab, useNotifications
|
||||
|
||||
### Phase 4: CasesPage (komplexeste)
|
||||
- useCases, useCaseMutation, useKvnrMutation, useIcdMutation
|
||||
- useInlineEdit intern auf Mutations umstellen
|
||||
- onCaseSaved-Callback entfernen
|
||||
Loading…
Reference in a new issue