Skip to main content

Слои архитектуры

Архитектура проекта построена на принципе строгого разделения ответственности между слоями.
Каждый слой решает свою задачу и взаимодействует с другими слоями только через определённые контракты.


Обзор слоёв

В проекте выделены три основных слоя:

  • App — пользовательский интерфейс и сценарии взаимодействия
  • Domain — бизнес-логика и правила предметной области
  • Data — доступ к данным и внешним источникам

Слой App

Директория app содержит логику отрисовки пользовательского интерфейса на фронтенде: компоненты, их состояние и взаимодействие с пользователем.

Ответственность

  • отображение UI
  • обработка пользовательских событий
  • управление состоянием интерфейса
  • навигация и маршрутизация
  • вызов бизнес-сценариев из domain

Что разрешено

  • компоненты и хуки
  • UI-состояние (loading, error, visibility)
  • адаптация данных для отображения
  • локальная валидация форм

Что запрещено

  • бизнес-правила
  • прямой доступ к данным

Типовая структура

app
├── common
│ ├── const
│ └── service
├── modules
│ └── user
├── routes
├── tools
│ ├── layouts
│ └── provider
├── ui
│ ├── component
│ └── style
└── utils

common - это фундаментальная конфигурация фронтенда, которая инициализирует приложение и обеспечивает его каркас. Здесь нет бизнес-логики модулей и фич.

  • config/ - чтение и валидация переменных окружения, runtime-конфиг, feature-flags.
  • providers/ - композиция корневых провайдеров (стор, тема, i18n, query-client и т. п.).
  • styles/ - глобальные стили, reset/normalize, базовые CSS-переменные.
  • theme/ - темы, дизайн-токены (если не ведёте их в ui).
  • i18n/ - инициализация локализации.
  • store/ - создание корневого стора/контейнера состояния (Redux/Zustand/etc).
  • errors/ - корневые ErrorBoundary/fallback-экраны и обработка непойманных ошибок.
  • metrics/ - инициализация аналитики/логирования (например, Sentry).
  • types/ - общие типы конфигурации приложения.
  • constants/ - глобальные константы приложения.

Пример: providers/AppProviders.tsx собирает все провайдеры и используется в корневом App.

router

Директория router содержит инфраструктурную логику роутинга и конфигурацию навигации. Сами маршруты и их страницы находятся в modules.

tools

Директория tools - дополнения, расширяющие функциональность модулей:

  • Layouts - шаблоны компоновки страниц.
  • Middleware - промежуточные обработчики для дополнительных проверок/логики.
  • Guards - “охранники” маршрутов перед переходом (аутентификация, права).
  • Error Boundaries - обработка ошибок на уровне модулей/страниц.

ui

Директория ui - UI-кит приложения и кастомные надстройки над ним:

  • Базовые UI-компоненты (кнопки, поля форм и т.д.).
  • Специализированные компоненты (например, кастомный TextField для пароля).
  • Стили(локальные/глобальные)

utils

Директория utils включает утилитарные функции, используемые во всех модулях приложения. Примеры:

  • Функции дебаунсинга (debounce).
  • Утилиты для работы с датами.
  • Функции фильтрации данных.
  • Другие вспомогательные функции.
  • Хуки

modules

Директория modules содержит функциональные модули приложения (например, модуль user). Внутренняя структура поддерживает вложенность для кейсов различной сложности.

Пример структуры модуля user:

user
└── case
├── authorization
│ ├── case
│ │ ├── presenter
│ │ └── request
│ ├── component
│ └── const
├── registration
│ ├── case
│ │ ├── presenter
│ │ └── request
│ ├── component
│ └── const
├── schema // схема находится тут тк она используется в несокльких модулях сразу
└── modal

Пояснения

  1. Кейсы (case)
    Каждый кейс — это отдельная функциональная единица (например, авторизация или регистрация).

    • Поддиректория case внутри кейса содержит внутренние сценарии или шаги.
    • presenter — связывает данные и действия с UI.
    • request — выполняет запросы к серверу или работу с API.
  2. Компоненты (component)
    UI-часть кейса, страница или набор компонентов, относящихся к кейсу.

  3. Константы (const)
    Специфичные для кейса константы (строки, значения, ключи и т.д.).

  4. Схемы (schema)
    Общие схемы валидации, которые используются сразу в нескольких кейсах или модулях, выносятся на уровень модуля, а не внутри отдельного кейса.

  5. Общие элементы (modal)
    Если функциональность используется в нескольких кейсах, её стоит вынести на уровень модуля, чтобы избежать дублирования и облегчить поддержку.

Файл presenter/index.ts отвечает за логику представления (связывает данные и действия с интерфейсом).
Файл request/index.ts отвечает за выполнение запросов к серверу и обработку ответов.

Примечание: перечни поддиректорий не являются исчерпывающими и могут расширяться при необходимости. Новые имена должны соответствовать принятым правилам нейминга и архитектурным договорённостям проекта.


Важно: при добавлении новых фич или элементов, которые могут использоваться в других модулях, их следует размещать * выше уровня кейса*, аналогично modal или schema.
Это обеспечивает повторное использование и чистую архитектуру.


Слой Domain

Слой domain — центральная часть системы и источник бизнес-правил.

Ответственность

  • бизнес-логика и политики поведения
  • use-case (бизнес-сценарии)
  • доменная валидация
  • описание контрактов (port, dto, repositories)

Ключевые принципы

  • не зависит от UI и инфраструктуры
  • не использует фреймворки
  • не знает о способах хранения данных

Типовая структура

domain
├── user
│ ├── interface
│ │ ├── port
│ │ ├── dto
│ │ ├── use-case
│ │ └── repository
│ ├── common
│ │ └── use-case
│ └── use-case
│ └── get-all
└── service/common

Слой Data

Слой data отвечает за реализацию инфраструктурных деталей.

Ответственность

  • реализация репозиториев
  • HTTP-клиенты и соединения с БД
  • маппинг моделей
  • обработка ошибок
  • список может дополняться в зависимости от задач
    • пример: хранение json для переводов

Ограничения

  • не содержит бизнес-правил
  • не зависит от app
  • использует только контракты из domain/interface

Типовая структура

data
├── repository
│ ├── employee
│ │ ├── port
│ │ ├── dto
│ │ ├── use-case
│ │ └── repository
│ ├── common
│ │ └── use-case
│ └── use-case
│ └── get-all
└── singleton