# 🏗️ Паттерн модульной архитектуры для React компонентов

> ⚠️ **ОФИЦИАЛЬНЫЙ СТАНДАРТ АРХИТЕКТУРЫ SFERA**  
> Этот документ описывает **ОБЯЗАТЕЛЬНУЮ** модульную архитектуру по умолчанию для большинства компонентов в системе SFERA.

## 🎯 СТАТУС АРХИТЕКТУРНОГО СТАНДАРТА

### 🟢 ПРИНЯТЫЕ СТАНДАРТЫ (готовы к использованию):

- ✅ **create-suppliers-supply-page.tsx** → Модульная архитектура (ФАЗА 1-4 завершены)
- ✅ **direct-supply-creation.tsx** → Модульная архитектура (ЭТАПЫ 1-5 завершены)

### 📋 ПРАВИЛА ПРИМЕНЕНИЯ:

#### ✅ ВСЕГДА МОДУЛЬНАЯ АРХИТЕКТУРА (без исключений):

**1. Страницы и основные разделы:**

- ВСЕ файлы `page.tsx` в `/app/**/`
- ВСЕ дашборды любых типов
- ВСЕ разделы управления (supplies, employees, products, settings)
- ВСЕ wizard/multi-step компоненты

**2. Формы (даже простые!):**

- ЛЮБАЯ форма создания/редактирования сущности
- Формы с >3 полей
- Многошаговые формы
- Формы с динамическими полями
- _Почему: формы ВСЕГДА разрастаются (валидация, автозаполнение, зависимые поля)_

**3. Таблицы и списки:**

- ЛЮБАЯ таблица с данными из БД
- Таблицы с фильтрацией/сортировкой
- Таблицы с inline-редактированием
- Списки с действиями (approve/reject/delete)
- _Почему: всегда добавятся фильтры, сортировка, экспорт, bulk-операции_

**4. Комплексные компоненты:**

- Чаты/мессенджеры
- Календари/планировщики
- Графики/аналитика
- Файловые менеджеры
- Корзины/калькуляторы

#### ❌ ИСКЛЮЧЕНИЯ (только эти остаются простыми):

1. **Чистые UI из Radix/shadcn** - уже оптимизированы
2. **Stateless компоненты** < 50 строк без логики
3. **Чистые Layout** компоненты (Header/Footer)
4. **Utility компоненты** (ErrorBoundary, LoadingState)
5. **Простые модалки** подтверждения (Да/Нет)

## 🎯 КЛЮЧЕВОЕ ПРАВИЛО SFERA

> **"Если сомневаешься - делай модульным. Лучше иметь избыточную структуру папок, чем 2000-строчный спагетти-код через месяц."**

### 📏 Критерии принятия решения:

```typescript
// Алгоритм принятия решения о модульности
function shouldUseModularArchitecture(component) {
  // Автоматически ДА
  if (
    component.type === 'page' ||
    component.type === 'dashboard' ||
    component.type === 'form' ||
    component.type === 'table' ||
    component.expectedSize > 300
  ) {
    return true
  }

  // Проверяем сложность
  const complexityScore =
    component.stateVariables + // количество useState
    component.apiCalls * 2 + // API вызовы весят больше
    component.formFields + // поля форм
    (component.hasBusinessLogic ? 3 : 0) // бизнес-логика

  return complexityScore >= 5
}
```

### Кандидаты для рефакторинга (legacy компонентов):

- **Размер**: >800 строк кода
- **Сложность**: Множественные состояния и бизнес-логика
- **Многообразие UI**: Различные секции интерфейса
- **Частые изменения**: Активно развивающиеся компоненты

### Большие компоненты в SFERA (кандидаты):

```
3052 строки - timesheet-demo.tsx
2012 строк - fulfillment-warehouse-dashboard.tsx
1654 строки - navigation-demo.tsx
1637 строк - direct-supply-creation.tsx        ✅ ЗАВЕРШЕН (модульная архитектура)
1563 строки - user-settings.tsx
1523 строки - advertising-tab.tsx
1304 строки - wb-product-cards.tsx
```

## 📁 Универсальная структура модуля

