Files
peikarband/docs/handbook.md
Ehsan.Asadi 8a924f6091
Some checks failed
CD - Build & Deploy / build-and-push (push) Has been cancelled
CD - Build & Deploy / package-helm (push) Has been cancelled
CD - Build & Deploy / deploy-staging (push) Has been cancelled
CD - Build & Deploy / deploy-production (push) Has been cancelled
CD - Build & Deploy / release (push) Has been cancelled
CI / test (3.11) (push) Has been cancelled
CI / test (3.12) (push) Has been cancelled
CI / security (push) Has been cancelled
[INIT-001] Initial project setup with Clean Architecture (feat)
- Implemented Clean Architecture with Domain, Application, Infrastructure, Presentation layers
- Added comprehensive project structure following SOLID principles
- Created Kubernetes deployment with Helm charts (HPA, PDB, NetworkPolicy)
- Configured ArgoCD for automated deployment (production + staging)
- Implemented CI/CD pipeline with GitHub Actions
- Added comprehensive documentation (handbook, architecture, coding standards)
- Configured PostgreSQL, Redis, Celery for backend services
- Created modern landing page with Persian fonts (Vazirmatn)
- Added Docker multi-stage build for production
- Configured development tools (pytest, black, flake8, mypy, isort)
- Added pre-commit hooks for code quality
- Implemented Makefile for common operations
2025-12-26 15:52:50 +03:30

903 lines
23 KiB
Markdown

# پروژه پیکربند - 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
```
<type>(<scope>): <subject>
<body>
<footer>
```
**Types**:
- feat: ویژگی جدید
- fix: رفع باگ
- docs: تغییرات مستندات
- style: فرمت‌بندی
- refactor: بازنویسی
- test: اضافه کردن تست
- chore: کارهای نگهداری
**Example**:
```
feat(auth): add two-factor authentication
- Implement TOTP-based 2FA
- Add QR code generation for authenticator apps
- Add backup codes feature
Closes #123
```
### 11.2 CHANGELOG.md
تمام تغییرات باید در CHANGELOG.md ثبت شود:
```markdown
# Changelog
## [Unreleased]
## [1.0.0] - 2025-01-24
### Added
- User authentication system
- Two-factor authentication
- Password reset functionality
### Changed
- Improved database schema
- Updated UI components
### Fixed
- Payment gateway timeout issue
- Email verification bug
```
---
## پیوست‌ها
### A. فایل‌های مهم
- `docs/architecture/`: معماری سیستم
- `docs/development/`: راهنمای توسعه
- `docs/changelog/`: تاریخچه تغییرات
- `docs/api/`: مستندات API
### B. لینک‌های مفید
- [Python PEP 8](https://pep8.org/)
- [Clean Architecture](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)
- [SOLID Principles](https://en.wikipedia.org/wiki/SOLID)
---
**این handbook باید همیشه به‌روز نگه داشته شود.**