# Technical Context: Web Application ## Technology Stack ### Core Technologies - React (Client-side rendering, SPA) - TypeScript (strict mode enabled) - Vite (build tool, dev server) - Tailwind CSS (utility-first styling, dark theme) - Effector (Flux-style state management) ### Authentication & API - OpenID Connect (OIDC) via dynamic `/oidc.json` - `useApiService` hook for authenticated API calls - Tokens stored in `localStorage`, auto-refresh on expiration ### Development & Testing Tools - ESLint (linting) - Prettier (formatting) - Husky (Git hooks) - Jest & Testing Library (unit and integration tests) ## Project Structure ``` src/ app/ root.tsx # entry and routing routes.tsx # Route definitions domains/ / model.ts # Effector events, stores, effects (pure, testable) view-model.ts # Hooks adapting model to React ui/ # Presentational components shared/ ui/ # Design-system atoms lib/ # Utilities and helpers services/ apiService.ts # Authenticated API wrapper utils/ config.ts # getBasePath(), getAssetPath() components/ # Miscellaneous components (if any) public/ config.js # Base path placeholder replaced at runtime oidc.json # Dynamic OIDC config ``` ## Component Organization - **Feature domains**: Self-contained under `src/domains/` - **ViewModel layer**: Thin hooks (`view-model.ts`) encapsulate Effector logic - **UI components**: Presentational, located in each domain’s `ui/` folder - **Shared UI atoms**: In `src/shared/ui`, for consistent design ## State Management with Effector - **Events** (`createEvent`): Actions triggered by user or effects - **Stores** (`createStore`): Immutable state containers updated via `.on(...)` - **Effects** (`createEffect`): Async side-effects dispatching done/fail events - **Advanced patterns**: Derived stores, combine, reset events ## Authentication - **OIDC Flow**: `AuthProvider` initializes using `/oidc.json` - **ProtectedRoute**: Secures routes, supports role-based access - **useAuth** & **useApiService** hooks manage login, logout, token handling ## Deployment & Environment Variables - **Path-agnostic SPA**: `BASE_PATH` injected into `public/config.js` by `docker-entrypoint.sh` - **Client-side vars** (`CLIENT_BASE_PATH`, `CLIENT_API_URL`, `CLIENT_APP_NAME`, `CLIENT_DEBUG`) exposed on `window.appConfig` - **Asset utils**: `getBasePath()` and `getAssetPath()` in `src/utils/config.ts` ## Coding Guidelines - **TypeScript strict mode**: Ensures type safety - **Pure domain logic**: In `model.ts`, avoid side-effects - **Named exports only**: Prevents default-export rename issues - **Small files, single responsibility**: Easier automated refactoring - **Co-located tests**: Provide regression safety - **Runtime schema checks** (e.g., Zod): Fail fast on invalid data ## Architecture Rationale Flux with Effector was chosen over MVVM for: - Native React integration and unidirectional data flow - Minimal boilerplate and predictable state management - High testability and TypeScript support - Lower complexity for automated refactors Refer to `docs/flux-vs-mvvm.md` for the decision matrix and detailed comparison.