55 lines
2.3 KiB
Markdown
55 lines
2.3 KiB
Markdown
# System Patterns: Web Application
|
|
|
|
## Architecture Overview
|
|
The application follows a domain-driven, Effector-based Flux architecture.
|
|
|
|
### Domain Structure
|
|
Each feature domain in `src/domains/<feature>/` contains:
|
|
- `model.ts`: Effector events, stores, and effects (pure, testable)
|
|
- `view-model.ts`: React hooks (`useStore`/`useUnit`) adapting model logic to components
|
|
- `ui/`: Dumb presentational React components
|
|
|
|
The application entry point (`<App />`) and routing are in `src/app/root.tsx` and `src/app/routes.tsx`.
|
|
|
|
## Key Design Patterns
|
|
|
|
### Effector-based Flux
|
|
- **Events**: `createEvent()` represent actions triggered by the user or effects
|
|
- **Stores**: `createStore()` hold application state and update via `.on(event, ...)`
|
|
- **Effects**: `createEffect()` handle async side-effects, dispatching success/fail events
|
|
- **Domains**: Group related events, stores, and effects into isolated modules
|
|
|
|
### ViewModel Layer
|
|
- Encapsulates Effector usage in thin hooks (`view-model.ts`)
|
|
- Components consume view-model hooks and remain focused on presentation
|
|
|
|
### UI Components
|
|
- Design-system atoms in `src/shared/ui/`
|
|
- Domain-specific components in `src/domains/<feature>/ui/`
|
|
- Core UI components include: Button, Input, Textarea, Switch, Tabs, ImageUpload, Card, Dialog
|
|
|
|
## Data Flow
|
|
```
|
|
event ───┐
|
|
│ triggers
|
|
store ───┤ updates ──> view-model hook ──> React component render
|
|
│
|
|
effect <─┘ (async; dispatches done/fail events)
|
|
```
|
|
User interactions invoke events, stores update state, view-model hooks propagate changes to the UI.
|
|
|
|
## Authentication
|
|
- OpenID Connect (OIDC) for authentication via dynamic `/oidc.json` configuration
|
|
- `AuthProvider` initializes auth flow; tokens stored in `localStorage` with auto-refresh
|
|
- Protected routes using the `ProtectedRoute` component with optional `requiredRoles`
|
|
|
|
## Deployment
|
|
- Path-agnostic SPA deployment with Vite and Docker
|
|
- `BASE_PATH` injected into `public/config.js` at container startup by `docker-entrypoint.sh`
|
|
- Client-side environment variables (`CLIENT_*`) surfaced on `window.appConfig`
|
|
- Asset paths managed via `getAssetPath()` in `src/utils/config.ts`
|
|
|
|
## Styling
|
|
- Tailwind CSS configured via `tailwind.config.js`
|
|
- Utility-first styling with dark theme support and a consistent design system
|