124 lines
4.8 KiB
Markdown
124 lines
4.8 KiB
Markdown
# Архитектура проекта
|
||
|
||
Дата актуализации: 2026-06-22
|
||
|
||
## Базовый принцип
|
||
|
||
Проект следует Feature-Sliced Design в прагматичном варианте: слой добавляется только тогда,
|
||
когда у него есть реальная ответственность. Главный рабочий поток сейчас построен вокруг
|
||
страниц `auth` и `dashboard`, защищенного layout и общего shared-инструментария.
|
||
|
||
## Слои
|
||
|
||
```text
|
||
src/
|
||
app/ # инициализация приложения, router, providers, базовые стили
|
||
pages/ # route-level страницы и их page-specific model/api/ui
|
||
widgets/ # крупные композиционные блоки, собирающие entities/features/shared
|
||
entities/ # доменные сущности
|
||
shared/ # инфраструктура, API client, базовый UI, helpers, local UI-kit
|
||
```
|
||
|
||
`features` сейчас не используется намеренно. Например, logout используется только внутри
|
||
`widgets/protected-app-layout`, поэтому orchestration живет в widget model, а не в отдельном
|
||
feature slice. Если действие начнет использоваться в нескольких независимых flows, его можно
|
||
поднять в `features/logout-session`.
|
||
|
||
## Правила импортов
|
||
|
||
- Верхние слои могут импортировать нижние: `app -> pages -> widgets -> features -> entities -> shared`.
|
||
- Нижние слои не импортируют верхние.
|
||
- Между слайсами одного слоя не должно быть cross-imports.
|
||
- Внутри одного слайса допускаются относительные импорты между сегментами.
|
||
- Внешний код импортирует слайс через public API `index.ts`.
|
||
- Generated API не импортируется напрямую из app/pages/widgets/entities. Используется facade `@/shared/api`.
|
||
|
||
## Текущие ключевые слайсы
|
||
|
||
### `pages/dashboard`
|
||
|
||
```text
|
||
src/pages/dashboard/
|
||
api/
|
||
competenceMapAnalyticsApi.ts
|
||
model/
|
||
chartData.ts
|
||
constants.ts
|
||
dashboardStore.ts
|
||
emptyState.ts
|
||
error.ts
|
||
filterDefinitions.ts
|
||
filterDraft.ts
|
||
filters.ts
|
||
formatters.ts
|
||
queryKeys.ts
|
||
sorting.ts
|
||
tooltip.ts
|
||
types.ts
|
||
ui/
|
||
DashboardPage.vue
|
||
ReportsView.vue
|
||
CompetenceMapFilters.vue
|
||
CompetenceMapToolbar.vue
|
||
components/
|
||
styles/
|
||
```
|
||
|
||
Dashboard page владеет аналитическими фильтрами, вкладками, API wrappers, DTO-to-view helpers,
|
||
табличной сортировкой, tooltip templates и page-specific компонентами. TanStack Query отвечает
|
||
за server state cache; ручной response cache удален.
|
||
|
||
### `pages/auth`
|
||
|
||
```text
|
||
src/pages/auth/
|
||
model/
|
||
loginSchema.ts
|
||
redirect.ts
|
||
useAuthLogin.ts
|
||
ui/
|
||
```
|
||
|
||
UI формы не содержит schema и redirect validation. Эти правила находятся в model-сегменте и
|
||
покрыты unit-тестами.
|
||
|
||
### `widgets/protected-app-layout`
|
||
|
||
Widget собирает защищенную часть приложения: header, sidebar, page content, footer и scroll-up.
|
||
Здесь живут current-user composition, logout orchestration, sidebar route matching, route preload
|
||
и persisted expanded groups. `shared/ui/AppSidebar` остается pure UI и не знает про Vue Router.
|
||
|
||
### `shared/api`
|
||
|
||
Содержит API client, auth token primitives, refresh/session infrastructure, error normalization,
|
||
generated API и public facade. Прикладной код импортирует endpoint functions и DTO-типы через
|
||
`@/shared/api`, а не из `generated-api`.
|
||
|
||
## Generated и vendor-зоны
|
||
|
||
Эти зоны исключены из FSD/formatting-оценки как generated/vendor:
|
||
|
||
- `src/shared/api/generated-api`
|
||
- `src/shared/model/generated-zod`
|
||
- `src/shared/ui-kit`
|
||
|
||
Ручные wrappers, adapters и page models не должны попадать в эти исключения.
|
||
|
||
## Проверки архитектуры
|
||
|
||
Основная команда:
|
||
|
||
```bash
|
||
bun run check:full
|
||
```
|
||
|
||
Она запускает ESLint, Steiger, unit tests, typecheck/build и Playwright E2E. Для быстрой проверки
|
||
FSD-границ:
|
||
|
||
```bash
|
||
bun run lint:fsd
|
||
```
|
||
|
||
Перед передачей изменений заказчику `lint:fsd` должен проходить без ошибок или иметь явно
|
||
задокументированное точечное исключение.
|