sync
This commit is contained in:
19
OLD_parts/1-assistent.md
Normal file
19
OLD_parts/1-assistent.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# Ассистент
|
||||
|
||||
## Для ассистента
|
||||
|
||||
- Всегда используй Русский язык для общения и генерации документации/комментариев/коммитов.
|
||||
- Всегда следуй этим правилам при генерации кода и ответах.
|
||||
- Всегда пиши план действий перед генерацией кода.
|
||||
- Всегда спрашивай разрешения у пользователя перед генерацией кода.
|
||||
- Всегда проверяй, что код соответствует линтингу и форматированию.
|
||||
- Всегда сверяйся с чек-листом при генерации кода.
|
||||
- Не предлагай решения, которые противоречат этим правилам этого файла.
|
||||
- Если не уверен — уточни у пользователя, не гадай, не придумывай.
|
||||
|
||||
## Обязательность чек-листов
|
||||
|
||||
- Все чек-листы, приведённые в правилах, обязательны к исполнению.
|
||||
- Ассистент обязан сверяться с чек-листом при выполнении любой задачи, связанной с кодом.
|
||||
- Нельзя сокращать, игнорировать или опускать пункты чек-листа — каждый пункт должен быть выполнен или явно отмечен как невыполнимый с объяснением причины.
|
||||
- В каждом ответе, связанном с генерацией или изменением кода, ассистент обязан ссылаться на соответствующий чек-лист и подтверждать его выполнение.
|
||||
84
OLD_parts/10-stores.md
Normal file
84
OLD_parts/10-stores.md
Normal file
@@ -0,0 +1,84 @@
|
||||
---
|
||||
title: Stores
|
||||
---
|
||||
|
||||
# Stores
|
||||
|
||||
## Сторы (Stores)
|
||||
|
||||
> В этом разделе собраны основные правила и рекомендации по созданию и оформлению сторов. Следуйте этим принципам, чтобы обеспечить чистую архитектуру, удобство поддержки и единый стиль работы с состоянием в проекте.
|
||||
> В проекте для организации состояния используется только библиотека Zustand.
|
||||
|
||||
### Структура
|
||||
- Store размещается в файле `<store-name>.store.ts` в папке `stores/` на своём уровне абстракции согласно архитектуре проекта.
|
||||
- Интерфейс состояния описывается в этом же файле с суффиксом `State` (PascalCase).
|
||||
- Для каждого store создаётся отдельный хук доступа (например, `useTodoStore`).
|
||||
- Для глобальных сторов используйте только `shared/store`.
|
||||
|
||||
### Именование
|
||||
- Соблюдайте [правила именования файлов и папок](#правила-именования-файлов-и-папок):
|
||||
- Файл store — `<store-name>.store.ts` (kebab-case).
|
||||
- Имя интерфейса состояния — PascalCase с суффиксом `State`.
|
||||
- Имя хука — camelCase с префиксом `use`.
|
||||
|
||||
### Требования
|
||||
- В store допускается только хранение состояния и методы управления им, без бизнес-логики, асинхронных операций и side-effects (см. раздел "Правила организации и использовалья Store").
|
||||
- Для методов, изменяющих состояние через set, если используется функция — тело функции в фигурных скобках, return с новой строки после стрелки.
|
||||
- Не дублируйте логику между сторами.
|
||||
|
||||
### Типизация
|
||||
- Всегда указывайте типы для всех полей состояния и методов.
|
||||
- Не используйте неявное приведение типов и не полагайтесь на автоматический вывод, если это может снизить читаемость или безопасность.
|
||||
|
||||
### Документирование
|
||||
- Документируйте только назначение store и смысл полей, строго по [правилам документирования кода](#правило-для-документирования-кода).
|
||||
|
||||
### Экспорт
|
||||
- Экспортируйте хук доступа к store и интерфейс состояния через `index.ts` слоя/компонента.
|
||||
|
||||
### Примеры
|
||||
|
||||
```ts
|
||||
import { create } from 'zustand';
|
||||
import { TodoItem } from './types/todo-item.interface';
|
||||
|
||||
/**
|
||||
* Состояние хранилища задач.
|
||||
*/
|
||||
export interface TodoStoreState {
|
||||
/** Массив задач. */
|
||||
items: TodoItem[];
|
||||
/** Добавить задачу. */
|
||||
addTodo: (item: TodoItem) => void;
|
||||
/** Удалить задачу. */
|
||||
removeTodo: (id: string) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Хук для доступа к хранилищу задач.
|
||||
*/
|
||||
export const useTodoStore = create<TodoStoreState>((set) => ({
|
||||
items: [],
|
||||
addTodo: (item) => set((state) => {
|
||||
return {
|
||||
items: [...state.items, item],
|
||||
};
|
||||
}),
|
||||
removeTodo: (id) => set((state) => {
|
||||
return {
|
||||
items: state.items.filter((t) => t.id !== id),
|
||||
};
|
||||
}),
|
||||
}));
|
||||
```
|
||||
|
||||
### Чек-лист
|
||||
|
||||
- [ ] Store размещён в `stores/<store-name>.store.ts` на своём уровне абстракции согласно архитектуре проекта.
|
||||
- [ ] Именование файлов и сущностей соответствует [правилам именования файлов и папок](#правила-именования-файлов-и-папок).
|
||||
- [ ] Все поля и методы строго типизированы (см. [общие правила типизации](#общие-правила-типизации)).
|
||||
- [ ] В store только состояние и методы управления им, без бизнес-логики и side-effects.
|
||||
- [ ] Для методов, изменяющих состояние через set, используется функция с return с новой строки.
|
||||
- [ ] Документировано только назначение store и смысл полей (см. [правила документирования кода](#правило-для-документирования-кода)).
|
||||
- [ ] Нет неиспользуемого или невалидного кода.
|
||||
- [ ] Экспорт через индексный файл.
|
||||
227
OLD_parts/11-css.md
Normal file
227
OLD_parts/11-css.md
Normal file
@@ -0,0 +1,227 @@
|
||||
---
|
||||
title: CSS
|
||||
---
|
||||
|
||||
# CSS
|
||||
|
||||
## Правила оформления и стилизации CSS-кода
|
||||
|
||||
- **Препроцессоры**
|
||||
Используй PostCSS и модули для стилизации.
|
||||
|
||||
- **Архитектура написания стилей**
|
||||
Используй подход **Mobile First**
|
||||
Используй CSS переменные для стилизации.
|
||||
Используй Custom Media Queries для адаптивных стилей.
|
||||
Используй BEM для именования классов.
|
||||
Между каждым CSS-правилом (селектором) должен быть один пустой сброс строки, пример:
|
||||
```css
|
||||
.todo-list {
|
||||
max-width: 600px;
|
||||
padding: var(--space-3);
|
||||
|
||||
@media (--md) {
|
||||
max-width: 800px;
|
||||
}
|
||||
}
|
||||
|
||||
.todo-list__text {
|
||||
font-size: 18px;
|
||||
|
||||
@media (--md) {
|
||||
font-size: 22px;
|
||||
}
|
||||
}
|
||||
```
|
||||
Запрещено писать правила подряд без пустой строки:
|
||||
```css
|
||||
/* Так делать нельзя! */
|
||||
.todo-list { ... }
|
||||
.todo-list__text { ... }
|
||||
```
|
||||
|
||||
- **Методология именования классов**
|
||||
Использовать методологию **BEM** для именования классов.
|
||||
- Блок: kebab-case, пример `.user-bar { }`
|
||||
- Елемент: kebab-case, соеденный с блоком двойным нижним подчеркиванием, пример `.user-bar__slide { }`
|
||||
- Модификатор: kebab-case, отдельный самостоятельный класс, **не соединяется** с блоком/елементом, имя модификатора всегда начинается с нижнего подчеркивания, пример: `._red { }`
|
||||
|
||||
- **Единицы измерения**
|
||||
Используй `px` как основная единица измирения, так-же допускается использовать остальные единицы измерения если того требует реализуемый дизайн.
|
||||
|
||||
- **Импорт стилей**
|
||||
Стили компонента должны импортироваться только внутри соответствующего компонента.
|
||||
Запрещено импортировать стили одного компонента в другой.
|
||||
Запрещено импортировать `css переменные` в файлы стилей, они доступны глобально.
|
||||
Запрещено импортировать `custom media` в файлы стилей, они доступны глобально.
|
||||
|
||||
- **Переменные**
|
||||
Все значения переменных нужно писать в `/shared/styles` или в Mantine ThemeProvider.
|
||||
Все что не является цветами, брекпоинтами, отступами, скруглением допускаются использоваться в компонентах.
|
||||
Обязательное создавай CSS перменные для:
|
||||
- "Цветов", пример: `--color-danger: red;`.
|
||||
- "Брекпоинты", описываем в (Сustom media) пример: `@custom-media --md (min-width: 62em);`.
|
||||
- "Отспупы (--space)", , пример: `--space-1: 4px;`, `--space-2: 8px;`, `--space-3: 12px;` итд..
|
||||
- "Скругление углов (--radius)", пример: `--radius-1: 4px;`,`--radius-2: 8px;`,`--radius-3: 12px;` итд..
|
||||
|
||||
- **Вложенность селекторов**
|
||||
Запрещено использовать вложенность селекторов.
|
||||
Разрешено использовать вложенность только для:
|
||||
- Псевдо-классов `:hover`, `:active` итд..
|
||||
- Псевдо-елементов `::before`, `::after`
|
||||
- Медиа запросов `@media`
|
||||
- Классы **модификаторы** по методологии BEM
|
||||
Каждый вложенный селектор отделяется 1 пустой строкой.
|
||||
|
||||
- **Медиа запросы**
|
||||
Строго запрещено использовать `@media` без вложения в селектор.
|
||||
Строго запрещено использовать в теле `@media` любые селекторы.
|
||||
Разрешено использовать только Custom Media Queries (например, `@media (--md) {}`).
|
||||
Запрещено использовать любые произвольные значения breakpoints (например, max-width: 768px).
|
||||
**Пример как правильно писать @media**
|
||||
```css
|
||||
.todo-list {
|
||||
max-width: 600px;
|
||||
padding: 24px;
|
||||
|
||||
@media (--md) {
|
||||
max-width: 800px;
|
||||
}
|
||||
}
|
||||
|
||||
.todo-list__text {
|
||||
font-size: 18px;
|
||||
|
||||
@media (--md) {
|
||||
font-size: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
**Пример как неправильно писать @media**
|
||||
```css
|
||||
// Медиа запрос не вложен в селектор
|
||||
@media (--md) {
|
||||
.todo-list {
|
||||
max-width: 600px;
|
||||
padding: 24px;
|
||||
}
|
||||
.todo-list__text {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
// Используется стандартный `min-width: 992px` вмето Custom Media Queries
|
||||
@media (min-width: 992px) {
|
||||
// Внутри @media запроса используются селекторы
|
||||
.todo-list {
|
||||
max-width: 600px;
|
||||
padding: 24px;
|
||||
}
|
||||
.todo-list__text {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- **Глобальные стили и сбросы**
|
||||
Все глобальные стили (например, сбросы) должны располагаться в отдельном файле, например, `src/app/styles/global.css`.
|
||||
|
||||
- **Использование Mantine и PostCSS**
|
||||
Для стандартных визуальных компонентов (кнопки, инпуты, layout, grid, notifications и т.д.) использовать только Mantine и его ThemeProvider.
|
||||
Запрещено использовать в Mantine компонентах его props/styling, вмето этого нужно добавлять кастомные стили PostCSS.
|
||||
Кастомные стили допускаются только в случае, если требуемый дизайн невозможно реализовать средствами Mantine.
|
||||
При написании кастомных стилей стараться использовать переменные и токены Mantine, если это возможно.
|
||||
|
||||
- **Порядок CSS-свойств**
|
||||
В стилях рекомендуется придерживаться логического порядка свойств:
|
||||
1. Позиционирование (position, top, left, z-index и т.д.)
|
||||
2. Блочная модель (display, width, height, margin, padding и т.д.)
|
||||
3. Оформление (background, border, box-shadow и т.д.)
|
||||
4. Текст (font, color, text-align и т.д.)
|
||||
5. Прочее (transition, animation и т.д.)
|
||||
|
||||
- **Комментарии**
|
||||
В стилях запрещено использовать комментарии.
|
||||
|
||||
- **Дублирования**
|
||||
Не дублировать стили между компонентами. Общие стили выносить в shared/styles или использовать переменные.
|
||||
|
||||
- **Примеры кода стилей**
|
||||
Пример как хорошо:
|
||||
```css
|
||||
/* Блок BEM */
|
||||
.user-bar {
|
||||
display: none;
|
||||
color: black;
|
||||
|
||||
/* Медиа запрос custom media и отделяется 1 пустой строкой */
|
||||
@media (--md) {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
/* Елемент BEM отделяется 1 пустой строкой*/
|
||||
.user-bar__button-next {
|
||||
background-color: #f0f0f0;
|
||||
|
||||
/* Псевдо-класс отделяется 1 пустой строкой*/
|
||||
&:hover {
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
|
||||
/* Модификатор BEM отделяется 1 пустой строкой*/
|
||||
&._blue {
|
||||
background-color: #2b2bbe;
|
||||
}
|
||||
|
||||
/* Модификатор BEM отделяется 1 пустой строкой*/
|
||||
&._green {
|
||||
background-color: #29c53d;
|
||||
}
|
||||
}
|
||||
```
|
||||
Пример как плохо писать:
|
||||
```css
|
||||
.user-bar {
|
||||
display: none;
|
||||
color: black;
|
||||
&__button {
|
||||
&_next {
|
||||
background-color: #f0f0f0;
|
||||
&:hover {
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
&._blue {
|
||||
background-color: #2b2bbe;
|
||||
}
|
||||
&._green {
|
||||
background-color: #29c53d;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@media (min-width: 992px) {
|
||||
.user-bar {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Чек лист для проверки стилизации.**
|
||||
- [ ] Используется PostCSS и CSS-модули для стилизации.
|
||||
- [ ] Применён подход Mobile First.
|
||||
- [ ] Именование классов строго по BEM:
|
||||
- [ ] Модификатор — отдельный класс, начинается с нижнего подчёркивания (например, `._red`, `._active`)
|
||||
- [ ] Все CSS-переменные (цвета, брейкпоинты, отступы, скругления) определены только в `/shared/styles` или через Mantine ThemeProvider.
|
||||
- [ ] Для медиа-запросов используются только custom media переменные из `/shared/styles/media.css`.
|
||||
- [ ] Соблюдается правила вложености селекторов.
|
||||
- [ ] Соблюдается правила отступов селекторов.
|
||||
- [ ] Глобальные стили (reset) вынесены в отдельный файл, остальные стили — модульные.
|
||||
- [ ] Для стандартных UI-элементов используются только компоненты Mantine, кастомные стили — только при необходимости.
|
||||
- [ ] В Mantine-компонентах не используются props/styling для стилизации, только PostCSS.
|
||||
- [ ] Кастомные стили используют переменные и токены Mantine, если это возможно.
|
||||
- [ ] В стилях нет комментариев.
|
||||
- [ ] Стили компонента импортируются только внутри соответствующего компонента.
|
||||
- [ ] Нет импорта стилей одного компонента в другой.
|
||||
- [ ] Нет импорта файлов переменных и custom media — они доступны глобально.
|
||||
- [ ] Нет дублирования стилей между компонентами, общие стили вынесены в shared/styles или используются переменные.
|
||||
88
OLD_parts/12-components.md
Normal file
88
OLD_parts/12-components.md
Normal file
@@ -0,0 +1,88 @@
|
||||
---
|
||||
title: Компоненты
|
||||
---
|
||||
|
||||
# Компоненты
|
||||
|
||||
## Правила создания и работы с компонентами.
|
||||
|
||||
### 1. Структура компонента
|
||||
Ассистент при создании/рефакторинге компонента должен **строго** придерживаться следующей структуры файлов и папок:
|
||||
|
||||
```
|
||||
component-name/
|
||||
index.ts
|
||||
component-name.tsx
|
||||
styles/
|
||||
component-name.module.css
|
||||
locales/
|
||||
ru.json
|
||||
en.json
|
||||
types/
|
||||
component-name.interface.ts
|
||||
component-name.type.ts
|
||||
component-name.enum.ts
|
||||
schemas/
|
||||
schema-name.schema.ts
|
||||
utils/
|
||||
util-name.util.ts
|
||||
hooks/
|
||||
use-hook-name.hook.ts
|
||||
stores/
|
||||
store-name.store.ts
|
||||
ui/
|
||||
... # вложенные компоненты для component-name
|
||||
```
|
||||
|
||||
Пояснения к структуре компонента:
|
||||
**Обязательные файлы** обязательны для всех компонентов, даже если они пустые.
|
||||
- component-name/: Папка компонента корень для всего компонента.
|
||||
- index.ts: экспортирует главный компонент, интерфейс и всё, что может быть переиспользовано.
|
||||
- component-name.tsx: главный компонент.
|
||||
- styles/component-name.module.css: стили компонента.
|
||||
- locales/ru.json: локализация на русском языке.
|
||||
- locales/en.json: локализация на английском языке.
|
||||
- types/component-name.interface.ts: интерфейс пропсов компонента.
|
||||
**Не обязательные файлы** добавляются только при необходимости
|
||||
- types/component-name.type.ts: типы компонента.
|
||||
- types/component-name.enum.ts: enum компонента.
|
||||
- schemas/schema-name.schema.ts: схемы валидации.
|
||||
- utils/util-name.util.ts: утилиты компонента.
|
||||
- hooks/use-hook-name.hook.ts: хуки компонента.
|
||||
- stores/store-name.store.ts: хранилища состояния компонента.
|
||||
- ui/: Папка для вложенных компонентов.
|
||||
|
||||
### Требования к компоненту
|
||||
- Использовать `memo()` для всех компонентов, которые принимают пропсы.
|
||||
- Использовать `useMemo` для всех вычислений, которые передаются в пропсы других компонентов.
|
||||
- Использовать `useCallback` для всех функций/методов, которые передаются в пропсы других компонентов.
|
||||
|
||||
### Требования к вложенным компонентам
|
||||
- Вложенный компонент — это полноценный компонент, который обязан полностью соблюдать все правила, описанные для компонентов (структура, именование, документация, типизация, стилизация и т.д.).
|
||||
- Все вложенные компоненты размещаются только в папке ui/ основного компонента.
|
||||
|
||||
**Пояснение**
|
||||
Нет необходимости повторять структуру и требования — вложенный компонент подчиняется тем же правилам, что и любой другой компонент, только располагается в папке ui/ родительского компонента.
|
||||
|
||||
### Требования к локализации
|
||||
- Все добавленные локализации обязательно подключать в экземпляр `app/i18n` (чтобы новые namespace были доступны для i18next).
|
||||
|
||||
---
|
||||
|
||||
### Чек-лист для создания нового компонента
|
||||
- [ ] Главный компонент размещён в корне и назван по правилу PascalCase.
|
||||
- [ ] Создан файл стилей в папке `styles/`, имя в kebab-case, используется BEM.
|
||||
- [ ] Все классы применяются через `className={styles['component-name']}`.
|
||||
- [ ] Создана папка `locales/` с файлами `ru.json` и `en.json`.
|
||||
- [ ] Создан файл интерфейса пропсов в папке `types/`, даже если интерфейс пустой.
|
||||
- [ ] Создан файл `index.ts` с экспортом главного компонента и интерфейса.
|
||||
- [ ] Внутренние компоненты (если есть) размещены в папке `ui/`.
|
||||
- [ ] Все важные части кода документированы по TSDoc (см. раздел 16).
|
||||
- [ ] Остальные файлы (schemas, дополнительные типы, enum) добавлены только при необходимости.
|
||||
- [ ] Именование файлов и папок соответствует правилам (см. выше).
|
||||
- [ ] Нет неиспользуемого или невалидного кода.
|
||||
- [ ] Для компонентов с пропсами используется `React.memo`.
|
||||
- [ ] Для вычислений, передаваемых в пропсы, используется `useMemo`.
|
||||
- [ ] Для функций, передаваемых в пропсы, используется `useCallback`.
|
||||
- [ ] Все тексты вынесены в локализационные файлы и используются через i18n.
|
||||
- [ ] Новые namespace подключены в экземпляр i18n.
|
||||
68
OLD_parts/13-hooks.md
Normal file
68
OLD_parts/13-hooks.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# Хуки (React Hooks)
|
||||
|
||||
> В проекте для создания пользовательских хуков используется только React (функциональные компоненты и хуки).
|
||||
> В этом разделе собраны основные правила и рекомендации по созданию и оформлению хуков. Следуйте этим принципам, чтобы обеспечить чистую архитектуру, переиспользуемость и единый стиль работы с хуками в проекте.
|
||||
|
||||
## Рекомендации по использованию сторонних хуков
|
||||
- Если есть возможность, используйте хуки Mantine в компонентах и кастомных хуках для работы с состоянием, темизацией, медиа-запросами и другими возможностями библиотеки.
|
||||
- Не дублируйте функциональность, уже реализованную в Mantine.
|
||||
|
||||
## Структура
|
||||
- Каждый хук размещается в отдельном файле с именем `use-<hook-name>.hook.ts` в папке `hooks/` на своём уровне абстракции согласно архитектуре проекта.
|
||||
- Имя хука — в стиле camelCase с префиксом `use` (например, `useTodoFilter`).
|
||||
- Для сложных возвращаемых структур использовать отдельные типы или интерфейсы, размещая их в папке `types/` на своём уровне абстракции.
|
||||
|
||||
## Именование
|
||||
- Соблюдайте [правила именования файлов и папок](#правила-именования-файлов-и-папок):
|
||||
- Файл хука — `use-<hook-name>.hook.ts` (kebab-case).
|
||||
- Имя хука — camelCase с префиксом `use`.
|
||||
|
||||
## Требования
|
||||
- Хук должен быть строго типизирован: все параметры, возвращаемые значения и внутренние переменные должны иметь явные типы.
|
||||
- Не хранить бизнес-логику, связанную с несколькими слоями — хук должен быть изолирован в рамках своего слоя/feature.
|
||||
- Не дублировать логику между хуками — общие части выносить в shared.
|
||||
- Не использовать side-effects вне useEffect/useLayoutEffect.
|
||||
- Для мемоизации возвращаемых значений и функций использовать useMemo и useCallback.
|
||||
- Не использовать устаревшие или неразрешённые паттерны React.
|
||||
|
||||
## Типизация
|
||||
- Всегда явно указывать типы для всех параметров, возвращаемых значений и состояния внутри хука.
|
||||
- Не используйте неявное приведение типов и не полагайтесь на автоматический вывод, если это может снизить читаемость или безопасность.
|
||||
|
||||
## Документирование
|
||||
- Документируйте только назначение хука (описание), строго по [правилам документирования кода](#правило-для-документирования-кода).
|
||||
|
||||
## Экспорт
|
||||
- Экспортируйте хук только именованным экспортом через `index.ts` слоя/компонента.
|
||||
|
||||
## Примеры
|
||||
|
||||
```ts
|
||||
import { useMemo } from 'react';
|
||||
import { TodoItem } from '../types/todo-item.interface';
|
||||
import { TodoStatus } from '../types/todo-status.enum';
|
||||
|
||||
/**
|
||||
* Хук фильтрации задач по статусу.
|
||||
*/
|
||||
export const useTodoFilter = (items: TodoItem[], filter: TodoStatus): TodoItem[] => {
|
||||
return useMemo(() => {
|
||||
if (filter === TodoStatus.ALL) return items;
|
||||
if (filter === TodoStatus.ACTIVE) return items.filter((t) => !t.completed);
|
||||
return items.filter((t) => t.completed);
|
||||
}, [items, filter]);
|
||||
};
|
||||
```
|
||||
|
||||
## Чек-лист
|
||||
|
||||
- [ ] Хук размещён в файле `use-<hook-name>.hook.ts` в папке `hooks/` на своём уровне абстракции согласно архитектуре проекта.
|
||||
- [ ] Именование файлов и сущностей соответствует [правилам именования файлов и папок](#правила-именования-файлов-и-папок).
|
||||
- [ ] Все параметры, возвращаемые значения и внутренние переменные строго типизированы.
|
||||
- [ ] Вся бизнес-логика изолирована в рамках слоя/feature.
|
||||
- [ ] Нет дублирования логики между хуками.
|
||||
- [ ] Для мемоизации используется useMemo/useCallback.
|
||||
- [ ] Не используются side-effects вне useEffect/useLayoutEffect.
|
||||
- [ ] Документировано только назначение хука (см. [правила документирования кода](#правило-для-документирования-кода)).
|
||||
- [ ] Нет неиспользуемого или невалидного кода.
|
||||
- [ ] Экспорт только именованный через индексный файл.
|
||||
124
OLD_parts/14-api-hooks.md
Normal file
124
OLD_parts/14-api-hooks.md
Normal file
@@ -0,0 +1,124 @@
|
||||
# Хуки API (React Hooks)
|
||||
|
||||
> В проекте для работы с API-хуками используется только React и библиотека SWR для получения данных (GET-запросы).
|
||||
> В этом разделе собраны основные правила и рекомендации по созданию и оформлению хуков для работы с API. Следуйте этим принципам, чтобы обеспечить чистую архитектуру, переиспользуемость и единый стиль работы с API-хуками в проекте.
|
||||
|
||||
## Описание и назначение API-хуков
|
||||
|
||||
API-хуки предназначены для получения данных с сервера (GET-запросы) и используются в компонентах или других хуках.
|
||||
В проекте для этого применяется библиотека SWR, которая обеспечивает кэширование, автоматическое обновление и удобную работу с асинхронными запросами.
|
||||
|
||||
**Fetcher** — это функция, которую использует SWR для выполнения запроса к API. В проекте fetcher обычно экспортируется из файла клиента (например, `backendFetcher` из `shared/api/backend/client.ts`) и инкапсулирует логику обращения к конкретному API-клиенту.
|
||||
|
||||
**API-клиент** — это отдельный модуль (папка), отвечающий за взаимодействие с конкретным внешним или внутренним API.
|
||||
API-клиент включает:
|
||||
- инициализацию экземпляра HTTP-клиента (например, Axios),
|
||||
- настройку базового URL, интерцепторов и общих обработчиков ошибок,
|
||||
- организацию всех сущностей и методов для работы с этим API (например, users, auth, orders и т.д.),
|
||||
- экспорт всех функций, типов и fetcher через индексные файлы.
|
||||
|
||||
Каждый API-клиент размещается в папке `src/shared/api/<client-name>/` и имеет собственную структуру согласно архитектуре проекта.
|
||||
|
||||
## Структура
|
||||
- Каждый API-хук размещается в отдельном файле с именем `use-<method-name>.hook-api.ts` в папке `hooks/api/<client-name>/` на своём уровне абстракции согласно архитектуре проекта.
|
||||
- Имя хука — в стиле camelCase с префиксом `use` (например, `useGetUser`).
|
||||
- Для сложных возвращаемых структур используйте отдельные типы или интерфейсы, размещая их в папке `types/` на своём уровне абстракции.
|
||||
|
||||
## Именование
|
||||
- Соблюдайте [правила именования файлов и папок](#правила-именования-файлов-и-папок):
|
||||
- Файл хука — `use-<method-name>.hook-api.ts` (kebab-case).
|
||||
- Имя хука — camelCase с префиксом `use`.
|
||||
|
||||
## Требования
|
||||
- Хук должен быть строго типизирован: все параметры, возвращаемые значения и внутренние переменные должны иметь явные типы.
|
||||
- Для получения данных используйте только SWR.
|
||||
- Не дублируйте логику между хуками — общие части выносите в shared.
|
||||
- Не используйте side-effects вне useEffect/useLayoutEffect.
|
||||
|
||||
## Типизация
|
||||
- Всегда явно указывайте типы для всех параметров, возвращаемых значений и состояния внутри хука.
|
||||
- Придерживайтесь [общих правил типизации проекта](#общие-правила-типизации).
|
||||
- Не используйте неявное приведение типов и не полагайтесь на автоматический вывод, если это может снизить читаемость или безопасность.
|
||||
|
||||
## Документирование
|
||||
- Документируйте только назначение хука (описание), строго по [правилам документирования кода](#правило-для-документирования-кода).
|
||||
|
||||
## Экспорт
|
||||
- Экспортируйте хук только именованным экспортом через `index.ts` слоя/компонента.
|
||||
|
||||
## Пример API хука
|
||||
|
||||
```ts
|
||||
// use-get-me.hook-api.ts
|
||||
import useSWR from 'swr';
|
||||
import { backendFetcher } from 'shared/api/backend/client';
|
||||
import { UserDto } from 'shared/api/backend/entities/users/get-me.api';
|
||||
|
||||
/**
|
||||
* Хук для получения информации о текущем пользователе.
|
||||
*/
|
||||
export const useGetMe = () => {
|
||||
const { data, error, isLoading } = useSWR<UserDto>('/users/me', backendFetcher);
|
||||
|
||||
return {
|
||||
data,
|
||||
error,
|
||||
isLoading,
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
### Пример использования хука в компоненте
|
||||
|
||||
```tsx
|
||||
import React from 'react';
|
||||
import { useGetMe } from 'shared/hooks/api/backend/use-get-me.hook-api';
|
||||
|
||||
export const UserInfo: React.FC = () => {
|
||||
const { data, error, isLoading } = useGetMe();
|
||||
|
||||
if (isLoading) {
|
||||
return <div>Загрузка...</div>;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return <div>Ошибка загрузки данных</div>;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
return <div>Нет данных о пользователе</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>Имя: {data.name}</div>
|
||||
<div>Email: {data.email}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## Чек-лист для создания API-хука
|
||||
|
||||
- [ ] Для каждого GET-запроса создан отдельный хук.
|
||||
- [ ] Хук размещён в `hooks/api/<client-name>/use-<method-name>.hook-api.ts` на своём уровне абстракции согласно архитектуре проекта.
|
||||
- [ ] Именование файлов и сущностей соответствует [правилам именования файлов и папок](#правила-именования-файлов-и-папок).
|
||||
- [ ] Используется SWR для получения данных.
|
||||
- [ ] Все параметры, возвращаемые значения и внутренние переменные строго типизированы.
|
||||
- [ ] Нет дублирования логики между хуками.
|
||||
- [ ] Не используются side-effects вне useEffect/useLayoutEffect.
|
||||
- [ ] Документировано только назначение хука (см. [правила документирования кода](#правило-для-документирования-кода)).
|
||||
- [ ] Нет неиспользуемого или невалидного кода.
|
||||
- [ ] Экспорт только именованный через индексный файл.
|
||||
|
||||
---
|
||||
|
||||
## Чек-лист для использования API-хука
|
||||
|
||||
- [ ] Импортируется только нужный хук через публичные экспорты (`index.ts`).
|
||||
- [ ] Использование хука строго по назначению (только для получения данных).
|
||||
- [ ] Если требуется получить данные через GET-запрос в компоненте — обязательно используется соответствующий API-хук.
|
||||
**Запрещено вызывать GET-методы API напрямую в компонентах, только через хуки.**
|
||||
- [ ] Обработка состояний загрузки, ошибки и данных реализована корректно.
|
||||
- [ ] Не происходит дублирования логики, связанной с получением данных.
|
||||
- [ ] Нет неиспользуемого или невалидного кода.
|
||||
242
OLD_parts/15-api.md
Normal file
242
OLD_parts/15-api.md
Normal file
@@ -0,0 +1,242 @@
|
||||
# API
|
||||
|
||||
> В этом разделе собраны основные правила и рекомендации по созданию, оформлению и использованию API-клиентов и функций для работы с сервером. Следуйте этим принципам, чтобы обеспечить единый стиль, безопасность и удобство поддержки API-слоя в проекте.
|
||||
|
||||
## Описание и назначение API-клиента
|
||||
|
||||
API-клиент — это модуль (папка), отвечающий за взаимодействие с конкретным внешним или внутренним API.
|
||||
В проекте для HTTP-запросов используется только Axios.
|
||||
API-клиент инкапсулирует:
|
||||
- инициализацию экземпляра Axios,
|
||||
- настройку базового URL, интерцепторов, обработчиков ошибок,
|
||||
- организацию всех сущностей и методов для работы с этим API (например, users, auth, orders и т.д.),
|
||||
- экспорт всех функций, типов и fetcher через индексные файлы.
|
||||
|
||||
Каждый API-клиент размещается в папке `src/shared/api/<client-name>/` и имеет собственную структуру согласно архитектуре проекта.
|
||||
|
||||
|
||||
## Использование методов API
|
||||
|
||||
- Все методы API должны использоваться строго внутри блока `try...catch`.
|
||||
- При вызове методов API всегда используйте полный путь, например:
|
||||
`await api.backend.createUser({ email, password });`
|
||||
- Запрещено вызывать методы API вне блока `try...catch` даже в тестах, утилитах и других вспомогательных функциях.
|
||||
|
||||
|
||||
## Структура клиента
|
||||
```text
|
||||
src/shared/api/backend/
|
||||
│
|
||||
├── client.ts
|
||||
├── index.ts
|
||||
└── entities/
|
||||
├── users/
|
||||
│ ├── get-me.api.ts
|
||||
│ ├── create-user.api.ts
|
||||
│ ├── update-user.api.ts
|
||||
│ └── index.ts
|
||||
├── auth/
|
||||
│ ├── login.api.ts
|
||||
│ ├── register.api.ts
|
||||
│ └── index.ts
|
||||
└── index.ts
|
||||
```
|
||||
|
||||
## Описание ключевых элементов
|
||||
|
||||
- **client.ts**
|
||||
Экземпляр Axios с настройками, интерцепторами, экспортом fetcher для SWR.
|
||||
|
||||
- **index.ts**
|
||||
Главная точка экспорта: экспортирует client, fetcher, все сущности и их методы.
|
||||
|
||||
- **entities/**
|
||||
Папка для бизнес-сущностей (например, users, auth, orders и т.д.).
|
||||
|
||||
- **`<entity>/`**
|
||||
Папка для отдельной сущности. Имя — в kebab-case, отражает бизнес-область (например, users, auth).
|
||||
|
||||
- **`<operation>.api.ts`**
|
||||
Файл для каждой операции (CRUD, спец. действия).
|
||||
Внутри:
|
||||
- DTO (интерфейсы запроса/ответа)
|
||||
- Функция, реализующая запрос через client
|
||||
|
||||
- **index.ts (внутри `<entity>`/)**
|
||||
Экспортирует все методы и типы этой сущности.
|
||||
|
||||
- **index.ts (внутри entities/)**
|
||||
Экспортирует все сущности (users, auth и т.д.).
|
||||
|
||||
|
||||
## Именование
|
||||
|
||||
- Соблюдайте [правила именования файлов и папок](#правила-именования-файлов-и-папок):
|
||||
- Файл клиента — `client.ts`.
|
||||
- Файл функции — `<operation>-<entity>.api.ts` (например, `create-user.api.ts`).
|
||||
- DTO — в папке `dto/` (например, `create-user.dto.ts`).
|
||||
- Все функции и типы экспортируются через индексные файлы на каждом уровне (сущность, entities, клиент).
|
||||
|
||||
|
||||
## Требования
|
||||
|
||||
- Для каждого действия (CRUD, спец. действия) — отдельная функция и файл.
|
||||
- Все функции используют общий экземпляр Axios из `client.ts`.
|
||||
- Все функции строго типизированы (используются DTO).
|
||||
- DTO объявляется в отдельном файле в папке `dto/` перед функцией, которая его использует.
|
||||
- Для каждого GET метода обязательно должен быть создан API-хук.
|
||||
- Все API-хуки должны создаваться строго по [документации раздела "Хуки для API"](#хуки-для-api-api-hooks).
|
||||
|
||||
|
||||
## Типизация
|
||||
|
||||
- Все функции и DTO строго типизированы.
|
||||
- Все интерфейсы, типы и enum размещены в папке `types/` на своём уровне абстракции.
|
||||
- Все DTO размещены в папке `dto/` на своём уровне абстракции.
|
||||
- Придерживайтесь [общих правил типизации проекта](#общие-правила-типизации).
|
||||
|
||||
|
||||
## Документирование
|
||||
|
||||
- Документируйте только назначение функций и DTO.
|
||||
- В описании указывается только смысл функции/типа.
|
||||
|
||||
|
||||
## Экспорт
|
||||
|
||||
- Все функции и типы экспортируются через индексные файлы на каждом уровне (сущность, entities, клиент).
|
||||
|
||||
|
||||
## Примеры
|
||||
|
||||
### Пример клиента API
|
||||
|
||||
```ts
|
||||
// client.ts
|
||||
import axios, { AxiosInstance } from "axios";
|
||||
export { AxiosError, isAxiosError } from 'axios';
|
||||
export type { AxiosResponse } from 'axios';
|
||||
|
||||
/**
|
||||
* Экземпляр HTTP-клиента для работы с backend API.
|
||||
*/
|
||||
export const backendHttpClient: AxiosInstance = axios.create({
|
||||
baseURL: '/api',
|
||||
timeout: 10000,
|
||||
});
|
||||
|
||||
// Интерцептор запроса
|
||||
backendHttpClient.interceptors.request.use(
|
||||
(config) => {
|
||||
// Здесь можно добавить авторизационные заголовки или другую логику
|
||||
return config;
|
||||
},
|
||||
(error) => Promise.reject(error)
|
||||
);
|
||||
|
||||
// Интерцептор ответа
|
||||
backendHttpClient.interceptors.response.use(
|
||||
(response) => response,
|
||||
(error) => {
|
||||
// Здесь можно обработать ошибки (например, показать уведомление)
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
### Пример DTO
|
||||
|
||||
```ts
|
||||
// dto/create-user.dto.ts
|
||||
/**
|
||||
* DTO для создания пользователя.
|
||||
*/
|
||||
export interface CreateUserDto {
|
||||
/** Email пользователя. */
|
||||
email: string;
|
||||
/** Пароль пользователя. */
|
||||
password: string;
|
||||
}
|
||||
```
|
||||
|
||||
### Пример API-функции
|
||||
|
||||
```ts
|
||||
// create-user.api.ts
|
||||
import { backendHttpClient } from '../client';
|
||||
import { CreateUserDto } from './dto/create-user.dto';
|
||||
|
||||
/**
|
||||
* Создать пользователя.
|
||||
*/
|
||||
export const createUser = (data: CreateUserDto) => backendHttpClient.post('/users', data);
|
||||
```
|
||||
|
||||
### Пример index.ts (в папке сущности)
|
||||
|
||||
```ts
|
||||
export * from './create-user.api';
|
||||
export * from './get-user.api';
|
||||
```
|
||||
|
||||
### Пример использования API-функции в компоненте
|
||||
|
||||
```tsx
|
||||
import React, { useState } from 'react';
|
||||
import { api } from 'shared/api';
|
||||
|
||||
export const CreateUserForm: React.FC = () => {
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
try {
|
||||
await api.backend.createUser({ email, password });
|
||||
console.log('Пользователь создан!');
|
||||
} catch {
|
||||
console.log('Ошибка создания пользователя');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<input
|
||||
type="email"
|
||||
value={email}
|
||||
onChange={e => setEmail(e.target.value)}
|
||||
placeholder="Email"
|
||||
required
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={e => setPassword(e.target.value)}
|
||||
placeholder="Пароль"
|
||||
required
|
||||
/>
|
||||
<button type="submit">Создать пользователя</button>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
## Чек-лист для создания клиента
|
||||
- [ ] Новый клиент размещён в `src/shared/api/<client-name>/`.
|
||||
- [ ] В корне клиента есть client.ts (экземпляр Axios) и index.ts (главный экспорт).
|
||||
- [ ] Все бизнес-сущности размещены в entities/, каждая — в отдельной папке.
|
||||
- [ ] Для каждой операции создан отдельный файл `<operation>`.api.ts с DTO и функцией.
|
||||
- [ ] DTO объявлен непосредственно перед функцией.
|
||||
- [ ] В каждой папке сущности есть свой index.ts для экспорта методов и типов.
|
||||
- [ ] В папке entities/ есть общий index.ts для экспорта всех сущностей.
|
||||
- [ ] Все экспорты организованы через индексные файлы.
|
||||
- [ ] Для каждого GET-метода создан отдельный SWR-хук (см. правила API-хуков).
|
||||
- [ ] Нет дублирования кода и неиспользуемых файлов.
|
||||
|
||||
## Чек-лист для использования API
|
||||
- [ ] Импортируется только нужный метод через публичные экспорты (index.ts).
|
||||
- [ ] Все вызовы API обёрнуты в try...catch.
|
||||
- [ ] Используются только строго типизированные методы.
|
||||
- [ ] Не происходит обращения к Axios напрямую — только через client.
|
||||
- [ ] Нет дублирования логики и неиспользуемого кода.
|
||||
21
OLD_parts/3-general-principles.md
Normal file
21
OLD_parts/3-general-principles.md
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
title: Общие принципы
|
||||
---
|
||||
|
||||
# Общие принципы
|
||||
|
||||
## Стек технологий и библиотеки
|
||||
- Использовать **TypeScript** для всех файлов логики и компонентов.
|
||||
- Использовать **FSD (Feature-Sliced Design)**: разделять код на features, entities, processes, widgets, shared.
|
||||
- Использовать **React** (функциональные компоненты, хуки).
|
||||
- Использовать **Mantine UI** для UI-компонентов.
|
||||
- Использовать **Axios** в качестве клиента для работы с API.
|
||||
- Использовать **SWR** для data fetching (GET-запросы).
|
||||
- Использовать **Zustand** для глобального состояния.
|
||||
- Использовать **i18n** для локализации.
|
||||
- Использовать **Vitest** для тестирования.
|
||||
- Использовать **PostCSS модули** для стилизации.
|
||||
- Использовать **BEM** для именований классов в стилях
|
||||
- Использовать **Mobile First** подход для написания стилей.
|
||||
- Использовать **Context7** примеров использования библиотек.
|
||||
- Использовать **i18n** (i18next) для локализации всех пользовательских текстов.
|
||||
22
OLD_parts/4-arkhitektura.md
Normal file
22
OLD_parts/4-arkhitektura.md
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: Архитектура
|
||||
---
|
||||
|
||||
# Архитектура
|
||||
|
||||
## Архитектура проекта
|
||||
В проекте используется FSD (Feature-Sliced Design) архитектура.
|
||||
|
||||
- **FSD-границы**
|
||||
- Не нарушать границы слоёв (например, feature не может импортировать из widgets).
|
||||
- Бизнес-логика должна быть вынесена в хуки или сервисы.
|
||||
- **Импорты**
|
||||
- Внутри слоя — относительные импорты.
|
||||
- Между слоями — абсолютные импорты.
|
||||
- **Требования**
|
||||
- Не смешивать логику разных слоёв.
|
||||
- Не хранить бизнес-логику в UI-компонентах.
|
||||
- **Именование**
|
||||
- Файлы и папки kebab-case.
|
||||
|
||||
---
|
||||
74
OLD_parts/5-code-style.md
Normal file
74
OLD_parts/5-code-style.md
Normal file
@@ -0,0 +1,74 @@
|
||||
---
|
||||
title: Стиль кода
|
||||
---
|
||||
|
||||
# Стиль кода
|
||||
|
||||
## Отступы
|
||||
|
||||
Используем 2 пробела для отступов во всём проекте. Не используем табы.
|
||||
|
||||
|
||||
## Кавычки
|
||||
|
||||
Используем **одинарные кавычки** для строк в JavaScript/TypeScript, и **двойные кавычки** для атрибутов в JSX/TSX.
|
||||
|
||||
**Пример:**
|
||||
|
||||
```ts
|
||||
// JavaScript/TypeScript
|
||||
const message = 'Привет, мир!';
|
||||
const name = 'ProjectName';
|
||||
```
|
||||
|
||||
```tsx
|
||||
// JSX/TSX
|
||||
<input type="text" placeholder="Введите имя" />
|
||||
<button title="Сохранить">Сохранить</button>
|
||||
```
|
||||
|
||||
## Строгая типизация
|
||||
|
||||
всегда указывать типы для пропсов, возвращаемых значений, параметров функций.
|
||||
|
||||
## Ранние возвраты
|
||||
|
||||
(early return) для повышения читаемости.
|
||||
|
||||
## Мемоизация
|
||||
|
||||
Старайся оптимизировать код если это возможно.
|
||||
|
||||
## Документирование
|
||||
|
||||
Документируем ТОЛЬКО ОПИСАНИЕ (функций, компонентов, типов и их полей).
|
||||
|
||||
## any, unknown
|
||||
|
||||
запрещено использовать без крайней необходимости.
|
||||
|
||||
## Классы в TSX
|
||||
|
||||
Для стилизации компонентов используем CSS-модули и методологию BEM. Классы подключаются через объект стилей, импортированный из соответствующего `.module.css` файла.
|
||||
|
||||
> Объект стилей всегда импортируется с именем `s` (сокращённо от style), а не `styles`.
|
||||
|
||||
**Пример:**
|
||||
|
||||
```tsx
|
||||
import s from './my-component.module.css';
|
||||
|
||||
export const MyComponent = () => (
|
||||
<div className={s['my-component']}>
|
||||
<button className={s['my-component__button']}>Кнопка</button>
|
||||
<span className={s['my-component__text']}>Текст</span>
|
||||
<button className={s['my-component__button'] + ' ' + s._active}>
|
||||
Активная кнопка
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
```
|
||||
|
||||
- Имя класса всегда берётся из объекта `s`.
|
||||
- Для модификаторов используется отдельный класс с нижним подчёркиванием (например, `s._active`).
|
||||
- Не используйте строковые литералы с классами напрямую — только через объект `s`.
|
||||
18
OLD_parts/6-naming.md
Normal file
18
OLD_parts/6-naming.md
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
title: Именование
|
||||
---
|
||||
|
||||
# Именование
|
||||
|
||||
## Именование файлов и папок
|
||||
- Папка компонента: kebab-case, совпадает с названием компонента, пример: `component-name`.
|
||||
- React-компонент: kebab-case, совпадает с названием компонента, пример: `component-name.tsx`.
|
||||
- Стили: kebab-case, шаблон: `<style-name>.module.css`, пример: `style-name.module.css`.
|
||||
- Интерфейсы: kebab-case, шаблон: `<interface-name>.interface.ts`, пример: `interface-name.interface.ts`.
|
||||
- Типы: kebab-case, шаблон: `<type-name>.type.ts`, пример: `type-name.type.ts`.
|
||||
- Enum: kebab-case, шаблон: `<enum-name>.enum.ts`, пример: `enum-name.enum.ts`.
|
||||
- Схемы: kebab-case, шаблон: `<schema-name>.schema.ts`, пример: `schema-name.schema.ts`.
|
||||
- Локализация: kebab-case, пример: `ru.json`, `en.json`.
|
||||
- Утилиты: kebab-case, шаблон: `<util-name>.util.ts`, пример: `util-name.util.ts`
|
||||
- React Hooks: kebab-case, шаблон: `use-<hook-name>.hook.ts`, пример: `use-hook-name.hook.ts`
|
||||
- Хранилища состояния компонента: kebab-case, шаблон: `<store-name>.store.ts`, пример: `store-name.store.ts`
|
||||
69
OLD_parts/7-docs.md
Normal file
69
OLD_parts/7-docs.md
Normal file
@@ -0,0 +1,69 @@
|
||||
---
|
||||
title: Документирование
|
||||
---
|
||||
|
||||
# Документирование
|
||||
|
||||
## Правило для документирования кода
|
||||
|
||||
- Документировать разрешено только описание (назначение) функций, компонентов, типов, интерфейсов, enum и их полей.
|
||||
- Строго запрещено документировать параметры, возвращаемые значения, типы пропсов, аргументы, возвращаемые значения функций, компоненты, хуки и т.д.
|
||||
- В интерфейсах, типах и enum разрешено документировать только смысл (описание) каждого поля или значения.
|
||||
- В React-компонентах, функциях, хранилищах, схемах, утилитах разрешено документировать только назначение (описание), без детализации параметров и возвращаемых значений.
|
||||
- Описание должно быть кратким, информативным и реально помогать понять структуру и бизнес-логику.
|
||||
- Не допускается избыточная или дублирующая очевидное документация.
|
||||
- В конце описания всегда ставить точку.
|
||||
|
||||
**Примеры правильного документирования**
|
||||
```tsx
|
||||
/**
|
||||
* Список задач пользователя.
|
||||
*/
|
||||
export const TodoList = memo(() => { ... });
|
||||
|
||||
/**
|
||||
* Интерфейс задачи.
|
||||
*/
|
||||
export interface TodoItem {
|
||||
/** Уникальный идентификатор задачи. */
|
||||
id: string;
|
||||
/** Текст задачи. */
|
||||
text: string;
|
||||
/** Статус выполнения задачи. */
|
||||
completed: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Перечисление фильтров задач.
|
||||
*/
|
||||
export enum TodoFilter {
|
||||
/** Все задачи. */
|
||||
All = 'all',
|
||||
/** Только активные задачи. */
|
||||
Active = 'active',
|
||||
/** Только выполненные задачи. */
|
||||
Completed = 'completed',
|
||||
}
|
||||
```
|
||||
|
||||
**Примеры неправильного документирования**
|
||||
```ts
|
||||
// ❌ Не нужно:/
|
||||
/**
|
||||
* @param id - идентификатор задачи
|
||||
* @returns объект задачи
|
||||
*/
|
||||
|
||||
// ❌ Не нужно:/
|
||||
/**
|
||||
* @param props - пропсы компонента
|
||||
* @returns JSX.Element
|
||||
*/
|
||||
|
||||
// ❌ Не нужно:/
|
||||
/**
|
||||
* id — идентификатор задачи
|
||||
* text — текст задачи
|
||||
* completed — статус выполнения
|
||||
*/
|
||||
```
|
||||
187
OLD_parts/8-typing.md
Normal file
187
OLD_parts/8-typing.md
Normal file
@@ -0,0 +1,187 @@
|
||||
---
|
||||
title: Типизация
|
||||
---
|
||||
|
||||
# Типизация
|
||||
|
||||
## Общие правила типизации
|
||||
|
||||
> Данный раздел определяет единые требования к типизации для всего проекта. Соблюдение этих правил обеспечивает читаемость, предсказуемость и безопасность кода.
|
||||
|
||||
- Использовать только строгую типизацию TypeScript для всех файлов логики, компонентов, хуков, API, сторов и утилит.
|
||||
- Всегда явно указывать типы для:
|
||||
- Пропсов компонентов
|
||||
- Параметров функций и методов
|
||||
- Возвращаемых значений функций и методов
|
||||
- Всех переменных состояния (в том числе в store)
|
||||
- Всех значимых переменных и констант, если их тип не очевиден из присваивания
|
||||
- Не использовать `any` и `unknown` без крайней необходимости. Если использование неизбежно — обязательно добавить комментарий с обоснованием.
|
||||
- Все интерфейсы, типы и enum всегда размещать в папке `types/` на своём уровне абстракции (например, `features/todo/types/`).
|
||||
- Для DTO всегда использовать отдельную папку `dto/` на уровне сущности или слоя.
|
||||
- Для сложных структур использовать отдельные интерфейсы или типы, размещая их в соответствующих файлах в папке `types/`.
|
||||
- Для DTO, enum, схем и других сущностей — всегда создавать отдельные типы/интерфейсы с осмысленными именами.
|
||||
- Ключи enum всегда писать ЗАГЛАВНЫМИ_БУКВАМИ (SCREAMING_SNAKE_CASE).
|
||||
- Не использовать неявное приведение типов и не полагаться на автоматический вывод, если это может снизить читаемость или безопасность.
|
||||
- Для массивов и объектов всегда указывать тип элементов/ключей.
|
||||
- Для возвращаемых значений асинхронных функций всегда указывать тип Promise.
|
||||
- Типизацию коллбеков и функций, передаваемых в пропсы, указывать инлайн, не выносить в отдельные типы.
|
||||
- Для типизации внешних библиотек использовать официальные типы или создавать собственные декларации при необходимости.
|
||||
- Не использовать устаревшие или не рекомендуемые паттерны типизации (например, `Function`, `Object`, `{}`).
|
||||
---
|
||||
|
||||
### Примеры
|
||||
|
||||
#### Интерфейс и типы для сущностей (всегда в папке types/)
|
||||
|
||||
```ts
|
||||
// features/todo/types/todo-item.interface.ts
|
||||
|
||||
/**
|
||||
* Интерфейс задачи.
|
||||
*/
|
||||
export interface TodoItem {
|
||||
/** Уникальный идентификатор задачи. */
|
||||
id: string;
|
||||
/** Текст задачи. */
|
||||
text: string;
|
||||
/** Статус выполнения задачи. */
|
||||
completed: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
#### Типизация enum (всегда в папке types/)
|
||||
|
||||
```ts
|
||||
// features/todo/types/todo-status.enum.ts
|
||||
|
||||
/**
|
||||
* Перечисление статусов задачи.
|
||||
*/
|
||||
export enum TodoStatus {
|
||||
/** Активная задача. */
|
||||
ACTIVE = 'active',
|
||||
/** Выполненная задача. */
|
||||
COMPLETED = 'completed',
|
||||
}
|
||||
```
|
||||
|
||||
#### Типизация пропсов компонента
|
||||
|
||||
```ts
|
||||
import { FC, memo } from 'react';
|
||||
import { TodoItem } from './types/todo-item.interface';
|
||||
|
||||
/**
|
||||
* Список задач.
|
||||
*/
|
||||
export interface TodoListProps {
|
||||
/** Массив задач. */
|
||||
items: TodoItem[];
|
||||
}
|
||||
|
||||
export const TodoList: FC<TodoListProps> = memo(({ items }) => (
|
||||
<ul>
|
||||
{items.map((item) => (
|
||||
<li key={item.id}>{item.text}</li>
|
||||
))}
|
||||
</ul>
|
||||
));
|
||||
```
|
||||
|
||||
#### Типизация функций и коллбеков (инлайн)
|
||||
|
||||
```ts
|
||||
/**
|
||||
* Функция фильтрации задач.
|
||||
*/
|
||||
export const getCompletedTodos = (items: TodoItem[]): TodoItem[] => {
|
||||
return items.filter((t) => t.completed);
|
||||
};
|
||||
|
||||
/**
|
||||
* Колбэк для обработки клика (инлайн).
|
||||
*/
|
||||
const handleClick = (id: string): void => {
|
||||
console.log('Clicked:', id);
|
||||
};
|
||||
```
|
||||
|
||||
#### Типизация асинхронных функций
|
||||
|
||||
```ts
|
||||
/**
|
||||
* Получить задачи с сервера.
|
||||
*/
|
||||
export const fetchTodos = async (): Promise<TodoItem[]> => {
|
||||
const response = await fetch('/api/todos');
|
||||
return response.json();
|
||||
};
|
||||
```
|
||||
|
||||
#### Типизация состояния в store (интерфейс в types/)
|
||||
|
||||
```ts
|
||||
// features/todo/types/todo-store.interface.ts
|
||||
|
||||
/**
|
||||
* Состояние хранилища задач.
|
||||
*/
|
||||
export interface TodoStoreState {
|
||||
/** Массив задач. */
|
||||
items: TodoItem[];
|
||||
/** Добавить задачу. */
|
||||
addTodo: (item: TodoItem) => void;
|
||||
/** Удалить задачу. */
|
||||
removeTodo: (id: string) => void;
|
||||
}
|
||||
```
|
||||
|
||||
#### Типизация DTO (всегда в папке dto/)
|
||||
|
||||
```ts
|
||||
// features/todo/dto/create-todo.dto.ts
|
||||
|
||||
/**
|
||||
* DTO для создания задачи.
|
||||
*/
|
||||
export interface CreateTodoDto {
|
||||
/** Текст задачи. */
|
||||
text: string;
|
||||
}
|
||||
|
||||
// features/todo/dto/todo-response.dto.ts
|
||||
|
||||
/**
|
||||
* DTO ответа сервера.
|
||||
*/
|
||||
export interface TodoResponseDto {
|
||||
/** Созданная задача. */
|
||||
todo: TodoItem;
|
||||
}
|
||||
```
|
||||
|
||||
#### Типизация внешних библиотек
|
||||
|
||||
```ts
|
||||
import type { AxiosResponse } from 'axios';
|
||||
|
||||
export const getData = async (): Promise<AxiosResponse<TodoItem[]>> => {
|
||||
// ...
|
||||
};
|
||||
```
|
||||
### Чек-лист проверки типизации
|
||||
|
||||
- [ ] Все пропсы компонентов явно типизированы через интерфейс или тип в папке `types/`.
|
||||
- [ ] Все параметры и возвращаемые значения функций и методов явно типизированы.
|
||||
- [ ] Все переменные состояния (в том числе в store) имеют явные типы.
|
||||
- [ ] Все интерфейсы, типы и enum размещены в папке `types/` на своём уровне абстракции.
|
||||
- [ ] Ключи всех enum написаны ЗАГЛАВНЫМИ_БУКВАМИ (SCREAMING_SNAKE_CASE).
|
||||
- [ ] Все DTO размещены в папке `dto/` на своём уровне абстракции.
|
||||
- [ ] Не используется `any` и `unknown` без крайней необходимости и поясняющего комментария.
|
||||
- [ ] Для сложных структур используются отдельные интерфейсы или типы.
|
||||
- [ ] Для массивов и объектов указан тип элементов/ключей.
|
||||
- [ ] Для асинхронных функций указан тип Promise с конкретным типом результата.
|
||||
- [ ] Типы коллбеков и функций, передаваемых в пропсы, указаны инлайн.
|
||||
- [ ] Не используются устаревшие типы (`Function`, `Object`, `{}`).
|
||||
- [ ] Для внешних библиотек используются официальные типы или собственные декларации.
|
||||
- [ ] Нет неявного приведения типов, все типы читаемы и прозрачны.
|
||||
12
OLD_parts/9-localization.md
Normal file
12
OLD_parts/9-localization.md
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
title: Локализация
|
||||
---
|
||||
|
||||
# Локализация
|
||||
|
||||
## Правила использования локализации
|
||||
|
||||
- Все пользовательские тексты должны быть вынесены в локализационные файлы.
|
||||
- Для каждого компонента создавать папку `locales/` с файлами `ru.json`, `en.json` и т.д.
|
||||
- Новые namespace обязательно регистрировать в экземпляре i18n (см. `app/i18n.ts`).
|
||||
- В коде использовать только функцию перевода из i18n, не использовать "жёстко" прописанные строки.
|
||||
Reference in New Issue
Block a user