Skip to content

Commit f186bd2

Browse files
committed
refactor: улучшение качества кода, архитектуры и надежности CLI утилиты
Реализованы улучшения качества кода и архитектуры: - добавлена система логирования с уровнями (DEBUG, INFO, WARN, ERROR, SILENT) - создана иерархия кастомных ошибок (CLIError, ValidationError, FileNotFoundError и др.) - реализована расширенная валидация входных данных с детальными сообщениями - улучшена типобезопасность (заменен any на JSONSchema типы) - добавлено кеширование для оптимизации производительности - заменены синхронные файловые операции на асинхронные - исправлены проблемы безопасности (command injection в execSync) - добавлены JSDoc комментарии на русском языке для всех публичных функций - вынесены конфигурационные значения в константы - улучшен CLI интерфейс (версия, verbose режим, короткие опции, примеры) - добавлена детальная обработка ошибок с трассировкой Обновлена документация: - расширено описание особенностей NSC-CLI - добавлены примеры использования новых опций - описана система логирования - обновлены таблицы опций с короткими вариантами
1 parent 95a8a35 commit f186bd2

19 files changed

Lines changed: 741 additions & 411 deletions

.cursor/rules/semantic-release.mdc

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
---
2+
description: Правила для коммитов в стиле Semantic Release (Conventional Commits)
3+
globs: []
4+
alwaysApply: true
5+
---
6+
7+
# Правила коммитов в стиле Semantic Release
8+
9+
## Формат коммитов (Conventional Commits)
10+
11+
Все коммиты должны следовать формату Conventional Commits для совместимости с Semantic Release:
12+
13+
```
14+
<type>(<scope>): <subject>
15+
16+
<body>
17+
18+
<footer>
19+
```
20+
21+
## Типы коммитов
22+
23+
Используй следующие типы коммитов:
24+
25+
- **feat**: Новая функциональность (увеличивает MINOR версию)
26+
- **fix**: Исправление бага (увеличивает PATCH версию)
27+
- **docs**: Изменения в документации
28+
- **style**: Изменения форматирования кода (не влияют на выполнение кода)
29+
- **refactor**: Рефакторинг кода (не добавляет функциональность и не исправляет баги)
30+
- **perf**: Улучшения производительности
31+
- **test**: Добавление или изменение тестов
32+
- **build**: Изменения в системе сборки или внешних зависимостях
33+
- **ci**: Изменения в CI/CD конфигурации
34+
- **chore**: Прочие изменения (не влияют на код пользователя)
35+
- **revert**: Откат предыдущего коммита
36+
37+
## Область (scope)
38+
39+
Область указывает на часть кодовой базы, которую затрагивает коммит:
40+
- Название сервиса (например: `user`, `notifier`, `gate`)
41+
- Название модуля или компонента
42+
- Может быть опущена, если изменения затрагивают весь проект
43+
44+
## Описание (subject)
45+
46+
- Начинается с маленькой буквы
47+
- Не заканчивается точкой
48+
- Используй повелительное наклонение ("добавить", "исправить", "обновить")
49+
- Максимальная длина: 72 символа
50+
- Описывает ЧТО изменено, а не ЗАЧЕМ
51+
52+
## Тело коммита (body)
53+
54+
- Опционально, но рекомендуется для коммитов с типом `feat` или `fix`
55+
- Отделяется от subject пустой строкой
56+
- Объясняет ЗАЧЕМ и КАК были внесены изменения
57+
- Может содержать ссылки на issues/PRs
58+
59+
## Футер (footer)
60+
61+
- Опционально
62+
- Используется для breaking changes: `BREAKING CHANGE: <описание>`
63+
- Может содержать ссылки на issues: `Closes #123`, `Fixes #456`
64+
65+
## Breaking Changes
66+
67+
Для breaking changes используй один из форматов:
68+
69+
1. Добавь `!` после типа и scope: `feat(api)!: изменить формат ответа`
70+
2. Добавь в футер: `BREAKING CHANGE: изменить формат ответа API`
71+
72+
## Примеры правильных коммитов
73+
74+
```
75+
feat(user): добавить аутентификацию через JWT
76+
77+
Реализована система аутентификации пользователей с использованием JWT токенов.
78+
Добавлены эндпоинты для логина и обновления токенов.
79+
80+
Closes #123
81+
```
82+
83+
```
84+
fix(gate): исправить обработку ошибок при валидации запросов
85+
86+
Исправлена проблема, когда некорректные запросы вызывали падение сервиса.
87+
Теперь все ошибки валидации возвращаются с корректным HTTP статусом 400.
88+
```
89+
90+
```
91+
docs: обновить документацию по архитектуре
92+
93+
Добавлены диаграммы взаимодействия сервисов и описание API gateway.
94+
```
95+
96+
```
97+
refactor(notifier): оптимизировать отправку уведомлений
98+
99+
Вынес логику отправки в отдельный класс для улучшения тестируемости.
100+
```
101+
102+
```
103+
feat(api)!: изменить формат ответа на JSON API
104+
105+
BREAKING CHANGE: Все эндпоинты теперь возвращают данные в формате JSON API.
106+
Необходимо обновить клиентские приложения.
107+
```
108+
109+
```
110+
chore: обновить зависимости
111+
112+
Обновлены пакеты в package.json для устранения уязвимостей безопасности.
113+
```
114+
115+
## Правила для Cursor
116+
117+
1. **Всегда используй формат Conventional Commits** при создании коммитов
118+
2. **Выбирай правильный тип** в зависимости от характера изменений
119+
3. **Указывай scope**, если изменения затрагивают конкретный сервис или модуль
120+
4. **Пиши понятные описания** на русском языке
121+
5. **Добавляй body** для коммитов типа `feat` и `fix`, если изменения нетривиальные
122+
6. **Используй breaking change notation**, если изменения ломают обратную совместимость
123+
7. **Ссылайся на issues/PRs** в футере, если они связаны с коммитом
124+
125+
## GitLab доска и лейблы
126+
127+
GitLab доска использует лейблы для отображения движения задач по статусам и категориям.
128+
129+
**Важно:**
130+
- **Всегда используй лейблы из `.gitlab/labels.yml`** при создании или обновлении issues/merge requests
131+
- Не создавай новые лейблы без необходимости — сначала проверь существующие в `.gitlab/labels.yml`
132+
- Лейблы используются для фильтрации и организации задач на доске проекта
133+
134+
**Категории лейблов:**
135+
- `component::*` — компоненты платформы
136+
- `track::*` — направления разработки
137+
- `type::*` — типы задач (feature, bug, refactor и т.д.)
138+
- `priority::*` — приоритеты задач
139+
- `status::*` — статусы задач (backlog, in-progress, code-review и т.д.)
140+
141+
## Исключения
142+
143+
- Коммиты типа `chore`, `docs`, `style` обычно не требуют body
144+
- Для мелких исправлений достаточно короткого subject без body
145+
- Breaking changes всегда должны быть явно обозначены
146+
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
---
2+
description: "TypeScript стиль кода: настройки, именование, форматирование, импорты"
3+
globs: ["**/*.ts", "**/*.tsx"]
4+
alwaysApply: false
5+
---
6+
7+
# TypeScript и стиль кода
8+
9+
## Настройки TypeScript
10+
11+
- Строгий режим: `strict: true`, `noImplicitAny: true`, `strictNullChecks: true`
12+
- Экспериментальные декораторы: `experimentalDecorators: true`, `emitDecoratorMetadata: true`
13+
- Требуется `reflect-metadata` для работы декораторов
14+
- Всегда используйте типы, избегайте `any` (допускается только с предупреждением)
15+
- Используйте `unknown` для неизвестных типов вместо `any`
16+
17+
## Именование
18+
19+
- Классы: `PascalCase` (например: `UsersRepository`, `OrderCreate`)
20+
- Методы и функции: `camelCase` (например: `getUserById`, `createOrder`)
21+
- Константы: `UPPER_SNAKE_CASE` (например: `MAX_FILE_SIZE`)
22+
- Приватные поля: начинаются с `_` (например: `_id`, `_client`)
23+
- Файлы: `PascalCase` для классов, `camelCase` для утилит
24+
- Интерфейсы: `PascalCase`, часто с префиксом `I` или без него (следуйте конвенциям проекта)
25+
26+
## Форматирование (Prettier)
27+
28+
- Табы: 2 пробела
29+
- Кавычки: одинарные
30+
- Точка с запятой: обязательна
31+
- Trailing comma: `all`
32+
- Print width: 120 символов
33+
- Arrow parens: `avoid` (когда возможно)
34+
- Используйте `prettier-plugin-organize-imports` для автоматической организации импортов
35+
36+
## Импорты
37+
38+
### ESM модули
39+
40+
Все сервисы используют ESM (ES Modules) с `"type": "module"` в `package.json`.
41+
42+
**Важно:**
43+
44+
- Для локальных импортов **всегда используй расширение `.js`**, даже если файл имеет расширение `.ts`
45+
- Это требование ESM в TypeScript: компилятор не меняет пути импортов, а в runtime файлы будут `.js`
46+
- TypeScript автоматически разрешит `.js` импорты к соответствующим `.ts` файлам
47+
48+
### Порядок импортов
49+
50+
1. Внешние библиотеки (npm пакеты из `node_modules`)
51+
2. Workspace пакеты (например: `'shared'`, `'namespace'`)
52+
3. Локальные импорты (из текущего сервиса/пакета)
53+
54+
Между группами импортов должна быть пустая строка.
55+
56+
### Workspace импорты
57+
58+
Используй прямые импорты по имени пакета из workspace (без относительных путей):
59+
60+
```typescript
61+
// ✅ Правильно - workspace импорт
62+
import { validateConfigs, logger, Logger, LogsOutputFormatter } from 'shared';
63+
import { codes } from 'shared';
64+
import { ApplicationConfig } from 'shared';
65+
66+
// ❌ Неправильно - относительный путь к workspace пакету
67+
import { logger } from '../../shared';
68+
```
69+
70+
Workspace пакеты настраиваются через npm workspaces в корневом `package.json`.
71+
72+
### Локальные импорты
73+
74+
Для локальных импортов **всегда указывай расширение `.js`**:
75+
76+
```typescript
77+
// ✅ Правильно - с расширением .js
78+
import { TYPES } from './inversion.types.js';
79+
import { configs, ISMTPConfig } from './configs/index.js';
80+
import { MailSender } from './MailSender/index.js';
81+
import type { MailSenderPort } from './domain/ports/index.js';
82+
import { Empty } from './methods/Empty/index.js';
83+
84+
// ❌ Неправильно - без расширения или с .ts
85+
import { TYPES } from './inversion.types';
86+
import { TYPES } from './inversion.types.ts';
87+
```
88+
89+
### Type-only импорты
90+
91+
Используй `import type` для импорта только типов (не значений):
92+
93+
```typescript
94+
// ✅ Правильно - type-only импорт
95+
import type { NatsConnection } from 'nats';
96+
import type { EmptyRequest, EmptyResponse } from './interfaces.js';
97+
import type { MailSenderPort } from './domain/ports/index.js';
98+
99+
// ✅ Правильно - смешанный импорт (типы и значения)
100+
import { Client, Baggage, CacheSettings } from '@lad-tech/nsc-toolkit';
101+
import type { NatsConnection } from 'nats';
102+
```
103+
104+
### JSON импорты
105+
106+
Для импорта JSON файлов используй синтаксис `with { type: 'json' }`:
107+
108+
```typescript
109+
// ✅ Правильно - JSON импорт с type assertion
110+
import serviceSchema from './service.schema.json' with { type: 'json' };
111+
```
112+
113+
### Полный пример
114+
115+
```typescript
116+
// 1. Внешние библиотеки (npm пакеты)
117+
import { DependencyType, Service, container } from '@lad-tech/nsc-toolkit';
118+
import { connect } from 'nats';
119+
import type { NatsConnection } from 'nats';
120+
121+
// 2. Workspace пакеты
122+
import { validateConfigs, logger, Logger, LogsOutputFormatter } from 'shared';
123+
import { codes } from 'shared';
124+
import { ApplicationConfig } from 'shared';
125+
126+
// 3. Локальные импорты (с расширением .js)
127+
import { TYPES } from './inversion.types.js';
128+
import { configs, ISMTPConfig } from './configs/index.js';
129+
import { MailSender } from './MailSender/index.js';
130+
import type { MailSenderPort } from './domain/ports/index.js';
131+
import { Empty } from './methods/Empty/index.js';
132+
import serviceSchema from './service.schema.json' with { type: 'json' };
133+
```
134+
135+
### Правила для Cursor
136+
137+
1. **Всегда используй расширение `.js`** для локальных импортов в TypeScript файлах
138+
2. **Используй workspace импорты** по имени пакета (например `'shared'`), не относительные пути
139+
3. **Разделяй группы импортов** пустыми строками (внешние → workspace → локальные)
140+
4. **Используй `import type`** для импорта только типов
141+
5. **Используй `with { type: 'json' }`** для импорта JSON файлов
142+
6. **Не указывай расширения** для внешних npm пакетов и workspace пакетов
143+
144+
## Запрещено
145+
146+
- `console.log` в продакшн коде (используйте логгер из `@lad-tech/toolbelt`)
147+
- `any` без необходимости (только с предупреждением и комментарием)
148+
- Прямые вызовы других сервисов (используйте `service.buildService()` из `@lad-tech/nsc-toolkit`)

0 commit comments

Comments
 (0)