@bonesofspring/ai-rules 0.1.31 → 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/claude/next/agents/playwright-test-generator.md +3 -3
- package/presets/claude/next/agents/playwright-test-healer.md +3 -3
- package/presets/claude/next/agents/playwright-test-planner.md +2 -2
- package/presets/cursor/next/rules/README.md +20 -0
- package/presets/cursor/next/rules/api-services.mdc +14 -13
- package/presets/cursor/next/rules/architecture-boundaries.mdc +30 -12
- package/presets/cursor/next/rules/code-quality-and-refactoring.mdc +2 -2
- package/presets/cursor/next/rules/code-review-mr.mdc +19 -11
- 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 +86 -0
- package/presets/cursor/next/rules/no-type-assertion-as-import-export.mdc +56 -0
- package/presets/cursor/next/rules/playwright-agents.mdc +5 -5
- package/presets/cursor/next/rules/react-ui.mdc +14 -19
- package/presets/cursor/next/rules/store-rtk.mdc +12 -5
- package/presets/cursor/next/rules/technical-retro.mdc +58 -0
- package/presets/cursor/next/rules/tests-e2e-structure.mdc +3 -3
- package/presets/cursor/next/rules/tests-unit.mdc +26 -11
- package/presets/cursor/next/rules/types-jsdoc.mdc +42 -0
- package/presets/cursor/next/rules/types-public-imports.mdc +29 -0
- package/presets/cursor/next/rules/emedcard-core.mdc +0 -77
package/package.json
CHANGED
|
@@ -10,7 +10,7 @@ You are a Playwright Test Generator, an expert in browser automation and end-to-
|
|
|
10
10
|
Your specialty is creating robust, reliable Playwright tests that accurately simulate user interactions and validate
|
|
11
11
|
application behavior.
|
|
12
12
|
|
|
13
|
-
## Project-specific test structure (
|
|
13
|
+
## Project-specific test structure (Next.js preset)
|
|
14
14
|
|
|
15
15
|
In this project you MUST respect the existing e2e layout:
|
|
16
16
|
|
|
@@ -22,9 +22,9 @@ In this project you MUST respect the existing e2e layout:
|
|
|
22
22
|
When you generate tests:
|
|
23
23
|
|
|
24
24
|
- Use the corresponding `*.cases.md` file under `app/__tests__/e2e/**` as the source plan (for example,
|
|
25
|
-
`app/__tests__/e2e/
|
|
25
|
+
`app/__tests__/e2e/OrderHistory/order-history.cases.md`).
|
|
26
26
|
- Write or update Playwright test files only under `app/__tests__/e2e/**` (for example,
|
|
27
|
-
`app/__tests__/e2e/
|
|
27
|
+
`app/__tests__/e2e/OrderHistory/order-history.spec.ts`) instead of creating files in a separate `tests/` folder.
|
|
28
28
|
|
|
29
29
|
# For each test you generate
|
|
30
30
|
- Obtain the test plan with all the steps and verification specification
|
|
@@ -10,7 +10,7 @@ You are the Playwright Test Healer, an expert test automation engineer specializ
|
|
|
10
10
|
resolving Playwright test failures. Your mission is to systematically identify, diagnose, and fix
|
|
11
11
|
broken Playwright tests using a methodical approach.
|
|
12
12
|
|
|
13
|
-
## Project-specific test structure (
|
|
13
|
+
## Project-specific test structure (Next.js preset)
|
|
14
14
|
|
|
15
15
|
In this project you MUST respect the existing e2e layout:
|
|
16
16
|
|
|
@@ -23,8 +23,8 @@ When healing tests:
|
|
|
23
23
|
|
|
24
24
|
- Only read and modify `*.spec.ts` files under `app/__tests__/e2e/**`.
|
|
25
25
|
- Use the `*.cases.md` file in the same folder as the failing test as the source of truth for intended behavior
|
|
26
|
-
(for example, `app/__tests__/e2e/
|
|
27
|
-
`app/__tests__/e2e/
|
|
26
|
+
(for example, `app/__tests__/e2e/OrderHistory/order-history.cases.md` for
|
|
27
|
+
`app/__tests__/e2e/OrderHistory/order-history.spec.ts`).
|
|
28
28
|
|
|
29
29
|
Your workflow:
|
|
30
30
|
1. **Initial Execution**: Run all tests using `test_run` tool to identify failing tests
|
|
@@ -10,7 +10,7 @@ You are an expert web test planner with extensive experience in quality assuranc
|
|
|
10
10
|
scenario design. Your expertise includes functional testing, edge case identification, and comprehensive test coverage
|
|
11
11
|
planning.
|
|
12
12
|
|
|
13
|
-
## Project-specific test structure (
|
|
13
|
+
## Project-specific test structure (Next.js preset)
|
|
14
14
|
|
|
15
15
|
In this project you MUST respect the existing e2e layout:
|
|
16
16
|
|
|
@@ -22,7 +22,7 @@ In this project you MUST respect the existing e2e layout:
|
|
|
22
22
|
When you create or update a test plan:
|
|
23
23
|
|
|
24
24
|
- Use the appropriate `*.cases.md` file under `app/__tests__/e2e/**` (for example,
|
|
25
|
-
`app/__tests__/e2e/
|
|
25
|
+
`app/__tests__/e2e/OrderHistory/order-history.cases.md`) instead of creating files in a separate `specs/` folder.
|
|
26
26
|
- Treat these `*.cases.md` files as the canonical, human-readable test plans for the Generator and Healer agents.
|
|
27
27
|
|
|
28
28
|
You will:
|
|
@@ -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
|
-
description: Конвенции API сервисов и мапперов
|
|
3
|
-
globs: src/api/services/**/*.ts
|
|
2
|
+
description: Конвенции API сервисов и мапперов
|
|
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
|
-
- Для каждой доменной области (
|
|
21
|
-
- отдельный каталог в `src/api/services
|
|
20
|
+
- Для каждой доменной области (например, заказы, биллинг, настройки аккаунта):
|
|
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
|
|
|
@@ -42,8 +43,8 @@ alwaysApply: false
|
|
|
42
43
|
- не должен "глотать" ошибки без следа;
|
|
43
44
|
- либо бросает доменные/унифицированные ошибки;
|
|
44
45
|
- либо возвращает результат в `Result<T, E>`‑подобной форме (если такой паттерн принят в проекте).
|
|
45
|
-
- Интеграция с
|
|
46
|
-
-
|
|
46
|
+
- Интеграция с APM/трассировкой (если есть в проекте):
|
|
47
|
+
- централизованно (HTTP‑клиент, обёртки), а не в каждом методе сервиса.
|
|
47
48
|
|
|
48
49
|
# Требование к агенту
|
|
49
50
|
|
|
@@ -51,6 +52,6 @@ alwaysApply: false
|
|
|
51
52
|
- Следовать существующим сервисам и мапперам как эталону.
|
|
52
53
|
- Не смешивать слой API и UI/store:
|
|
53
54
|
- компоненты не должны зависеть от DTO;
|
|
54
|
-
- store не должен
|
|
55
|
-
- При использовании API‑сервисов в UI, store и утилитах импортировать только из public API файлов модуля (например, `@/api/services/
|
|
55
|
+
- store не должен сам собирать URL/коды эндпоинтов и не обходить сервисы; **транспортный тип ответа** и **контракт ошибки** из `@/types` (как у прикладного клиента) допустимы во thunk при разборе `catch`/payload, если так выстроен сервис (см. `store-rtk.mdc`, `http-client.mdc`).
|
|
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
|
-
- обращаться к HTTP
|
|
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
|
- Всегда использовать алиас `@/...` для импортов между слоями.
|
|
@@ -31,12 +49,12 @@ alwaysApply: true
|
|
|
31
49
|
|
|
32
50
|
# Организация фич
|
|
33
51
|
|
|
34
|
-
- Для сложных фич (например,
|
|
35
|
-
- Страница: `src/ui/pages/
|
|
52
|
+
- Для сложных фич (например, `OrderCheckout`):
|
|
53
|
+
- Страница: `app/src/ui/pages/OrderCheckoutPage/**`.
|
|
36
54
|
- Локальные компоненты: поддиректории `components/**` внутри страницы.
|
|
37
|
-
- Связанный store: `src/store/slices/
|
|
38
|
-
- API: `src/api/services/
|
|
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
|
|
|
@@ -10,7 +10,7 @@ alwaysApply: true
|
|
|
10
10
|
- минимизировать "стилистический шум" (лишние правки форматирования, rename без нужды).
|
|
11
11
|
- Перед добавлением нового решения:
|
|
12
12
|
- искать аналогичное в коде и **повторять подход**, а не изобретать новый.
|
|
13
|
-
- проверять, нет ли уже подходящего компонента или паттерна в
|
|
13
|
+
- проверять, нет ли уже подходящего компонента или паттерна в существующем UI‑коде и пакетах проекта, прежде чем добавлять новый кастомный контрол.
|
|
14
14
|
- использовать при обращении к чужим модулям только их **public API** (index/barrel‑файлы и явно экспортируемые сущности), а deep‑импорты внутренних файлов рассматривать как повод для рефакторинга.
|
|
15
15
|
|
|
16
16
|
# Рефакторинг при изменениях
|
|
@@ -23,7 +23,7 @@ alwaysApply: true
|
|
|
23
23
|
- вынести дублирующуюся логику в общий хук/утилиту;
|
|
24
24
|
- типизировать `any` и `unknown`, если это безболезненно;
|
|
25
25
|
- разделить слишком крупный компонент на несколько более простых;
|
|
26
|
-
- заменить локальные «магические» CSS‑значения (цвета, отступы, размеры) на
|
|
26
|
+
- заменить локальные «магические» CSS‑значения (цвета, отступы, размеры) на токены/примитивы дизайна проекта;
|
|
27
27
|
- заменить deep‑импорты внутренних файлов других модулей на обращения к их public API.
|
|
28
28
|
|
|
29
29
|
# Ограничения
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Требования к code review агентами Cursor для
|
|
2
|
+
description: Требования к code review агентами Cursor для merge requests
|
|
3
3
|
alwaysApply: true
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -7,30 +7,38 @@ alwaysApply: true
|
|
|
7
7
|
|
|
8
8
|
- **Когда применять**
|
|
9
9
|
- Если пользователь просит: "проведи ревью", "оценить MR/ветку/дифф", "посмотри изменения".
|
|
10
|
-
- Опираться на локальный репозиторий: текущую ветку, `git diff` и открытые файлы, а не на данные
|
|
10
|
+
- Опираться на локальный репозиторий: текущую ветку, `git diff` и открытые файлы, а не на данные внешнего API хостинга.
|
|
11
11
|
|
|
12
12
|
- **Что обязан проверить агент**
|
|
13
13
|
- **Архитектура и слои**:
|
|
14
|
-
- Соблюдение правил из `architecture-boundaries.mdc` и `
|
|
15
|
-
- UI (`src/ui/**`) не ходит напрямую в HTTP
|
|
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
|
-
- **UI
|
|
26
|
-
- Для компонентов и стилей сверяться с `react-ui.mdc` и `
|
|
27
|
-
-
|
|
25
|
+
- **UI и стили**:
|
|
26
|
+
- Для компонентов и стилей сверяться с `react-ui.mdc` и `next-app-core.mdc`:
|
|
27
|
+
- Соблюдать принятый в проекте способ стилей и общие UI‑примитивы/токены, а не "магические" значения.
|
|
28
28
|
- Сохранять консистентность с существующими компонентами и паттернами.
|
|
29
29
|
- **Тесты**:
|
|
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** (дифф относительно целевой ветки), а не на всём проекте.
|
|
@@ -41,7 +49,7 @@ alwaysApply: true
|
|
|
41
49
|
- без "больших рефакторингов" в духе `code-quality-and-refactoring.mdc`, если задача локальная.
|
|
42
50
|
|
|
43
51
|
- **Ограничения для агента**
|
|
44
|
-
- Не придумывать несуществующие
|
|
52
|
+
- Не придумывать несуществующие метаданные из хостинга (лейблы MR, авторов, статусы CI), если их нет в локальных данных.
|
|
45
53
|
- Не менять общую архитектуру фичи без прямого запроса пользователя.
|
|
46
54
|
- Следовать принципу "boy scout rule": предлагать улучшения, которые реально можно внести в рамках MR.
|
|
47
55
|
|
|
@@ -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‑стек** без явной задачи и согласования с архитектурой репозитория.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Базовые принципы, стек и архитектура Next.js приложения (preset)
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Стек и окружение
|
|
7
|
+
|
|
8
|
+
Конкретные версии пакетов и инструментов — **из `package.json` и конфигов целевого репозитория**. Ниже — рамка preset (Next.js + React + TypeScript), без привязки к конкретному вендору UI, моков или APM:
|
|
9
|
+
|
|
10
|
+
- **Фреймворк:** Next.js, React, TypeScript (strict — если включён в проекте).
|
|
11
|
+
- **Сборка и Node:** как задано в репозитории.
|
|
12
|
+
- **Тесты:** unit/integration — runner и библиотеки проекта; e2e — инструмент проекта (правила для агентов Playwright — в отдельных файлах preset).
|
|
13
|
+
- **Моки HTTP/API:** если приняты в репо — повторять существующую схему (каталоги, регистрация, точка входа).
|
|
14
|
+
- **Стили и UI:** способ стилизации и **дизайн‑система / токены** — как уже заведено в коде; приоритет общим примитивам и токенам вместо разрозненных «магических» значений.
|
|
15
|
+
- **Наблюдаемость:** только если уже подключена в проекте — централизованно (клиент, обёртки), без дублирования в каждом методе.
|
|
16
|
+
|
|
17
|
+
# Структура проекта (верхний уровень)
|
|
18
|
+
|
|
19
|
+
- `app/` — корень Next.js приложения.
|
|
20
|
+
- `app/src/**` — исходный код приложения.
|
|
21
|
+
- `app/__tests__/e2e/**` — e2e‑тесты и планы.
|
|
22
|
+
- `app/tsconfig.json`:
|
|
23
|
+
- `baseUrl: "."`
|
|
24
|
+
- `paths: { "@/*": ["./src/*"] }`
|
|
25
|
+
|
|
26
|
+
**Требование:** во всех новых изменениях использовать алиас `@/*` вместо относительных импортов выше по дереву.
|
|
27
|
+
|
|
28
|
+
# Архитектурные слои
|
|
29
|
+
|
|
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
|
+
- Сервисы и мапперы, инкапсулирующие HTTP‑логику.
|
|
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 (сервисы + доменные типы), а **реализация HTTP** изолирована в **`app/src/lib/clients/**`** и **`app/src/api/clients/**`**. Детали транспорта — `http-client.mdc`.
|
|
48
|
+
|
|
49
|
+
# Общие архитектурные принципы
|
|
50
|
+
|
|
51
|
+
- **Чёткое разделение слоёв**:
|
|
52
|
+
- UI знает о доменных типах (из `@/types` / `@/types/enums`) и публичных API store и при необходимости **`@/api/services`** — см. политику в `architecture-boundaries.mdc` (**«UI и обращение к `@/api/services`»**).
|
|
53
|
+
- Store знает о доменных типах и 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/**`.
|
|
77
|
+
|
|
78
|
+
# Работа агента
|
|
79
|
+
|
|
80
|
+
При генерации кода:
|
|
81
|
+
- Определить целевой слой (UI/store/API/типизация/тесты).
|
|
82
|
+
- Найти в соответствующей директории похожие примеры и **копировать архитектурный паттерн** (структура файлов, типы, именование).
|
|
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. Устранять найденное в зоне изменений, если это возможно без искажения бизнес‑логики.
|
|
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`).
|
|
@@ -21,8 +21,8 @@ When acting as a **Planner** (or working with the Playwright planner agent):
|
|
|
21
21
|
- **Treat `*.cases.md` as the canonical test plan files**, equivalent to Playwright's `specs/*.md`.
|
|
22
22
|
- **Location**:
|
|
23
23
|
- For a feature/domain, use the corresponding `*.cases.md` file under `app/__tests__/e2e`, e.g.:
|
|
24
|
-
- `app/__tests__/e2e/
|
|
25
|
-
- `app/__tests__/e2e/
|
|
24
|
+
- `app/__tests__/e2e/OrderHistory/order-history.cases.md`
|
|
25
|
+
- `app/__tests__/e2e/BillingReport/invoice-list.cases.md`
|
|
26
26
|
- **Content requirements**:
|
|
27
27
|
- Group scenarios by feature and subfeature using headings.
|
|
28
28
|
- For each scenario include:
|
|
@@ -44,13 +44,13 @@ When acting as a **Generator** (or working with the Playwright generator agent):
|
|
|
44
44
|
- Use the relevant `*.cases.md` file under `app/__tests__/e2e/**` as the test plan.
|
|
45
45
|
- **Target for tests**:
|
|
46
46
|
- Generate or update `*.spec.ts` files under the same folder, e.g.:
|
|
47
|
-
- plan: `app/__tests__/e2e/
|
|
48
|
-
- tests: `app/__tests__/e2e/
|
|
47
|
+
- plan: `app/__tests__/e2e/OrderHistory/order-history.cases.md`
|
|
48
|
+
- tests: `app/__tests__/e2e/OrderHistory/order-history.spec.ts` (or additional `*.spec.ts` in that folder if needed).
|
|
49
49
|
- **Structure**:
|
|
50
50
|
- Use `test.describe` to group by top-level plan sections (feature / user flow).
|
|
51
51
|
- Use `test(...)` titles that match scenario names from the plan.
|
|
52
52
|
- Prefer Page Object and fluent interfaces that already exist in this project, for example:
|
|
53
|
-
- `app/__tests__/e2e/
|
|
53
|
+
- `app/__tests__/e2e/OrderHistory/OrderHistoryPage.ts`
|
|
54
54
|
- shared helpers under `app/__tests__/e2e/_shared/`.
|
|
55
55
|
- **Seed**:
|
|
56
56
|
- If a seed test is needed, use `app/__tests__/e2e/seed.spec.ts` as the reference for environment setup.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Паттерны React/Next UI и
|
|
3
|
-
globs: src/ui/**/*.tsx
|
|
2
|
+
description: Паттерны React/Next UI и стилей (preset)
|
|
3
|
+
globs: app/src/ui/**/*.tsx
|
|
4
4
|
alwaysApply: false
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -10,8 +10,8 @@ alwaysApply: false
|
|
|
10
10
|
- Компонент должен:
|
|
11
11
|
- быть максимально "тонким" по бизнес‑логике;
|
|
12
12
|
- делегировать состояние в store/хуки, если оно нужно в нескольких местах;
|
|
13
|
-
-
|
|
14
|
-
- Перед
|
|
13
|
+
- опираться на **общие UI‑примитивы дизайна проекта** (пакеты или локальная библиотека компонентов), если они есть.
|
|
14
|
+
- Перед новым кастомным контролом — поискать готовый или близкий компонент в репозитории / пакетах UI проекта и переиспользовать или расширить его.
|
|
15
15
|
- Для повторяемой логики создавать `useSomething`‑хуки рядом или в `src/ui/hooks/**`.
|
|
16
16
|
- При обращении к store, API, общим хелперам и утилитам компоненты и хуки должны использовать только их **public API** (например, `@/store`, `@/store/slices/Foo`, `@/lib/utils`), а не импортировать внутренние файлы реализации других модулей.
|
|
17
17
|
|
|
@@ -19,35 +19,30 @@ alwaysApply: false
|
|
|
19
19
|
|
|
20
20
|
Для страницы/крупного блока:
|
|
21
21
|
- `FeatureBlock.tsx` — JSX и композиция.
|
|
22
|
-
- `styles.ts` —
|
|
22
|
+
- `styles.ts` или соседний модуль стилей — по конвенции репозитория (CSS Modules, CSS-in-JS, и т.д.).
|
|
23
23
|
- `index.ts` — реэкспорт (если нужно наружу).
|
|
24
24
|
|
|
25
25
|
Для переиспользуемого компонента:
|
|
26
26
|
- Папка с именем компонента:
|
|
27
27
|
- `ComponentName.tsx`
|
|
28
|
-
-
|
|
28
|
+
- файлы стилей по принятой схеме;
|
|
29
29
|
- опционально: `types.ts`, `hooks.ts`.
|
|
30
30
|
|
|
31
|
-
#
|
|
31
|
+
# Стили и дизайн‑токены
|
|
32
32
|
|
|
33
|
-
- Для
|
|
34
|
-
- кнопки, чекбоксы, поля ввода и т.д.
|
|
35
|
-
- Стили:
|
|
36
|
-
- Использовать Linaria (`@linaria/react`, `@linaria/core`) со статическими стилями.
|
|
37
|
-
- Стили располагать в `styles.ts` рядом с компонентом.
|
|
38
|
-
- Применять дизайн‑токены из `@sds/tokens-*`, `@sds/brand-colors` и `@sds/tokens-typography` для цветов, типографики, отступов, размеров, радиусов, теней и т.д., а не “магические” значения.
|
|
33
|
+
- Для визуала использовать **тот стек стилей и токенов, который уже в проекте** (переменные, тема, общие классы, дизайн‑пакет).
|
|
39
34
|
- Избегать:
|
|
40
|
-
- inline‑стилей, кроме
|
|
41
|
-
- дублирования
|
|
42
|
-
-
|
|
43
|
-
|
|
35
|
+
- inline‑стилей, кроме простых случаев;
|
|
36
|
+
- дублирования оформления, уже закрытого общими примитивами;
|
|
37
|
+
- «магических» литералов (`#xxxxxx`, произвольные `17px` / `23px`), если в проекте есть токены или масштаб.
|
|
38
|
+
- Если подходящего токена нет — локальный примитив **в одном месте** с последующим выравниванием под систему дизайна при возможности.
|
|
44
39
|
|
|
45
40
|
# Пропсы и типизация
|
|
46
41
|
|
|
47
42
|
- Описывать пропсы через `type Props = { ... }` или `interface Props { ... }`.
|
|
48
43
|
- Не использовать `any`; при необходимости:
|
|
49
44
|
- обобщения (`<T>`), `unknown`, тип‑предикаты и user‑defined type guards.
|
|
50
|
-
- Для доменных сущностей использовать типы из `@/types
|
|
45
|
+
- Для доменных сущностей использовать типы из `@/types` (и enum из `@/types/enums`), а не описывать их заново (`types-public-imports.mdc`).
|
|
51
46
|
|
|
52
47
|
# Логика и side effects
|
|
53
48
|
|
|
@@ -61,7 +56,7 @@ alwaysApply: false
|
|
|
61
56
|
# Тестирование UI
|
|
62
57
|
|
|
63
58
|
- Для нетривиальных компонентов добавлять тесты:
|
|
64
|
-
-
|
|
59
|
+
- **Testing Library** для React, как принято в проекте;
|
|
65
60
|
- проверять поведение и бизнес‑правила, а не конкретные CSS‑классы.
|
|
66
61
|
- В тестах ориентироваться на текст, роли и aria‑атрибуты.
|
|
67
62
|
|
|
@@ -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` именованным экспортом;
|
|
@@ -31,16 +31,22 @@ alwaysApply: false
|
|
|
31
31
|
- через `createAsyncThunk` или RTK Query.
|
|
32
32
|
- внутри thunk:
|
|
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
|
+
- Если пользователь просит только шаблон — выдать **шаблон повестки и доски** (колонки, таймбоксы) без выдуманного контента.
|
|
@@ -19,7 +19,7 @@ alwaysApply: false
|
|
|
19
19
|
- Каждый сценарий из `*.cases.md` должен иметь соответствующий тест (или набор тестов).
|
|
20
20
|
- **Нельзя** ослаблять проверки в тестах, если это противоречит бизнес‑ожиданиям из планов.
|
|
21
21
|
- Предпочтительно использовать:
|
|
22
|
-
- page‑objects (например, `
|
|
22
|
+
- page‑objects (например, `OrderHistoryPage.ts`);
|
|
23
23
|
- общие хелперы из `_shared`.
|
|
24
24
|
|
|
25
25
|
# Именование e2e‑тестов
|
|
@@ -29,10 +29,10 @@ alwaysApply: false
|
|
|
29
29
|
- Формат заголовков e2e‑тестов (`test(...)` / `it(...)`):
|
|
30
30
|
- перед текстовым описанием сценария указывается **префикс с номером** в формате: `ПРЕФИКС-XXX Описание сценария`.
|
|
31
31
|
- `ПРЕФИКС` — аббревиатура из **первых букв слов** тестируемой сущности, записанная **латиницей в верхнем регистре**.
|
|
32
|
-
- пример: `
|
|
32
|
+
- пример: `OrderHistory` → `OH`, `BillingReport` → `BR`.
|
|
33
33
|
- `XXX` — порядковый номер теста **с тремя разрядами и лидирующими нулями**: `001`, `002`, `010`, `123` и т.д.
|
|
34
34
|
- пример полного названия e2e‑теста:
|
|
35
|
-
- `test('
|
|
35
|
+
- `test('OH-001 Отображается список заказов', async ({ page }) => { ... })`
|
|
36
36
|
- внутри одной сущности (`ПРЕФИКС`) номера тестов должны образовывать **непротиворечивую последовательность**, без дубликатов номеров.
|
|
37
37
|
|
|
38
38
|
# data-testid для e2e
|
|
@@ -1,32 +1,47 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Unit и интеграционные тесты (
|
|
3
|
-
globs: src/**/*.test.{ts,tsx}
|
|
2
|
+
description: Unit и интеграционные тесты (Testing Library и runner проекта)
|
|
3
|
+
globs: app/src/**/*.{spec,test}.{ts,tsx}
|
|
4
4
|
alwaysApply: false
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Общие правила тестирования
|
|
8
8
|
|
|
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
|
|
|
18
28
|
- Использовать `render` из `@testing-library/react`.
|
|
19
29
|
- Ассерты:
|
|
20
|
-
-
|
|
30
|
+
- матчеры DOM для Testing Library, как подключены в проекте (`toBeInTheDocument`, `toHaveTextContent` и т.п.).
|
|
21
31
|
- Взаимодействия:
|
|
22
32
|
- `userEvent` из `@testing-library/user-event`.
|
|
23
33
|
|
|
24
34
|
# Изоляция и моки
|
|
25
35
|
|
|
26
36
|
- Для работы с API/store:
|
|
27
|
-
- мокать store (через test‑store) или использовать
|
|
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
|
-
- по возможности опираться на данные и
|
|
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`.
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Базовые принципы, стек и архитектура emedcard-web
|
|
3
|
-
alwaysApply: true
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Стек и окружение
|
|
7
|
-
|
|
8
|
-
- Проект: **Next.js 16**, **React 19**, **TypeScript 5 (strict)**.
|
|
9
|
-
- Сборка: Webpack/Rspack, Node >= 24.
|
|
10
|
-
- Тесты: Jest + Testing Library, e2e — Playwright.
|
|
11
|
-
- Моки: **MSW** (`msw`, `public/mockServiceWorker.js`).
|
|
12
|
-
- Стили и UI:
|
|
13
|
-
- CSS-in-JS: **Linaria** (`@linaria/core`, `@linaria/react`).
|
|
14
|
-
- Дизайн‑система: **SDS** (`@sds/*`) и набор дизайн‑токенов (`@sds/tokens-*`, `@sds/brand-colors`, `@sds/tokens-typography`).
|
|
15
|
-
- Трассировка и мониторинг: Sentry, OpenTelemetry.
|
|
16
|
-
|
|
17
|
-
# Структура проекта (верхний уровень)
|
|
18
|
-
|
|
19
|
-
- `app/` — корень Next.js приложения.
|
|
20
|
-
- `app/src/**` — исходный код приложения.
|
|
21
|
-
- `app/__tests__/e2e/**` — e2e‑тесты и планы.
|
|
22
|
-
- `app/tsconfig.json`:
|
|
23
|
-
- `baseUrl: "."`
|
|
24
|
-
- `paths: { "@/*": ["./src/*"] }`
|
|
25
|
-
|
|
26
|
-
**Требование:** во всех новых изменениях использовать алиас `@/*` вместо относительных импортов выше по дереву.
|
|
27
|
-
|
|
28
|
-
# Архитектурные слои
|
|
29
|
-
|
|
30
|
-
- **UI слой** (`src/ui/**`):
|
|
31
|
-
- `src/ui/pages/**` — страницы и контейнеры.
|
|
32
|
-
- `src/ui/components/**` — переиспользуемые компоненты.
|
|
33
|
-
- **Store слой** (`src/store/**`):
|
|
34
|
-
- `src/store/slices/**` — Redux Toolkit слайсы.
|
|
35
|
-
- `src/store/middleware/**` — middleware для сайд‑эффектов (например, файлы, аналитика).
|
|
36
|
-
- **API слой** (`src/api/services/**`):
|
|
37
|
-
- Сервисы и мапперы, инкапсулирующие HTTP‑логику.
|
|
38
|
-
- **Типы** (`src/types/**`):
|
|
39
|
-
- Общие доменные типы (OfflineConsultation, Medcard, Conclusion и т.д.).
|
|
40
|
-
- **Моки и тестовые данные** (`src/mocks/**`):
|
|
41
|
-
- Моковые данные и обработчики для MSW.
|
|
42
|
-
|
|
43
|
-
# Общие архитектурные принципы
|
|
44
|
-
|
|
45
|
-
- **Чёткое разделение слоёв**:
|
|
46
|
-
- UI знает только о доменных типах и публичных интерфейсах store/API.
|
|
47
|
-
- Store знает о доменных типах и API‑сервисах.
|
|
48
|
-
- API знает о транспортном слое (HTTP, axios и пр.) и DTO.
|
|
49
|
-
- **Никаких "проникновений" слоёв**:
|
|
50
|
-
- UI не обращается к API напрямую — только через store или абстракции сервисов.
|
|
51
|
-
- Store не работает напрямую с "сырыми" HTTP‑ответами — только через мапперы.
|
|
52
|
-
- **Типы — источник правды**:
|
|
53
|
-
- Новые сущности описывать в `src/types/**`, переиспользовать, а не дублировать типы по слоям.
|
|
54
|
-
- Не использовать `any`; при необходимости — `unknown` + безопасное сужение типа.
|
|
55
|
-
|
|
56
|
-
# Кодстайл и качества кода
|
|
57
|
-
|
|
58
|
-
- Следовать конфигам `eslint.config.mjs`, `.prettierrc`, `.stylelintrc`.
|
|
59
|
-
- Поддерживать:
|
|
60
|
-
- KISS, DRY, SOLID (в разумных пределах для фронта).
|
|
61
|
-
- Модульность и переиспользование через компоненты, хуки, слайсы, сервисы.
|
|
62
|
-
- Консистентный визуальный стиль за счёт использования готовых компонентов `@sds/*` и дизайн‑токенов @sds вместо локальных "магических" значений.
|
|
63
|
-
- При добавлении нового кода **искать и копировать существующие паттерны**:
|
|
64
|
-
- Для страниц — аналогичные файлы в `src/ui/pages/**`.
|
|
65
|
-
- Для блоков — компоненты в `src/ui/components/**`.
|
|
66
|
-
- Для API — сервисы в `src/api/services/**`.
|
|
67
|
-
- Для состояния — слайсы в `src/store/slices/**`.
|
|
68
|
-
|
|
69
|
-
# Работа агента
|
|
70
|
-
|
|
71
|
-
При генерации кода:
|
|
72
|
-
- Определить целевой слой (UI/store/API/типизация/тесты).
|
|
73
|
-
- Найти в соответствующей директории похожие примеры и **копировать архитектурный паттерн** (структура файлов, типы, именование).
|
|
74
|
-
- Не упрощать архитектуру в ущерб существующим слоям (не тянуть API в UI, не описывать "DTO" прямо в компонентах).
|
|
75
|
-
- Избегать использования `any` при типизации кода; при необходимости использовать `unknown` с последующим безопасным сужением типов.
|
|
76
|
-
- После создания или редактирования любых файлов **обязательно проверять проект на ошибки TypeScript и ESLint** (либо точечно по изменённым файлам, либо по всему проекту) и устранять найденные проблемы, если это возможно без изменения бизнес‑логики.
|
|
77
|
-
|