# پروژه پیکربند - Handbook جامع **نسخه**: 1.0.0 **آخرین بروزرسانی**: 2025-01-24 **نویسنده**: تیم توسعه پیکربند --- ## فهرست مطالب 1. [معرفی پروژه](#1-معرفی-پروژه) 2. [معماری کلی](#2-معماری-کلی) 3. [قوانین و استانداردها](#3-قوانین-و-استانداردها) 4. [راه‌اندازی محیط توسعه](#4-راهاندازی-محیط-توسعه) 5. [ساختار پروژه](#5-ساختار-پروژه) 6. [Design Patterns](#6-design-patterns) 7. [Best Practices](#7-best-practices) 8. [Testing Strategy](#8-testing-strategy) 9. [Deployment Guide](#9-deployment-guide) 10. [Troubleshooting](#10-troubleshooting) 11. [مستندسازی تغییرات](#11-مستندسازی-تغییرات) --- ## 1. معرفی پروژه ### 1.1 هدف پیکربند یک پلتفرم جامع مدیریت هاستینگ و زیرساخت ابری است که شامل: - **هاستینگ وردپرس**: مدیریت حرفه‌ای سایت‌های WordPress - **فروش دامین**: ثبت و مدیریت دامین‌ها - **سرورهای اختصاصی**: VPS و Dedicated Servers - **خدمات DevOps**: مشاوره و پیاده‌سازی - **پنل مدیریت**: پنل کنترل سفارشی شبیه cPanel ### 1.2 تکنولوژی‌های استفاده شده | تکنولوژی | نسخه | کاربرد | |----------|------|--------| | Python | 3.11+ | زبان اصلی | | Reflex | 0.4.0 | Frontend/Backend Framework | | PostgreSQL | 14+ | Database اصلی | | Redis | 7+ | Cache & Sessions | | SQLAlchemy | 2.0+ | ORM | | Celery | 5.3+ | Task Queue | | pytest | 7.4+ | Testing | ### 1.3 اصول طراحی #### Clean Architecture پروژه بر اساس معماری تمیز طراحی شده که شامل 4 لایه اصلی است: 1. **Domain Layer**: منطق کسب‌وکار خالص 2. **Application Layer**: موارد استفاده (Use Cases) 3. **Infrastructure Layer**: جزئیات فنی 4. **Presentation Layer**: رابط کاربری #### SOLID Principles - **S**ingle Responsibility Principle - **O**pen/Closed Principle - **L**iskov Substitution Principle - **I**nterface Segregation Principle - **D**ependency Inversion Principle #### سایر اصول - **DRY**: Don't Repeat Yourself - **KISS**: Keep It Simple, Stupid - **YAGNI**: You Aren't Gonna Need It - **Convention over Configuration** --- ## 2. معماری کلی ### 2.1 نمای کلی لایه‌ها ``` ┌─────────────────────────────────────────┐ │ Presentation Layer (Reflex UI) │ │ ┌────────┐ ┌────────┐ ┌────────┐ │ │ │Landing │ │Dashboard│ │ Admin │ │ │ └────────┘ └────────┘ └────────┘ │ └──────────────────┬──────────────────────┘ │ ┌──────────────────┴──────────────────────┐ │ Application Layer (Use Cases) │ │ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │ │ │ Auth │ │Billing│ │Server│ │Ticket│ │ │ └──────┘ └──────┘ └──────┘ └──────┘ │ └──────────────────┬──────────────────────┘ │ ┌──────────────────┴──────────────────────┐ │ Domain Layer (Business Logic) │ │ ┌────────┐ ┌────────┐ ┌────────┐ │ │ │Entities│ │ Values │ │Services│ │ │ └────────┘ └────────┘ └────────┘ │ └──────────────────┬──────────────────────┘ │ ┌──────────────────┴──────────────────────┐ │ Infrastructure Layer (Technical) │ │ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ │ │ DB │ │Cache│ │ API │ │Tasks│ │ │ └─────┘ └─────┘ └─────┘ └─────┘ │ └─────────────────────────────────────────┘ ``` ### 2.2 جریان داده ``` User Request → Presentation → Application → Domain ↓ Infrastructure ← Application ← Domain Logic ↓ External APIs ``` ### 2.3 Layer های جزئی #### Domain Layer - **Entities**: موجودیت‌های اصلی (User, Service, Invoice, etc.) - **Value Objects**: اشیاء ارزشی (Email, Money, Phone) - **Domain Services**: منطق پیچیده دامین - **Enums**: مقادیر ثابت - **Exceptions**: خطاهای دامین #### Application Layer - **Use Cases**: موارد استفاده سیستم - **DTOs**: Data Transfer Objects - **Interfaces**: تعریف رابط‌های سرویس‌ها - **Validators**: اعتبارسنجی ورودی‌ها #### Infrastructure Layer - **Database**: Models و Repositories - **Cache**: Redis implementation - **External**: API های خارجی - **Tasks**: Background jobs - **Security**: Authentication & Authorization - **Logging**: Structured logging #### Presentation Layer - **Web**: Reflex components و pages - **API**: REST endpoints (optional) - **State**: Reflex state management --- ## 3. قوانین و استانداردها ### 3.1 Python Code Style (PEP 8) #### Naming Conventions ```python # Classes: PascalCase class UserService: pass class PaymentGateway: pass # Functions & Methods: snake_case def create_user(email: str) -> User: pass def process_payment(amount: Decimal) -> PaymentResult: pass # Constants: UPPER_SNAKE_CASE MAX_LOGIN_ATTEMPTS = 3 DEFAULT_TIMEOUT = 30 API_VERSION = "v1" # Private methods: _leading_underscore def _internal_helper(): pass # Protected: __double_underscore (name mangling) class BaseClass: def __private_method(self): pass # Variables: snake_case user_email = "test@example.com" total_amount = Decimal("100.00") ``` ### 3.2 Type Hints (الزامی) ```python from typing import Optional, List, Dict, Any, Union from decimal import Decimal # Function signatures def get_user_by_id(user_id: int) -> Optional[User]: pass def create_invoice( user_id: int, amount: Decimal, items: List[InvoiceItem] ) -> Invoice: pass # Return types def get_users(limit: int = 10) -> List[User]: pass def find_service(service_id: int) -> Optional[Service]: pass # Complex types def process_config(config: Dict[str, Any]) -> bool: pass UserOrNone = Optional[User] ServiceList = List[Service] ``` ### 3.3 Docstrings (Google Style - الزامی) ```python def create_user( email: str, password: str, full_name: str, phone: Optional[str] = None ) -> User: """Create a new user account. This function creates a new user in the system with the provided information. Password is automatically hashed before storage. Args: email: User's email address (must be unique) password: Plain text password (will be hashed) full_name: User's full name phone: Optional phone number Returns: User: Created user object Raises: EmailAlreadyExistsException: If email is already registered InvalidEmailException: If email format is invalid WeakPasswordException: If password doesn't meet requirements Example: >>> user = create_user( ... email="test@example.com", ... password="SecurePass123!", ... full_name="John Doe", ... phone="+989123456789" ... ) >>> print(user.id) 1 """ pass ``` ### 3.4 Import Order (با isort) ```python # 1. Standard library imports import os import sys from typing import Optional, List from decimal import Decimal from datetime import datetime # 2. Third-party imports import redis from sqlalchemy import Column, Integer, String from pydantic import BaseModel # 3. Local application imports from src.config.settings import settings from src.core.domain.entities.user import User from src.infrastructure.database.repositories.user_repository import UserRepository ``` ### 3.5 Error Handling ```python # ✅ GOOD: Specific exceptions try: user = user_repository.get_by_id(user_id) if not user: raise UserNotFoundException(f"User {user_id} not found") except DatabaseException as e: logger.error("database_error", error=str(e), user_id=user_id) raise except Exception as e: logger.critical("unexpected_error", error=str(e)) raise InfrastructureException("Internal server error") from e # ❌ BAD: Generic exceptions try: # code except: # Never do this! pass # ❌ BAD: Too broad try: # code except Exception: pass ``` ### 3.6 Logging Best Practices ```python import structlog logger = structlog.get_logger(__name__) # ✅ GOOD: Structured logging with context logger.info( "user_created", user_id=user.id, email=user.email, registration_source="web", ip_address=request.ip ) logger.error( "payment_failed", user_id=user.id, invoice_id=invoice.id, amount=str(invoice.amount), gateway="zarinpal", error_code=response.code, error_message=response.message ) # ❌ BAD: String concatenation logger.info("User " + str(user.id) + " created") ``` --- ## 4. راه‌اندازی محیط توسعه ### 4.1 پیش‌نیازها ```bash # Check Python version (3.11+) python --version # Check PostgreSQL (14+) psql --version # Check Redis (7+) redis-cli --version # Check Node.js (18+) node --version ``` ### 4.2 نصب وابستگی‌ها ```bash # Clone repository git clone https://github.com/yourusername/peikarband.git cd peikarband # Create virtual environment python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate # Install dependencies pip install -r requirements.txt pip install -r requirements-dev.txt # Install pre-commit hooks pre-commit install ``` ### 4.3 تنظیم Environment Variables ```bash # Copy example env file cp .env.example .env # Edit .env file nano .env # Required variables: # - DATABASE_URL # - REDIS_URL # - SECRET_KEY # - JWT_SECRET_KEY ``` ### 4.4 راه‌اندازی دیتابیس ```bash # Create database createdb peikarband # Or using psql psql -U postgres CREATE DATABASE peikarband; \q # Run migrations alembic upgrade head # (Optional) Seed database python scripts/seed_database.py ``` ### 4.5 اجرای پروژه ```bash # Development mode python -m reflex run # With auto-reload python -m reflex run --reload # Production mode python -m reflex run --env production ``` --- ## 5. ساختار پروژه ### 5.1 نمای کلی ``` peikarband/ ├── docs/ # Documentation ├── src/ # Source code ├── tests/ # Tests ├── scripts/ # Utility scripts ├── .github/workflows/ # CI/CD └── [config files] # Configuration ``` ### 5.2 src/ Structure ``` src/ ├── config/ # Configuration │ ├── settings.py # Main settings │ ├── database.py # DB config │ ├── cache.py # Redis config │ └── logging.py # Log config │ ├── core/ # Core business logic │ ├── domain/ # Domain layer │ │ ├── entities/ # Business entities │ │ ├── value_objects/ # Value objects │ │ ├── enums/ # Enumerations │ │ └── exceptions/ # Domain exceptions │ │ │ ├── application/ # Application layer │ │ ├── use_cases/ # Use cases │ │ ├── dto/ # DTOs │ │ ├── interfaces/ # Service interfaces │ │ └── validators/ # Validators │ │ │ └── utils/ # Core utilities │ ├── infrastructure/ # Infrastructure layer │ ├── database/ # Database implementation │ ├── cache/ # Cache implementation │ ├── external/ # External APIs │ ├── tasks/ # Background tasks │ ├── security/ # Security utilities │ └── logging/ # Logging setup │ ├── presentation/ # Presentation layer │ ├── web/ # Reflex web app │ │ ├── pages/ # Pages │ │ ├── components/ # Components │ │ ├── state/ # State management │ │ └── styles/ # Styling │ │ │ └── api/ # REST API (optional) │ └── shared/ # Shared code ├── events/ # Domain events └── messaging/ # Event bus ``` --- ## 6. Design Patterns ### 6.1 Repository Pattern ```python from abc import ABC, abstractmethod from typing import Optional, List # Interface (in core/application/interfaces/repositories/) class IUserRepository(ABC): @abstractmethod def get_by_id(self, user_id: int) -> Optional[User]: """Get user by ID.""" pass @abstractmethod def get_by_email(self, email: str) -> Optional[User]: """Get user by email.""" pass @abstractmethod def save(self, user: User) -> User: """Save or update user.""" pass @abstractmethod def delete(self, user_id: int) -> bool: """Delete user.""" pass # Implementation (in infrastructure/database/repositories/) class UserRepository(IUserRepository): def __init__(self, session: Session): self._session = session def get_by_id(self, user_id: int) -> Optional[User]: model = self._session.query(UserModel).filter_by(id=user_id).first() return self._to_entity(model) if model else None def save(self, user: User) -> User: model = self._to_model(user) self._session.add(model) self._session.commit() self._session.refresh(model) return self._to_entity(model) ``` ### 6.2 Unit of Work Pattern ```python from contextlib import contextmanager class UnitOfWork: """Manages database transactions.""" def __init__(self, session_factory): self.session_factory = session_factory self._session = None def __enter__(self): self._session = self.session_factory() self.users = UserRepository(self._session) self.services = ServiceRepository(self._session) return self def __exit__(self, exc_type, exc_val, exc_tb): if exc_type: self._session.rollback() else: self._session.commit() self._session.close() # Usage with UnitOfWork(SessionLocal) as uow: user = uow.users.get_by_id(1) user.email = "new@email.com" uow.users.save(user) # Automatically commits on success ``` ### 6.3 Factory Pattern ```python from abc import ABC, abstractmethod class ICloudProvider(ABC): @abstractmethod def create_server(self, config: ServerConfig) -> Server: pass class DigitalOceanProvider(ICloudProvider): def create_server(self, config: ServerConfig) -> Server: # Implementation pass class HetznerProvider(ICloudProvider): def create_server(self, config: ServerConfig) -> Server: # Implementation pass class CloudProviderFactory: @staticmethod def create(provider_type: str) -> ICloudProvider: providers = { "digitalocean": DigitalOceanProvider, "hetzner": HetznerProvider, "ovh": OVHProvider, } provider_class = providers.get(provider_type) if not provider_class: raise ValueError(f"Unknown provider: {provider_type}") return provider_class() # Usage provider = CloudProviderFactory.create("digitalocean") server = provider.create_server(config) ``` ### 6.4 Strategy Pattern ```python class PaymentStrategy(ABC): @abstractmethod def pay(self, amount: Decimal) -> PaymentResult: pass class ZarinpalPayment(PaymentStrategy): def pay(self, amount: Decimal) -> PaymentResult: # Zarinpal implementation pass class IdPayPayment(PaymentStrategy): def pay(self, amount: Decimal) -> PaymentResult: # IdPay implementation pass class PaymentProcessor: def __init__(self, strategy: PaymentStrategy): self._strategy = strategy def process(self, amount: Decimal) -> PaymentResult: return self._strategy.pay(amount) # Usage processor = PaymentProcessor(ZarinpalPayment()) result = processor.process(Decimal("100.00")) ``` --- ## 7. Best Practices ### 7.1 کد تمیز ```python # ✅ GOOD: Clear and simple def calculate_total_price(items: List[Item]) -> Decimal: """Calculate total price of items.""" return sum(item.price * item.quantity for item in items) # ❌ BAD: Too complex def calc(i): t = 0 for x in i: t += x[0] * x[1] return t ``` ### 7.2 Don't Repeat Yourself (DRY) ```python # ❌ BAD: Repetition def get_user_name(user_id: int) -> str: session = SessionLocal() user = session.query(User).filter_by(id=user_id).first() session.close() return user.name def get_user_email(user_id: int) -> str: session = SessionLocal() user = session.query(User).filter_by(id=user_id).first() session.close() return user.email # ✅ GOOD: Reusable def get_user(user_id: int) -> User: with get_db_context() as session: return session.query(User).filter_by(id=user_id).first() def get_user_name(user_id: int) -> str: user = get_user(user_id) return user.name if user else None ``` ### 7.3 Single Responsibility ```python # ❌ BAD: Multiple responsibilities class User: def save(self): # Saves to database pass def send_email(self): # Sends email pass def calculate_discount(self): # Business logic pass # ✅ GOOD: Separated class User: # Just entity pass class UserRepository: def save(self, user: User): pass class EmailService: def send_welcome_email(self, user: User): pass class DiscountService: def calculate_user_discount(self, user: User): pass ``` --- ## 8. Testing Strategy ### 8.1 Test Pyramid ``` /\ /E2E\ 10% - End-to-End Tests /------\ /Integr-\ 20% - Integration Tests /----------\ / Unit \ 70% - Unit Tests ``` ### 8.2 Unit Test Example ```python import pytest from decimal import Decimal class TestInvoiceCalculation: def test_calculate_total_with_items(self): # Arrange items = [ InvoiceItem(name="Item 1", price=Decimal("10.00"), quantity=2), InvoiceItem(name="Item 2", price=Decimal("5.00"), quantity=3), ] invoice = Invoice(items=items) # Act total = invoice.calculate_total() # Assert assert total == Decimal("35.00") def test_calculate_total_empty(self): invoice = Invoice(items=[]) assert invoice.calculate_total() == Decimal("0.00") ``` ### 8.3 Integration Test Example ```python @pytest.mark.integration class TestUserRepository: def test_save_and_retrieve_user(self, db_session): # Arrange repository = UserRepository(db_session) user = User(email="test@example.com", name="Test User") # Act saved_user = repository.save(user) retrieved_user = repository.get_by_id(saved_user.id) # Assert assert retrieved_user is not None assert retrieved_user.email == "test@example.com" ``` --- ## 9. Deployment Guide ### 9.1 Production Checklist - [ ] همه تست‌ها pass شدند - [ ] Code coverage بالای 80% - [ ] Security audit انجام شد - [ ] Environment variables set شدند - [ ] Database migrations اجرا شدند - [ ] Monitoring setup شد - [ ] Backup strategy تعریف شد - [ ] SSL certificates نصب شدند - [ ] Firewall rules تنظیم شدند --- ## 10. Troubleshooting ### 10.1 مشکلات رایج #### Database Connection Error **Problem**: `sqlalchemy.exc.OperationalError` **Solution**: 1. Check DATABASE_URL in .env 2. Verify PostgreSQL is running 3. Check firewall rules 4. Test connection: `psql $DATABASE_URL` #### Redis Connection Error **Problem**: `redis.exceptions.ConnectionError` **Solution**: 1. Check REDIS_URL in .env 2. Verify Redis is running: `redis-cli ping` 3. Check Redis password if set --- ## 11. مستندسازی تغییرات ### 11.1 Commit Message Format ``` ():