# 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