```
src/components/[domain]/[component-name]/
├── index.tsx                          # Главный компонент-оркестратор
├── blocks/                           # UI блок-компоненты
│   ├── [Feature]Block.tsx           # Функциональные блоки
│   ├── [Section]Block.tsx           # Секции интерфейса
│   └── [Action]Block.tsx            # Блоки действий
├── hooks/                           # Бизнес-логика
│   ├── use[Domain][Action].ts       # Специфичная логика
│   ├── use[Entity]Management.ts     # CRUD операции
│   └── use[Feature]State.ts         # Управление состоянием
├── types/                           # TypeScript типы
│   └── index.ts                     # Все интерфейсы модуля
└── constants/                       # Константы (опционально)
    └── index.ts                     # Конфигурация и моки
```

## 🔄 Процесс рефакторинга

### ЭТАП 1: Анализ и планирование

1. **Выделить основные секции UI**
   - Определить логические блоки интерфейса
   - Найти повторяющиеся паттерны

2. **Проанализировать состояния**
   - Сгруппировать связанные useState
   - Выделить логику управления состоянием

3. **Найти бизнес-логику**
   - useEffect с API вызовами
   - Обработчики форм и событий
   - Вычисляемые значения

### ЭТАП 2: Создание типов

```typescript
// types/index.ts
export interface [Entity] {
  id: string
  // ... поля сущности
}

export interface [Component]Props {
  // ... props компонента
}

export interface [Block]Props {
  // ... props блока
}
```

### ЭТАП 3: Извлечение hooks

```typescript
// hooks/use[Feature].ts
export function use[Feature]() {
  const [state, setState] = useState()

  const handleAction = useCallback(() => {
    // бизнес-логика
  }, [dependencies])

  return {
    state,
    handleAction,
    // ... другие возвращаемые значения
  }
}
```

### ЭТАП 4: Создание блок-компонентов

```typescript
// blocks/[Feature]Block.tsx
export const [Feature]Block = React.memo(function [Feature]Block({
  // ... props
}: [Feature]BlockProps) {
  return (
    <div className="...">
      {/* UI блока */}
    </div>
  )
})
```

### ЭТАП 5: Интеграция в главном компоненте

```typescript
// index.tsx
export function [Component]() {
  // Подключение hooks
  const featureA = useFeatureA()
  const featureB = useFeatureB()

  // Обработчики с useCallback
  const handleAction = useCallback((data) => {
    // координация между features
  }, [featureA.method, featureB.method])

  return (
    <div>
      <FeatureABlock {...featureA} onAction={handleAction} />
      <FeatureBBlock {...featureB} onAction={handleAction} />
    </div>
  )
}
```

## ⚡ Оптимизация производительности

### Мемоизация компонентов

```typescript
// Все блоки обернуть в React.memo
export const MyBlock = React.memo(function MyBlock(props) {
  // ...
})

// Главный компонент: useCallback для обработчиков
const handleEvent = useCallback(
  (data) => {
    // логика
  },
  [dependency1, dependency2],
)
```

### Управление ререндерами

```typescript
// В hooks: useMemo для тяжелых вычислений
const expensiveValue = useMemo(() => {
  return heavyCalculation(data)
}, [data])

// Оптимизация зависимостей useCallback
const optimizedHandler = useCallback(
  (item) => {
    // вместо передачи всего массива
    // передавать только нужные методы
  },
  [addItem, removeItem],
) // не [items, addItem, removeItem]
```

## 🧪 Тестирование модульной архитектуры

### Unit тесты для hooks

```typescript
import { renderHook, act } from '@testing-library/react'
import { useFeature } from '../hooks/useFeature'

describe('useFeature', () => {
  it('should handle action correctly', () => {
    const { result } = renderHook(() => useFeature())

    act(() => {
      result.current.handleAction('test')
    })

    expect(result.current.state).toEqual(expectedState)
  })
})
```

### Component тесты для блоков

```typescript
import { render, screen } from '@testing-library/react'
import { FeatureBlock } from '../blocks/FeatureBlock'

describe('FeatureBlock', () => {
  it('should render with props', () => {
    render(<FeatureBlock data={mockData} onAction={mockHandler} />)
    expect(screen.getByText('Expected Text')).toBeInTheDocument()
  })
})
```

