Refactor provider composition and ESLint configuration

- Add new provider composition system with validation
- Create providerComposition.tsx for centralized provider management
- Implement providerOrderValidator.tsx to ensure correct provider order
- Add comprehensive tests for provider composition
- Create custom ESLint rules in frontend/eslint-rules/
- Update ESLint configuration
- Update architecture and tasks documentation

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-05-01 17:33:56 +02:00
parent 4f7316c484
commit c988b4b8b6
9 changed files with 1580 additions and 50 deletions

View File

@@ -949,11 +949,57 @@ Shared TypeScript interfaces and type aliases. Purely declarative — no runtime
React context providers for application-wide concerns.
**Provider Ordering and Compile-Time Validation**
Provider order is **order-sensitive** and enforced at compile-time through TypeScript discriminated unions. The required order (outermost to innermost) is:
1. `ThemeProvider` — must be outermost; provides theme context to `AppContents`
2. `FluentProvider` — supplies Fluent UI theme and design tokens to all Fluent UI consumers
3. `NotificationProvider` — provides notification service; must wrap error boundaries
4. `ErrorBoundary` — catches catastrophic errors at the top level
5. `BrowserRouter` — enables client-side routing
6. `NavigationCancellationProvider` — manages route-aware request cancellation using `useLocation()`
7. `AuthProvider` — validates session on mount; must be inside BrowserRouter (uses `useNavigate()`)
8. `TimezoneProvider` — fetches timezone after auth; wraps protected routes only
**Compile-Time Validation:**
A type-safe builder pattern (`ProviderCompositionBuilder`) in `providerComposition.tsx` enforces this order using TypeScript's discriminated unions. The builder prevents adding providers out of order at compile-time:
```tsx
const tree = createProviderComposition()
.withTheme({ children })
.withFluent(theme) // ✓ Must come after withTheme
.withNotification() // ✓ Must come after withFluent
.withErrorBoundary() // ✓ Correct order enforced
.withBrowserRouter()
.withNavigationCancellation()
.withAuth()
.build(routes);
```
Attempting to add providers out of order results in TypeScript errors (no runtime overhead).
**Runtime Validation (Development):**
A runtime validator (`providerOrderValidator.tsx`) provides fallback validation for development:
- `validateProviderPosition()` — checks if a provider is correctly nested
- `validateProvidersExist()` — ensures required providers are in the tree
- `hasProvider()` — queries provider presence
- `useProviderValidation()` — development-only hook that warns if required providers are missing
See `src/providers/PROVIDER_ORDER.md` for detailed dependency rationale.
**Provider Reference:**
| Provider | Purpose |
|---|---|
| `AuthProvider` | Holds authentication state; exposes `isAuthenticated`, `login()`, and `logout()` via `useAuth()`. Synchronizes logout events across browser tabs in real-time using the BroadcastChannel API (with storage event fallback for older browsers). When a user logs out in any tab, all other open tabs immediately reflect the logout state without requiring a page refresh. |
| `TimezoneProvider` | Reads the configured IANA timezone from the backend and supplies it to all children via `useTimezone()` |
| `ThemeProvider` | Manages light/dark theme selection, supplies the active Fluent UI theme to `FluentProvider` |
| `NotificationProvider` | Provides notification service via `useNotification()` hook; must wrap error boundaries so they can display error notifications |
| `NavigationCancellationProvider` | Detects route changes and automatically aborts pending API requests; call `useNavigationAbortSignal()` to get an `AbortSignal` that lives for the current route |
#### Theme (`src/theme/`)

View File

@@ -1,52 +1,3 @@
## [IMPORTANT] Error response schema inconsistent
**Where found**
- Different handlers return different response shapes
- Fail2Ban errors: `{ "error_code": "...", "detail": "..." }`
- Validation errors: `{ "detail": [...] }`
- Not found errors: `{ "detail": "...", "error_code": "..." }`
**Why this is needed**
Frontend must normalize multiple shapes, making error handling fragile and error-prone.
**Goal**
Unify all error responses to single schema.
**What to do**
1. Define canonical error response:
```python
class ErrorResponse(BaseModel):
error_code: str
message: str
status: int
details: dict | None = None
```
2. Update all handlers to return this format
3. Update frontend to expect unified schema
**Possible traps and issues**
- Backward compatibility with old clients
- FastAPI's built-in handlers may override custom
- Rich detail structures need accommodation
**Docs changes needed**
- Update API documentation with unified error schema
- Add error code reference table
**Doc references**
- `Docs/API.md` (error codes)
- `backend/app/main.py` (exception handlers)
---
## [IMPORTANT] Provider ordering fragility (Frontend)
**Where found**