Примеры навыков¶
1. Создание React компонентов¶
Файл: .koda/skills/react-component/SKILL.md
---
name: react-component
description: Создание React компонентов с лучшими практиками
---
# React Component Creation
## Purpose
Создание React компонентов с соблюдением лучших практик проекта.
## When to use
Когда пользователь просит создать React компонент или упоминает "component", "React", "JSX".
## Instructions
### 1. Структура компонента
Всегда создавай компоненты в следующем порядке:
1. **Импорты** — сгруппированные по типу
```typescript
// React
import React, { FC, useState, useEffect } from 'react';
// Библиотеки
import { classNames } from '@/utils';
// Локальные
import { Button } from '../Button';
```
2. **Типы** — перед компонентом
```typescript
interface ComponentProps {
title: string;
onClick?: () => void;
}
```
3. **Компонент** — с явным типом
```typescript
export const MyComponent: FC<ComponentProps> = ({ title, onClick }) => {
// Логика
return <div>{title}</div>;
};
```
### 2. Именование
- Используй PascalCase для имён компонентов
- Префикс `use` для хуков: `useAuth`, `useForm`
- Суффикс `Props` для типов пропсов
### 3. Стиль кода
- Используй функциональные компоненты
- Избегай классовых компонентов
- Применяй хуки вместо lifecycle методов
- Типизируй всё через TypeScript
### 4. Тесты
Для каждого компонента создавай тест:
- Файл: `ComponentName.test.tsx`
- Библиотека: React Testing Library
- Покрытие: основные сценарии использования
## Examples
### Пример компонента
```typescript
import React, { FC, useState } from 'react';
import { Button } from '../Button';
interface CounterProps {
initialValue?: number;
}
export const Counter: FC<CounterProps> = ({ initialValue = 0 }) => {
const [count, setCount] = useState(initialValue);
return (
<div>
<p>Count: {count}</p>
<Button onClick={() => setCount(count + 1)}>
Increment
</Button>
</div>
);
};
```
2. Python API Best Practices¶
Файл: .agents/skills/python-api/SKILL.md
---
name: python-api
description: Создание Python API с использованием FastAPI
---
# Python API Development
## Purpose
Создание REST API на Python с использованием FastAPI и соблюдением стандартов проекта.
## When to use
Когда пользователь просит создать API, endpoint, или упоминает "FastAPI", "Python API".
## Instructions
### 1. Структура проекта
```
app/
├── main.py # Точка входа
├── api/ # API роуты
│ ├── v1/
│ │ ├── endpoints/
│ │ └── router.py
├── core/ # Конфигурация
│ ├── config.py
│ └── security.py
├── models/ # SQLAlchemy модели
├── schemas/ # Pydantic схемы
└── services/ # Бизнес-логика
```
### 2. Создание endpoint
Всегда следуй шаблону:
```python
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from app.core.database import get_db
from app.schemas import ItemCreate, ItemResponse
from app.services import item_service
router = APIRouter()
@router.post("/items/", response_model=ItemResponse)
def create_item(
item: ItemCreate,
db: Session = Depends(get_db)
) -> ItemResponse:
"""
Create a new item.
- **name**: Item name (required)
- **price**: Item price (required, must be positive)
"""
return item_service.create(db=db, item=item)
```
### 3. Валидация
Используй Pydantic для валидации:
```python
from pydantic import BaseModel, Field, validator
class ItemCreate(BaseModel):
name: str = Field(..., min_length=1, max_length=100)
price: float = Field(..., gt=0)
@validator('name')
def name_must_not_be_empty(cls, v):
if not v.strip():
raise ValueError('name cannot be empty')
return v
```
### 4. Обработка ошибок
```python
from fastapi import HTTPException, status
def get_item_or_404(db: Session, item_id: int):
item = db.query(Item).filter(Item.id == item_id).first()
if not item:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Item not found"
)
return item
```
## Examples
### Полный пример endpoint
```python
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from typing import List
from app.core.database import get_db
from app.schemas import UserCreate, UserResponse, UserUpdate
from app.services import user_service
from app.models import User
router = APIRouter(prefix="/users", tags=["users"])
@router.post("/", response_model=UserResponse, status_code=status.HTTP_201_CREATED)
def create_user(user: UserCreate, db: Session = Depends(get_db)):
"""Create a new user."""
return user_service.create(db=db, user=user)
@router.get("/{user_id}", response_model=UserResponse)
def get_user(user_id: int, db: Session = Depends(get_db)):
"""Get a specific user by ID."""
return get_item_or_404(db, user_id)
@router.get("/", response_model=List[UserResponse])
def list_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
"""List all users with pagination."""
return db.query(User).offset(skip).limit(limit).all()
```
3. Git Commit Messages¶
Файл: .koda/skills/git-commit/SKILL.md
---
name: git-commit
description: Генерация сообщений коммитов в формате Conventional Commits
---
# Git Commit Messages
## Purpose
Создание сообщений коммитов в стандарте Conventional Commits.
## When to use
Когда пользователь просит сгенерировать commit message или использует команду `/commit`.
## Instructions
### 1. Формат сообщения
```
<type>(<scope>): <description>
[optional body]
[optional footer]
```
### 2. Типы коммитов
- **feat**: Новая функциональность
- **fix**: Исправление бага
- **docs**: Изменения в документации
- **style**: Форматирование, отступы (без изменений кода)
- **refactor**: Рефакторинг кода
- **test**: Добавление тестов
- **chore**: Изменения в сборке, зависимостях
- **perf**: Улучшение производительности
- **ci**: Изменения в CI/CD
- **build**: Изменения в системе сборки
### 3. Правила
- Заголовок до 50 символов
- Тело до 72 символов на строку
- Используй повелительное наклонение: "add", не "added"
- Не заканчивай точкой
- Указывай breaking changes в footer
### 4. Примеры
✅ **Хорошо**:
```
feat(auth): добавить OAuth2 аутентификацию
- Интеграция с Google OAuth
- Добавлены эндпоинты /auth/google
- Обновлены типы User
Closes #123
```
❌ **Плохо**: `fix: исправил баги и добавил фичи`
## Examples
### Пример для исправления бага
```
fix(api): исправить утечку памяти в WebSocket
Закрытие соединения не освобождало ресурсы.
Добавлен явный вызов cleanup() при отключении.
Fixes #456
```
### Пример для новой фичи
```
feat(ui): добавить тёмную тему
- Реализовано переключение тем
- Сохранение выбора в localStorage
- Обновлены цветовые переменные CSS
BREAKING CHANGE: Изменены названия цветовых переменных
```
4. Database Migrations¶
Файл: .koda/skills/db-migration/SKILL.md
---
name: db-migration
description: Создание миграций базы данных с лучшими практиками
---
# Database Migrations
## Purpose
Создание безопасных миграций базы данных с возможностью отката.
## When to use
Когда пользователь просит создать миграцию, изменить схему БД, или упоминает "migration", "schema".
## Instructions
### 1. Именование файлов
```
YYYYMMDDHHMMSS_description.sql
```
Пример:
```
20250115143022_add_users_table.sql
```
### 2. Структура миграции
Всегда включай:
- **UP** — применение миграции
- **DOWN** — откат миграции
```sql
-- UP
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_users_email ON users(email);
-- DOWN
DROP INDEX IF EXISTS idx_users_email;
DROP TABLE IF EXISTS users;
```
### 3. Правила
- Всегда пиши DOWN миграцию
- Используй транзакции
- Добавляй индексы для внешних ключей
- Не изменяй существующие данные в UP
- Тестируй откат перед применением
### 4. Безопасные изменения
**Добавление колонки**:
```sql
-- UP
ALTER TABLE users ADD COLUMN phone VARCHAR(20);
-- DOWN
ALTER TABLE users DROP COLUMN phone;
```
**Изменение типа колонки**:
```sql
-- UP (сначала новая колонка)
ALTER TABLE users ADD COLUMN phone_new VARCHAR(20);
UPDATE users SET phone_new = phone;
ALTER TABLE users DROP COLUMN phone;
ALTER TABLE users RENAME COLUMN phone_new TO phone;
-- DOWN
ALTER TABLE users ADD COLUMN phone_old VARCHAR(10);
UPDATE users SET phone_old = phone;
ALTER TABLE users DROP COLUMN phone;
ALTER TABLE users RENAME COLUMN phone_old TO phone;
```
## Examples
### Миграция с внешним ключом
```sql
-- UP
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL,
total DECIMAL(10,2) NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
CONSTRAINT fk_orders_user
FOREIGN KEY (user_id)
REFERENCES users(id)
ON DELETE CASCADE
);
CREATE INDEX idx_orders_user_id ON orders(user_id);
CREATE INDEX idx_orders_created_at ON orders(created_at);
-- DOWN
DROP INDEX IF EXISTS idx_orders_created_at;
DROP INDEX IF EXISTS idx_orders_user_id;
DROP TABLE IF EXISTS orders;
```