### Версии зависимостей
- Версии зависимостей в Cargo.toml (включая edition) не являются багами
- Не предлагать исправлять или обновлять версии зависимостей без явного запроса пользователя
- Edition "2024" и версии зависимостей в Cargo.toml оставлять как есть

### GraphQL запросы
- GraphQL запросы хранятся как константы в `src/queries.rs`
- При изменении запросов обновляй соответствующую константу (ANIMES_QUERY, MANGAS_QUERY и т.д.)
- Не дублируй запросы — используй существующие константы
- Если нужен новый запрос, создай константу с именем в формате `{ENTITY}_QUERY` или `{ENTITY}_{VARIANT}_QUERY`

### Валидация параметров
- Все методы поиска (`animes`, `mangas`, `characters`, `people`, `user_rates`) должны валидировать параметры перед запросом
- Используй существующие методы валидации: `val_lim()`, `val_pg()`, `val_ids()`
- Валидация должна возвращать `ShikicrateError::Validation` с понятным сообщением
- Правила валидации: `limit > 0`, `page >= 1`, `ids` не пустой вектор

### Retry логика
- Retry выполняется только для retryable ошибок (сетевые, rate limit 429)
- Используй `is_retryable()` для проверки
- Максимум 3 retry (всего 4 попытки) с задержками: 1s, 2s, 4s
- Для rate limit используй `Retry-After` заголовок (максимум 60 секунд)
- Ошибки валидации, GraphQL и API (кроме 429) не повторяются

### Обработка ошибок
- Используй `thiserror::Error` для всех типов ошибок
- Все ошибки должны реализовывать `std::error::Error` и `std::fmt::Display`
- При добавлении нового типа ошибки обновляй `ShikicrateError` enum
- Ошибки GraphQL должны собирать все сообщения, а не только первое

### Пагинация
- Пагинаторы используют `futures::stream` для ленивой загрузки
- Пагинаторы возвращают `Box<dyn Stream<Item = Result<T>> + Send + Unpin>`
- Используй `stream::unfold` для управления состоянием пагинации
- При ошибке в пагинаторе сохраняй её в state и останавливай стрим
- Для пагинации нужен `Arc<ShikicrateClient>` — используй `to_arc()`

### Типы данных
- Все типы данных в `src/types.rs` должны иметь `#[derive(Debug, Clone, Serialize, Deserialize)]`
- Для ID используй кастомные десериализаторы `deser_id` и `deser_opt_id` (поддерживают int и string)
- Опциональные поля используй везде, где API может вернуть null
- Документируй все публичные поля через doc comments

### HTTP клиент
- Используй `reqwest::Client` с rustls (без native-tls)
- User-agent: `shikicrate/{version}` (из `CARGO_PKG_VERSION`)
- Валидация URL: только http/https, обязателен host (защита от SSRF)
- Таймаут по умолчанию: 30 секунд
- Все запросы асинхронные через `tokio`

### Тестирование
- Unit тесты в `#[cfg(test)]` модулях внутри файлов
- Integration тесты в `tests/integration_test.rs`
- Используй `#[tokio::test]` для async тестов
- Тесты должны проверять валидацию, но не делать реальные HTTP запросы (кроме integration)
- Для тестов используй `tokio-test` из dev-dependencies

### Builder pattern
- `ShikicrateClientBuilder` для гибкой конфигурации
- Методы builder возвращают `Self` для цепочки вызовов
- `build()` валидирует параметры и возвращает `Result<ShikicrateClient>`
- Builder должен иметь `Default` implementation

### Документация
- Все публичные методы, структуры и типы должны иметь doc comments
- Используй `# Примеры` секции в документации с `no_run` блоками
- Документируй все параметры, возвращаемые значения и возможные ошибки
- В doc comments используй русский язык (как в существующем коде)