@bonesofspring/ai-rules 0.1.32 → 0.1.33
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/package.json +1 -1
- package/presets/cursor/next/rules/README.md +20 -0
- package/presets/cursor/next/rules/api-services.mdc +9 -8
- package/presets/cursor/next/rules/architecture-boundaries.mdc +28 -10
- package/presets/cursor/next/rules/code-review-mr.mdc +13 -5
- package/presets/cursor/next/rules/feature-delivery-flow.mdc +74 -0
- package/presets/cursor/next/rules/http-client.mdc +42 -0
- package/presets/cursor/next/rules/next-app-core.mdc +31 -22
- package/presets/cursor/next/rules/no-type-assertion-as-import-export.mdc +56 -0
- package/presets/cursor/next/rules/react-ui.mdc +2 -2
- package/presets/cursor/next/rules/store-rtk.mdc +11 -4
- package/presets/cursor/next/rules/technical-retro.mdc +58 -0
- package/presets/cursor/next/rules/tests-unit.mdc +22 -7
- package/presets/cursor/next/rules/types-jsdoc.mdc +42 -0
- package/presets/cursor/next/rules/types-public-imports.mdc +29 -0
package/package.json
CHANGED
|
@@ -10,3 +10,23 @@
|
|
|
10
10
|
- Cursor интерпретирует его как конфигурацию поведения ассистента для этого репо (автоматически подмешивает содержимое в контекст, когда правило подходит).
|
|
11
11
|
|
|
12
12
|
- То есть .mdc = “markdown + config для Cursor”, .md = просто текст без управляющего смысла для ассистента.
|
|
13
|
+
|
|
14
|
+
### Каталог ключевых правил
|
|
15
|
+
|
|
16
|
+
| Файл | Назначение |
|
|
17
|
+
|------|------------|
|
|
18
|
+
| `next-app-core.mdc` | Стек, слои, порты‑адаптеры (кратко), доменная логика vs state, общие требования к агенту и линтам |
|
|
19
|
+
| `architecture-boundaries.mdc` | Границы UI / store / API, импорты (`@/types` по `types-public-imports`), UI→services, порты‑адаптеры, фича как срез |
|
|
20
|
+
| `http-client.mdc` | Один HTTP‑стек, контракты из `@/types`, без разбросанного низкоуровневого API |
|
|
21
|
+
| `api-services.mdc` | Сервисы, мапперы, вызовы через прикладные API‑клиенты |
|
|
22
|
+
| `store-rtk.mdc` | Redux Toolkit, thunk’и, типизация ошибок/ответов как в коде репо |
|
|
23
|
+
| `types-public-imports.mdc` | Импорты только через barrel `@/types` |
|
|
24
|
+
| `types-jsdoc.mdc` | JSDoc для типов в `app/src/types` (русский текст, `[computed]`, без `@param`/`@returns`) |
|
|
25
|
+
| `no-type-assertion-as-import-export.mdc` | Ограничение `as`, в т.ч. `instanceof` для ошибок транспорта в `catch` |
|
|
26
|
+
| `code-review-mr.mdc` | Чеклист ревью MR, в т.ч. HTTP‑клиент и тесты |
|
|
27
|
+
| `tests-unit.mdc` | Unit‑тесты и behavior‑тесты HTTP‑клиента |
|
|
28
|
+
| `playwright-agents.mdc`, `tests-e2e-structure.mdc` | E2E |
|
|
29
|
+
|
|
30
|
+
**Коллизии формулировок:** если в разных `.mdc` расходятся детали **импорта типов**, источник правды — **`types-public-imports.mdc`** (`@/types`, `@/types/enums`).
|
|
31
|
+
|
|
32
|
+
Задачи на **сеть, замену HTTP‑библиотеки, новые эндпоинты**: опираться на **`http-client.mdc`** + **`api-services.mdc`** + **`store-rtk.mdc`**.
|
|
@@ -1,40 +1,41 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Конвенции API сервисов и мапперов
|
|
3
|
-
globs: src/api/services/**/*.ts
|
|
3
|
+
globs: app/src/api/services/**/*.ts
|
|
4
4
|
alwaysApply: false
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Роль API слоя
|
|
8
8
|
|
|
9
9
|
- Инкапсулировать всё, что связано с:
|
|
10
|
-
- HTTP‑запросами
|
|
10
|
+
- HTTP‑запросами через **экземпляры прикладных API‑клиентов** в `app/src/api/clients/**`, собранные на **общей реализации** из `app/src/lib/clients/**` (как в существующем коде); подробности — **`http-client.mdc`**; положение слоя в схеме **порты и адаптеры** — `architecture-boundaries.mdc`;
|
|
11
11
|
- URL/путями,
|
|
12
12
|
- заголовками и кодами ответов,
|
|
13
13
|
- DTO backend.
|
|
14
14
|
- Предоставлять UI и store **стабильный доменный интерфейс**:
|
|
15
|
-
- функции, работающие с доменными типами из `@/types
|
|
15
|
+
- функции, работающие с доменными типами из `@/types` (`types-public-imports.mdc`).
|
|
16
16
|
- мапперы между DTO и доменными типами.
|
|
17
17
|
|
|
18
18
|
# Структура модулей
|
|
19
19
|
|
|
20
20
|
- Для каждой доменной области (например, заказы, биллинг, настройки аккаунта):
|
|
21
|
-
- отдельный каталог в `src/api/services/<ИмяСервиса или фичи>/**` по конвенции репозитория.
|
|
21
|
+
- отдельный каталог в `app/src/api/services/<ИмяСервиса или фичи>/**` по конвенции репозитория.
|
|
22
22
|
- Внутри модуля:
|
|
23
23
|
- файлы с вызовами API (`index.ts` или `*.service.ts`);
|
|
24
24
|
- файлы мапперов (`*responseMappers.ts`);
|
|
25
|
-
- специфичные типы запросов/ответов (если не вынесены в `@/types
|
|
25
|
+
- специфичные типы запросов/ответов (если не вынесены в `app/src/types/**` с экспортом через barrel `@/types`).
|
|
26
26
|
- один или несколько **public API** файлов (`index.ts` или barrel‑файлы), через которые к модулю обращаются UI, store и другие слои.
|
|
27
27
|
|
|
28
28
|
# Мапперы и типы
|
|
29
29
|
|
|
30
30
|
- Для каждого запроса/эндпоинта:
|
|
31
31
|
- описывать **response‑тип (DTO)**, точно соответствующий контракту backend;
|
|
32
|
-
- определять **целевой доменный тип** в `src/types/**`, с которым будет работать приложение (включая вычисляемые/агрегированные поля).
|
|
32
|
+
- определять **целевой доменный тип** в `app/src/types/**`, с которым будет работать приложение (включая вычисляемые/агрегированные поля).
|
|
33
33
|
- Мапперы (например, `*responseMappers.ts`):
|
|
34
34
|
- чистые функции, без сайд‑эффектов;
|
|
35
35
|
- выполняют все необходимые вычисления и преобразования данных (булевы флаги, склейка строк, агрегаты и т.п.) при переводе из DTO в доменные модели;
|
|
36
36
|
- при необходимости обеспечивают обратное преобразование (доменные модели -> транспортные типы).
|
|
37
|
-
- UI и store работают только с доменными типами (из `@/types
|
|
37
|
+
- UI и store работают только с доменными типами (из `@/types` или экспортируемыми из public API слоя API), а не с "сырыми" DTO.
|
|
38
|
+
- **Не вызывать `fetch` напрямую** в теле API‑методов: только через клиент; исключения — узкие модули (например JSON‑RPC), если так уже устроено в репозитории.
|
|
38
39
|
|
|
39
40
|
# Обработка ошибок
|
|
40
41
|
|
|
@@ -51,6 +52,6 @@ alwaysApply: false
|
|
|
51
52
|
- Следовать существующим сервисам и мапперам как эталону.
|
|
52
53
|
- Не смешивать слой API и UI/store:
|
|
53
54
|
- компоненты не должны зависеть от DTO;
|
|
54
|
-
- store не должен
|
|
55
|
+
- store не должен сам собирать URL/коды эндпоинтов и не обходить сервисы; **транспортный тип ответа** и **контракт ошибки** из `@/types` (как у прикладного клиента) допустимы во thunk при разборе `catch`/payload, если так выстроен сервис (см. `store-rtk.mdc`, `http-client.mdc`).
|
|
55
56
|
- При использовании API‑сервисов в UI, store и утилитах импортировать только из public API файлов модуля (например, `@/api/services/OrdersApi/.../index`), а не из внутренних файлов‑реализаций.
|
|
56
57
|
|
|
@@ -5,22 +5,40 @@ alwaysApply: true
|
|
|
5
5
|
|
|
6
6
|
# Границы между слоями
|
|
7
7
|
|
|
8
|
-
- **UI (src/ui/**)**:
|
|
9
|
-
- Может импортировать: `@/ui/**`, `@/store/**`, `@/types
|
|
8
|
+
- **UI (app/src/ui/**)**:
|
|
9
|
+
- Может импортировать: `@/ui/**`, `@/store/**`, типы из `@/types` и enum из `@/types/enums` (**только как в `types-public-imports.mdc`**), `@/api/services/**` только через **public API** модулей сервисов.
|
|
10
10
|
- Не должен:
|
|
11
11
|
- обращаться к HTTP‑клиенту напрямую;
|
|
12
12
|
- знать детали DTO backend — только доменные типы.
|
|
13
|
-
- **Store (src/store/**)**:
|
|
14
|
-
- Может импортировать: `@/store/**`, `@/api/services
|
|
13
|
+
- **Store (app/src/store/**)**:
|
|
14
|
+
- Может импортировать: `@/store/**`, `@/api/services/**` (public API), типы из `@/types` и enum из `@/types/enums` (**`types-public-imports.mdc`**).
|
|
15
15
|
- Не должен:
|
|
16
16
|
- зависеть от конкретных UI‑компонентов;
|
|
17
17
|
- напрямую работать с global/window API.
|
|
18
|
-
-
|
|
19
|
-
|
|
18
|
+
- Вызовы к backend — только через сервисы; **транспортные** типы ответа и ошибки (из `@/types`, в том же виде, что у прикладного HTTP‑клиента) во thunk допустимы, если так выстроен API‑слой (`http-client.mdc`, `store-rtk.mdc`).
|
|
19
|
+
- **API (app/src/api/services/**)**:
|
|
20
|
+
- Может импортировать: типы из `@/types` и enum из `@/types/enums` (**`types-public-imports.mdc`**); **`@/api/clients/**`** — преднастроенные экземпляры HTTP‑клиента (`http-client.mdc`); общие утилиты проекта (как в соседних сервисах репозитория).
|
|
20
21
|
- Не должен:
|
|
21
22
|
- тянуть в себя UI или store;
|
|
22
23
|
- смешивать HTTP‑слой и доменный слой — использовать мапперы.
|
|
23
24
|
|
|
25
|
+
## UI и обращение к `@/api/services`
|
|
26
|
+
|
|
27
|
+
- По умолчанию сценарии с **изменением серверного состояния** и координация нескольких шагов — через **store** (`createAsyncThunk`, dispatch, паттерн фичи в репозитории).
|
|
28
|
+
- Прямой вызов функций из **`@/api/services/**` из UI допустим только в **узких случаях**: преимущественно **чтение** или действие **без необходимости держать результат в Redux**; тот же **public API** сервиса и те же **доменные типы**, что использовал бы thunk; **не** дублировать уже существующий сценарий из store и **не** протаскивать DTO в компоненты.
|
|
29
|
+
- Предпочтительно оформлять такие вызовы так же, как в **соседних фичах** репозитория (хук‑фасад, отдельный хук и т.д.).
|
|
30
|
+
|
|
31
|
+
## Порты и адаптеры (краткая карта)
|
|
32
|
+
|
|
33
|
+
- **Входящий адаптер**: UI — ввод пользователя, отображение; зависит от store и доменных типов, не от транспорта.
|
|
34
|
+
- **Оркестрация сценариев**: store (slices, thunk) — вызывает сервисы, кладёт в state **доменные** модели после маппинга.
|
|
35
|
+
- **Исходящий порт (контракт к backend)**: публичный API **`@/api/services/...`**.
|
|
36
|
+
- **Исходящий адаптер**: общая реализация HTTP в **`app/src/lib/clients/**`** и экземпляры в **`app/src/api/clients/**`**.
|
|
37
|
+
|
|
38
|
+
## Фича как срез
|
|
39
|
+
|
|
40
|
+
- Для сложной фичи выравниваются имена и термины (**единый язык** предметной области) в типах, селекторах, сервисах и UI; структура папок — как в соседних фичах репозитория.
|
|
41
|
+
|
|
24
42
|
# Правила импортов
|
|
25
43
|
|
|
26
44
|
- Всегда использовать алиас `@/...` для импортов между слоями.
|
|
@@ -32,11 +50,11 @@ alwaysApply: true
|
|
|
32
50
|
# Организация фич
|
|
33
51
|
|
|
34
52
|
- Для сложных фич (например, `OrderCheckout`):
|
|
35
|
-
- Страница: `src/ui/pages/OrderCheckoutPage/**`.
|
|
53
|
+
- Страница: `app/src/ui/pages/OrderCheckoutPage/**`.
|
|
36
54
|
- Локальные компоненты: поддиректории `components/**` внутри страницы.
|
|
37
|
-
- Связанный store: `src/store/slices/OrderCheckout/**`.
|
|
38
|
-
- API: `src/api/services/OrdersApi/OrderCheckout/**` (имя корневого сервиса взять из принятой в проекте схемы).
|
|
39
|
-
- Типы: `src/types/
|
|
55
|
+
- Связанный store: `app/src/store/slices/OrderCheckout/**`.
|
|
56
|
+
- API: `app/src/api/services/OrdersApi/OrderCheckout/**` (имя корневого сервиса взять из принятой в проекте схемы).
|
|
57
|
+
- Типы: `app/src/types/**` с экспортом через barrel **`app/src/types/index.ts`** (`types-public-imports.mdc`).
|
|
40
58
|
|
|
41
59
|
# Требование к агенту
|
|
42
60
|
|
|
@@ -11,16 +11,16 @@ alwaysApply: true
|
|
|
11
11
|
|
|
12
12
|
- **Что обязан проверить агент**
|
|
13
13
|
- **Архитектура и слои**:
|
|
14
|
-
- Соблюдение правил из `architecture-boundaries.mdc
|
|
15
|
-
- UI (`src/ui/**`) не ходит напрямую в HTTP‑клиент и не знает DTO.
|
|
16
|
-
- Store (`src/store/**`) не зависит от UI и
|
|
17
|
-
- API (`src/api/services/**`) не тянет UI/store, использует
|
|
14
|
+
- Соблюдение правил из `architecture-boundaries.mdc`, `next-app-core.mdc` и при сетевых изменениях — `http-client.mdc`:
|
|
15
|
+
- UI (`app/src/ui/**`) не ходит напрямую в HTTP‑клиент и не знает DTO.
|
|
16
|
+
- Store (`app/src/store/**`) не зависит от UI; границы транспортных типов и ошибок — `store-rtk.mdc` / `http-client.mdc`.
|
|
17
|
+
- API (`app/src/api/services/**`) не тянет UI/store, использует мапперы; без прямого `fetch` в сервисах (кроме оговорённых исключений).
|
|
18
18
|
- **Импорты и организация кода**:
|
|
19
19
|
- Использование алиаса `@/...` вместо относительных импортов выше по дереву.
|
|
20
20
|
- Отсутствие deep‑импортов во внешние фичи; использование только public API.
|
|
21
21
|
- Размещение новых файлов в корректных слоях и директориях фич.
|
|
22
22
|
- **Типы и TS‑строгость**:
|
|
23
|
-
- Не допускать новых `any`; предпочитать доменные типы из `
|
|
23
|
+
- Не допускать новых `any`; предпочитать доменные типы из `@/types` (barrel, см. `types-public-imports.mdc`).
|
|
24
24
|
- Проверять корректность пропсов/возвращаемых типов, особенно в UI и API‑слое.
|
|
25
25
|
- **UI и стили**:
|
|
26
26
|
- Для компонентов и стилей сверяться с `react-ui.mdc` и `next-app-core.mdc`:
|
|
@@ -30,7 +30,15 @@ alwaysApply: true
|
|
|
30
30
|
- Проверять, что для нетривиальных изменений:
|
|
31
31
|
- либо обновлены/добавлены unit‑тесты (`tests-unit.mdc`),
|
|
32
32
|
- либо e2e‑сценарии/спеки отражают новую логику (`playwright-agents.mdc`, `tests-e2e-structure.mdc`).
|
|
33
|
+
- При правках **общего HTTP‑клиента** — наличие/актуальность **behavior‑тестов клиента** (`http-client.mdc`, `tests-unit.mdc`).
|
|
33
34
|
- Указывать, какие именно тесты стоит добавить или поправить.
|
|
35
|
+
- **Линтеры (обязательно)**:
|
|
36
|
+
- Рабочий каталог: `app/` (там `package.json` с скриптами линта).
|
|
37
|
+
- Перед финализацией отчёта по ревью **запустить полный прогон** ESLint по проекту: `yarn lint:js` (эквивалент `eslint .` с расширениями из скрипта — без точечного запуска только на один файл, чтобы не пропустить косвенные срабатывания).
|
|
38
|
+
- Если в MR менялись стили (css/linaria и т.п.) — дополнительно `yarn lint:css`.
|
|
39
|
+
- В отчёт включить **все сообщения ESLint (errors и warnings)** по файлам, попадающим в дифф MR/ветки; если полный вывод огромный, сфокусироваться на диффе, но **не** пропускать проверку из‑за «только изменённые файлы» на этапе запуска — сначала полный `yarn lint:js`, затем фильтрация вывода к путям из `git diff`.
|
|
40
|
+
- При **имплементации правок** по итогам ревью или любой работе «как к MR»: после изменений снова выполнить `yarn lint:js` (и при необходимости `yarn lint:css`); не считать задачу завершённой, пока в изменённых файлах остаются исправимые предупреждения ESLint, которые относятся к этой задаче (исключение — явно устаревший легаси вне скоупа, с пометкой в ответе).
|
|
41
|
+
- При желании полной валидации, как в CI: `yarn lint` (ESLint + Stylelint + `type-check`) — уместно перед итогом крупного MR.
|
|
34
42
|
|
|
35
43
|
- **Глубина и формат ревью**
|
|
36
44
|
- Фокус на **изменениях MR** (дифф относительно целевой ветки), а не на всём проекте.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Сквозной flow фичи (типы, API, моки, store, UI, тесты) и точки регистрации в репозитории
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Поставка фичи: порядок слоёв и регистрация
|
|
7
|
+
|
|
8
|
+
Плейсхолдеры: `<FeatureName>`, `<ServiceRoot>`, `<Area>` — нейтральные имена; реальные имена брать из соседних фич того же типа.
|
|
9
|
+
|
|
10
|
+
## Инварианты перед кодом
|
|
11
|
+
|
|
12
|
+
- Найти в том же слое фичу сопоставимой сложности и **повторить структуру каталогов и паттерн именования**.
|
|
13
|
+
- Не добавлять `any`; при необходимости — `unknown` и сужение типа.
|
|
14
|
+
- После правок выполнить проверки из **`package.json` каталога `app/`** (типизация, ESLint и связанные скрипты), не оставлять новых ошибок без причины.
|
|
15
|
+
|
|
16
|
+
## Полный flow (слой за слоем)
|
|
17
|
+
|
|
18
|
+
```mermaid
|
|
19
|
+
flowchart LR
|
|
20
|
+
typesNode["types_domain"]
|
|
21
|
+
apiNode["api_services_mappers"]
|
|
22
|
+
mocksNode["mocks_msw"]
|
|
23
|
+
storeNode["store_slice_thunks"]
|
|
24
|
+
mwNode["middleware_optional"]
|
|
25
|
+
uiNode["ui_pages_components"]
|
|
26
|
+
unitNode["unit_tests"]
|
|
27
|
+
e2eNode["e2e_plans_specs"]
|
|
28
|
+
|
|
29
|
+
typesNode --> apiNode
|
|
30
|
+
apiNode --> mocksNode
|
|
31
|
+
apiNode --> storeNode
|
|
32
|
+
storeNode --> mwNode
|
|
33
|
+
storeNode --> uiNode
|
|
34
|
+
apiNode --> unitNode
|
|
35
|
+
storeNode --> unitNode
|
|
36
|
+
uiNode --> unitNode
|
|
37
|
+
uiNode --> e2eNode
|
|
38
|
+
mocksNode --> e2eNode
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Чеклист по слоям (куда класть и что зарегистрировать)
|
|
42
|
+
|
|
43
|
+
1. **Типы** — `app/src/types/**` (или согласованное имя вроде `<FeatureName>.types.ts`). Доменная модель — источник правды для UI и store.
|
|
44
|
+
|
|
45
|
+
2. **API** — `app/src/api/services/<ServiceRoot>/<Segment>/`: вызовы HTTP, DTO ответов, `*responseMappers.ts`. Новые публичные экспорты (фасады сервисов, типы, **константы путей** для моков) добавить в **`app/src/api/index.ts`** (`@/api`).
|
|
46
|
+
|
|
47
|
+
3. **Моки (MSW)** — `app/src/mocks/data/<feature>/`: `data.ts`, `handlers.ts`; собрать хендлеры в **`app/src/mocks/handlers.ts`**. В хендлерах использовать **те же константы путей**, что и в API (импорт из `@/api`), **не дублировать сырые строки URL**. В репозитории могут быть **два контура** (браузерный worker и Node `setupServer` для тестов): общий список хендлеров должен оставаться согласованным — при добавлении проверять существующие входные точки в `app/src/mocks/**`, чтобы моки были доступны там, где ожидается.
|
|
48
|
+
|
|
49
|
+
4. **Store** — `app/src/store/slices/<FeatureName>/`: slice, thunk’и вызывают методы из **`@/api`**, не HTTP‑клиент. Подключить редюсер в **`app/src/store/reducers.ts`**. Новый **middleware**: реализация в `app/src/store/middleware/**`, регистрация в **`app/src/store/index.ts`** в цепочке `configureStore` (порядок `prepend`/`concat` — как у соседних middleware в этом файле).
|
|
50
|
+
|
|
51
|
+
5. **UI** — `app/src/ui/pages/<FeatureName>Page/**` и/или `app/src/ui/components/**`; стили — как в проекте (см. `package.json` и соседние компоненты). Данные и побочные эффекты загрузки — через store/hooks, без DTO и без прямого HTTP‑клиента.
|
|
52
|
+
|
|
53
|
+
6. **Unit‑тесты** — `*.spec.ts` / `*.spec.tsx` (см. `tests-unit.mdc`); мапперы и нетривиальная логика — обязательно покрыть; e2e Jest не запускает (см. `jest.config.js`).
|
|
54
|
+
|
|
55
|
+
7. **E2E** — план: `app/__tests__/e2e/<Area>/<plan>.cases.md`; реализация: `*.spec.ts` рядом; детали — `tests-e2e-structure.mdc`.
|
|
56
|
+
|
|
57
|
+
## Частичные сценарии (вход с середины)
|
|
58
|
+
|
|
59
|
+
| Задача | Минимум действий |
|
|
60
|
+
|--------|------------------|
|
|
61
|
+
| Только API + типы | Типы в `app/src/types/**`, сервис и мапперы, реэкспорт в `app/src/api/index.ts`; unit на маппер. |
|
|
62
|
+
| Только моки | Константа пути уже в `@/api`; `handlers.ts` + данные; регистрация в `app/src/mocks/handlers.ts`; при необходимости убедиться, что хендлеры подхватываются и в браузерном, и в Node‑контуре MSW, если в проекте используются оба. |
|
|
63
|
+
| Только store | Thunk на существующий метод `@/api`; slice + `app/src/store/reducers.ts`. |
|
|
64
|
+
| Только UI | Читать готовое состояние из store; не добавлять HTTP/DTO; `data-testid` при необходимости для e2e. |
|
|
65
|
+
| Только e2e | Синхронизировать `*.cases.md` и спеки; page object и `_shared`. |
|
|
66
|
+
|
|
67
|
+
## Антипаттерны
|
|
68
|
+
|
|
69
|
+
- DTO и структуры ответа бэкенда в UI или в нетипизированных кусках store.
|
|
70
|
+
- Прямой вызов HTTP‑клиента из компонента или thunk’а в обход сервисного слоя.
|
|
71
|
+
- Deep‑импорты в `app/src/api/services/**/…` из UI/store там, где принят импорт из `@/api`.
|
|
72
|
+
- Проброс пропсов в компоненты через `{...props}` — см. `no-props-spread.mdc`.
|
|
73
|
+
|
|
74
|
+
Подробные границы слоёв: `architecture-boundaries.mdc`, `store-rtk.mdc`, `api-services.mdc`, `react-ui.mdc`.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Единый HTTP-клиент, типы ошибок и ответов
|
|
3
|
+
globs:
|
|
4
|
+
- app/src/lib/clients/HttpClient/**/*.ts
|
|
5
|
+
- app/src/api/clients/**/*.ts
|
|
6
|
+
alwaysApply: false
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# HTTP-транспорт
|
|
10
|
+
|
|
11
|
+
**Имена** фабрик, классов ошибок, типов ответа и конфига — **как в текущем коде репозитория** и в barrel `app/src/types/index.ts`. Ниже — **архитектурные правила**, а не спецификация переименований.
|
|
12
|
+
|
|
13
|
+
## Роль слоя
|
|
14
|
+
|
|
15
|
+
- Обычные REST‑вызовы к backend идут через **одну реализацию** в `app/src/lib/clients/**` (модуль общего клиента) и **преднастроенные экземпляры** в `app/src/api/clients/**`, по тому же паттерну, что уже принят в проекте.
|
|
16
|
+
- Место транспорта в общей картине **порты и адаптеры** — в `architecture-boundaries.mdc` (раздел **«Порты и адаптеры»**).
|
|
17
|
+
- **Не** вызывать `fetch` напрямую из `api/services`, store и UI (см. `architecture-boundaries.mdc`, `api-services.mdc`).
|
|
18
|
+
- **Исключения** (узкие протоколы, отдельный транспорт) — только там, где в репозитории уже есть образец; повторять его, не плодить произвольные обходы общего клиента.
|
|
19
|
+
|
|
20
|
+
## Типы
|
|
21
|
+
|
|
22
|
+
- Всё, что относится к **контракту запроса/ответа/ошибки** приложения и реэкспортируется для HTTP‑слоя, импортировать **только** из barrel `@/types`, без deep‑импортов из внутренних файлов `app/src/types/**` (см. `types-public-imports.mdc`).
|
|
23
|
+
- Не поднимать в новом коде **типы и зависимости от внешнего HTTP‑клиента**, от которого проект ушёл; ориентир — **`package.json`** и существующие вызовы.
|
|
24
|
+
|
|
25
|
+
## Контракт ошибок
|
|
26
|
+
|
|
27
|
+
- Ошибки сети и HTTP должны приходить в **едином виде**, который задаёт общий клиент (обычно класс/обёртка с полем вроде `response` для тела и статуса).
|
|
28
|
+
- В **`catch`** ориентироваться на **фактическую форму** ошибки в этом репозитории (как в соседних слайсах/сервисах): доступ к телу ошибки, статусу, диагностическому коду — **по полям текущей реализации**, без выдумывания второго формата.
|
|
29
|
+
|
|
30
|
+
## Поведение, которое остаётся в клиенте
|
|
31
|
+
|
|
32
|
+
- Общие заголовки, `credentials`, загрузка файлов (**FormData** / снятие лишних заголовков), бинарные ответы (**blob** и аналоги), единообразный разбор JSON и прочих тел.
|
|
33
|
+
- Перехват **401 / refresh**, обработка **404** и т.п. — **централизованно**, если так уже сделано в клиенте; не дублировать ту же логику в каждом сервисе.
|
|
34
|
+
|
|
35
|
+
## Связь со store
|
|
36
|
+
|
|
37
|
+
- Thunk может возвращать **тип обёртки успешного ответа**, если сервис так устроен; в **state** по возможности класть **доменные** типы после маппинга. Подробнее — `store-rtk.mdc`.
|
|
38
|
+
|
|
39
|
+
## Требование к агенту
|
|
40
|
+
|
|
41
|
+
- Меняя реализацию общего клиента — **обновить или добавить behavior‑тесты** рядом с модулем клиента (`tests-unit.mdc`).
|
|
42
|
+
- Не вводить **второй полноценный HTTP‑стек** без явной задачи и согласования с архитектурой репозитория.
|
|
@@ -27,30 +27,39 @@ alwaysApply: true
|
|
|
27
27
|
|
|
28
28
|
# Архитектурные слои
|
|
29
29
|
|
|
30
|
-
- **UI слой** (`src/ui/**`):
|
|
31
|
-
- `src/ui/pages/**` — страницы и контейнеры.
|
|
32
|
-
- `src/ui/components/**` — переиспользуемые компоненты.
|
|
33
|
-
- **Store слой** (`src/store/**`):
|
|
34
|
-
- `src/store/slices/**` — модули состояния (в этом preset — Redux Toolkit; подробности в `store-rtk.mdc`).
|
|
35
|
-
- `src/store/middleware/**` — middleware для сайд‑эффектов (например, файлы, аналитика).
|
|
36
|
-
- **API слой** (`src/api/services/**`):
|
|
30
|
+
- **UI слой** (`app/src/ui/**`):
|
|
31
|
+
- `app/src/ui/pages/**` — страницы и контейнеры.
|
|
32
|
+
- `app/src/ui/components/**` — переиспользуемые компоненты.
|
|
33
|
+
- **Store слой** (`app/src/store/**`):
|
|
34
|
+
- `app/src/store/slices/**` — модули состояния (в этом preset — Redux Toolkit; подробности в `store-rtk.mdc`).
|
|
35
|
+
- `app/src/store/middleware/**` — middleware для сайд‑эффектов (например, файлы, аналитика).
|
|
36
|
+
- **API слой** (`app/src/api/services/**`):
|
|
37
37
|
- Сервисы и мапперы, инкапсулирующие HTTP‑логику.
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
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/**`):
|
|
41
43
|
- По структуре и назначению — как принято в репозитории.
|
|
42
44
|
|
|
45
|
+
## Порты и адаптеры (сопоставление с каталогами)
|
|
46
|
+
|
|
47
|
+
Та же идея, что в `architecture-boundaries.mdc` (раздел **«Порты и адаптеры»**): UI и store зависят от **контракта** к backend (сервисы + доменные типы), а **реализация HTTP** изолирована в **`app/src/lib/clients/**`** и **`app/src/api/clients/**`**. Детали транспорта — `http-client.mdc`.
|
|
48
|
+
|
|
43
49
|
# Общие архитектурные принципы
|
|
44
50
|
|
|
45
51
|
- **Чёткое разделение слоёв**:
|
|
46
|
-
- UI знает
|
|
52
|
+
- UI знает о доменных типах (из `@/types` / `@/types/enums`) и публичных API store и при необходимости **`@/api/services`** — см. политику в `architecture-boundaries.mdc` (**«UI и обращение к `@/api/services`»**).
|
|
47
53
|
- Store знает о доменных типах и API‑сервисах.
|
|
48
|
-
- API
|
|
54
|
+
- API‑сервисы знают о DTO, мапперах и вызовах через клиенты из `app/src/api/clients/**` (`http-client.mdc`).
|
|
49
55
|
- **Никаких "проникновений" слоёв**:
|
|
50
|
-
- UI не
|
|
51
|
-
- Store не
|
|
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`.
|
|
52
60
|
- **Типы — источник правды**:
|
|
53
|
-
-
|
|
61
|
+
- При коллизии с другими правилами по **импорту типов** — ориентир **`types-public-imports.mdc`**.
|
|
62
|
+
- Новые сущности описывать в `app/src/types/**` и экспортировать через barrel; потребители не обходят `types-public-imports.mdc`.
|
|
54
63
|
- Не использовать `any`; при необходимости — `unknown` + безопасное сужение типа.
|
|
55
64
|
|
|
56
65
|
# Кодстайл и качества кода
|
|
@@ -61,17 +70,17 @@ alwaysApply: true
|
|
|
61
70
|
- Модульность и переиспользование через компоненты, хуки, слайсы, сервисы.
|
|
62
71
|
- Визуальную консистентность за счёт принятых в проекте UI‑примитивов и токенов, а не разовых литералов в стилях.
|
|
63
72
|
- При добавлении нового кода **искать и копировать существующие паттерны**:
|
|
64
|
-
- Для страниц — аналогичные файлы в `src/ui/pages/**`.
|
|
65
|
-
- Для блоков — компоненты в `src/ui/components/**`.
|
|
66
|
-
- Для API — сервисы в `src/api/services/**`.
|
|
67
|
-
- Для состояния — слайсы в `src/store/slices/**`.
|
|
73
|
+
- Для страниц — аналогичные файлы в `app/src/ui/pages/**`.
|
|
74
|
+
- Для блоков — компоненты в `app/src/ui/components/**`.
|
|
75
|
+
- Для API — сервисы в `app/src/api/services/**`.
|
|
76
|
+
- Для состояния — слайсы в `app/src/store/slices/**`.
|
|
68
77
|
|
|
69
78
|
# Работа агента
|
|
70
79
|
|
|
71
80
|
При генерации кода:
|
|
72
81
|
- Определить целевой слой (UI/store/API/типизация/тесты).
|
|
73
82
|
- Найти в соответствующей директории похожие примеры и **копировать архитектурный паттерн** (структура файлов, типы, именование).
|
|
74
|
-
- Не упрощать архитектуру в ущерб существующим слоям (не тянуть
|
|
75
|
-
|
|
76
|
-
|
|
83
|
+
- Не упрощать архитектуру в ущерб существующим слоям (не тянуть DTO и HTTP в UI; вызовы сервисов из UI — только в рамках `architecture-boundaries.mdc`).
|
|
84
|
+
- Избегать использования `any` при типизации кода; при необходимости использовать `unknown` с последующим безопасным сужением типов.
|
|
85
|
+
- После создания или редактирования файлов **обязательно** устранять проблемы линтера и типов: из каталога `app/` минимум **`yarn lint:js`** (полный прогон ESLint по проекту, как в `package.json`), при правках стилей — ещё **`yarn lint:css`**; для проверки типов — **`yarn type-check`**. Точечный ESLint только на один файл не заменяет полный прогон при завершении задачи/MR. Устранять найденное в зоне изменений, если это возможно без искажения бизнес‑логики.
|
|
77
86
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Избегать приведения типов через as на границах модулей (импорт/экспорт)
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Не использовать `as` для приведения типов при экспорте и импорте (кроме необходимых случаев)
|
|
7
|
+
|
|
8
|
+
## О чём речь
|
|
9
|
+
|
|
10
|
+
Речь о **type assertion** в TypeScript: выражение вида `значение as Тип`.
|
|
11
|
+
|
|
12
|
+
**Не относится к правилу** (это не assertion, а синтаксис модулей):
|
|
13
|
+
|
|
14
|
+
- переименование при экспорте: `export { foo as bar }`, `export { default as Baz } from '...'`;
|
|
15
|
+
- переименование при импорте: `import { foo as bar } from '...'`;
|
|
16
|
+
- `import type { Foo as Bar }` — алиас типа в импорте типов.
|
|
17
|
+
|
|
18
|
+
## Требование
|
|
19
|
+
|
|
20
|
+
- На **публичной границе модуля** (то, что **экспортируется** из файла / barrel, и то, что сразу **присваивается импортированным символам** с принудительным приведением) **не использовать** `as Тип` для «подгонки» типов, если можно обойтись нормальной типизацией.
|
|
21
|
+
|
|
22
|
+
## Предпочитать вместо `as`
|
|
23
|
+
|
|
24
|
+
- явную аннотацию: `const x: T = ...` / `function f(): T`;
|
|
25
|
+
- **дженерики** у функций и классов;
|
|
26
|
+
- **`satisfies`** (когда нужно проверить совместимость без сужения до `any`);
|
|
27
|
+
- сужение **`unknown`** после проверки (type guards, `zod` и т.п.);
|
|
28
|
+
- правку **исходных типов/DTO/мапперов**, а не assertion на выходе.
|
|
29
|
+
|
|
30
|
+
## Когда `as` допустим
|
|
31
|
+
|
|
32
|
+
- взаимодействие с **не типизированными** или некорректно типизированными внешними модулями, где нет разумной альтернативы;
|
|
33
|
+
- узкие места после **валидации** данных, если типовый гард всё ещё не выразить без шума (предпочтительно всё же guard/`satisfies`);
|
|
34
|
+
- **`as const`** — когда нужны литеральные типы и широкий вывод ломает контракт (это отдельный механизм; применять по делу, не как замену типизации API).
|
|
35
|
+
- блок **`catch (error)`** после вызова HTTP через общий клиент: по возможности сужать через **`instanceof`** на **класс ошибки транспорта** из `@/types` (какой именно — по существующей реализации) и работать с уже суженным типом; голый **`as` к тому же типу** — только если `instanceof` недоступен (иной источник выброса) и осознанно.
|
|
36
|
+
|
|
37
|
+
## Примеры
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
// ❌ Плохо: assertion на экспортируемом API
|
|
41
|
+
export const config = loadRaw() as AppConfig
|
|
42
|
+
|
|
43
|
+
// ✅ Лучше: аннотация + проверка или маппер
|
|
44
|
+
export const config: AppConfig = mapToAppConfig(loadRaw())
|
|
45
|
+
|
|
46
|
+
// ❌ Плохо: сразу после импорта «ломаем» тип
|
|
47
|
+
import { getData } from './api'
|
|
48
|
+
export const data = getData() as MyDto[]
|
|
49
|
+
|
|
50
|
+
// ✅ Лучше: типизировать getData / обернуть типобезопасной функцией
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Требование к агенту
|
|
54
|
+
|
|
55
|
+
При ревью и генерации кода **не добавлять** новые `as Тип` на экспортируемые сущности и на цепочку import → export без явной необходимости; по возможности исправлять контракт типов в источнике.
|
|
56
|
+
- В слайсах и сервисах при обработке ошибок API сначала рассматривать **`instanceof`** на класс ошибки транспорта из `@/types` по образцу существующего кода (`http-client.mdc`, `store-rtk.mdc`).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Паттерны React/Next UI и стилей (preset)
|
|
3
|
-
globs: src/ui/**/*.tsx
|
|
3
|
+
globs: app/src/ui/**/*.tsx
|
|
4
4
|
alwaysApply: false
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -42,7 +42,7 @@ alwaysApply: false
|
|
|
42
42
|
- Описывать пропсы через `type Props = { ... }` или `interface Props { ... }`.
|
|
43
43
|
- Не использовать `any`; при необходимости:
|
|
44
44
|
- обобщения (`<T>`), `unknown`, тип‑предикаты и user‑defined type guards.
|
|
45
|
-
- Для доменных сущностей использовать типы из `@/types
|
|
45
|
+
- Для доменных сущностей использовать типы из `@/types` (и enum из `@/types/enums`), а не описывать их заново (`types-public-imports.mdc`).
|
|
46
46
|
|
|
47
47
|
# Логика и side effects
|
|
48
48
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Redux Toolkit и состояние приложения
|
|
3
|
-
globs: src/store/**/*.ts
|
|
3
|
+
globs: app/src/store/**/*.ts
|
|
4
4
|
alwaysApply: false
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -16,7 +16,7 @@ alwaysApply: false
|
|
|
16
16
|
|
|
17
17
|
# Структура слайсов
|
|
18
18
|
|
|
19
|
-
- Каждый доменный модуль — свой слайс в `src/store/slices/**`.
|
|
19
|
+
- Каждый доменный модуль — свой слайс в `app/src/store/slices/**`.
|
|
20
20
|
- Слайс экспортирует:
|
|
21
21
|
- `reducer` по умолчанию;
|
|
22
22
|
- `actions` именованным экспортом;
|
|
@@ -33,14 +33,20 @@ alwaysApply: false
|
|
|
33
33
|
- вызывать API через сервисы из `@/api/services/**`;
|
|
34
34
|
- не вызывать HTTP‑клиент напрямую — только через сервисы `@/api/services/**`.
|
|
35
35
|
- Сайд‑эффекты (логирование, аналитика, работа с файлами):
|
|
36
|
-
- выносить в middleware (`src/store/middleware/**`) или специализированные слайсы.
|
|
36
|
+
- выносить в middleware (`app/src/store/middleware/**`) или специализированные слайсы.
|
|
37
37
|
|
|
38
38
|
# Типизация
|
|
39
39
|
|
|
40
40
|
- Использовать `RootState`, `AppDispatch` и типизированные хуки `useAppDispatch`, `useAppSelector` (если есть).
|
|
41
|
+
- **HTTP и ошибки API**:
|
|
42
|
+
- не импортировать типы **сторонних HTTP‑библиотек**, которых нет в актуальных зависимостях и существующих слайсах (ориентир — **`package.json`** и соседние файлы);
|
|
43
|
+
- когда сервис возвращает **обёртку ответа** прикладного клиента — использовать **соответствующий тип из `@/types`** (как в barrel и в аналогичных thunk’ах);
|
|
44
|
+
- при ошибках после вызова сервиса — опираться на **тот же класс/контракт ошибки транспорта**, что использует общий клиент (из `@/types`), и разбирать тело/статус **по полям текущей реализации**, а не по воображаемому API;
|
|
45
|
+
- в **`catch`** предпочитать **`instanceof`** на класс ошибки транспорта из `@/types` (если он есть в коде) вместо голого `as`, когда это выразимо без шума (см. `no-type-assertion-as-import-export.mdc`).
|
|
41
46
|
- Для сущностей:
|
|
42
|
-
- доменные типы (включая вычисляемые поля) определять в
|
|
47
|
+
- доменные типы (включая вычисляемые поля) определять в `app/src/types/**`, экспортировать через barrel и импортировать в слайсы из `@/types` как **источник правды** для структуры данных (`types-public-imports.mdc`);
|
|
43
48
|
- избегать дублирования описаний сущностей в нескольких местах.
|
|
49
|
+
- **Граница домена**: в **state** хранить доменные модели; тип **обёртки ответа клиента** допустим как тип **возвращаемого значения thunk** или промежуточно до маппинга — без дублирования DTO в полях state без нужды (согласовано с `api-services.mdc` и `http-client.mdc`).
|
|
44
50
|
|
|
45
51
|
# Тестирование слайсов
|
|
46
52
|
|
|
@@ -56,4 +62,5 @@ alwaysApply: false
|
|
|
56
62
|
- Не класть логику API внутрь редюсеров/компонентов.
|
|
57
63
|
- Строго типизировать state и actions.
|
|
58
64
|
- Использовать единый стиль именования actions и селекторов, как в существующих слайсах.
|
|
65
|
+
- При работе с ошибками и ответами HTTP опираться на **`http-client.mdc`** и контракты из `@/types`, а не на типы внешних HTTP‑библиотек вне зависимостей проекта.
|
|
59
66
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Роль агента для проведения технического ретроспективы (retro) команды / спринта
|
|
3
|
+
alwaysApply: false
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Техническое ретро — роль агента
|
|
7
|
+
|
|
8
|
+
Агент выступает как **нейтральный фасилитатор технической ретроспективы**, а не как ревьюер кода или оценщик людей. Цель — вынести уроки, согласовать действия и улучшить процесс разработки.
|
|
9
|
+
|
|
10
|
+
## Когда включать
|
|
11
|
+
|
|
12
|
+
- Пользователь просит: «ретро», «техническое ретро», «разбор спринта/итерации», «что пошло хорошо / плохо», «action items после релиза».
|
|
13
|
+
- Есть контекст: период (спринт, квартал), тема (релиз, инцидент, миграция), или приложены заметки/линки.
|
|
14
|
+
|
|
15
|
+
## Входные данные (запросить при нехватке)
|
|
16
|
+
|
|
17
|
+
- **Период и фокус** (например: две недели, релиз X, постмортем).
|
|
18
|
+
- **Участники/роли** (если важно для формулировок): только разработка или весь кросс‑функциональный поток.
|
|
19
|
+
- **Ограничения**: время (15 / 30 / 60 мин), формат (async в чате vs синхронная повестка).
|
|
20
|
+
- По желанию: список deliverables, метрики, ссылки на тикеты/MR — **без выдумывания** фактов, которых нет в сообщении или репозитории.
|
|
21
|
+
|
|
22
|
+
Если контекста мало — задать **1–3 коротких уточняющих вопроса**, затем продолжить с явными допущениями в шапке вывода.
|
|
23
|
+
|
|
24
|
+
## Принципы фасилитации
|
|
25
|
+
|
|
26
|
+
- **Безопасность и нейтральность**: формулировки про процесс и систему, не про «виноватых»; избегать ярлыков к людям.
|
|
27
|
+
- **Конкретика**: от абстрактного «надо лучше общаться» — к наблюдаемым событиям и договорённостям.
|
|
28
|
+
- **Баланс**: зафиксировать и позитив (что усилить), и зоны роста.
|
|
29
|
+
- **Один владелец и срок** у каждого action item; избегать списка «сделает команда» без имени/роли.
|
|
30
|
+
- **Не смешивать с code review**: ретро не заменяет построчный разбор диффа; при запросе «и ретро, и ревью» — развести два блока в ответе.
|
|
31
|
+
|
|
32
|
+
## Рекомендуемая структура сессии (по умолчанию)
|
|
33
|
+
|
|
34
|
+
Подстроить под указанное время. Для короткого async‑формата — сжать до шагов 2–4.
|
|
35
|
+
|
|
36
|
+
1. **Цель и рамки** (1–2 предложения): зачем встреча, что в фокусе / что вне скоупа.
|
|
37
|
+
2. **Сбор фактов** (молча в чате — списком от пользователя; агент структурирует):
|
|
38
|
+
- что шло хорошо,
|
|
39
|
+
- что мешало / вызывало риски,
|
|
40
|
+
- сюрпризы (технический долг, узкие места, зависимости).
|
|
41
|
+
3. **Группировка тем**: объединить дубли, выделить 3–7 тем для обсуждения (приоритет — влияние × изменяемость).
|
|
42
|
+
4. **Корневые причины (легко)**: для 1–2 самых болезненных тем — кратко «5 почему» или «что в процессе/артефактах позволило этому случиться», без морализаторства.
|
|
43
|
+
5. **Эксперименты на следующий цикл**: не больше 1–3 изменений процесса/инструментов; каждое — измеримое или с явным критерием «успех/не успех».
|
|
44
|
+
6. **Action items**: таблица или список с **что / владелец / до когда / как поймём, что сработало**.
|
|
45
|
+
|
|
46
|
+
## Формат ответа агента
|
|
47
|
+
|
|
48
|
+
- Краткая **шапка**: период, фокус, допущения (если были).
|
|
49
|
+
- **Повестка** или итог по этапам выше.
|
|
50
|
+
- **Темы** — буллеты; по спорным местам — **вопросы команде**, а не окончательные выводы без данных.
|
|
51
|
+
- **Решения и эксперименты** отдельным блоком.
|
|
52
|
+
- **Action items** — в конце, каждый пункт с владельцем и дедлайном (или пометка «нужно назначить на встрече»).
|
|
53
|
+
|
|
54
|
+
## Ограничения
|
|
55
|
+
|
|
56
|
+
- Не приписывать команде цитаты или факты, которых не было во входе.
|
|
57
|
+
- Не выдавать юридические/HR‑рекомендации; при явных конфликтах или токсичности — мягко предложить эскалацию человеку, ответственному за команду, без детализации «наказаний».
|
|
58
|
+
- Если пользователь просит только шаблон — выдать **шаблон повестки и доски** (колонки, таймбоксы) без выдуманного контента.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Unit и интеграционные тесты (Testing Library и runner проекта)
|
|
3
|
-
globs: src/**/*.test.{ts,tsx}
|
|
3
|
+
globs: app/src/**/*.{spec,test}.{ts,tsx}
|
|
4
4
|
alwaysApply: false
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -9,9 +9,19 @@ alwaysApply: false
|
|
|
9
9
|
- **Runner и матчеры** — как в проекте (часто Jest или Vitest); для компонентов — **@testing-library/react**.
|
|
10
10
|
- Основная цель тестов:
|
|
11
11
|
- проверять **поведение и бизнес‑правила**, а не реализацию или внутренние детали.
|
|
12
|
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
12
|
+
- **Именование unit‑тестов** (строки в `describe` / `it` / `test`):
|
|
13
|
+
- формулировки **только на русском языке** — понятные бизнес‑фразы (что проверяется и какой ожидается результат);
|
|
14
|
+
- **каждое предложение** в названии **начинается с заглавной буквы** (в том числе после `.`, `!`, `?` и при нескольких предложениях в одной строке); первая буква всей строки — тоже заглавная.
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
// ✅ Хорошо
|
|
18
|
+
it('Возвращает пустой список. Пользователь не авторизован', () => {})
|
|
19
|
+
it('При ошибке сети показывается сообщение об ошибке', () => {})
|
|
20
|
+
|
|
21
|
+
// ❌ Плохо (не с заглавной после точки; или не русский)
|
|
22
|
+
it('Возвращает пустой список. пользователь не авторизован', () => {})
|
|
23
|
+
it('Returns empty list when user is guest', () => {})
|
|
24
|
+
```
|
|
15
25
|
|
|
16
26
|
# Тесты компонентов
|
|
17
27
|
|
|
@@ -27,6 +37,11 @@ alwaysApply: false
|
|
|
27
37
|
- мокать store (через test‑store) или использовать принятый в проекте способ моков HTTP/API.
|
|
28
38
|
- Не мокать то, что является частью публичного контракта фичи, если это ломает смысл теста.
|
|
29
39
|
|
|
40
|
+
# HTTP‑клиент
|
|
41
|
+
|
|
42
|
+
- При изменении **реализации общего HTTP‑клиента** (разбор тел, заголовки, ветки ошибок, 401/refresh, `FormData`, `blob` и т.п.) — **обновить или добавить behavior‑тесты** рядом с модулем клиента в `app/src/lib/clients/**` (`*.spec.ts` / `*.test.ts` — как принято в репо).
|
|
43
|
+
- Проверять смысловые ветки: успешный JSON, HTTP‑ошибка, сеть, релевантные для проекта сценарии авторизации.
|
|
44
|
+
|
|
30
45
|
# Мапперы и преобразование данных
|
|
31
46
|
|
|
32
47
|
- Функции маппинга данных (DTO -> доменная модель и обратно), особенно содержащие вычисляемые поля и ветвления, должны быть покрыты unit‑тестами.
|
|
@@ -35,11 +50,11 @@ alwaysApply: false
|
|
|
35
50
|
# Требование к агенту
|
|
36
51
|
|
|
37
52
|
При добавлении тестов:
|
|
38
|
-
- Следовать существующей структуре и паттернам тестов в `src/**/__tests__/**` или рядом с компонентом.
|
|
53
|
+
- Следовать существующей структуре и паттернам тестов в `app/src/**/__tests__/**` или рядом с компонентом.
|
|
39
54
|
- Добавлять тесты для критичных веток логики и edge‑кейсов.
|
|
40
55
|
- При работе с данными:
|
|
41
|
-
- использовать **типы респонса** из API (DTO‑типы), а также **целевые доменные типы** из `@/types
|
|
42
|
-
- по возможности опираться на данные и обработчики из `src/mocks/**` (или аналог в репо), а не плодить случайные тестовые данные "с нуля".
|
|
56
|
+
- использовать **типы респонса** из API (DTO‑типы), а также **целевые доменные типы** из `@/types`, не дублировать интерфейсы в тестах;
|
|
57
|
+
- по возможности опираться на данные и обработчики из `app/src/mocks/**` (или аналог в репо), а не плодить случайные тестовые данные "с нуля".
|
|
43
58
|
- При написании unit‑тестов рядом с компонентом или модулем:
|
|
44
59
|
- **не создавать** поддиректорию `__tests__` внутри папки компонента;
|
|
45
60
|
- именовать файлы тестов с суффиксом `*.spec.ts` / `*.spec.tsx`, а не `*.test.ts` / `*.test.tsx`.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Стиль JSDoc для доменных и транспортных типов в app/src/types
|
|
3
|
+
globs: app/src/types/**/*.ts
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Документация типов в `app/src/types`
|
|
8
|
+
|
|
9
|
+
При добавлении или существенном изменении типов в этом слое **следовать уже принятому в репозитории стилю JSDoc** (см. примеры: `User.types.ts`, `Common.types.ts`, `ServerValidation.types.ts`, `TreatmentPlan/*.types.ts`).
|
|
10
|
+
|
|
11
|
+
## Язык и форма
|
|
12
|
+
|
|
13
|
+
- Текст комментариев — **на русском**, кратко и по делу: что означает тип или поле в предметной области или в контракте с API.
|
|
14
|
+
- **Не опираться** на теги в духе `@param`, `@returns`, `@see`, `@deprecated` для описания типов — в этом слое они **не используются**; достаточно обычного текста в `/** … */`.
|
|
15
|
+
|
|
16
|
+
## Экспортируемый `type` / `interface`
|
|
17
|
+
|
|
18
|
+
- Сразу **перед объявлением** — блок `/** … */`.
|
|
19
|
+
- Если нужно пояснить источник данных, ограничения или неочевидности — **второй абзац** в том же блоке (в JSDoc для абзаца — пустая строка между строками текста).
|
|
20
|
+
- Для **вложенных** объектов в том же файле каждый такой тип документируется отдельным блоком над своим объявлением.
|
|
21
|
+
|
|
22
|
+
## Поля
|
|
23
|
+
|
|
24
|
+
- У **каждого** публичного свойства — **однострочный** `/** … */` на строке непосредственно **над** полем.
|
|
25
|
+
- Если поле **не приходит с бэкенда «как есть»**, а вычисляется или дополняется на фронте (маппер, селектор, UI) — начать описание с префикса **`[computed]`** (как в `TUserProfile`, типах плана лечения).
|
|
26
|
+
- Для форматов данных указывать это **в тексте**: например дата `YYYY-MM-DD`, пример отображаемой строки в кавычках.
|
|
27
|
+
|
|
28
|
+
## Классы и прочие объявления
|
|
29
|
+
|
|
30
|
+
- Для **классов** (например ошибки транспорта) при изменении публичного API — краткий блок над классом и **комментарии к публичным полям** по тем же правилам, что у свойств интерфейса.
|
|
31
|
+
|
|
32
|
+
## `enum`
|
|
33
|
+
|
|
34
|
+
- В `enums.ts` исторически часто **без JSDoc** на каждом члене; для новых enum допустимо короткое описание **над самим enum**, если назначение неочевидно из имени. Подписи для UI — как принято, через объекты `*Names` рядом с enum.
|
|
35
|
+
|
|
36
|
+
## Практика для агента
|
|
37
|
+
|
|
38
|
+
- Добавляя новый тип или поле, **не оставлять** новые публичные поля без пояснения, если смысл не равен имени на 100%.
|
|
39
|
+
- Правя файл, где уже есть такие комментарии, **поддерживать тот же стиль**, а не смешивать с англоязычными или «теговыми» блоками.
|
|
40
|
+
- Не раздувать комментарии: одна-две фразы на тип, одна строка на поле — норма; исключение — действительно сложная доменная оговорка.
|
|
41
|
+
|
|
42
|
+
См. также импорты и barrel: `types-public-imports.mdc`.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Импорт доменных типов только через публичный API @/types
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Импорты из `@/types`
|
|
7
|
+
|
|
8
|
+
- **Публичный API типов** — barrel `app/src/types/index.ts`, импортировать типы и интерфейсы только как `@/types` (или `@/types/index` при необходимости явного пути).
|
|
9
|
+
- **Запрещено** для потребителей слоя обходить barrel: любой импорт вида `@/types/<что‑угодно>`, кроме перечисленного ниже исключения для enum.
|
|
10
|
+
- Отдельно **нельзя** импортировать из вложенных файлов `*.types.ts` по путям `@/types/**/…*.types.ts` (типичный deep‑импорт).
|
|
11
|
+
- **Исключение — enum**: перечисления можно импортировать только из `@/types/enums` / `@/types/enums.ts` (не из других файлов под `@/types`).
|
|
12
|
+
|
|
13
|
+
## Внутри слоя `app/src/types/**`
|
|
14
|
+
|
|
15
|
+
- При реализации и поддержке barrel‑файла допустимы **относительные** импорты между файлами внутри `app/src/types` (например `from './User.types'`). Это не относится к потребителям слоя.
|
|
16
|
+
|
|
17
|
+
## Примеры
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
// ✅ Допустимо — доменные и транспортные сущности с теми именами, что экспортирует barrel
|
|
21
|
+
import type { TUserProfile } from '@/types'
|
|
22
|
+
import { SomeEnum } from '@/types/enums'
|
|
23
|
+
|
|
24
|
+
// ❌ Запрещено (обход публичного API)
|
|
25
|
+
import type { TUserProfile } from '@/types/User.types'
|
|
26
|
+
import { TransportError } from '@/types/TransportError'
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
При ревью и правках кода **не добавлять** новые импорты типов из `@/types/...` кроме `@/types` и `@/types/enums`.
|