""" BankAPI — внешний сервис для управления "картой" пользователя. Сейчас заглушка (mock), архитектура под настоящий REST. """ import random from datetime import datetime, timedelta from typing import Optional class BankAPIClient: """ Клиент для взаимодействия с Bank API. В будущем — HTTP-клиент к внешнему сервису. Сейчас — in-memory заглушка. """ def __init__(self, base_url: str = "http://bank-api:8000"): self.base_url = base_url # mock: user_id -> {balance, transactions} self._mock_balances: dict[int, float] = {} self._mock_txns: dict[int, list] = {} self._initial_balance = 1000.0 def _ensure_user(self, user_id: int): if user_id not in self._mock_balances: self._mock_balances[user_id] = self._initial_balance self._mock_txns[user_id] = [] async def get_balance(self, user_id: int) -> float: """Сколько денег на карте пользователя""" self._ensure_user(user_id) return self._mock_balances[user_id] async def transfer_to_site(self, user_id: int, amount: float, promo_code: Optional[str] = None) -> dict: """ Перевод с карты на баланс сайта. Возвращает: {success, amount, new_card_balance, promo_effect} """ self._ensure_user(user_id) if self._mock_balances[user_id] < amount: return {"success": False, "error": "Недостаточно средств на карте"} self._mock_balances[user_id] -= amount self._mock_txns[user_id].append({ "type": "card_to_site", "amount": amount, "promo": promo_code, "timestamp": datetime.utcnow().isoformat() }) return { "success": True, "amount": amount, "new_card_balance": self._mock_balances[user_id], "promo_effect": None } async def withdraw_to_card(self, user_id: int, amount: float) -> dict: """ Вывод с баланса сайта на карту. Возвращает: {success, amount, new_card_balance, fee} """ self._ensure_user(user_id) fee = round(amount * 0.10, 2) # 10% комиссия net = round(amount - fee, 2) self._mock_balances[user_id] += net self._mock_txns[user_id].append({ "type": "site_to_card", "gross": amount, "fee": fee, "net": net, "timestamp": datetime.utcnow().isoformat() }) return { "success": True, "amount": amount, "fee": fee, "net": net, "new_card_balance": self._mock_balances[user_id] } async def validate_promo(self, user_id: int, promo_code: str) -> dict: """ Проверяет промокод. Возвращает его эффект для перевода card->site. """ # Заглушка — реальная логика будет в PromoCode сервисе return { "valid": True, "promo_type": "card_to_site", "amount": 0, "luck_boost": 0, "ceiling_boost": 0 } async def get_transaction_history(self, user_id: int, limit: int = 50) -> list: """История транзакций по карте""" self._ensure_user(user_id) return self._mock_txns[user_id][-limit:] # Singleton bank_client = BankAPIClient()