# Сквозная корзина (Persistent Cart) для Remnawave Bedolaga Telegram Bot

## Общее описание

Система сквозной корзины позволяет пользователям продолжить оформление подписки после пополнения баланса, не теряя уже выбранные параметры (период, трафик, серверы, устройства и т.д.).

## Архитектура

### 1. Сервис корзины (UserCartService)

Расположение: `app/services/user_cart_service.py`

Использует Redis для хранения данных корзины между сессиями пользователя.

#### Основные методы:
- `save_user_cart(user_id, cart_data, ttl)` - сохраняет корзину пользователя
- `get_user_cart(user_id)` - возвращает данные корзины пользователя
- `delete_user_cart(user_id)` - удаляет корзину пользователя
- `has_user_cart(user_id)` - проверяет наличие корзины у пользователя

### 2. Обновленные обработчики подписки

Расположение: `app/handlers/subscription/purchase.py`

#### Основные функции:
- `save_cart_and_redirect_to_topup` - сохраняет текущую корзину в Redis при недостатке средств и перенаправляет к пополнению
- `return_to_saved_cart` - восстанавливает параметры подписки из Redis и продолжает процесс оформления
- `clear_saved_cart` - очищает сохраненную корзину

### 3. Обновленные клавиатуры

Расположение: `app/keyboards/inline.py`

#### Основные изменения:
- `get_insufficient_balance_keyboard` - добавлена поддержка флага `has_saved_cart` для отображения кнопки возврата к оформлению
- `get_insufficient_balance_keyboard_with_cart` - обновлена для использования флага `has_saved_cart`
- `get_main_menu_keyboard` - добавлен параметр `has_saved_cart` для отображения кнопки возврата к оформлению

### 4. Интеграция с главным меню

Расположение: `app/handlers/menu.py`

Функция `show_main_menu` теперь проверяет наличие сохраненной корзины и отображает соответствующую кнопку.

## Использование

### Сохранение корзины

Когда пользователь не может завершить покупку из-за недостатка средств, его параметры автоматически сохраняются в Redis с TTL 1 час.

### Восстановление корзины

При пополнении баланса пользователь может вернуться к оформлению подписки, нажав на кнопку "Вернуться к оформлению подписки" или через главное меню, если у него есть сохраненная корзина.

### Очистка корзины

Корзина автоматически очищается после успешного оформления подписки или по запросу пользователя.

## Тестирование

Тесты расположены в:
- `tests/test_user_cart_service.py` - модульные тесты сервиса корзины
- `tests/test_subscription_cart_integration.py` - интеграционные тесты

## Безопасность

- Данные корзины хранятся в Redis с ограниченным временем жизни (TTL)
- Используется идентификатор пользователя для изоляции данных
- Корзина автоматически очищается после успешной покупки

## Масштабируемость

- Использование Redis позволяет системе масштабироваться на несколько инстансов бота
- TTL автоматически очищает старые данные
- Нагрузка на Redis минимальна благодаря короткому времени хранения данных