86 lines
3.2 KiB
Markdown
86 lines
3.2 KiB
Markdown
# 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 # <App /> entry and routing
|
||
routes.tsx # Route definitions
|
||
domains/
|
||
<feature>/
|
||
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/<feature>`
|
||
- **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.
|