# Project Structure This document outlines the structure of our application, which follows a domain-driven, Flux-style architecture using Effector for state management. ## Directory Structure ``` src/ app/ # Application entry point and configuration root.tsx # Root component routes.tsx # Route definitions domains/ # Feature domains / # e.g., products, auth, orders model.ts # Effector events, stores, effects view-model.ts # React hooks for connecting to the model ui/ # React components index.ts # Exports all components Component.tsx # Individual components shared/ # Shared code lib/ # Utilities, helpers, adapters ui/ # Reusable UI components tests/ # Test files ``` ## Domain Structure Each domain follows a consistent structure: ### model.ts Contains all Effector-related code: - Events (actions) - Stores (state) - Effects (async operations) Example: ```typescript // domains/products/model.ts import { createStore, createEvent, createEffect } from 'effector'; import { ProductsViewsService } from '@lib/api/merchant/services/ProductsViewsService'; import type { productCompositeDto } from '@lib/api/merchant/models/productCompositeDto'; // Events export const setProductsFilter = createEvent>(); // Effects export const fetchProductsFx = createEffect(async (filter: productQueryRequestDto) => { return await ProductsViewsService.postApiProductCompositeQueryByCanonical({ requestBody: filter }); }); // Stores export const $products = createStore([]) .on(fetchProductsFx.doneData, (_, payload) => Array.isArray(payload) ? payload : [payload]); ``` ### view-model.ts Contains React hooks that connect to the Effector model: ```typescript // domains/products/view-model.ts import { useStore } from 'effector-react'; import { useCallback } from 'react'; import { $products, $productsLoading, setProductsFilter, fetchProductsFx } from './model'; export const useProducts = () => { const products = useStore($products); const isLoading = useStore($productsLoading); const updateFilter = useCallback((newFilter) => { setProductsFilter(newFilter); }, []); return { products, isLoading, updateFilter }; }; ``` ### ui/ Contains React components that use the view-model: ```typescript // domains/products/ui/ProductsList.tsx import React from 'react'; import { useProducts } from '../view-model'; import { ProductCard } from './ProductCard'; export const ProductsList: React.FC = () => { const { products, isLoading } = useProducts(); if (isLoading) { return
Loading...
; } return (
{products.map(product => ( ))}
); }; ``` ## Shared Code ### shared/lib/ Contains utilities, helpers, and adapters that are used across multiple domains. ### shared/ui/ Contains reusable UI components that are not tied to any specific domain. ## Tests Tests are organized alongside the code they test, following the same structure. ## Best Practices 1. **Keep domains isolated**: Each domain should be self-contained and not depend on other domains. 2. **Use named exports**: Avoid default exports to make refactoring easier. 3. **Keep files small**: Each file should have a single responsibility. 4. **Use TypeScript**: All files should be written in TypeScript for type safety. 5. **Follow Flux pattern**: Maintain unidirectional data flow from events to stores to views.