3.2 KiB
3.2 KiB
Technical Context: Merchant Operator 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 intopublic/config.js
bydocker-entrypoint.sh
- Client-side vars (
CLIENT_BASE_PATH
,CLIENT_API_URL
,CLIENT_APP_NAME
,CLIENT_DEBUG
) exposed onwindow.appConfig
- Asset utils:
getBasePath()
andgetAssetPath()
insrc/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.