@bonesofspring/ai-rules 0.1.42 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/package.json +1 -1
- package/presets/claude/next/CLAUDE.md +1 -1
- package/presets/claude/next/agents/README.md +61 -0
- package/presets/claude/next/agents/api-contract-reviewer.md +1 -1
- package/presets/claude/next/agents/build-verifier.md +2 -0
- package/presets/claude/next/agents/feature-developer.md +8 -21
- package/presets/claude/next/agents/task-router.md +24 -126
- package/presets/claude/next/commands/task.md +1 -1
- package/presets/claude/next/rules/README.md +3 -3
- package/presets/claude/next/rules/api-and-data/api-services.md +3 -3
- package/presets/claude/next/rules/api-and-data/http-client.md +2 -2
- package/presets/claude/next/rules/api-and-data/store-rtk.md +2 -2
- package/presets/claude/next/rules/architecture/README.md +8 -11
- package/presets/claude/next/rules/architecture/api-public-imports.md +3 -26
- package/presets/claude/next/rules/architecture/architecture-boundaries.md +6 -6
- package/presets/claude/next/rules/architecture/feature-delivery-workflow.md +44 -69
- package/presets/claude/next/rules/architecture/layer-barrel-exports.md +5 -5
- package/presets/claude/next/rules/architecture/public-imports.md +46 -0
- package/presets/claude/next/rules/architecture/reference-features.md +4 -1
- package/presets/claude/next/rules/architecture/types-public-imports.md +3 -29
- package/presets/claude/next/rules/stack/next-app-core.md +20 -70
- package/presets/claude/next/rules/stack/no-type-assertion.md +3 -2
- package/presets/claude/next/rules/stack/types-jsdoc.md +1 -1
- package/presets/claude/next/rules/tooling-and-review/agent-team-intake.md +6 -0
- package/presets/claude/next/rules/tooling-and-review/agent-team-orchestrator.md +14 -1
- package/presets/claude/next/rules/tooling-and-review/code-quality.md +3 -11
- package/presets/claude/next/rules/tooling-and-review/code-review-mr.md +2 -2
- package/presets/claude/next/rules/tooling-and-review/package-manager.md +6 -15
- package/presets/claude/next/rules/tooling-and-review/post-change-lint.md +14 -24
- package/presets/claude/next/rules/ui-and-accessibility/css-property-order.md +6 -18
- package/presets/claude/next/rules/ui-and-accessibility/react-ui.md +1 -1
- package/presets/claude/next/skills/feature-delivery/SKILL.md +5 -20
- package/presets/cursor/next/AGENTS.md +1 -1
- package/presets/cursor/next/agents/README.md +81 -0
- package/presets/cursor/next/agents/api-contract-reviewer.md +1 -1
- package/presets/cursor/next/agents/build-verifier.md +2 -0
- package/presets/cursor/next/agents/code-reviewer.md +1 -1
- package/presets/cursor/next/agents/feature-developer.md +9 -30
- package/presets/cursor/next/agents/task-router.md +23 -125
- package/presets/cursor/next/commands/task.md +1 -1
- package/presets/cursor/next/rules/README.md +6 -7
- package/presets/cursor/next/rules/agent-team-intake.mdc +2 -2
- package/presets/cursor/next/rules/agent-team-orchestrator.mdc +14 -1
- package/presets/cursor/next/rules/api-public-imports.mdc +3 -24
- package/presets/cursor/next/rules/api-services.mdc +3 -3
- package/presets/cursor/next/rules/architecture-boundaries.mdc +6 -6
- package/presets/cursor/next/rules/code-quality-and-refactoring.mdc +3 -11
- package/presets/cursor/next/rules/code-review-mr.mdc +2 -2
- package/presets/cursor/next/rules/css-property-order-stylelint.mdc +6 -18
- package/presets/cursor/next/rules/feature-delivery-workflow.mdc +45 -22
- package/presets/cursor/next/rules/http-client.mdc +2 -2
- package/presets/cursor/next/rules/layer-barrel-exports.mdc +5 -5
- package/presets/cursor/next/rules/next-app-core.mdc +18 -71
- package/presets/cursor/next/rules/no-type-assertion-as-import-export.mdc +4 -1
- package/presets/cursor/next/rules/package-manager.mdc +6 -15
- package/presets/cursor/next/rules/post-change-lint.mdc +14 -24
- package/presets/cursor/next/rules/public-imports.mdc +48 -0
- package/presets/cursor/next/rules/react-ui.mdc +1 -1
- package/presets/cursor/next/rules/reference-features.mdc +5 -1
- package/presets/cursor/next/rules/store-rtk.mdc +2 -2
- package/presets/cursor/next/rules/types-jsdoc.mdc +1 -1
- package/presets/cursor/next/rules/types-public-imports.mdc +3 -26
- package/presets/cursor/next/skills/feature-delivery/SKILL.md +5 -20
- package/presets/cursor/next/rules/feature-delivery-flow.mdc +0 -74
|
@@ -7,18 +7,18 @@ alwaysApply: false
|
|
|
7
7
|
# Границы между слоями
|
|
8
8
|
|
|
9
9
|
- **UI (app/src/ui/**)**:
|
|
10
|
-
- Может импортировать: `@/ui/**`, `@/store/**`, типы из `@/types` и enum из `@/types/enums` (**только как в `
|
|
10
|
+
- Может импортировать: `@/ui/**`, `@/store/**`, типы из `@/types` и enum из `@/types/enums` (**только как в `public-imports.mdc`**), контракт к API — **только** `import … from '@/api'` (**`public-imports.mdc`**).
|
|
11
11
|
- Не должен:
|
|
12
12
|
- обращаться к HTTP‑клиенту напрямую;
|
|
13
13
|
- знать детали DTO backend — только доменные типы.
|
|
14
14
|
- **Store (app/src/store/**)**:
|
|
15
|
-
- Может импортировать: `@/store/**`, сервисы и публичные сущности API — **только** из `@/api` (**`
|
|
15
|
+
- Может импортировать: `@/store/**`, сервисы и публичные сущности API — **только** из `@/api` (**`public-imports.mdc`**), типы из `@/types` и enum из `@/types/enums` (**`public-imports.mdc`**).
|
|
16
16
|
- Не должен:
|
|
17
17
|
- зависеть от конкретных UI‑компонентов;
|
|
18
18
|
- напрямую работать с global/window API.
|
|
19
19
|
- Вызовы к backend — только через сервисы, импортируемые из `@/api`; **транспортные** типы ответа и ошибки (из `@/types`, в том же виде, что у прикладного HTTP‑клиента) во thunk допустимы, если так выстроен API‑слой (`http-client.mdc`, `store-rtk.mdc`).
|
|
20
20
|
- **API (`app/src/api/**`)** — реализация в `services/**`, `clients/**`, реэкспорт в `app/src/api/index.ts`:
|
|
21
|
-
- Внутри слоя: типы из `@/types` и enum из `@/types/enums` (**`
|
|
21
|
+
- Внутри слоя: типы из `@/types` и enum из `@/types/enums` (**`public-imports.mdc`**); импорты `@/api/services/**`, `@/api/clients/**`, относительные пути между файлами слоя (`http-client.mdc`, `api-services.mdc`).
|
|
22
22
|
- Не должен:
|
|
23
23
|
- тянуть в себя UI или store;
|
|
24
24
|
- смешивать HTTP‑слой и доменный слой — использовать мапперы.
|
|
@@ -33,7 +33,7 @@ alwaysApply: false
|
|
|
33
33
|
|
|
34
34
|
- **Входящий адаптер**: UI — ввод пользователя, отображение; зависит от store и доменных типов, не от транспорта.
|
|
35
35
|
- **Оркестрация сценариев**: store (slices, thunk) — вызывает сервисы, кладёт в state **доменные** модели после маппинга.
|
|
36
|
-
- **Исходящий порт (контракт к backend)**: публичный API **`@/api`** (barrel `app/src/api/index.ts`; реализация — в `app/src/api/services/**` и т.д., см. `
|
|
36
|
+
- **Исходящий порт (контракт к backend)**: публичный API **`@/api`** (barrel `app/src/api/index.ts`; реализация — в `app/src/api/services/**` и т.д., см. `public-imports.mdc`).
|
|
37
37
|
- **Исходящий адаптер**: общая реализация HTTP в **`app/src/lib/clients/**`** и экземпляры в **`app/src/api/clients/**`**.
|
|
38
38
|
|
|
39
39
|
## Фича как срез
|
|
@@ -44,7 +44,7 @@ alwaysApply: false
|
|
|
44
44
|
|
|
45
45
|
- Всегда использовать алиас `@/...` для импортов между слоями.
|
|
46
46
|
- Внутри одного модуля/фичи можно использовать относительные импорты, но **без подъёма выше корня фичи** (избегать `../../../`).
|
|
47
|
-
- При обращении из компонентов, хуков, утилит и других модулей к чужому слою или фиче использовать только **public API** (barrel/index‑файлы и явно экспортируемые сущности), не делать deep‑импорты внутренних файлов других фич; для регламентированных слоёв — **`layer-barrel-exports.mdc`** и
|
|
47
|
+
- При обращении из компонентов, хуков, утилит и других модулей к чужому слою или фиче использовать только **public API** (barrel/index‑файлы и явно экспортируемые сущности), не делать deep‑импорты внутренних файлов других фич; для регламентированных слоёв — **`layer-barrel-exports.mdc`** и `public-imports.mdc`; для API‑слоя снаружи `app/src/api/**` — **`public-imports.mdc`** (только `@/api`).
|
|
48
48
|
- При добавлении нового кода проверять:
|
|
49
49
|
- если модуль переиспользуемый — он должен зависеть только от более "низких" слоёв (types, utils, api), но не от страниц.
|
|
50
50
|
|
|
@@ -55,7 +55,7 @@ alwaysApply: false
|
|
|
55
55
|
- Локальные компоненты: поддиректории `components/**` внутри страницы.
|
|
56
56
|
- Связанный store: `app/src/store/slices/OrderCheckout/**`.
|
|
57
57
|
- API: `app/src/api/services/OrdersApi/OrderCheckout/**` (имя корневого сервиса взять из принятой в проекте схемы).
|
|
58
|
-
- Типы: `app/src/types/**` с экспортом через barrel **`app/src/types/index.ts`** (`
|
|
58
|
+
- Типы: `app/src/types/**` с экспортом через barrel **`app/src/types/index.ts`** (`public-imports.mdc`).
|
|
59
59
|
|
|
60
60
|
# Требование к агенту
|
|
61
61
|
|
|
@@ -35,19 +35,11 @@ alwaysApply: true
|
|
|
35
35
|
- сначала локально улучшить архитектуру минимальными шагами;
|
|
36
36
|
- оставить код в консистентном состоянии.
|
|
37
37
|
|
|
38
|
-
#
|
|
38
|
+
# Линтеры
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
- Учитывать **Stylelint** для CSS и CSS-in-JS (конфиг: `app/.stylelintrc`; порядок свойств — `css-property-order-stylelint.mdc`).
|
|
42
|
-
- Новый или изменённый код не должен нарушать эти правила.
|
|
43
|
-
- После **каждого** изменения кода агент **обязан** выполнить **`post-change-lint.mdc`**: полный прогон **`lint:js`** и **`lint:css`**, анализ вывода, исправление срабатываний в зоне задачи.
|
|
44
|
-
- Отключение правила (`eslint-disable`) — только **точечно** (строка/небольшой блок) и с **кратким комментарием**, зачем это нужно; отключать «на весь файл» без веской причины не следует.
|
|
40
|
+
Lint/stylelint — только **`post-change-lint.mdc`**; ESLint config: `app/eslint.config.mjs`. Отключение правила (`eslint-disable`) — только **точечно** (строка/небольшой блок) с кратким комментарием «зачем».
|
|
45
41
|
|
|
46
42
|
# Требование к агенту
|
|
47
43
|
|
|
48
|
-
|
|
49
|
-
- Поддерживать принцип **“boy scout rule”**:
|
|
50
|
-
- оставлять модуль в немного лучшем состоянии, чем до изменения (простые, безопасные улучшения).
|
|
44
|
+
- **Boy scout rule:** оставлять модуль немного лучше, чем до изменения (простые, безопасные улучшения).
|
|
51
45
|
- Не жертвовать архитектурой и слоями ради краткости реализации.
|
|
52
|
-
- **Не завершать задачу**, пока не пройдены обязательные линтеры (`post-change-lint.mdc`).
|
|
53
|
-
|
|
@@ -17,11 +17,11 @@ alwaysApply: false
|
|
|
17
17
|
- API (`app/src/api/**`) не тянет UI/store, использует мапперы; без прямого `fetch` в сервисах (кроме оговорённых исключений).
|
|
18
18
|
- **Импорты и организация кода**:
|
|
19
19
|
- Использование алиаса `@/...` вместо относительных импортов выше по дереву.
|
|
20
|
-
- Отсутствие deep‑импортов во внешние фичи; использование только public API; в файлах вне `app/src/api/**` импорты из API — только `from '@/api'` (`
|
|
20
|
+
- Отсутствие deep‑импортов во внешние фичи; использование только public API; в файлах вне `app/src/api/**` импорты из API — только `from '@/api'` (`public-imports.mdc`, дублирует ESLint).
|
|
21
21
|
- При новых/изменённых модулях в регламентированных слоях — реэкспорт публичных символов в корневой barrel по **`layer-barrel-exports.mdc`**.
|
|
22
22
|
- Размещение новых файлов в корректных слоях и директориях фич.
|
|
23
23
|
- **Типы и TS‑строгость**:
|
|
24
|
-
- Не допускать новых `any`; предпочитать доменные типы из `@/types` (barrel, см. `
|
|
24
|
+
- Не допускать новых `any`; предпочитать доменные типы из `@/types` (barrel, см. `public-imports.mdc`).
|
|
25
25
|
- Проверять корректность пропсов/возвращаемых типов, особенно в UI и API‑слое.
|
|
26
26
|
- **UI и стили**:
|
|
27
27
|
- Для компонентов и стилей сверяться с `react-ui.mdc` и `next-app-core.mdc`:
|
|
@@ -1,28 +1,16 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Порядок CSS-свойств по Stylelint (idiomatic-order) — для любых стилей в проекте
|
|
3
3
|
globs:
|
|
4
|
-
- app/src/**/*.
|
|
4
|
+
- app/src/ui/**/*.styles.ts
|
|
5
|
+
- app/src/ui/**/*.styles.tsx
|
|
6
|
+
- app/src/ui/**/styles.ts
|
|
7
|
+
- app/src/ui/**/styles.tsx
|
|
5
8
|
- app/**/*.css
|
|
6
9
|
alwaysApply: false
|
|
7
10
|
---
|
|
8
11
|
|
|
9
12
|
# Порядок CSS-свойств (как в Stylelint)
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
Для CSS в `.css`, `styles.ts(x)`, `styled` / Linaria — порядок свойств как в **`app/.stylelintrc`** (`@sh/stylelint-config-react` → `stylelint-config-idiomatic-order`).
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Пиши объявления в **одном** блоке в такой последовательности групп:
|
|
16
|
-
|
|
17
|
-
1. **`composes`** — только для CSS Modules (если есть).
|
|
18
|
-
2. **`all`**
|
|
19
|
-
3. **Позиционирование:** `position`, `z-index`, затем `top`, `right`, `bottom`, `left`.
|
|
20
|
-
4. **Отображение и раскладка:** `display`, `overflow`.
|
|
21
|
-
5. **Размеры:** `width`, `min-width`, `max-width`, `height`, `min-height`, `max-height`, `box-sizing`.
|
|
22
|
-
6. **Flex:** `flex`, `flex-basis`, `flex-direction`, `flex-flow`, `flex-grow`, `flex-shrink`, `flex-wrap`, `align-content`, `align-items`, `align-self`, `justify-content`, `order`.
|
|
23
|
-
7. **Внутренние отступы:** `padding-top`, `padding-right`, `padding-bottom`, `padding-left`.
|
|
24
|
-
8. **Рамка:** общие `border`, `border-width`, `border-style`, `border-color`, `border-radius`; затем для сторон **сверху по часовой** — `border-top` и его `-width`, `-style`, `-color`, `-radius`, то же для `right`, `bottom`, `left`.
|
|
25
|
-
9. **Внешние отступы:** `margin-top`, `margin-right`, `margin-bottom`, `margin-left`.
|
|
26
|
-
10. **Остальные свойства** — после перечисленных, **по алфавиту** (типографика, фон, анимации, `cursor`, и т.д.).
|
|
27
|
-
|
|
28
|
-
Автоисправление из каталога `app`: `yarn lint:css --fix` (проверяет `**/*.{css,ts}`).
|
|
16
|
+
Не дублировать список свойств вручную. Автоисправление из `app/`: **`yarn lint:css --fix`** (или менеджер пакетов репо). Полный прогон — **`post-change-lint.mdc`**.
|
|
@@ -5,19 +5,19 @@ alwaysApply: false
|
|
|
5
5
|
|
|
6
6
|
# Доставка фичи (сквозной порядок)
|
|
7
7
|
|
|
8
|
-
Типичная фича с данными с backend и общим состоянием. Детали слоёв —
|
|
8
|
+
Типичная фича с данными с backend и общим состоянием. Детали слоёв — `architecture-boundaries.mdc`, `next-app-core.mdc`.
|
|
9
9
|
|
|
10
10
|
## Чеклист (порядок работ)
|
|
11
11
|
|
|
12
|
-
1. **Доменные типы** — `app/src/types/**`, экспорт через barrel
|
|
13
|
-
2. **Контракт API** — DTO
|
|
14
|
-
3. **Мапперы** — DTO → домен в `*responseMappers.ts`
|
|
15
|
-
4. **Сервисы** —
|
|
16
|
-
5. **Состояние** — `createSlice` / `createAsyncThunk
|
|
17
|
-
6. **UI** —
|
|
18
|
-
7. **Моки** — по схеме
|
|
19
|
-
8. **Тесты** — unit для мапперов
|
|
20
|
-
9. **Завершение** — **`post-change-lint.mdc`**:
|
|
12
|
+
1. **Доменные типы** — `app/src/types/**`, экспорт через barrel (`public-imports.mdc`, **`layer-barrel-exports.mdc`**); JSDoc — `types-jsdoc.mdc`.
|
|
13
|
+
2. **Контракт API** — DTO там, где принято; доменные типы в `@/types`.
|
|
14
|
+
3. **Мапперы** — DTO → домен в `*responseMappers.ts` (`api-services.mdc`).
|
|
15
|
+
4. **Сервисы** — клиенты `app/src/api/clients/**`, barrel `@/api` (`api-services.mdc`, `http-client.mdc`, **`layer-barrel-exports.mdc`**). Без `fetch` из UI/store.
|
|
16
|
+
5. **Состояние** — `createSlice` / `createAsyncThunk` (`store-rtk.mdc`); thunk → сервисы из `@/api`.
|
|
17
|
+
6. **UI** — типы из `@/types`, без DTO (`react-ui.mdc`, `architecture-boundaries.mdc`, `no-props-spread.mdc`).
|
|
18
|
+
7. **Моки** — по схеме репо; регистрация в `app/src/mocks/handlers.ts` (см. ниже).
|
|
19
|
+
8. **Тесты** — unit для мапперов (`tests-unit.mdc`); e2e по `*.cases.md` (`tests-e2e-structure.mdc`, `playwright-agents.mdc`).
|
|
20
|
+
9. **Завершение** — **`post-change-lint.mdc`**: `lint:js` + `lint:css` + `type-check`; менеджер — `package-manager.mdc`.
|
|
21
21
|
|
|
22
22
|
## Поток данных (ориентир)
|
|
23
23
|
|
|
@@ -35,19 +35,42 @@ flowchart LR
|
|
|
35
35
|
Store --> UI[UI]
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
##
|
|
38
|
+
## Регистрация по слоям
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
40
|
+
1. **Типы** — `app/src/types/**`; доменная модель — источник правды для UI и store.
|
|
41
|
+
2. **API** — `app/src/api/services/<ServiceRoot>/<Segment>/`; публичные экспорты (в т.ч. **константы путей** для моков) → **`app/src/api/index.ts`**.
|
|
42
|
+
3. **Моки (MSW)** — `app/src/mocks/data/<feature>/`; хендлеры в **`app/src/mocks/handlers.ts`**. Пути из `@/api`, не дублировать URL-строки. Проверить браузерный worker и Node `setupServer`, если оба используются.
|
|
43
|
+
4. **Store** — `app/src/store/slices/<FeatureName>/`; редюсер в **`app/src/store/reducers.ts`**. Middleware → `app/src/store/middleware/**`, регистрация в **`app/src/store/index.ts`**.
|
|
44
|
+
5. **UI** — `app/src/ui/pages/<FeatureName>Page/**` и/или `components/**`; данные через store/hooks.
|
|
45
|
+
6. **Unit** — `*.spec.ts(x)`; мапперы и нетривиальная логика — обязательно.
|
|
46
|
+
7. **E2E** — `app/__tests__/e2e/<Area>/<plan>.cases.md` + `*.spec.ts`.
|
|
47
|
+
|
|
48
|
+
## Частичные сценарии
|
|
49
|
+
|
|
50
|
+
| Задача | Минимум действий |
|
|
51
|
+
|--------|------------------|
|
|
52
|
+
| Только API + типы | Типы, сервис, мапперы, `@/api` barrel; unit на маппер. |
|
|
53
|
+
| Только моки | Путь в `@/api`; handlers + `mocks/handlers.ts`. |
|
|
54
|
+
| Только store | Thunk на `@/api`; slice + `reducers.ts`. |
|
|
55
|
+
| Только UI | Store state; без HTTP/DTO. |
|
|
56
|
+
| Только e2e | `*.cases.md` + spec; page object. |
|
|
48
57
|
|
|
49
|
-
|
|
58
|
+
## Антипаттерны
|
|
50
59
|
|
|
51
|
-
|
|
60
|
+
- DTO в UI или нетипизированном store.
|
|
61
|
+
- HTTP-клиент из компонента/thunk в обход сервиса.
|
|
62
|
+
- Deep-import `@/api/services/**` из UI/store.
|
|
63
|
+
- `{...props}` в компоненты — `no-props-spread.mdc`.
|
|
64
|
+
|
|
65
|
+
## Матрица: зона → правила
|
|
66
|
+
|
|
67
|
+
| Зона | Правила |
|
|
68
|
+
|------|---------|
|
|
69
|
+
| `app/src/api/clients/**`, `app/src/lib/clients/**` | `http-client.mdc`, `tests-unit.mdc` (behavior) |
|
|
70
|
+
| `app/src/api/services/**` | `api-services.mdc`, `layer-barrel-exports.mdc`, `http-client.mdc` |
|
|
71
|
+
| `app/src/store/**` | `store-rtk.mdc`, `architecture-boundaries.mdc`, `public-imports.mdc` |
|
|
72
|
+
| `app/src/ui/**` | `react-ui.mdc`, `no-props-spread.mdc`, `public-imports.mdc` |
|
|
73
|
+
| `app/src/types/**` | `public-imports.mdc`, `types-jsdoc.mdc`, `layer-barrel-exports.mdc` |
|
|
74
|
+
| `app/__tests__/e2e/**` | `tests-e2e-structure.mdc`, `playwright-agents.mdc` |
|
|
52
75
|
|
|
53
|
-
При добавлении или
|
|
76
|
+
При добавлении или расширении фичи **пройти чеклист** и правила из таблицы для затронутых зон.
|
|
@@ -14,12 +14,12 @@ alwaysApply: false
|
|
|
14
14
|
|
|
15
15
|
- Обычные REST‑вызовы к backend идут через **одну реализацию** в `app/src/lib/clients/**` (модуль общего клиента) и **преднастроенные экземпляры** в `app/src/api/clients/**`, по тому же паттерну, что уже принят в проекте.
|
|
16
16
|
- Место транспорта в общей картине **порты и адаптеры** — в `architecture-boundaries.mdc` (раздел **«Порты и адаптеры»**).
|
|
17
|
-
- **Не** вызывать `fetch` напрямую из `app/src/api/services/**`, store и UI (см. `architecture-boundaries.mdc`, `api-services.mdc`); из store/UI — только вызовы через сервисы из `@/api` (`
|
|
17
|
+
- **Не** вызывать `fetch` напрямую из `app/src/api/services/**`, store и UI (см. `architecture-boundaries.mdc`, `api-services.mdc`); из store/UI — только вызовы через сервисы из `@/api` (`public-imports.mdc`).
|
|
18
18
|
- **Исключения** (узкие протоколы, отдельный транспорт) — только там, где в репозитории уже есть образец; повторять его, не плодить произвольные обходы общего клиента.
|
|
19
19
|
|
|
20
20
|
## Типы
|
|
21
21
|
|
|
22
|
-
- Всё, что относится к **контракту запроса/ответа/ошибки** приложения и реэкспортируется для HTTP‑слоя, импортировать **только** из barrel `@/types`, без deep‑импортов из внутренних файлов `app/src/types/**` (см. `
|
|
22
|
+
- Всё, что относится к **контракту запроса/ответа/ошибки** приложения и реэкспортируется для HTTP‑слоя, импортировать **только** из barrel `@/types`, без deep‑импортов из внутренних файлов `app/src/types/**` (см. `public-imports.mdc`).
|
|
23
23
|
- Не поднимать в новом коде **типы и зависимости от внешнего HTTP‑клиента**, от которого проект ушёл; ориентир — **`package.json`** и существующие вызовы.
|
|
24
24
|
|
|
25
25
|
## Контракт ошибок
|
|
@@ -11,7 +11,7 @@ alwaysApply: false
|
|
|
11
11
|
Для **любого слоя** (каталога, пакета, bounded context), у которого:
|
|
12
12
|
|
|
13
13
|
- есть **корневой barrel** — единая точка импорта для внешних потребителей;
|
|
14
|
-
- deep-импорты внутрь слоя **запрещены** снаружи (ESLint `no-restricted-imports`, правила
|
|
14
|
+
- deep-импорты внутрь слоя **запрещены** снаружи (ESLint `no-restricted-imports`, правила `public-imports.mdc`).
|
|
15
15
|
|
|
16
16
|
Примеры alias/entry point в разных проектах: `@/api`, `@/types`, `@/core`, `@/store`, `packages/foo`.
|
|
17
17
|
|
|
@@ -34,7 +34,7 @@ alwaysApply: false
|
|
|
34
34
|
|
|
35
35
|
При добавлении или существенном расширении **модуля внутри регламентированного слоя**:
|
|
36
36
|
|
|
37
|
-
1. Определить слой, его **корневой barrel** и доп. entry points (
|
|
37
|
+
1. Определить слой, его **корневой barrel** и доп. entry points (`public-imports.mdc`).
|
|
38
38
|
2. Создать/обновить **локальный** `index.ts` — только публичные символы.
|
|
39
39
|
3. Если в слое есть **фасад/агрегатор** (`*ApiService.ts`, `rootReducer`, …) — подключить модуль там.
|
|
40
40
|
4. Добавить **реэкспорт** новых публичных символов в **корневой barrel** слоя.
|
|
@@ -44,7 +44,7 @@ alwaysApply: false
|
|
|
44
44
|
|
|
45
45
|
## Как найти регламентированные слои в репозитории
|
|
46
46
|
|
|
47
|
-
1. Правила
|
|
47
|
+
1. Правила `public-imports.mdc` в `.cursor/rules/`.
|
|
48
48
|
2. ESLint `no-restricted-imports` — паттерны `@/<layer>/*` с исключением barrel.
|
|
49
49
|
3. `architecture-boundaries.mdc`, README проекта.
|
|
50
50
|
|
|
@@ -52,8 +52,8 @@ alwaysApply: false
|
|
|
52
52
|
|
|
53
53
|
| Слой | Корневой barrel | Правило импортов |
|
|
54
54
|
|------|-------------------|------------------|
|
|
55
|
-
| API | `app/src/api/index.ts` | `
|
|
56
|
-
| Types | `app/src/types/index.ts` | `
|
|
55
|
+
| API | `app/src/api/index.ts` | `public-imports.mdc` |
|
|
56
|
+
| Types | `app/src/types/index.ts` | `public-imports.mdc` (+ `@/types/enums`) |
|
|
57
57
|
| Core | `app/src/core/index.ts` | ESLint: `@/core/index` |
|
|
58
58
|
|
|
59
59
|
Иллюстрация двух уровней (API): локальный `services/.../<Feature>/index.ts` → фасад `*ApiService.ts` → `app/src/api/index.ts`.
|
|
@@ -5,83 +5,30 @@ alwaysApply: true
|
|
|
5
5
|
|
|
6
6
|
# Стек и окружение
|
|
7
7
|
|
|
8
|
-
Конкретные версии
|
|
8
|
+
Конкретные версии — **из `package.json` и конфигов целевого репозитория**. Рамка preset: Next.js, React, TypeScript; runner/e2e/mocks/UI/APM — как заведено в репо.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
- **Сборка и Node:** как задано в репозитории.
|
|
12
|
-
- **Тесты:** unit/integration — runner и библиотеки проекта; e2e — инструмент проекта (правила для агентов Playwright — в отдельных файлах preset).
|
|
13
|
-
- **Моки HTTP/API:** если приняты в репо — повторять существующую схему (каталоги, регистрация, точка входа).
|
|
14
|
-
- **Стили и UI:** способ стилизации и **дизайн‑система / токены** — как уже заведено в коде; приоритет общим примитивам и токенам вместо разрозненных «магических» значений.
|
|
15
|
-
- **Наблюдаемость:** только если уже подключена в проекте — централизованно (клиент, обёртки), без дублирования в каждом методе.
|
|
10
|
+
# Структура проекта
|
|
16
11
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
- `app/src/**` — исходный код приложения.
|
|
21
|
-
- `app/__tests__/e2e/**` — e2e‑тесты и планы.
|
|
22
|
-
- `app/tsconfig.json`:
|
|
23
|
-
- `baseUrl: "."`
|
|
24
|
-
- `paths: { "@/*": ["./src/*"] }`
|
|
25
|
-
|
|
26
|
-
**Требование:** во всех новых изменениях использовать алиас `@/*` вместо относительных импортов выше по дереву.
|
|
12
|
+
- `app/` — корень Next.js; `app/src/**` — код; `app/__tests__/e2e/**` — e2e.
|
|
13
|
+
- `app/tsconfig.json`: `baseUrl: "."`, `paths: { "@/*": ["./src/*"] }`.
|
|
14
|
+
- **Требование:** `@/*` вместо относительных импортов выше по дереву.
|
|
27
15
|
|
|
28
16
|
# Архитектурные слои
|
|
29
17
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
- **HTTP‑транспорт** (модуль общего клиента под `app/src/lib/clients/**`, экземпляры под `app/src/api/clients/**` — как в репозитории):
|
|
39
|
-
- Один механизм запросов, без разбросанного «сырого» `fetch`/`XMLHttpRequest` по фичам. Детали и исключения — **`http-client.mdc`**.
|
|
40
|
-
- **Типы** (`app/src/types/**`):
|
|
41
|
-
- Доменные модели и при необходимости транспортные контракты; **потребители** импортируют только через **`types-public-imports.mdc`** (`@/types`, `@/types/enums`).
|
|
42
|
-
- **Моки и тестовые данные** (`app/src/mocks/**`):
|
|
43
|
-
- По структуре и назначению — как принято в репозитории.
|
|
44
|
-
|
|
45
|
-
## Порты и адаптеры (сопоставление с каталогами)
|
|
46
|
-
|
|
47
|
-
Та же идея, что в `architecture-boundaries.mdc` (раздел **«Порты и адаптеры»**): UI и store зависят от **контракта** к backend (публичный API `@/api` + доменные типы), а **реализация HTTP** изолирована в **`app/src/lib/clients/**`** и **`app/src/api/clients/**`**. Детали транспорта — `http-client.mdc`; импорты `@/api` — `api-public-imports.mdc`.
|
|
18
|
+
| Слой | Каталог | Детали |
|
|
19
|
+
|------|---------|--------|
|
|
20
|
+
| UI | `app/src/ui/**` (pages, components) | `react-ui.mdc`, `architecture-boundaries.mdc` |
|
|
21
|
+
| Store | `app/src/store/**` (slices, middleware) | `store-rtk.mdc` |
|
|
22
|
+
| API | `app/src/api/**` (services, clients, barrel) | `api-services.mdc`, `http-client.mdc` |
|
|
23
|
+
| HTTP | `app/src/lib/clients/**`, `app/src/api/clients/**` | `http-client.mdc` |
|
|
24
|
+
| Types | `app/src/types/**` | `public-imports.mdc`, `types-jsdoc.mdc` |
|
|
25
|
+
| Mocks | `app/src/mocks/**` | по схеме репозитория |
|
|
48
26
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
- **Чёткое разделение слоёв**:
|
|
52
|
-
- UI знает о доменных типах (из `@/types` / `@/types/enums`) и публичных API store и при необходимости импортирует из **`@/api`** — см. `api-public-imports.mdc` и `architecture-boundaries.mdc` (**«UI и обращение к API»**).
|
|
53
|
-
- Store знает о доменных типах и вызывает API‑сервисы через импорты из **`@/api`**.
|
|
54
|
-
- API‑сервисы знают о DTO, мапперах и вызовах через клиенты из `app/src/api/clients/**` (`http-client.mdc`).
|
|
55
|
-
- **Никаких "проникновений" слоёв**:
|
|
56
|
-
- UI не вызывает HTTP‑клиент и не работает с DTO; сценарии с записью в общий state — через store; узкие исключения для вызова сервисов из UI — только по правилам `architecture-boundaries.mdc`.
|
|
57
|
-
- Store не собирает запросы сам и не обходит API‑сервисы; данные для state — доменные модели после маппинга. Допустимые **транспортные** типы ответа/ошибки во thunk — как в `@/types` и согласованно с `http-client.mdc`, `store-rtk.mdc`.
|
|
58
|
-
- **Доменная логика и state**:
|
|
59
|
-
- Нетривиальные правила предметной области и преобразования **DTO → домен** — в **мапперах** и чистых функциях/модулях фичи (`api-services.mdc`); **редюсеры и селекторы** держать узкими (обновление state и проекции), без дублирования тяжёлой бизнес‑логики, если её место в маппере или доменном помощнике. Подробности — `store-rtk.mdc`.
|
|
60
|
-
- **Типы — источник правды**:
|
|
61
|
-
- При коллизии с другими правилами по **импорту типов** — ориентир **`types-public-imports.mdc`**.
|
|
62
|
-
- Новые сущности описывать в `app/src/types/**` и экспортировать через barrel; потребители не обходят `types-public-imports.mdc`.
|
|
63
|
-
- Не использовать `any`; при необходимости — `unknown` + безопасное сужение типа.
|
|
64
|
-
|
|
65
|
-
# Кодстайл и качества кода
|
|
66
|
-
|
|
67
|
-
- Следовать конфигам линтеров и форматтера **проекта** (`eslint`, `prettier`, `stylelint` — какие есть в репо).
|
|
68
|
-
- Поддерживать:
|
|
69
|
-
- KISS, DRY, SOLID (в разумных пределах для фронта).
|
|
70
|
-
- Модульность и переиспользование через компоненты, хуки, слайсы, сервисы.
|
|
71
|
-
- Визуальную консистентность за счёт принятых в проекте UI‑примитивов и токенов, а не разовых литералов в стилях.
|
|
72
|
-
- При добавлении нового кода **искать и копировать существующие паттерны**:
|
|
73
|
-
- Для страниц — аналогичные файлы в `app/src/ui/pages/**`.
|
|
74
|
-
- Для блоков — компоненты в `app/src/ui/components/**`.
|
|
75
|
-
- Для API — сервисы в `app/src/api/services/**`.
|
|
76
|
-
- Для состояния — слайсы в `app/src/store/slices/**`.
|
|
27
|
+
Границы слоёв, порты/адаптеры, UI→API — **`architecture-boundaries.mdc`**. Импорты `@/types`, `@/api` — **`public-imports.mdc`**.
|
|
77
28
|
|
|
78
29
|
# Работа агента
|
|
79
30
|
|
|
80
|
-
|
|
81
|
-
-
|
|
82
|
-
-
|
|
83
|
-
-
|
|
84
|
-
- Не упрощать архитектуру в ущерб существующим слоям (не тянуть DTO и HTTP в UI; вызовы сервисов из UI — только в рамках `architecture-boundaries.mdc`).
|
|
85
|
-
- Избегать использования `any` при типизации кода; при необходимости использовать `unknown` с последующим безопасным сужением типов.
|
|
86
|
-
- После **любых** изменений кода — **`post-change-lint.mdc`**: из каталога `app/` обязательно запустить **`lint:js`** и **`lint:css`** (полный прогон), проанализировать вывод, исправить errors/warnings в зоне задачи; задача не завершена, пока оба линтера не проходят. Дополнительно — **`type-check`** при правках TypeScript. Менеджер пакетов — **`package-manager.mdc`**.
|
|
87
|
-
|
|
31
|
+
- Архитектура и импорты: `architecture-boundaries.mdc`, `public-imports.mdc`
|
|
32
|
+
- Фичи: `feature-delivery-workflow.mdc` + skill `feature-delivery`
|
|
33
|
+
- После правок: `post-change-lint.mdc`; менеджер пакетов: `package-manager.mdc`
|
|
34
|
+
- Копировать паттерны соседних файлов в целевом слое; не использовать `any` (предпочитать `unknown` + сужение)
|
|
@@ -5,21 +5,12 @@ alwaysApply: true
|
|
|
5
5
|
|
|
6
6
|
# Менеджер пакетов (терминал)
|
|
7
7
|
|
|
8
|
-
Перед **`npm install` / `yarn` / `pnpm` / `bun`** и
|
|
8
|
+
Перед **`npm install` / `yarn` / `pnpm` / `bun`** и **`… run …`** определи менеджер репозитория и **используй только его**.
|
|
9
9
|
|
|
10
|
-
## Как определить
|
|
10
|
+
## Как определить
|
|
11
11
|
|
|
12
|
-
1.
|
|
13
|
-
2. **Lockfile**
|
|
14
|
-
|
|
15
|
-
- `pnpm-lock.yaml` → **pnpm**
|
|
16
|
-
- `package-lock.json` → **npm**
|
|
17
|
-
- `bun.lock` / `bun.lockb` → **bun**
|
|
18
|
-
3. Если структура неоднозначна — критерий: где лежат **`node_modules`** и какой lockfile обновляют в CI / документации репо.
|
|
12
|
+
1. **`packageManager`** в `package.json` (корень или `app/package.json`).
|
|
13
|
+
2. **Lockfile** рядом: `yarn.lock` → yarn; `pnpm-lock.yaml` → pnpm; `package-lock.json` → npm; `bun.lock(b)` → bun.
|
|
14
|
+
3. Если неоднозначно — где `node_modules` и какой lockfile в CI.
|
|
19
15
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
- Рабочий каталог — тот, где **`package.json`** с нужными **scripts** (в этом репозитории зависимости и скрипты в **`app/`**).
|
|
23
|
-
- Примеры: `yarn lint`, `pnpm run test` — **в соответствии с обнаруженным менеджером**, без смешения разных CLI в одной задаче.
|
|
24
|
-
|
|
25
|
-
Если менеджер неочевиден — **посмотри файлы** (`package.json`, lockfile) инструментами чтения/списка каталога, **не угадывай**.
|
|
16
|
+
Рабочий каталог для scripts — **`app/`**. Примеры: `yarn lint`, `pnpm run test`. Не угадывай — проверь файлы.
|
|
@@ -7,42 +7,32 @@ alwaysApply: true
|
|
|
7
7
|
|
|
8
8
|
## Когда применять
|
|
9
9
|
|
|
10
|
-
После **любого** изменения исходников в
|
|
10
|
+
После **любого** изменения исходников в `app/**` (TS/TSX/JS/MJS, CSS, styled/Linaria в `.ts`/`.tsx`).
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Исключения: правки документации вне `app/`, конфигов CI, `.cursor/rules/**`, если исполняемый код приложения не менялся.
|
|
13
|
+
|
|
14
|
+
**Pipeline exception:** если задача идёт через agent team и следующий шаг — `build-verifier`, developer может ограничиться lint/type-check **изменённых файлов**; полный прогон — обязанность `build-verifier`. В single-agent режиме (без pipeline) — всегда полный прогон.
|
|
13
15
|
|
|
14
16
|
## Обязательные команды
|
|
15
17
|
|
|
16
|
-
Рабочий каталог — **`app
|
|
18
|
+
Рабочий каталог — **`app/`**. Менеджер пакетов — **`package-manager.mdc`**.
|
|
17
19
|
|
|
18
|
-
1. **`lint:js`** — полный ESLint по
|
|
20
|
+
1. **`lint:js`** — полный ESLint по проекту.
|
|
19
21
|
2. **`lint:css`** — полный Stylelint (`**/*.{css,ts}`).
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
Точечный ESLint/Stylelint только на один файл **не заменяет** полный прогон перед завершением задачи.
|
|
23
|
+
Точечный lint на один файл **не заменяет** полный прогон перед завершением задачи (кроме pipeline exception выше).
|
|
24
24
|
|
|
25
|
-
## Алгоритм
|
|
25
|
+
## Алгоритм
|
|
26
26
|
|
|
27
27
|
1. Завершить правки кода.
|
|
28
|
-
2. Запустить **`lint:js`** и **`lint:css`** из `app
|
|
29
|
-
3.
|
|
30
|
-
4.
|
|
31
|
-
5.
|
|
32
|
-
6. **Не считать задачу выполненной**, пока оба линтера не завершились с кодом 0 **или** в ответе пользователю не зафиксирован блокер (например, легаси вне скоупа) с перечислением оставшихся замечаний.
|
|
28
|
+
2. Запустить **`lint:js`** и **`lint:css`** из `app/`.
|
|
29
|
+
3. Проанализировать весь вывод; исправить errors/warnings в изменённых файлах; для Stylelint — **`lint:css --fix`** если автоисправимо.
|
|
30
|
+
4. Повторить до exit code 0 или зафиксировать блокер в ответе пользователю.
|
|
31
|
+
5. **`type-check`** при изменениях TypeScript. CI-уровень: **`lint`** (= `lint:js` + `lint:css` + `type-check`).
|
|
33
32
|
|
|
34
33
|
## Что исправлять
|
|
35
34
|
|
|
36
35
|
- **Errors** — обязательно.
|
|
37
|
-
- **Warnings** — обязательно в файлах
|
|
38
|
-
- **`eslint-disable`** — только точечно, с кратким комментарием «зачем» (`code-quality-and-refactoring.mdc`).
|
|
39
|
-
|
|
40
|
-
## Связанные проверки
|
|
41
|
-
|
|
42
|
-
- **`type-check`** — обязателен при изменениях TypeScript (`next-app-core.mdc`); не подменяет ESLint/Stylelint.
|
|
43
|
-
- Полная валидация как в CI: **`lint`** (= `lint:js` + `lint:css` + `type-check`) — уместна перед крупным MR.
|
|
44
|
-
|
|
45
|
-
## Конфиги
|
|
36
|
+
- **Warnings** — обязательно в файлах задачи; вне скоупа — упомянуть, если мешают нулевому exit code.
|
|
46
37
|
|
|
47
|
-
|
|
48
|
-
- Stylelint: `app/.stylelintrc` (порядок свойств — `css-property-order-stylelint.mdc`)
|
|
38
|
+
Конфиги: `app/eslint.config.mjs`, `app/.stylelintrc` (порядок CSS — `css-property-order-stylelint.mdc`).
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Импорт доменных типов и API только через публичные barrel @/types и @/api
|
|
3
|
+
globs:
|
|
4
|
+
- app/src/ui/**/*
|
|
5
|
+
- app/src/store/**/*
|
|
6
|
+
- app/src/lib/**/*
|
|
7
|
+
- app/src/types/**/*
|
|
8
|
+
- app/src/api/**/*
|
|
9
|
+
alwaysApply: false
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Публичные импорты (`@/types`, `@/api`)
|
|
13
|
+
|
|
14
|
+
**Коллизии:** импорт типов — раздел `@/types` ниже; API вне `app/src/api/**` — раздел `@/api` ниже (дублирует ESLint `no-restricted-imports` в `app/eslint.config.mjs`).
|
|
15
|
+
|
|
16
|
+
## `@/types`
|
|
17
|
+
|
|
18
|
+
- **Публичный API типов** — barrel `app/src/types/index.ts`; импортировать типы только как `@/types` (или `@/types/index`).
|
|
19
|
+
- **Запрещено** обходить barrel: `@/types/<что‑угодно>`, кроме enum.
|
|
20
|
+
- **Enum** — только `@/types/enums` / `@/types/enums.ts`.
|
|
21
|
+
- Внутри `app/src/types/**` — относительные импорты между файлами слоя.
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
// ✅
|
|
25
|
+
import type { TUserProfile } from '@/types'
|
|
26
|
+
import { SomeEnum } from '@/types/enums'
|
|
27
|
+
|
|
28
|
+
// ❌
|
|
29
|
+
import type { TUserProfile } from '@/types/User.types'
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Новые публичные типы — реэкспорт в `app/src/types/index.ts` по **`layer-barrel-exports.mdc`**.
|
|
33
|
+
|
|
34
|
+
## `@/api`
|
|
35
|
+
|
|
36
|
+
- **Публичный API** — barrel `app/src/api/index.ts`. Вне `app/src/api/**` — только `import … from '@/api'` (или `@/api/index`).
|
|
37
|
+
- **Запрещено** снаружи слоя: `@/api/<что‑угодно>`, кроме `@/api/index`.
|
|
38
|
+
- Внутри `app/src/api/**` — относительные импорты и `@/api/services/**`, `@/api/clients/**`.
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
// ✅ в store, UI, lib вне app/src/api
|
|
42
|
+
import { MedcardApiService } from '@/api'
|
|
43
|
+
|
|
44
|
+
// ❌ снаружи app/src/api
|
|
45
|
+
import { MedcardApiService } from '@/api/services/MedcardApiService/MedcardApiService'
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Новые публичные символы API — реэкспорт в `app/src/api/index.ts` по **`layer-barrel-exports.mdc`**.
|
|
@@ -71,7 +71,7 @@ alwaysApply: false
|
|
|
71
71
|
- Описывать пропсы через `type Props = { ... }` или `interface Props { ... }`.
|
|
72
72
|
- Не использовать `any`; при необходимости:
|
|
73
73
|
- обобщения (`<T>`), `unknown`, тип‑предикаты и user‑defined type guards.
|
|
74
|
-
- Для доменных сущностей использовать типы из `@/types` (и enum из `@/types/enums`), а не описывать их заново (`
|
|
74
|
+
- Для доменных сущностей использовать типы из `@/types` (и enum из `@/types/enums`), а не описывать их заново (`public-imports.mdc`).
|
|
75
75
|
|
|
76
76
|
# Логика и side effects
|
|
77
77
|
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Эталонные фичи репозитория — копировать структуру при реализации новых задач. Заполните пути после init в целевом репо.
|
|
3
|
-
globs:
|
|
3
|
+
globs:
|
|
4
|
+
- app/src/ui/**/*
|
|
5
|
+
- app/src/store/**/*
|
|
6
|
+
- app/src/api/**/*
|
|
7
|
+
- app/src/types/**/*
|
|
4
8
|
alwaysApply: false
|
|
5
9
|
---
|
|
6
10
|
|
|
@@ -30,7 +30,7 @@ alwaysApply: false
|
|
|
30
30
|
- Асинхронные запросы:
|
|
31
31
|
- через `createAsyncThunk` или RTK Query.
|
|
32
32
|
- внутри thunk:
|
|
33
|
-
- вызывать API через сервисы, импортированные из `@/api` (**`
|
|
33
|
+
- вызывать API через сервисы, импортированные из `@/api` (**`public-imports.mdc`**);
|
|
34
34
|
- не вызывать HTTP‑клиент напрямую — только через эти сервисы.
|
|
35
35
|
- Сайд‑эффекты (логирование, аналитика, работа с файлами):
|
|
36
36
|
- выносить в middleware (`app/src/store/middleware/**`) или специализированные слайсы.
|
|
@@ -44,7 +44,7 @@ alwaysApply: false
|
|
|
44
44
|
- при ошибках после вызова сервиса — опираться на **тот же класс/контракт ошибки транспорта**, что использует общий клиент (из `@/types`), и разбирать тело/статус **по полям текущей реализации**, а не по воображаемому API;
|
|
45
45
|
- в **`catch`** предпочитать **`instanceof`** на класс ошибки транспорта из `@/types` (если он есть в коде) вместо голого `as`, когда это выразимо без шума (см. `no-type-assertion-as-import-export.mdc`).
|
|
46
46
|
- Для сущностей:
|
|
47
|
-
- доменные типы (включая вычисляемые поля) определять в `app/src/types/**`, экспортировать через barrel и импортировать в слайсы из `@/types` как **источник правды** для структуры данных (`
|
|
47
|
+
- доменные типы (включая вычисляемые поля) определять в `app/src/types/**`, экспортировать через barrel и импортировать в слайсы из `@/types` как **источник правды** для структуры данных (`public-imports.mdc`);
|
|
48
48
|
- избегать дублирования описаний сущностей в нескольких местах.
|
|
49
49
|
- **Граница домена**: в **state** хранить доменные модели; тип **обёртки ответа клиента** допустим как тип **возвращаемого значения thunk** или промежуточно до маппинга — без дублирования DTO в полях state без нужды (согласовано с `api-services.mdc` и `http-client.mdc`).
|
|
50
50
|
|