## 📊 Метрики успеха рефакторинга

### Количественные метрики

- **Размер главного файла**: ↓ на 70-85%
- **Количество модулей**: ↑ в 5-10 раз
- **Время компиляции**: ↓ на 90%+
- **Переиспользуемые компоненты**: ↑ с 0 до N

### Качественные улучшения

- ✅ Читаемость и понимание кода
- ✅ Простота добавления новых фич
- ✅ Изолированное тестирование
- ✅ Переиспользование в других местах
- ✅ Параллельная разработка команды

## 🚨 Частые ошибки и как их избежать

### ❌ Чрезмерное дробление

```typescript
// ПЛОХО: слишком много мелких блоков
<HeaderBlock />
<SubHeaderBlock />
<TitleBlock />
<ButtonBlock />

// ХОРОШО: логичные функциональные блоки
<HeaderSection />
<ActionsSection />
```

### ❌ Плохие зависимости useCallback

```typescript
// ПЛОХО: передача всего объекта
const handler = useCallback(() => {
  doSomething(fullObject)
}, [fullObject]) // объект пересоздается каждый рендер

// ХОРОШО: передача только нужных значений
const handler = useCallback(() => {
  doSomething(fullObject.id, fullObject.name)
}, [fullObject.id, fullObject.name])
```

### ❌ Неправильное разделение состояния

```typescript
// ПЛОХО: состояние остается в главном компоненте
function MainComponent() {
  const [complexState, setComplexState] = useState() // управляется извне
  return <FeatureBlock state={complexState} setState={setComplexState} />
}

// ХОРОШО: состояние инкапсулировано в hook
function MainComponent() {
  const featureData = useFeature() // управляется внутри hook
  return <FeatureBlock {...featureData} />
}
```

## 📋 Чек-лист рефакторинга

### Перед началом

- [ ] Компонент относится к категории: page, form, table, dashboard
- [ ] ИЛИ ожидаемый размер >300 строк
- [ ] ИЛИ сложность по алгоритму ≥5 баллов
- [ ] ИЛИ есть несколько логических секций UI
- [ ] ИЛИ множественные useState и useEffect

### Планирование

- [ ] Определены основные UI блоки (3-6 штук)
- [ ] Выделена бизнес-логика для hooks (2-5 штук)
- [ ] Созданы TypeScript интерфейсы
- [ ] План поэтапного рефакторинга готов

### Реализация

- [ ] Создана структура папок
- [ ] Extracted типы в types/index.ts
- [ ] Hooks реализованы и протестированы
- [ ] Блоки созданы с React.memo
- [ ] Главный компонент интегрирует все части
- [ ] Старый файл удален

### Оптимизация

- [ ] Все обработчики используют useCallback
- [ ] Зависимости useCallback оптимизированы
- [ ] Тяжелые вычисления в useMemo
- [ ] Компонент работает без ошибок

### Документация

- [ ] README для модуля создан
- [ ] Примеры использования hooks
- [ ] Документация props для блоков
- [ ] Архитектурная диаграмма

## 🎯 Заключение

Модульная архитектура по умолчанию значительно улучшает качество кода, скорость разработки и поддержки в долгосрочной перспективе. В SFERA мы применяем принцип "лучше переструктурировать сразу, чем рефакторить потом".

### 🎯 Практические примеры применения:

**Модульные (новые стандарты):**

- `/app/suppliers/create/page.tsx` → CreateSupplierPage/
- `EmployeeManagementTable` → EmployeeManagement/
- `SupplyOrderForm` → SupplyOrderForm/
- `ProductCatalog` → ProductCatalog/
- `UserSettingsForm` → UserSettingsForm/

**Простые (исключения):**

- `Logo.tsx`
- `LoadingDots.tsx`
- `ConfirmDialog.tsx`
- `PriceDisplay.tsx`

---

**Основано на**: Успешном рефакторинге create-suppliers-supply-page.tsx (1,467→240 строк)  
**Обновлено**: Синхронизировано с правилами CLAUDE.md  
**Автор паттерна**: Claude Code  
**Дата**: Август 2025
