Глава 17: Cursor
Принцип
Cursor — IDE с встроенным AI. Ключевые возможности: Composer для мультифайлового редактирования, @ references для контекста, .cursorrules для настройки.
Composer
Мультифайловое редактирование одной командой.
Новая функциональность
Пример 1: CRUD endpoint
"Добавь CRUD для сущности Product
Файлы:
1. src/models/product.py — SQLAlchemy модель
- id, name, price, description, is\_active, created\_at
2. src/schemas/product.py — Pydantic схемы
- ProductCreate, ProductUpdate, ProductResponse
3. src/repositories/product.py — Repository
- get\_by\_id, get\_all, create, update, delete
4. src/services/product.py — Service
- бизнес-логика, валидация
5. src/api/products.py — FastAPI роутер
- GET /products, GET /products/\{id\}, POST, PUT, DELETE
Стиль: как существующий User CRUD"
Пример 2: Система кэширования
"Добавь Redis кэширование
Файлы:
1. src/core/config.py — настройки Redis (REDIS\_URL)
2. src/core/cache.py — класс RedisCache
- get, set, delete, get\_or\_set
- TTL по умолчанию 300 сек
3. src/services/user.py — добавить кэширование в get\_user
4. src/dependencies.py — DI для RedisCache
Не трогать другие файлы"
Пример 3: Аутентификация
"Добавь JWT аутентификацию
Файлы:
1. src/core/security.py
- create\_access\_token, verify\_token
- Алгоритм: HS256
2. src/api/auth.py
- POST /auth/login — получение токена
- POST /auth/refresh — обновление
3. src/middleware/auth.py
- Проверка токена в заголовке
4. src/dependencies.py
- get\_current\_user dependency
Использовать python-jose"
Рефакторинг
Пример 1: Переименование
"Переименуй класс User → Customer везде
Файлы для изменения:
- src/models/user.py → customer.py
- src/schemas/user.py → customer.py
- src/repositories/user.py → customer.py
- src/services/user.py → customer.py
- src/api/users.py → customers.py
- tests/test\_user\*.py → test\_customer\*.py
Обнови все импорты и ссылки"
Пример 2: Выделение модуля
"Выдели payment логику в отдельный модуль
Из src/services/order.py извлечь:
- process\_payment()
- refund\_payment()
- validate\_payment\_method()
В новый src/services/payment.py
Обнови импорты в:
- src/services/order.py
- src/api/orders.py
- tests/"
Пример 3: Миграция на async
"Переведи sync код на async
Файлы:
- src/repositories/\*.py — все методы async
- src/services/\*.py — все методы async
Замени:
- requests → httpx (async)
- psycopg2 → asyncpg
- redis-py → redis.asyncio
Обнови вызовы в API (добавь await)"
Исправление багов
Пример 1: Массовое исправление
"Исправь N+1 problem во всех репозиториях
Файлы: src/repositories/\*.py
Паттерн:
- Найди циклы с отдельными запросами
- Замени на joinedload / selectinload
Пример:
\`\`\`python
\# Было
for user in users:
orders = await session.execute(select(Order).where(Order.user\_id == user.id))
\# Стало
users = await session.execute(
select(User).options(selectinload(User.orders))
)
\`\`\`"
Пример 2: Security fix
"Исправь SQL injection во всём проекте
Найди паттерн:
\`\`\`python
query = f'SELECT \* FROM users WHERE id = \{user\_id\}'
Замени на:
query = select(User).where(User.id == user\_id)
Файлы: все .py в src/"
\#\# @ References
\#\#\# @file
Пример 1: Один файл "@src/models/user.py Добавь поле phone_number: str | None"
Пример 2: Несколько файлов "@src/models/order.py @src/services/order.py Добавь возможность отмены заказа. Новый статус: cancelled Метод: cancel_order(order_id, reason)"
Пример 3: С конкретным классом/функцией "@src/services/payment.py:PaymentService.process Добавь retry логику: 3 попытки с exponential backoff"
\#\#\# @folder
Пример 1: Весь модуль "@src/services/ Добавь логирование во все публичные методы. Формат: logger.info(f'{class_name}.{method_name} called with {args}')"
Пример 2: Тесты "@tests/unit/ Добавь тесты для новой функции validate_phone в src/utils/validators.py"
\#\#\# @codebase
Пример 1: Поиск паттерна "@codebase Как в проекте реализована пагинация? Покажи все места использования."
Пример 2: Архитектура "@codebase Объясни архитектуру проекта. Как взаимодействуют слои?"
Пример 3: Генерация по аналогии "@codebase Создай NotificationService по аналогии с существующими сервисами. Методы: send_email, send_push, send_sms"
\#\#\# @docs
Пример 1: Документация библиотеки "@docs https://fastapi.tiangolo.com/ Как добавить rate limiting?"
Пример 2: README проекта "@docs README.md Обнови раздел Installation с учётом новых зависимостей"
Пример 3: API документация "@docs docs/api.md Добавь документацию для нового endpoint POST /webhooks"
\#\#\# @web
Пример 1: Актуальная информация "@web Python 3.12 new features Какие новые возможности можно использовать в проекте?"
Пример 2: Лучшие практики "@web FastAPI dependency injection best practices 2024"
Пример 3: Решение проблемы "@web SQLAlchemy asyncio connection pool exhausted"
\#\# .cursorrules
\#\#\# Базовая структура
\`\`\`markdown
\# .cursorrules
\#\# Проект
E-commerce платформа на FastAPI
\#\# Технологии
- Python 3.11+
- FastAPI
- SQLAlchemy 2.0 (async)
- PostgreSQL
- Redis
- pytest
\#\# Структура
src/ ├── api/ # Роуты (только HTTP layer) ├── services/ # Бизнес-логика ├── repositories/ # Работа с БД ├── models/ # SQLAlchemy ├── schemas/ # Pydantic └── core/ # Config, security, utils
\#\# Код
\#\#\# Стиль
- Type hints везде
- Docstrings: Google style
- Async по умолчанию
- Форматирование: black
- Линтер: ruff
\#\#\# Паттерны
- Repository для БД операций
- Service для бизнес-логики
- Dependency Injection через FastAPI Depends
- Pydantic для валидации входа/выхода
\#\#\# Обработка ошибок
- Кастомные exceptions в src/core/exceptions.py
- HTTPException только в API layer
- Логирование через structlog
\#\# Тестирование
- pytest + pytest-asyncio
- Fixtures в conftest.py
- Моки через unittest.mock
- Отдельные БД для тестов
\#\# Не делать
- Sync код в async контексте
- Raw SQL без крайней необходимости
- Any в type hints (обосновать если нужно)
- print() вместо logging
- Хардкод credentials
- Mutable default arguments
Доменные правила
\# .cursorrules (дополнение для финтех)
\#\# Домен: финансовые операции
\#\#\# Деньги
- Только Decimal, никогда float
- Округление: ROUND\_HALF\_UP
- Хранение: копейки (int) в БД
\#\#\# Транзакции
- Все операции идемпотентны (idempotency\_key)
- Двойная запись (double-entry bookkeeping)
- Audit log для всех изменений
\#\#\# Безопасность
- Логировать все финансовые операции
- Маскировать карточные данные в логах
- Rate limiting на критичных endpoints
\#\#\# Валидация
- Проверка баланса перед списанием
- Проверка лимитов на операции
- Проверка статуса аккаунта
Правила для AI
\# .cursorrules (инструкции для AI)
\#\# Генерация кода
\#\#\# Всегда
- Добавлять type hints
- Писать docstring для публичных функций
- Обрабатывать edge cases
- Добавлять валидацию входных данных
\#\#\# Никогда
- Не добавлять TODO/FIXME без объяснения
- Не использовать deprecated API
- Не игнорировать исключения (bare except)
- Не хардкодить значения (использовать config)
\#\#\# Стиль ответов
- Сначала показать изменения, потом объяснить
- Группировать изменения по файлам
- Указывать номера строк для точных правок
\#\#\# При рефакторинге
- Сохранять обратную совместимость
- Не менять публичный API без необходимости
- Оставлять тесты рабочими
Keyboard shortcuts
| Действие | Mac | Windows |
|---|---|---|
| Composer | Cmd+K | Ctrl+K |
| Inline edit | Cmd+K в строке | Ctrl+K |
| Chat | Cmd+L | Ctrl+L |
| Accept suggestion | Tab | Tab |
| Reject | Esc | Esc |
| @ menu | @ | @ |
Интеграция с Git
Пример 1: Commit message
"Сгенерируй commit message для текущих изменений.
Формат: conventional commits
Язык: английский"
Пример 2: PR description
"Создай описание PR.
Включи:
- Summary изменений
- Как тестировать
- Breaking changes (если есть)"
Пример 3: Code review
"@git:diff
Проведи code review изменений.
Фокус: безопасность, производительность"
Сравнение с другими инструментами
| Возможность | Cursor | Copilot | Claude Code |
|---|---|---|---|
| Inline completion | ✓ | ✓ | - |
| Chat | ✓ | ✓ | ✓ |
| Мультифайловое редактирование | ✓ (Composer) | Частично | ✓ |
| Codebase search | ✓ | ✓ (@workspace) | ✓ |
| Кастомные правила | ✓ (.cursorrules) | ✓ (instructions) | ✓ (CLAUDE.md) |
| Terminal integration | ✓ | ✓ | ✓ |
| Web search | ✓ (@web) | - | ✓ |