# 🀝 Contributing to Remnawave Bedolaga Bot Бпасибо Π·Π° интСрСс ΠΊ Ρ€Π°Π·Π²ΠΈΡ‚ΠΈΡŽ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°! Π­Ρ‚ΠΎΡ‚ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ содСрТит ΠΏΡ€Π°Π²ΠΈΠ»Π° ΠΈ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΈ для ΠΊΠΎΠ½Ρ‚Ρ€ΠΈΠ±ΡŒΡŽΡ‚ΠΎΡ€ΠΎΠ². ## πŸ“‹ Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠ°Π½ΠΈΠ΅ - [КодСкс повСдСния](#-кодСкс-повСдСния) - [Как ΠΏΠΎΠΌΠΎΡ‡ΡŒ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ](#-ΠΊΠ°ΠΊ-ΠΏΠΎΠΌΠΎΡ‡ΡŒ-ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ) - [Настройка срСды Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ](#-настройка-срСды-Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ) - [Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚Ρ‹ ΠΊΠΎΠ΄Π°](#-стандарты-ΠΊΠΎΠ΄Π°) - [Π Π°Π±ΠΎΡ‚Π° с Git](#-Ρ€Π°Π±ΠΎΡ‚Π°-с-git) - [ВСстированиС](#-тСстированиС) - [ΠŸΡ€ΠΎΡ†Π΅ΡΡ Ρ€Π΅Π²ΡŒΡŽ](#-процСсс-Ρ€Π΅Π²ΡŒΡŽ) - [ДокумСнтация](#-докумСнтация) ## πŸ“œ КодСкс повСдСния ### ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΡ‹ - **Π£Π²Π°ΠΆΠ΅Π½ΠΈΠ΅** - ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅ΡΡŒ ΠΊ участникам ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° с ΡƒΠ²Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ - **ΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒ** - ΠΏΡ€Π΅Π΄Π»Π°Π³Π°ΠΉΡ‚Π΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ, Π° Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊΡ€ΠΈΡ‚ΠΈΠΊΡƒ - **ΠžΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΡΡ‚ΡŒ** - Π±ΡƒΠ΄ΡŒΡ‚Π΅ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ ΠΊ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠΉ связи ΠΈ Π½ΠΎΠ²Ρ‹ΠΌ идСям - **ΠŸΡ€ΠΎΡ„Π΅ΡΡΠΈΠΎΠ½Π°Π»ΠΈΠ·ΠΌ** - ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΠΉΡ‚Π΅ высокий ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ обсуТдСний ### НСдопустимоС ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ - ΠžΡΠΊΠΎΡ€Π±Π»Π΅Π½ΠΈΡ ΠΈ Π»ΠΈΡ‡Π½Ρ‹Π΅ Π°Ρ‚Π°ΠΊΠΈ - Π‘ΠΏΠ°ΠΌ ΠΈ ΠΎΡ„Ρ„-Ρ‚ΠΎΠΏΠΈΠΊ сообщСния - ΠŸΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΡ ΠΏΡ€ΠΈΠ²Π°Ρ‚Π½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ - Π›ΡŽΠ±Ρ‹Π΅ Ρ„ΠΎΡ€ΠΌΡ‹ дискриминации ## πŸš€ Как ΠΏΠΎΠΌΠΎΡ‡ΡŒ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ ### πŸ› БообщСния ΠΎ Π±Π°Π³Π°Ρ… ΠŸΠ΅Ρ€Π΅Π΄ созданиСм issue ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅: - [ ] Аналогичная ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π½Π΅ Π±Ρ‹Π»Π° описана Ρ€Π°Π½Π΅Π΅ - [ ] Π’Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ Π±ΠΎΡ‚Π° - [ ] ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° воспроизводится ΡΡ‚Π°Π±ΠΈΠ»ΡŒΠ½ΠΎ **Π¨Π°Π±Π»ΠΎΠ½ для Π±Π°Π³Ρ€Π΅ΠΏΠΎΡ€Ρ‚Π°:** ```markdown ## πŸ› ОписаниС Π±Π°Π³Π° ΠšΡ€Π°Ρ‚ΠΊΠΎΠ΅ описаниС ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ ## πŸ”„ Π¨Π°Π³ΠΈ воспроизвСдСния 1. ΠŸΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ ΠΊ '...' 2. ΠΠ°ΠΆΠ°Ρ‚ΡŒ Π½Π° '...' 3. Π£Π²ΠΈΠ΄Π΅Ρ‚ΡŒ ΠΎΡˆΠΈΠ±ΠΊΡƒ ## βœ… ОТидаСмоС ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π§Ρ‚ΠΎ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΡ‚ΠΈ ## ❌ ЀактичСскоС ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π§Ρ‚ΠΎ ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»ΠΎ Π½Π° самом Π΄Π΅Π»Π΅ ## 🌍 ΠžΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠ΅ - ВСрсия Π±ΠΎΡ‚Π°: [Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, 1.0.0] - Python вСрсия: [Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, 3.11.7] - ОБ: [Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ubuntu 22.04] - ВСрсия Docker: [Ссли ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ] ## πŸ“‹ Π›ΠΎΠ³ΠΈ ``` Π’ΡΡ‚Π°Π²ΡŒΡ‚Π΅ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ Π»ΠΎΠ³ΠΈ ``` ## πŸ“· Π‘ΠΊΡ€ΠΈΠ½ΡˆΠΎΡ‚Ρ‹ Если ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌΠΎ, Π΄ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ ΡΠΊΡ€ΠΈΠ½ΡˆΠΎΡ‚Ρ‹ ``` ### πŸ’‘ ΠŸΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Π»Π΅ΠΉΠ±Π» `enhancement` ΠΈ ΠΎΠΏΠΈΡˆΠΈΡ‚Π΅: - **ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ**, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Ρ€Π΅ΡˆΠ°Π΅Ρ‚ функция - **ΠŸΡ€Π΅Π΄Π»Π°Π³Π°Π΅ΠΌΠΎΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅** - **ΠΠ»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Ρ‹**, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²Ρ‹ рассматривали - **Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ** ΠΈ контСкст ### πŸ“ Π£Π»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΠ΅ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ - Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΎΠΏΠ΅Ρ‡Π°Ρ‚ΠΎΠΊ - Π”ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ² - ΠŸΠ΅Ρ€Π΅Π²ΠΎΠ΄ Π½Π° Π΄Ρ€ΡƒΠ³ΠΈΠ΅ языки - Π£Π»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΠ΅ структуры ## πŸ›  Настройка срСды Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ### ВрСбования - Python 3.11+ - Docker ΠΈ Docker Compose - Git - PostgreSQL 15+ (ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ для локальной Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ) - Redis (ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ для локальной Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ) ### Установка 1. **Π€ΠΎΡ€ΠΊΠ½ΠΈΡ‚Π΅ ΠΈ ΠΊΠ»ΠΎΠ½ΠΈΡ€ΡƒΠΉΡ‚Π΅ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ:** ```bash git clone https://github.com/Fr1ngg/remnawave-bedolaga-telegram-bot.git cd remnawave-bedolaga-telegram-bot ``` 2. **Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠ΅ ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠ΅:** ```bash python -m venv venv source venv/bin/activate # Linux/Mac # ΠΈΠ»ΠΈ venv\Scripts\activate # Windows ``` 3. **УстановитС зависимости:** ```bash pip install -r requirements.txt pip install -r requirements-dev.txt # Ссли Π΅ΡΡ‚ΡŒ dev зависимости ``` 4. **НастройтС ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠ΅:** ```bash cp .env.example .env # ΠžΡ‚Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΡƒΠΉΡ‚Π΅ .env Ρ„Π°ΠΉΠ» с вашими настройками ``` 5. **ЗапуститС Ρ‡Π΅Ρ€Π΅Π· Docker (рСкомСндуСтся):** ```bash docker compose up -d postgres redis python main.py ``` ### Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° ``` bedolaga_bot/ β”œβ”€β”€ app/ # Основной ΠΊΠΎΠ΄ прилоТСния β”‚ β”œβ”€β”€ handlers/ # ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ сообщСний β”‚ β”œβ”€β”€ services/ # БизнСс-Π»ΠΎΠ³ΠΈΠΊΠ° β”‚ β”œβ”€β”€ database/ # МодСли ΠΈ CRUD ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ β”‚ β”œβ”€β”€ utils/ # Π£Ρ‚ΠΈΠ»ΠΈΡ‚Ρ‹ β”‚ β”œβ”€β”€ middlewares/ # Middleware β”‚ └── external/ # Π’Π½Π΅ΡˆΠ½ΠΈΠ΅ API β”œβ”€β”€ migrations/ # ΠœΠΈΠ³Ρ€Π°Ρ†ΠΈΠΈ Π‘Π” (Ссли Π½ΡƒΠΆΠ½Ρ‹) β”œβ”€β”€ tests/ # ВСсты (ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΏΡ€ΠΈ нСобходимости) β”œβ”€β”€ docs/ # ДокумСнтация └── requirements.txt # Зависимости ``` ## 🎨 Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚Ρ‹ ΠΊΠΎΠ΄Π° ### Python ΡΡ‚ΠΈΠ»ΡŒ ΠœΡ‹ слСдуСм **PEP 8** с Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡΠΌΠΈ: ```python # βœ… Π₯ΠΎΡ€ΠΎΡˆΠΎ async def get_user_subscription(user_id: int) -> Optional[Subscription]: """ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ Π°ΠΊΡ‚ΠΈΠ²Π½ΡƒΡŽ подписку ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ.""" async with get_session() as session: result = await session.execute( select(Subscription) .where(Subscription.user_id == user_id) .where(Subscription.is_active == True) ) return result.scalar_one_or_none() # ❌ ΠŸΠ»ΠΎΡ…ΠΎ async def getUserSub(uid): session = get_session() sub = session.query(Subscription).filter(Subscription.user_id==uid,Subscription.is_active==True).first() return sub ``` ### ΠŸΡ€Π°Π²ΠΈΠ»Π° имСнования - **Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅**: `snake_case` - **ΠšΠ»Π°ΡΡΡ‹**: `PascalCase` - **ΠšΠΎΠ½ΡΡ‚Π°Π½Ρ‚Ρ‹**: `UPPER_CASE` - **ΠŸΡ€ΠΈΠ²Π°Ρ‚Π½Ρ‹Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹**: `_leading_underscore` ### Випизация ΠžΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ type hints: ```python from typing import Optional, List, Dict, Any async def create_subscription( user_id: int, duration_days: int, traffic_limit_gb: Optional[int] = None ) -> Subscription: """Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ Π½ΠΎΠ²ΡƒΡŽ подписку.""" # implementation ``` ### ДокумСнтация ΠΊΠΎΠ΄Π° ```python async def calculate_subscription_price( period_days: int, traffic_gb: int, devices_count: int, servers_count: int ) -> int: """ РассчитываСт ΡΡ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ подписки. Args: period_days: ΠŸΠ΅Ρ€ΠΈΠΎΠ΄ подписки Π² днях traffic_gb: Π›ΠΈΠΌΠΈΡ‚ Ρ‚Ρ€Π°Ρ„ΠΈΠΊΠ° Π² Π“Π‘ (0 = Π±Π΅Π·Π»ΠΈΠΌΠΈΡ‚) devices_count: ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ устройств servers_count: ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ сСрвСров Returns: Π‘Ρ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ Π² ΠΊΠΎΠΏΠ΅ΠΉΠΊΠ°Ρ… Raises: ValueError: Если ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Ρ‹ Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ """ # implementation ``` ### ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ошибок ```python # βœ… Π₯ΠΎΡ€ΠΎΡˆΠΎ try: subscription = await subscription_service.create_subscription(user_id, data) await message.answer("βœ… Подписка создана ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ!") except RemnaWaveAPIError as e: logger.error(f"RemnaWave API error: {e}") await message.answer("❌ Ошибка ΠΏΡ€ΠΈ создании подписки. ΠŸΠΎΠΏΡ€ΠΎΠ±ΡƒΠΉΡ‚Π΅ ΠΏΠΎΠ·ΠΆΠ΅.") except ValidationError as e: logger.warning(f"Validation error: {e}") await message.answer("❌ НСкоррСктныС Π΄Π°Π½Π½Ρ‹Π΅ для создания подписки.") # ❌ ΠŸΠ»ΠΎΡ…ΠΎ try: subscription = await subscription_service.create_subscription(user_id, data) await message.answer("βœ… Подписка создана ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ!") except: await message.answer("Ошибка") ``` ### Π›ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ```python import logging logger = logging.getLogger(__name__) # Π£Ρ€ΠΎΠ²Π½ΠΈ логирования logger.debug("Π”Π΅Ρ‚Π°Π»ΡŒΠ½Π°Ρ информация для ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ") logger.info("ΠžΠ±Ρ‰Π°Ρ информация ΠΎ Ρ€Π°Π±ΠΎΡ‚Π΅") logger.warning("ΠŸΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ ΠΎ ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠΉ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ΅") logger.error("Ошибка, которая Π½Π΅ ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ") logger.critical("ΠšΡ€ΠΈΡ‚ΠΈΡ‡Π΅ΡΠΊΠ°Ρ ошибка") ``` ## πŸ”„ Π Π°Π±ΠΎΡ‚Π° с Git ### Π’Π΅Ρ‚ΠΊΠΈ - `main` - ΡΡ‚Π°Π±ΠΈΠ»ΡŒΠ½Π°Ρ вСрсия - `dev` - Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½ΠΎΠ²Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ### ΠšΠΎΠΌΠΌΠΈΡ‚Ρ‹ Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ [Conventional Commits](https://www.conventionalcommits.org/): ```bash # Π’ΠΈΠΏΡ‹ ΠΊΠΎΠΌΠΌΠΈΡ‚ΠΎΠ² feat: Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ CryptoBot ΠΏΠ»Π°Ρ‚Π΅ΠΆΠ΅ΠΉ fix: ΠΈΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ ΠΎΡˆΠΈΠ±ΠΊΡƒ с расчСтом Ρ†Π΅Π½Ρ‹ подписки docs: ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ ΠΏΠΎ настройкС style: ΠΈΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠΎΠ΄Π° refactor: Ρ€Π΅Ρ„Π°ΠΊΡ‚ΠΎΡ€ΠΈΠ½Π³ сСрвиса ΠΏΠ»Π°Ρ‚Π΅ΠΆΠ΅ΠΉ test: Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ тСсты для subscription_service chore: ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ зависимости # ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ git commit -m "feat(payments): Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ YooKassa webhook" git commit -m "fix(subscription): ΠΈΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ расчСт стоимости устройств" git commit -m "docs(readme): ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΈΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡŽ ΠΏΠΎ установкС" ``` ### Pull Request процСсс 1. **Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ Π²Π΅Ρ‚ΠΊΡƒ** ΠΎΡ‚ `dev`: ```bash git checkout develop git pull origin develop git checkout -b feature/new-payment-method ``` 2. **Π Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°ΠΉΡ‚Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ** с соблюдСниСм стандартов 3. **ΠŸΡ€ΠΎΡ‚Π΅ΡΡ‚ΠΈΡ€ΡƒΠΉΡ‚Π΅** измСнСния локально 4. **Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ Pull Request** с описаниСм: ```markdown ## πŸ“ ОписаниС ΠšΡ€Π°Ρ‚ΠΊΠΎΠ΅ описаниС ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ ## 🎯 ΠœΠΎΡ‚ΠΈΠ²Π°Ρ†ΠΈΡ ΠŸΠΎΡ‡Π΅ΠΌΡƒ эти измСнСния Π½ΡƒΠΆΠ½Ρ‹? ## πŸ”§ Π’ΠΈΠΏ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ - [ ] Bug fix (исправлСниС) - [ ] New feature (новая функция) - [ ] Breaking change (Π»ΠΎΠΌΠ°ΡŽΡ‰ΠΈΠ΅ измСнСния) - [ ] Documentation update (ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ) ## βœ… ЧСклист - [ ] Код соотвСтствуСт стандартам ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° - [ ] Π”ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹/ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½Ρ‹ тСсты - [ ] ДокумСнтация ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½Π° - [ ] ΠŸΡ€ΠΎΠ²Π΅Ρ€Π΅Π½Π° Ρ€Π°Π±ΠΎΡ‚Π° Π² Docker - [ ] ΠŸΡ€ΠΎΠ²Π΅Ρ€Π΅Π½Π° ΡΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒ с ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ API ## πŸ§ͺ ВСстированиС Как Ρ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Π»ΠΈΡΡŒ измСнСния: - [ ] Π›ΠΎΠΊΠ°Π»ΡŒΠ½ΠΎΠ΅ тСстированиС - [ ] ВСстированиС с Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹ΠΌ Remnawave API - [ ] ВСстированиС ΠΏΠ»Π°Ρ‚Π΅ΠΆΠ½Ρ‹Ρ… систСм ``` ## πŸ§ͺ ВСстированиС ### Π›ΠΎΠΊΠ°Π»ΡŒΠ½ΠΎΠ΅ тСстированиС ```bash # Запуск с тСстовой Π±Π°Π·ΠΎΠΉ export DATABASE_URL="sqlite:///test.db" export BOT_TOKEN="test_token" python main.py ``` ### ВСстированиС ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² ```python # tests/test_subscription_service.py import pytest from app.services.subscription_service import SubscriptionService @pytest.mark.asyncio async def test_calculate_price(): price = await SubscriptionService.calculate_subscription_price( period_days=30, traffic_gb=100, devices_count=3, servers_count=1 ) assert price > 0 assert isinstance(price, int) ``` ### Integration тСсты ВСстируйтС ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡŽ с: - Remnawave API (с тСстовыми Π΄Π°Π½Π½Ρ‹ΠΌΠΈ) - Π‘Π°Π·ΠΎΠΉ Π΄Π°Π½Π½Ρ‹Ρ… - ΠŸΠ»Π°Ρ‚Π΅ΠΆΠ½Ρ‹ΠΌΠΈ систСмами (sandbox Ρ€Π΅ΠΆΠΈΠΌ) ## πŸ‘€ ΠŸΡ€ΠΎΡ†Π΅ΡΡ Ρ€Π΅Π²ΡŒΡŽ ### ВрСбования для Ρ€Π΅Π²ΡŒΡŽΠ΅Ρ€Π° - ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ соотвСтствиС стандартам ΠΊΠΎΠ΄Π° - Π£Π±Π΅Π΄ΠΈΡ‚ΡŒΡΡ Π² работоспособности - ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ (особСнно для ΠΏΠ»Π°Ρ‚Π΅ΠΆΠ½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ) - ΠžΡ†Π΅Π½ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ - ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ ΡΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒ с ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ API ### ВрСбования для Π°Π²Ρ‚ΠΎΡ€Π° - ΠžΡ‚Π²Π΅Ρ‚ΠΈΡ‚ΡŒ Π½Π° всС ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ - Π˜ΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ замСчания - ΠžΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ ΠΏΡ€ΠΈ нСобходимости - Π£Π±Π΅Π΄ΠΈΡ‚ΡŒΡΡ Π² ΠΏΡ€ΠΎΡ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠΈ всСх ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΎΠΊ ## πŸ“š ДокумСнтация ### ОбновлСниС Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ ΠŸΡ€ΠΈ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΈ Π½ΠΎΠ²Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ обновляйтС: - `README.md` - Ссли измСнился API ΠΈΠ»ΠΈ конфигурация - ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ Π² ΠΊΠΎΠ΄Π΅ - ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ использования - Changelog (Ссли Π΅ΡΡ‚ΡŒ) ### Π‘Ρ‚ΠΈΠ»ΡŒ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ - Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ясный ΠΈ понятный язык - ДобавляйтС ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ ΠΊΠΎΠ΄Π° - Π£ΠΊΠ°Π·Ρ‹Π²Π°ΠΉΡ‚Π΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ ошибки ΠΈ ΠΈΡ… Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ - Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ эмодзи для ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΡ читаСмости ## 🏷 Π›Π΅ΠΉΠ±Π»Ρ‹ Issues ΠΈ PR ### ΠŸΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ - `priority:high` - высокий ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ - `priority:medium` - срСдний ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ - `priority:low` - Π½ΠΈΠ·ΠΊΠΈΠΉ ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ ### Π’ΠΈΠΏ - `bug` - ошибка - `enhancement` - ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΠ΅ - `feature` - новая функция - `documentation` - докумСнтация - `question` - вопрос ### ΠžΠ±Π»Π°ΡΡ‚ΡŒ - `payments` - ΠΏΠ»Π°Ρ‚Π΅ΠΆΠ½Ρ‹Π΅ систСмы - `api` - Remnawave API - `database` - Π±Π°Π·Π° Π΄Π°Π½Π½Ρ‹Ρ… - `ui/ux` - интСрфСйс ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ - `admin` - Π°Π΄ΠΌΠΈΠ½ панСль ## πŸ” Π‘Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ ### БообщСния ΠΎ уязвимостях Для сообщСний ΠΎ критичСских уязвимостях бСзопасности: - Π‘Π²ΡΠΆΠΈΡ‚Π΅ΡΡŒ с [@fringg](https://t.me/fringg) Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ - НС создавайтС ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹Π΅ issues для уязвимостСй - Π”Π°ΠΉΡ‚Π΅ врСмя Π½Π° исправлСниС ΠΏΠ΅Ρ€Π΅Π΄ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΌ раскрытиСм ### Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΈ ΠΏΠΎ бСзопасности - Никогда Π½Π΅ ΠΊΠΎΠΌΠΌΠΈΡ‚ΡŒΡ‚Π΅ API ΠΊΠ»ΡŽΡ‡ΠΈ ΠΈ ΠΏΠ°Ρ€ΠΎΠ»ΠΈ - Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ окруТСния для Ρ‡ΡƒΠ²ΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… - Π’Π°Π»ΠΈΠ΄ΠΈΡ€ΡƒΠΉΡ‚Π΅ всС ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Π΅ - Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ HTTPS для всСх Π²Π½Π΅ΡˆΠ½ΠΈΡ… запросов ## πŸ“ž ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎΠΌΠΎΡ‰ΠΈ ### ΠšΠ°Π½Π°Π»Ρ‹ связи - **πŸ’¬ Telegram Group:** [Bedolaga Chat](https://t.me/+wTdMtSWq8YdmZmVi) - ΠΎΠ±Ρ‰ΠΈΠ΅ вопросы - **πŸ› GitHub Issues:** ВСхничСскиС вопросы ΠΈ Π±Π°Π³ΠΈ - **πŸ“§ ΠŸΡ€ΡΠΌΠΎΠΉ ΠΊΠΎΠ½Ρ‚Π°ΠΊΡ‚:** [@fringg](https://t.me/fringg) - Ρ‚ΠΎΠ»ΡŒΠΊΠΎ критичСскиС вопросы ### Часто Π·Π°Π΄Π°Π²Π°Π΅ΠΌΡ‹Π΅ вопросы **Q: Как Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ Π»ΠΎΠΊΠ°Π»ΡŒΠ½ΡƒΡŽ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ Π±Π΅Π· Docker?** A: УстановитС PostgreSQL ΠΈ Redis локально, ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚Π΅ DATABASE_URL ΠΈ REDIS_URL Π² .env **Q: МоТно Π»ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ SQLite для Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ?** A: Π”Π°, установитС DATABASE_MODE=sqlite Π² .env **Q: Как Ρ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ»Π°Ρ‚Π΅ΠΆΠ½Ρ‹Π΅ систСмы?** A: Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ тСстовыС/sandbox Ρ€Π΅ΠΆΠΈΠΌΡ‹ ΠΏΠ»Π°Ρ‚Π΅ΠΆΠ½Ρ‹Ρ… систСм **Q: Π§Ρ‚ΠΎ Π΄Π΅Π»Π°Ρ‚ΡŒ, Ссли тСсты Π½Π΅ проходят?** A: ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ .env ΠΈ ΡƒΠ±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ всС сСрвисы Π·Π°ΠΏΡƒΡ‰Π΅Π½Ρ‹ ## πŸ“‹ ЧСклист для ΠΊΠΎΠ½Ρ‚Ρ€ΠΈΠ±ΡŒΡŽΡ‚ΠΎΡ€ΠΎΠ² ΠŸΠ΅Ρ€Π΅Π΄ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΎΠΉ PR ΡƒΠ±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ: - [ ] βœ… Код соотвСтствуСт стандартам ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° - [ ] πŸ“ Π”ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ ΠΈ docstrings - [ ] πŸ§ͺ Π€ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ протСстирована - [ ] πŸ“š ДокумСнтация ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½Π° - [ ] πŸ”’ НСт Ρ‡ΡƒΠ²ΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… Π² ΠΊΠΎΠ΄Π΅ - [ ] 🐳 ИзмСнСния Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ Π² Docker - [ ] πŸ“‹ PR создан с ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Ρ‹ΠΌ описаниСм - [ ] 🏷 ΠŸΡ€ΠΎΡΡ‚Π°Π²Π»Π΅Π½Ρ‹ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ Π»Π΅ΠΉΠ±Π»Ρ‹ ## πŸŽ‰ Благодарности Бпасибо всСм, ΠΊΡ‚ΠΎ вносит Π²ΠΊΠ»Π°Π΄ Π² Ρ€Π°Π·Π²ΠΈΡ‚ΠΈΠ΅ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°! Π’Π°ΡˆΠ° ΠΏΠΎΠΌΠΎΡ‰ΡŒ Π΄Π΅Π»Π°Π΅Ρ‚ Bedolaga Bot Π»ΡƒΡ‡ΡˆΠ΅ для всСго сообщСства. --- **Made with ❀️ by community**