2025-04-19 19:26:03 +02:00

3.2 KiB
Raw Blame History

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 domains 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.