refactor: complete project restructure - clean and professional
🎯 New Structure: - landing/ (root) - Only Makefile, .gitignore, .woodpecker.yml - helm/ - Kubernetes deployment (with argocd inside chart) - docker/ - Docker build configs - peikarband/ - All source code (src, tests, assets, config, tools, docs) ✅ Changes: - Moved Docker files: build/docker/ → docker/ - Moved Helm charts: deploy/helm/ → helm/ - Moved ArgoCD: deploy/argocd/ → helm/peikarband/argocd/ - Moved all source code to peikarband/ - Removed duplicate files (7 files) - Removed old empty directories 🐳 Docker Fixes: - Added npm retry configuration (fetch-retry-mintimeout, etc.) - Added 3-attempt retry mechanism for reflex export - Fixed ECONNREFUSED errors - Updated paths for new structure 📦 Config Updates: - Makefile: Updated all paths (docker/, helm/, peikarband/) - .woodpecker.yml: Updated dockerfile and context paths - .gitignore: Updated data/ path 🧪 Tests: - ✓ Helm lint passes - ✓ All paths validated - ✓ Structure verified 📊 Result: - Before: 20+ files in root, scattered structure - After: 3 files + 3 directories, clean and organized - Production-ready ✨
This commit is contained in:
@@ -1,360 +0,0 @@
|
||||
# ساختار پروژه پیکربند - Landing Page
|
||||
|
||||
## 📁 ساختار کلی (بازسازی شده)
|
||||
|
||||
```
|
||||
peikarband-landing/
|
||||
├── README.md # Main project documentation
|
||||
├── requirements.txt # Production dependencies
|
||||
├── requirements-dev.txt # Development dependencies
|
||||
├── Makefile # Build automation commands
|
||||
├── rxconfig.py # Reflex config loader (imports from config/)
|
||||
├── .gitignore
|
||||
│
|
||||
├── build/ # 🔨 همه چیز مربوط به Build
|
||||
│ ├── docker/
|
||||
│ │ ├── Dockerfile # Main application Dockerfile
|
||||
│ │ ├── Dockerfile.base # Base image (reference)
|
||||
│ │ ├── docker-compose.yml # Local development setup
|
||||
│ │ └── .dockerignore
|
||||
│ └── ci/
|
||||
│ └── woodpecker.yml # CI/CD pipeline configuration
|
||||
│
|
||||
├── deploy/ # 🚀 همه چیز مربوط به Deployment
|
||||
│ ├── helm/
|
||||
│ │ └── peikarband/ # Helm chart
|
||||
│ │ ├── Chart.yaml
|
||||
│ │ ├── templates/ # K8s resource templates
|
||||
│ │ ├── values.yaml # Default values
|
||||
│ │ ├── values-production.yaml
|
||||
│ │ └── values-staging.yaml
|
||||
│ ├── kubernetes/
|
||||
│ │ └── secrets-template.yaml # K8s manifest templates
|
||||
│ └── argocd/ # ArgoCD GitOps configs
|
||||
│ ├── application.yaml
|
||||
│ ├── application-staging.yaml
|
||||
│ ├── README.md
|
||||
│ └── secrets/
|
||||
│
|
||||
├── config/ # ⚙️ همه Configuration Files
|
||||
│ ├── alembic.ini # Database migration config
|
||||
│ ├── mypy.ini # Type checking config
|
||||
│ ├── pytest.ini # Test configuration
|
||||
│ └── reflex.config.py # Reflex app configuration
|
||||
│
|
||||
├── tools/ # 🔧 Scripts و ابزارهای کمکی
|
||||
│ ├── scripts/
|
||||
│ │ ├── update-env-json.sh # Runtime config updater
|
||||
│ │ └── diagnose-502.sh # Diagnostic tools
|
||||
│ └── setup.py # Package setup
|
||||
│
|
||||
├── assets/ # 🎨 Static Assets (served by Reflex)
|
||||
│ ├── logo.png
|
||||
│ ├── banner-3.gif
|
||||
│ ├── custom.css
|
||||
│ ├── hero-*.svg
|
||||
│ └── wordpress*.gif
|
||||
│
|
||||
├── data/ # 💾 Local Data (gitignored)
|
||||
│ ├── db/ # Local database files
|
||||
│ ├── cache/ # Cache files
|
||||
│ └── logs/ # Log files
|
||||
│
|
||||
├── src/ # 💻 Source Code (Clean Architecture)
|
||||
│ ├── config/ # Application configuration
|
||||
│ │ ├── settings.py
|
||||
│ │ ├── database.py
|
||||
│ │ ├── cache.py
|
||||
│ │ └── logging.py
|
||||
│ ├── core/ # Core business logic
|
||||
│ │ ├── domain/ # Domain layer
|
||||
│ │ │ ├── entities/ # Domain entities
|
||||
│ │ │ ├── value_objects/ # Value objects
|
||||
│ │ │ ├── enums/ # Domain enums
|
||||
│ │ │ └── exceptions/ # Domain exceptions
|
||||
│ │ └── application/ # Application layer
|
||||
│ │ ├── use_cases/ # Use cases
|
||||
│ │ ├── dto/ # Data Transfer Objects
|
||||
│ │ ├── interfaces/ # Interfaces/Ports
|
||||
│ │ └── validators/ # Validators
|
||||
│ ├── infrastructure/ # Infrastructure layer
|
||||
│ │ ├── database/ # Database implementation
|
||||
│ │ │ ├── models/ # SQLAlchemy models
|
||||
│ │ │ ├── repositories/ # Repository implementations
|
||||
│ │ │ └── migrations/ # Alembic migrations
|
||||
│ │ ├── cache/ # Cache implementation (Redis)
|
||||
│ │ ├── external/ # External API integrations
|
||||
│ │ │ ├── email/
|
||||
│ │ │ ├── sms/
|
||||
│ │ │ ├── payment/
|
||||
│ │ │ └── providers/
|
||||
│ │ ├── security/ # Security implementations
|
||||
│ │ └── tasks/ # Background tasks (Celery)
|
||||
│ ├── presentation/ # Presentation layer
|
||||
│ │ ├── web/ # Reflex web application
|
||||
│ │ │ ├── pages/ # Reflex pages
|
||||
│ │ │ ├── components/ # Reusable components
|
||||
│ │ │ ├── state/ # Application state
|
||||
│ │ │ └── styles/ # Styling
|
||||
│ │ └── api/ # REST API endpoints (if needed)
|
||||
│ │ ├── routes/
|
||||
│ │ └── middleware/
|
||||
│ └── shared/ # Shared utilities
|
||||
│ ├── events/ # Event system
|
||||
│ └── messaging/ # Message bus
|
||||
│
|
||||
├── tests/ # 🧪 Test Suites
|
||||
│ ├── unit/ # Unit tests
|
||||
│ │ ├── core/
|
||||
│ │ └── infrastructure/
|
||||
│ ├── integration/ # Integration tests
|
||||
│ │ ├── database/
|
||||
│ │ └── external/
|
||||
│ ├── e2e/ # End-to-end tests
|
||||
│ │ └── scenarios/
|
||||
│ ├── fixtures/ # Test fixtures
|
||||
│ └── conftest.py # Pytest configuration
|
||||
│
|
||||
├── docs/ # 📚 Documentation
|
||||
│ ├── api/ # API documentation
|
||||
│ ├── architecture/ # Architecture docs
|
||||
│ │ ├── overview.md
|
||||
│ │ └── database-strategy.md
|
||||
│ ├── deployment/ # Deployment guides
|
||||
│ │ ├── DEPLOYMENT_CHECKLIST.md
|
||||
│ │ ├── DEPLOYMENT_QUICK_START.md
|
||||
│ │ ├── PRODUCTION_DEPLOYMENT.md
|
||||
│ │ ├── CHANGELOG-DEPLOYMENT.md
|
||||
│ │ └── kubernetes.md
|
||||
│ ├── development/ # Development guides
|
||||
│ │ ├── setup.md
|
||||
│ │ ├── coding-standards.md
|
||||
│ │ └── git-workflow.md
|
||||
│ ├── changelog/ # Change logs
|
||||
│ │ ├── CHANGELOG.md
|
||||
│ │ ├── migrations.md
|
||||
│ │ └── known-issues.md
|
||||
│ ├── operations/ # Operations docs
|
||||
│ ├── handbook.md # Complete handbook
|
||||
│ └── PROJECT_STRUCTURE.md # This file
|
||||
│
|
||||
└── tmp/ # Temporary files (gitignored)
|
||||
```
|
||||
|
||||
## 🎯 معماری جدید - Separation of Concerns
|
||||
|
||||
### 1. `build/` - Build Configurations
|
||||
**هدف**: جداسازی همه چیز مربوط به build process
|
||||
|
||||
- **`build/docker/`**: تمام فایلهای Docker
|
||||
- Multi-stage Dockerfile با optimization
|
||||
- Docker Compose برای development
|
||||
- .dockerignore
|
||||
|
||||
- **`build/ci/`**: CI/CD configurations
|
||||
- Woodpecker CI pipeline
|
||||
- سایر CI configs (GitHub Actions, GitLab CI)
|
||||
|
||||
**مزایا**:
|
||||
- ✅ Root directory تمیزتر
|
||||
- ✅ Build configs مدیریت شده در یک مکان
|
||||
- ✅ CI/CD configs جدا از کد
|
||||
|
||||
### 2. `deploy/` - Deployment Configurations
|
||||
**هدف**: تمرکز همه deployment configs
|
||||
|
||||
- **`deploy/helm/`**: Helm charts
|
||||
- Production و Staging values
|
||||
- Templates برای تمام K8s resources
|
||||
|
||||
- **`deploy/kubernetes/`**: Raw K8s manifests
|
||||
- Secret templates
|
||||
- Custom resources
|
||||
|
||||
- **`deploy/argocd/`**: ArgoCD GitOps
|
||||
- Application definitions
|
||||
- Sync policies
|
||||
|
||||
**مزایا**:
|
||||
- ✅ یک مکان برای همه deployment
|
||||
- ✅ واضح برای DevOps engineers
|
||||
- ✅ جداسازی از source code
|
||||
|
||||
### 3. `config/` - Configuration Files
|
||||
**هدف**: تمرکز همه config files
|
||||
|
||||
- `alembic.ini`: Database migrations
|
||||
- `mypy.ini`: Type checking
|
||||
- `pytest.ini`: Testing
|
||||
- `reflex.config.py`: Reflex framework
|
||||
|
||||
**مزایا**:
|
||||
- ✅ Root directory خلوتتر
|
||||
- ✅ Configs به راحتی پیدا میشوند
|
||||
- ✅ مدیریت بهتر
|
||||
|
||||
### 4. `tools/` - Utility Scripts
|
||||
**هدف**: جداسازی scripts و ابزارها
|
||||
|
||||
- Runtime scripts
|
||||
- Diagnostic tools
|
||||
- Setup utilities
|
||||
|
||||
**مزایا**:
|
||||
- ✅ Scripts منظم و دستهبندی شده
|
||||
- ✅ جدا از source code
|
||||
|
||||
### 5. `assets/` - Consolidated Assets
|
||||
**هدف**: یک مکان واحد برای همه static assets
|
||||
|
||||
**قبلاً**: Assets پراکنده در `assets/` و `src/presentation/web/assets/`
|
||||
**الان**: همه در `assets/` (served directly by Reflex)
|
||||
|
||||
**فایلهای موجود**:
|
||||
- `logo.png` - لوگوی پیکربند
|
||||
- `banner-3.gif` - Banner animation
|
||||
- `wordpress-logo.gif` - WordPress logo
|
||||
- `hero-*.svg` - Hero section icons
|
||||
- `custom.css` - Custom styles
|
||||
|
||||
**استفاده در کد**:
|
||||
```python
|
||||
rx.image(src="/logo.png") # Reflex serves from /assets
|
||||
```
|
||||
|
||||
**مزایا**:
|
||||
- ✅ No duplication
|
||||
- ✅ یک منبع حقیقت
|
||||
- ✅ مدیریت آسانتر
|
||||
- ✅ سازگار با Reflex
|
||||
|
||||
### 6. `data/` - Local Data (gitignored)
|
||||
**هدف**: Local development data
|
||||
|
||||
- `data/db/`: SQLite و database files
|
||||
- `data/cache/`: Redis dumps
|
||||
- `data/logs/`: Log files
|
||||
|
||||
**مزایا**:
|
||||
- ✅ Data جدا از code
|
||||
- ✅ .gitignore شده
|
||||
- ✅ Clean repository
|
||||
|
||||
## 🔗 ارتباط با پروژههای دیگر
|
||||
|
||||
### Base Image Repository
|
||||
- **Repo**: `peikarband/base`
|
||||
- **Registry**: `hub.peikarband.ir/peikarband/base:latest`
|
||||
- **Purpose**: Base image with Python, Node.js, bun, build tools
|
||||
- **Build**: Separate CI/CD pipeline
|
||||
- **Usage**: Referenced in `build/docker/Dockerfile`
|
||||
|
||||
### Landing Page (This Repo)
|
||||
- **Repo**: `peikarband/landing`
|
||||
- **Registry**: `hub.peikarband.ir/peikarband/landing:latest`
|
||||
- **Purpose**: Landing page application
|
||||
- **Dependencies**: Uses base image
|
||||
|
||||
## 📝 فایلهای Root (Minimal)
|
||||
|
||||
### ضروری
|
||||
- `README.md`: Main documentation
|
||||
- `requirements.txt`: Dependencies
|
||||
- `Makefile`: Build commands
|
||||
- `rxconfig.py`: Reflex config loader
|
||||
- `.gitignore`: Git ignore rules
|
||||
|
||||
### حذف شده از Root
|
||||
- ❌ `Dockerfile` → `build/docker/`
|
||||
- ❌ `docker-compose.yml` → `build/docker/`
|
||||
- ❌ `.woodpecker.yml` → `build/ci/`
|
||||
- ❌ `alembic.ini` → `config/`
|
||||
- ❌ `pytest.ini` → `config/`
|
||||
- ❌ `mypy.ini` → `config/`
|
||||
- ❌ `scripts/` → `tools/scripts/`
|
||||
- ❌ `setup.py` → `tools/`
|
||||
- ❌ `helm/` → `deploy/helm/`
|
||||
- ❌ `argocd/` → `deploy/argocd/`
|
||||
- ❌ Duplicate assets → `assets/static/`
|
||||
|
||||
## 🎯 Best Practices
|
||||
|
||||
### Root Directory
|
||||
- ✅ فقط فایلهای ضروری
|
||||
- ✅ Config files در `config/`
|
||||
- ✅ Build files در `build/`
|
||||
- ✅ Deploy files در `deploy/`
|
||||
|
||||
### Source Code (`src/`)
|
||||
- ✅ Clean Architecture layers
|
||||
- ✅ Separation of concerns
|
||||
- ✅ SOLID principles
|
||||
|
||||
### Documentation
|
||||
- ✅ همه docs در `docs/`
|
||||
- ✅ دستهبندی منطقی
|
||||
- ✅ بهروز و جامع
|
||||
|
||||
### Deployment
|
||||
- ✅ Helm charts محیطمحور
|
||||
- ✅ ArgoCD GitOps
|
||||
- ✅ Secrets جدا از code
|
||||
|
||||
### Testing
|
||||
- ✅ Unit/Integration/E2E جدا
|
||||
- ✅ Fixtures منظم
|
||||
- ✅ Coverage بالا
|
||||
|
||||
## 🚀 مزایای معماری جدید
|
||||
|
||||
1. **Clarity** ✨
|
||||
- واضح است که هر فایل کجا باشد
|
||||
- Navigation آسانتر
|
||||
|
||||
2. **Maintainability** 🔧
|
||||
- نگهداری آسانتر
|
||||
- Onboarding سریعتر
|
||||
|
||||
3. **Scalability** 📈
|
||||
- اضافه کردن configs جدید ساده
|
||||
- مقیاسپذیری بهتر
|
||||
|
||||
4. **Professional** 💼
|
||||
- استاندارد enterprise projects
|
||||
- Best practices معماری
|
||||
|
||||
5. **Developer Experience** 👨💻
|
||||
- کمتر سردرگم
|
||||
- Productivity بالاتر
|
||||
|
||||
## 📊 مقایسه قبل و بعد
|
||||
|
||||
### قبل
|
||||
```
|
||||
root/
|
||||
├── 15+ config files 😰
|
||||
├── Docker files
|
||||
├── CI configs
|
||||
├── helm/
|
||||
├── argocd/
|
||||
├── scripts/
|
||||
├── assets/ (duplicate!)
|
||||
└── src/
|
||||
```
|
||||
|
||||
### بعد
|
||||
```
|
||||
root/
|
||||
├── 4 essential files only 😌
|
||||
├── build/ (organized)
|
||||
├── deploy/ (organized)
|
||||
├── config/ (organized)
|
||||
├── tools/ (organized)
|
||||
├── assets/static/ (consolidated)
|
||||
└── src/ (clean)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**آخرین بروزرسانی**: 2025-01-30
|
||||
**نسخه معماری**: 2.0 (Restructured)
|
||||
@@ -1,453 +0,0 @@
|
||||
# استراتژی دیتابیس - انعطاف و مقیاسپذیری
|
||||
|
||||
## مشکل: انعطاف vs ثبات
|
||||
|
||||
با توجه به اینکه پروژه قرار است:
|
||||
- کلی feature جدید بگیره
|
||||
- Options و configurations متنوع داشته باشه
|
||||
- قابل توسعه سریع باشه
|
||||
|
||||
آیا PostgreSQL محدودیت ایجاد میکنه؟
|
||||
|
||||
## ✅ راه حل: Hybrid Database Architecture
|
||||
|
||||
### لایهبندی داده بر اساس نوع:
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────┐
|
||||
│ Application Layer │
|
||||
└────┬─────────────┬──────────────┬────────────┘
|
||||
│ │ │
|
||||
┌────▼─────┐ ┌───▼────┐ ┌───▼────┐
|
||||
│PostgreSQL│ │MongoDB │ │ Redis │
|
||||
│ │ │ │ │ │
|
||||
│Critical │ │Flexible│ │ Cache │
|
||||
│Structured│ │Dynamic │ │Session │
|
||||
└──────────┘ └────────┘ └────────┘
|
||||
```
|
||||
|
||||
### Tier 1: PostgreSQL - Critical Business Data
|
||||
|
||||
**چی بریزیم توی PostgreSQL:**
|
||||
- User accounts
|
||||
- Financial data (invoices, transactions, wallet)
|
||||
- Service subscriptions
|
||||
- Audit logs
|
||||
- Anything که نیاز به ACID داره
|
||||
|
||||
```python
|
||||
# ❌ اینها رو NEVER توی MongoDB نذاریم
|
||||
class Invoice(BaseModel):
|
||||
id: int
|
||||
user_id: int
|
||||
amount: Decimal # MUST be ACID
|
||||
status: str
|
||||
paid_at: datetime
|
||||
```
|
||||
|
||||
**چرا PostgreSQL؟**
|
||||
- ✅ ACID Transactions
|
||||
- ✅ Data Integrity
|
||||
- ✅ Complex Joins
|
||||
- ✅ Proven for financial data
|
||||
|
||||
### Tier 2: PostgreSQL JSONB - Flexible Structured
|
||||
|
||||
**چی بریزیم توی JSONB:**
|
||||
- Service configurations
|
||||
- User preferences
|
||||
- Feature flags
|
||||
- Custom metadata
|
||||
- Plugin settings
|
||||
|
||||
```python
|
||||
from sqlalchemy.dialects.postgresql import JSONB
|
||||
|
||||
class Service(BaseModel):
|
||||
# Structured
|
||||
id = Column(Integer, primary_key=True)
|
||||
user_id = Column(Integer)
|
||||
type = Column(String) # 'vps', 'hosting', etc.
|
||||
|
||||
# Flexible - هر چیزی میتونه باشه!
|
||||
config = Column(JSONB, default={})
|
||||
metadata = Column(JSONB, default={})
|
||||
|
||||
# Example 1: VPS
|
||||
vps = Service(
|
||||
type="vps",
|
||||
config={
|
||||
"cpu": 4,
|
||||
"ram": 8,
|
||||
"disk": 100,
|
||||
"os": "ubuntu-22.04"
|
||||
}
|
||||
)
|
||||
|
||||
# Example 2: WordPress Hosting
|
||||
wp = Service(
|
||||
type="wordpress",
|
||||
config={
|
||||
"domain": "example.com",
|
||||
"php_version": "8.2",
|
||||
"auto_update": True,
|
||||
"cdn_enabled": True,
|
||||
# Future features - بدون migration!
|
||||
"new_feature_2025": {"enabled": True}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
**Query کردن JSONB:**
|
||||
|
||||
```python
|
||||
# پیدا کردن VPS های بالای 4 CPU
|
||||
services = session.query(Service).filter(
|
||||
Service.config['cpu'].astext.cast(Integer) >= 4
|
||||
).all()
|
||||
|
||||
# پیدا کردن WordPress با CDN enabled
|
||||
services = session.query(Service).filter(
|
||||
Service.config['cdn_enabled'].astext == 'true'
|
||||
).all()
|
||||
|
||||
# Index روی JSONB برای performance
|
||||
from sqlalchemy import Index
|
||||
|
||||
Index(
|
||||
'idx_service_config_cpu',
|
||||
Service.config['cpu'].astext.cast(Integer)
|
||||
)
|
||||
```
|
||||
|
||||
### Tier 3: MongoDB - Completely Dynamic
|
||||
|
||||
**چی بریزیم توی MongoDB:**
|
||||
- Logs و events
|
||||
- Analytics data
|
||||
- User activity tracking
|
||||
- System metrics
|
||||
- Unstructured data
|
||||
|
||||
```python
|
||||
# MongoDB - No schema!
|
||||
{
|
||||
"_id": "service_log_123",
|
||||
"service_id": 123,
|
||||
"timestamp": "2025-01-24T...",
|
||||
"events": [
|
||||
{
|
||||
"type": "cpu_spike",
|
||||
"value": 95,
|
||||
"custom_field_1": "...",
|
||||
# هر چیزی که بخوایم!
|
||||
}
|
||||
],
|
||||
"metrics": {
|
||||
# Structure آزاد
|
||||
"anything": "goes here"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## پیادهسازی در کد
|
||||
|
||||
### 1. Service با JSONB:
|
||||
|
||||
```python
|
||||
# src/infrastructure/database/models/service_model.py
|
||||
|
||||
from sqlalchemy import Column, Integer, String, ForeignKey, Enum as SQLEnum
|
||||
from sqlalchemy.dialects.postgresql import JSONB
|
||||
from sqlalchemy.orm import relationship
|
||||
import enum
|
||||
|
||||
class ServiceType(enum.Enum):
|
||||
VPS = "vps"
|
||||
HOSTING = "hosting"
|
||||
WORDPRESS = "wordpress"
|
||||
DOMAIN = "domain"
|
||||
|
||||
class ServiceModel(BaseModel):
|
||||
__tablename__ = "services"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
user_id = Column(Integer, ForeignKey('users.id'), nullable=False)
|
||||
type = Column(SQLEnum(ServiceType), nullable=False)
|
||||
status = Column(String(20), nullable=False)
|
||||
|
||||
# Flexible configuration
|
||||
config = Column(JSONB, nullable=False, default={})
|
||||
metadata = Column(JSONB, nullable=False, default={})
|
||||
|
||||
# Relationships
|
||||
user = relationship("UserModel", back_populates="services")
|
||||
```
|
||||
|
||||
### 2. Repository با JSONB support:
|
||||
|
||||
```python
|
||||
# src/infrastructure/database/repositories/service_repository.py
|
||||
|
||||
from typing import Dict, Any, List
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
class ServiceRepository:
|
||||
def __init__(self, session: Session):
|
||||
self._session = session
|
||||
|
||||
def find_by_config(
|
||||
self,
|
||||
json_path: str,
|
||||
value: Any
|
||||
) -> List[ServiceModel]:
|
||||
"""Query by JSONB field.
|
||||
|
||||
Example:
|
||||
repo.find_by_config('cpu', 4)
|
||||
repo.find_by_config('cdn_enabled', True)
|
||||
"""
|
||||
return self._session.query(ServiceModel).filter(
|
||||
ServiceModel.config[json_path].astext == str(value)
|
||||
).all()
|
||||
|
||||
def update_config(
|
||||
self,
|
||||
service_id: int,
|
||||
config_updates: Dict[str, Any]
|
||||
) -> ServiceModel:
|
||||
"""Update service config partially."""
|
||||
service = self.get_by_id(service_id)
|
||||
if service:
|
||||
# Merge configs
|
||||
new_config = {**service.config, **config_updates}
|
||||
service.config = new_config
|
||||
self._session.commit()
|
||||
return service
|
||||
```
|
||||
|
||||
### 3. Domain Entity که flexible هست:
|
||||
|
||||
```python
|
||||
# src/core/domain/entities/service.py
|
||||
|
||||
from typing import Dict, Any, Optional
|
||||
from src.core.domain.entities.base import BaseEntity
|
||||
|
||||
class Service(BaseEntity):
|
||||
"""Service domain entity with flexible configuration."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
id: Optional[int] = None,
|
||||
user_id: int = None,
|
||||
type: str = None,
|
||||
status: str = None,
|
||||
config: Dict[str, Any] = None,
|
||||
metadata: Dict[str, Any] = None,
|
||||
**kwargs
|
||||
):
|
||||
super().__init__(id=id, **kwargs)
|
||||
self.user_id = user_id
|
||||
self.type = type
|
||||
self.status = status
|
||||
self.config = config or {}
|
||||
self.metadata = metadata or {}
|
||||
|
||||
def get_config(self, key: str, default: Any = None) -> Any:
|
||||
"""Get config value safely."""
|
||||
return self.config.get(key, default)
|
||||
|
||||
def set_config(self, key: str, value: Any) -> None:
|
||||
"""Set config value."""
|
||||
self.config[key] = value
|
||||
|
||||
def update_config(self, updates: Dict[str, Any]) -> None:
|
||||
"""Update multiple config values."""
|
||||
self.config.update(updates)
|
||||
```
|
||||
|
||||
## مقایسه روشها
|
||||
|
||||
### Migration-based (Traditional SQL)
|
||||
|
||||
```python
|
||||
# ❌ هر feature جدید = migration جدید
|
||||
|
||||
# Migration 001
|
||||
ALTER TABLE services ADD COLUMN cpu INTEGER;
|
||||
|
||||
# Migration 002
|
||||
ALTER TABLE services ADD COLUMN ram INTEGER;
|
||||
|
||||
# Migration 003
|
||||
ALTER TABLE services ADD COLUMN new_feature VARCHAR(255);
|
||||
|
||||
# بعد از 100 feature = 100 migration! 😱
|
||||
```
|
||||
|
||||
### JSONB-based (Flexible SQL)
|
||||
|
||||
```python
|
||||
# ✅ هیچ migration لازم نیست!
|
||||
|
||||
# روز اول
|
||||
service.config = {"cpu": 4}
|
||||
|
||||
# یک ماه بعد
|
||||
service.config = {"cpu": 4, "ram": 8}
|
||||
|
||||
# یک سال بعد
|
||||
service.config = {
|
||||
"cpu": 4,
|
||||
"ram": 8,
|
||||
"new_feature_2025": True,
|
||||
"another_feature": {"nested": "data"}
|
||||
}
|
||||
|
||||
# بدون هیچ migration! 🎉
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. تصمیمگیری: PostgreSQL vs MongoDB vs JSONB
|
||||
|
||||
```python
|
||||
# PostgreSQL (Structured)
|
||||
✅ User authentication
|
||||
✅ Financial transactions
|
||||
✅ Invoices
|
||||
✅ Core business entities
|
||||
|
||||
# PostgreSQL JSONB
|
||||
✅ Service configurations
|
||||
✅ User preferences
|
||||
✅ Feature flags
|
||||
✅ Plugin settings
|
||||
✅ Custom fields
|
||||
|
||||
# MongoDB
|
||||
✅ Logs & Events
|
||||
✅ Analytics
|
||||
✅ User activity
|
||||
✅ System metrics
|
||||
✅ Temporary data
|
||||
```
|
||||
|
||||
### 2. JSONB Schema Validation (در Application)
|
||||
|
||||
```python
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional
|
||||
|
||||
class VPSConfig(BaseModel):
|
||||
"""Schema for VPS service config."""
|
||||
cpu: int
|
||||
ram: int
|
||||
disk: int
|
||||
os: str
|
||||
backups: Optional[bool] = False
|
||||
|
||||
class WordPressConfig(BaseModel):
|
||||
"""Schema for WordPress service config."""
|
||||
domain: str
|
||||
php_version: str
|
||||
auto_update: bool
|
||||
cdn_enabled: Optional[bool] = False
|
||||
|
||||
# Validation
|
||||
def validate_service_config(service_type: str, config: dict):
|
||||
"""Validate config based on service type."""
|
||||
schemas = {
|
||||
"vps": VPSConfig,
|
||||
"wordpress": WordPressConfig,
|
||||
}
|
||||
schema = schemas.get(service_type)
|
||||
if schema:
|
||||
return schema(**config) # Validates
|
||||
return config
|
||||
```
|
||||
|
||||
### 3. Indexing برای Performance
|
||||
|
||||
```python
|
||||
# در migration
|
||||
from alembic import op
|
||||
|
||||
def upgrade():
|
||||
# Create GIN index on JSONB
|
||||
op.execute("""
|
||||
CREATE INDEX idx_services_config_gin
|
||||
ON services USING GIN (config);
|
||||
""")
|
||||
|
||||
# Index specific keys
|
||||
op.execute("""
|
||||
CREATE INDEX idx_services_config_cpu
|
||||
ON services ((config->>'cpu'));
|
||||
""")
|
||||
```
|
||||
|
||||
## مزایا و معایب
|
||||
|
||||
### PostgreSQL + JSONB (پیشنهاد من)
|
||||
|
||||
**مزایا:**
|
||||
- ✅ انعطاف بالا (مثل MongoDB)
|
||||
- ✅ ACID transactions (برای billing امن)
|
||||
- ✅ Query قدرتمند
|
||||
- ✅ یک database کمتر = سادهتر
|
||||
- ✅ Performance خوب با indexing
|
||||
- ✅ Data integrity
|
||||
|
||||
**معایب:**
|
||||
- ❌ JSONB query ها کمی پیچیدهتر از SQL معمولی
|
||||
- ❌ نیاز به validation در application layer
|
||||
|
||||
### Hybrid (PostgreSQL + MongoDB)
|
||||
|
||||
**مزایا:**
|
||||
- ✅ Best of both worlds
|
||||
- ✅ Separation of concerns
|
||||
- ✅ Optimal performance
|
||||
|
||||
**معایب:**
|
||||
- ❌ پیچیدگی بیشتر
|
||||
- ❌ دو database = maintenance بیشتر
|
||||
- ❌ Consistency بین دو DB
|
||||
|
||||
## نتیجهگیری
|
||||
|
||||
**پیشنهاد برای پیکربند:**
|
||||
|
||||
```python
|
||||
"""
|
||||
Tier 1: PostgreSQL - Critical
|
||||
- Users, Auth
|
||||
- Invoices, Transactions
|
||||
- Wallet, Payments
|
||||
|
||||
Tier 2: PostgreSQL JSONB - Flexible
|
||||
- Service configs
|
||||
- User preferences
|
||||
- Custom settings
|
||||
|
||||
Tier 3: Redis - Cache
|
||||
- Sessions
|
||||
- Cache
|
||||
- Rate limiting
|
||||
|
||||
(Optional) Tier 4: MongoDB - Logs
|
||||
- Activity logs
|
||||
- System metrics
|
||||
- Analytics
|
||||
"""
|
||||
```
|
||||
|
||||
**در عمل:**
|
||||
- شروع با PostgreSQL + JSONB
|
||||
- اگر لازم شد، MongoDB اضافه میکنیم
|
||||
- ساده، flexible، و قابل توسعه
|
||||
|
||||
**PostgreSQL دست و پای ما رو نمیبنده، اگر از JSONB استفاده کنیم!** ✨
|
||||
|
||||
@@ -1,174 +0,0 @@
|
||||
# معماری کلی سیستم
|
||||
|
||||
## نمای کلی
|
||||
|
||||
پلتفرم پیکربند بر اساس **Clean Architecture** طراحی شده که قابلیت تست، نگهداری و توسعه را به حداکثر میرساند.
|
||||
|
||||
## لایههای معماری
|
||||
|
||||
### 1. Domain Layer (هسته مرکزی)
|
||||
|
||||
مستقلترین لایه که شامل منطق کسبوکار خالص است:
|
||||
|
||||
**Components:**
|
||||
- **Entities**: موجودیتهای اصلی (User, Service, Invoice, Server)
|
||||
- **Value Objects**: Email, Money, Phone, IPAddress
|
||||
- **Domain Services**: منطق پیچیدهای که به چند entity مرتبط است
|
||||
- **Domain Events**: رویدادهای کسبوکار
|
||||
- **Exceptions**: خطاهای دامین
|
||||
|
||||
**قوانین:**
|
||||
- هیچ وابستگی به لایههای دیگر ندارد
|
||||
- فقط منطق کسبوکار
|
||||
- بدون وابستگی به framework
|
||||
- Pure Python
|
||||
|
||||
### 2. Application Layer (موارد استفاده)
|
||||
|
||||
**Components:**
|
||||
- **Use Cases**: موارد استفاده سیستم (RegisterUser, CreateInvoice)
|
||||
- **DTOs**: Data Transfer Objects
|
||||
- **Interfaces**: تعریف رابطهای سرویسها
|
||||
- **Validators**: اعتبارسنجی ورودیها
|
||||
|
||||
**قوانین:**
|
||||
- وابسته به Domain Layer
|
||||
- مستقل از Infrastructure
|
||||
- تعریف رابطهای مورد نیاز
|
||||
|
||||
### 3. Infrastructure Layer (جزئیات فنی)
|
||||
|
||||
**Components:**
|
||||
- **Database**: PostgreSQL + SQLAlchemy
|
||||
- **Cache**: Redis
|
||||
- **External APIs**: DigitalOcean, Hetzner, OVH
|
||||
- **Tasks**: Celery background jobs
|
||||
- **Security**: Authentication, Authorization
|
||||
- **Logging**: Structured logging
|
||||
|
||||
**قوانین:**
|
||||
- پیادهسازی interface های Application Layer
|
||||
- وابسته به تکنولوژیهای خاص
|
||||
- قابل تعویض
|
||||
|
||||
### 4. Presentation Layer (رابط کاربری)
|
||||
|
||||
**Components:**
|
||||
- **Web**: Reflex pages و components
|
||||
- **API**: REST endpoints (optional)
|
||||
- **State Management**: Reflex states
|
||||
|
||||
**قوانین:**
|
||||
- فقط به Application Layer وابسته
|
||||
- مستقل از Infrastructure details
|
||||
|
||||
## جریان داده
|
||||
|
||||
```
|
||||
User Action
|
||||
↓
|
||||
Presentation Layer (Reflex Component)
|
||||
↓
|
||||
Application Layer (Use Case)
|
||||
↓
|
||||
Domain Layer (Business Logic)
|
||||
↓
|
||||
Application Layer (Interfaces)
|
||||
↓
|
||||
Infrastructure Layer (Implementation)
|
||||
↓
|
||||
External Systems (Database, APIs)
|
||||
```
|
||||
|
||||
## Dependency Rule
|
||||
|
||||
وابستگیها همیشه به سمت داخل (به سمت Domain) هستند:
|
||||
|
||||
```
|
||||
Presentation → Application → Domain
|
||||
Infrastructure → Application → Domain
|
||||
```
|
||||
|
||||
**قانون طلایی**: لایههای داخلی هیچ چیز از لایههای خارجی نمیدانند.
|
||||
|
||||
## مزایای این معماری
|
||||
|
||||
1. **Testability**: هر لایه مستقلا قابل تست
|
||||
2. **Maintainability**: تغییرات محلی و جداسازی شده
|
||||
3. **Flexibility**: تعویض آسان تکنولوژیها
|
||||
4. **Scalability**: قابل مقیاسپذیری در هر لایه
|
||||
5. **Business Logic First**: تمرکز روی منطق کسبوکار
|
||||
|
||||
## Domain-Driven Design (DDD)
|
||||
|
||||
پروژه از اصول DDD استفاده میکند:
|
||||
|
||||
- **Ubiquitous Language**: زبان مشترک با کسبوکار
|
||||
- **Bounded Contexts**: محدودههای مشخص
|
||||
- **Aggregates**: مجموعههای یکپارچه
|
||||
- **Repositories**: دسترسی به داده
|
||||
- **Domain Events**: رویدادهای کسبوکار
|
||||
|
||||
## Technology Stack
|
||||
|
||||
### Core
|
||||
- **Language**: Python 3.11+
|
||||
- **Framework**: Reflex 0.4.0
|
||||
- **Database**: PostgreSQL 14+
|
||||
- **Cache**: Redis 7+
|
||||
- **ORM**: SQLAlchemy 2.0+
|
||||
|
||||
### Infrastructure
|
||||
- **Task Queue**: Celery 5.3+
|
||||
- **Testing**: pytest 7.4+
|
||||
- **Logging**: structlog
|
||||
- **API Client**: httpx
|
||||
|
||||
### External Services
|
||||
- **Cloud Providers**: DigitalOcean, Hetzner, OVH
|
||||
- **Payment**: Zarinpal, IDPay
|
||||
- **Monitoring**: Sentry, Prometheus
|
||||
|
||||
## Security Architecture
|
||||
|
||||
- **Authentication**: JWT + 2FA
|
||||
- **Authorization**: RBAC (Role-Based Access Control)
|
||||
- **Encryption**: Data at rest & in transit
|
||||
- **Secrets Management**: Environment variables
|
||||
- **Audit Logging**: تمام اقدامات مهم
|
||||
|
||||
## Scalability Strategy
|
||||
|
||||
### Horizontal Scaling
|
||||
- Load balancing برای Reflex
|
||||
- Database replication
|
||||
- Redis clustering
|
||||
- Celery workers
|
||||
|
||||
### Vertical Scaling
|
||||
- Connection pooling
|
||||
- Query optimization
|
||||
- Caching strategy
|
||||
- Async operations
|
||||
|
||||
## Monitoring & Observability
|
||||
|
||||
- **Metrics**: Request rate, response time, error rate
|
||||
- **Logs**: Structured logging با contextual info
|
||||
- **Tracing**: Request tracing
|
||||
- **Alerts**: Critical issues
|
||||
- **Dashboards**: Grafana/Prometheus
|
||||
|
||||
## Future Considerations
|
||||
|
||||
- Microservices architecture (در صورت نیاز)
|
||||
- Event-driven architecture
|
||||
- CQRS pattern
|
||||
- GraphQL API
|
||||
- Multi-tenancy
|
||||
|
||||
---
|
||||
|
||||
**نسخه**: 1.0.0
|
||||
**آخرین بروزرسانی**: 2025-01-24
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
# Changelog
|
||||
|
||||
تمام تغییرات قابل توجه این پروژه در این فایل مستند میشود.
|
||||
|
||||
فرمت بر اساس [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) است،
|
||||
و این پروژه از [Semantic Versioning](https://semver.org/spec/v2.0.0.html) پیروی میکند.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
- معماری اولیه پروژه بر اساس Clean Architecture
|
||||
- ساختار پوشههای اصلی
|
||||
- تنظیمات config با Pydantic
|
||||
- Setup PostgreSQL و SQLAlchemy
|
||||
- Setup Redis برای cache
|
||||
- Structured logging با structlog
|
||||
- pytest برای testing
|
||||
- Pre-commit hooks
|
||||
- مستندات جامع (Handbook)
|
||||
|
||||
### Changed
|
||||
- انتقال landing page به ساختار جدید
|
||||
|
||||
## [0.1.0] - 2025-01-24
|
||||
|
||||
### Added
|
||||
- شروع پروژه
|
||||
- Landing page اولیه با Reflex
|
||||
- رنگبندی آبی مطابق لوگو
|
||||
- بخش ویژه WordPress Cloud
|
||||
- Badge "بزودی کنار شما خواهیم بود"
|
||||
- فونت فارسی Vazirmatn
|
||||
|
||||
### Design
|
||||
- Hero section با gradient animations
|
||||
- Service cards
|
||||
- Pricing section
|
||||
- Server comparison table
|
||||
- Testimonials
|
||||
- Contact form
|
||||
- Floating chat button
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
# مشکلات شناخته شده (Known Issues)
|
||||
|
||||
این فایل لیست مشکلات شناخته شده و workaround های موقت را نگه میدارد.
|
||||
|
||||
## Format
|
||||
|
||||
هر issue باید شامل:
|
||||
- عنوان
|
||||
- توضیحات
|
||||
- تاریخ کشف
|
||||
- Priority (Critical/High/Medium/Low)
|
||||
- Status (Open/In Progress/Resolved)
|
||||
- Workaround (اگر وجود دارد)
|
||||
- Related tickets
|
||||
|
||||
---
|
||||
|
||||
## فعلا مشکلی گزارش نشده
|
||||
|
||||
پروژه در مراحل اولیه است و هنوز مشکل خاصی گزارش نشده.
|
||||
|
||||
---
|
||||
|
||||
## Template برای Issue های آینده
|
||||
|
||||
```markdown
|
||||
## [ISSUE-001] عنوان مشکل
|
||||
|
||||
**تاریخ کشف**: YYYY-MM-DD
|
||||
**Priority**: Critical/High/Medium/Low
|
||||
**Status**: Open/In Progress/Resolved
|
||||
**نسخه**: X.Y.Z
|
||||
|
||||
### توضیحات
|
||||
توضیحات کامل مشکل
|
||||
|
||||
### Steps to Reproduce
|
||||
1. Step 1
|
||||
2. Step 2
|
||||
3. Step 3
|
||||
|
||||
### Expected Behavior
|
||||
رفتار مورد انتظار
|
||||
|
||||
### Actual Behavior
|
||||
رفتار واقعی
|
||||
|
||||
### Environment
|
||||
- OS: Linux/Windows/Mac
|
||||
- Python: 3.11
|
||||
- Database: PostgreSQL 14
|
||||
|
||||
### Workaround
|
||||
راه حل موقت (اگر وجود دارد)
|
||||
|
||||
### Related
|
||||
- Ticket: #123
|
||||
- PR: #456
|
||||
|
||||
### Notes
|
||||
یادداشتهای اضافی
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## مشکلات حل شده
|
||||
|
||||
(لیست مشکلات حل شده به اینجا منتقل میشود)
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
# Database Migrations History
|
||||
|
||||
این فایل تاریخچه تمام migration های دیتابیس را نگه میدارد.
|
||||
|
||||
## Format
|
||||
|
||||
هر migration باید شامل موارد زیر باشد:
|
||||
- تاریخ
|
||||
- نام فایل migration
|
||||
- توضیحات کامل
|
||||
- جداول/ستونهای تغییر یافته
|
||||
- وابستگیها
|
||||
- دستور rollback
|
||||
|
||||
---
|
||||
|
||||
## Migrations
|
||||
|
||||
### 2025-01-24: Initial Setup
|
||||
|
||||
**Migration**: `pending`
|
||||
**Description**: آمادهسازی اولیه - هنوز migration اجرا نشده
|
||||
**Status**: Pending
|
||||
**Tables**: None yet
|
||||
**Dependencies**: None
|
||||
**Rollback**: N/A
|
||||
|
||||
**Note**: اولین migration در فاز بعدی (phase0-database) ایجاد خواهد شد.
|
||||
|
||||
---
|
||||
|
||||
## Template برای Migration های آینده
|
||||
|
||||
```markdown
|
||||
## YYYY-MM-DD: Title
|
||||
|
||||
**Migration**: `XXX_description.py`
|
||||
**Description**: توضیحات کامل تغییرات
|
||||
**Status**: Applied / Pending / Rolled Back
|
||||
**Tables**:
|
||||
- table_name_1
|
||||
- table_name_2
|
||||
|
||||
**Changes**:
|
||||
- Added column `column_name` to `table_name`
|
||||
- Created table `new_table`
|
||||
- Added index on `column_name`
|
||||
|
||||
**Dependencies**:
|
||||
- Previous migration: XXX
|
||||
|
||||
**SQL Summary**:
|
||||
```sql
|
||||
ALTER TABLE users ADD COLUMN two_factor_enabled BOOLEAN DEFAULT FALSE;
|
||||
```
|
||||
|
||||
**Rollback**:
|
||||
```bash
|
||||
alembic downgrade -1
|
||||
```
|
||||
|
||||
**Tested**: Yes/No
|
||||
**Production Deploy Date**: YYYY-MM-DD
|
||||
```
|
||||
|
||||
@@ -1,239 +0,0 @@
|
||||
# Changelog - Production Deployment Setup
|
||||
|
||||
تمام تغییرات مربوط به آمادهسازی دیپلوی Production در این فایل ثبت میشود.
|
||||
|
||||
## [1.0.0] - 2025-12-26 - ApprovalToken:PROD-001
|
||||
|
||||
### ✅ Added
|
||||
|
||||
#### CI/CD Pipeline
|
||||
- **woodpecker.yml**: پایپلاین کامل CI/CD با 11 stage
|
||||
- Linting (Python & YAML)
|
||||
- Unit & Integration Tests
|
||||
- Security Scanning (Safety, Bandit, Trivy, Trufflehog)
|
||||
- Docker Build & Push
|
||||
- Helm Validation
|
||||
- Database Migration Check
|
||||
- Automated Deployment (Staging & Production)
|
||||
- Post-Deployment Verification
|
||||
- Notifications (Telegram & Slack)
|
||||
|
||||
#### Docker & Registry
|
||||
- **.dockerignore**: بهینهسازی Docker build با exclude کردن فایلهای غیرضروری
|
||||
- **Dockerfile** (بهبود یافته):
|
||||
- Multi-stage build برای کاهش حجم image
|
||||
- Security hardening (non-root user, tini init, minimal runtime)
|
||||
- Build arguments برای versioning
|
||||
- Health checks بهبود یافته
|
||||
- Labels و metadata کامل
|
||||
|
||||
#### Kubernetes & Helm
|
||||
- **k8s/secrets-template.yaml**: Template کامل برای Kubernetes secrets
|
||||
- Harbor registry credentials
|
||||
- Application secrets (DB, Redis, JWT, etc.)
|
||||
- External provider credentials
|
||||
- CI/CD secrets
|
||||
- مثالهای External Secrets Operator
|
||||
|
||||
#### Configuration Files
|
||||
- **.env.example**: Template کامل environment variables (200+ configs)
|
||||
- Application settings
|
||||
- Database & Redis
|
||||
- Security & JWT
|
||||
- Cloud providers (DigitalOcean, Hetzner, OVH)
|
||||
- Payment gateways (Zarinpal, IDPay)
|
||||
- Notification services (Email, SMS, Telegram)
|
||||
- Monitoring & logging
|
||||
- Feature flags
|
||||
|
||||
- **.yamllint.yml**: پیکربندی YAML linter برای validation
|
||||
|
||||
#### Health Checks
|
||||
- **src/presentation/api/routes/health.py**: Endpoints کامل health checking
|
||||
- `/ping`: Basic health check
|
||||
- `/health`: Detailed health with dependencies
|
||||
- `/ready`: Readiness probe برای Kubernetes
|
||||
- `/live`: Liveness probe
|
||||
- `/metrics`: Basic metrics endpoint
|
||||
|
||||
#### Documentation
|
||||
- **docs/deployment/PRODUCTION_DEPLOYMENT.md**: راهنمای کامل 50+ صفحهای
|
||||
- تنظیمات Harbor Registry
|
||||
- پیکربندی Kubernetes
|
||||
- راهاندازی ArgoCD
|
||||
- تنظیمات Woodpecker CI
|
||||
- مراحل دیپلوی اولیه
|
||||
- مانیتورینگ و logging
|
||||
- عیبیابی مشکلات متداول
|
||||
|
||||
- **DEPLOYMENT_QUICK_START.md**: راهنمای سریع 10 دقیقهای
|
||||
- Setup سریع در 5 مرحله
|
||||
- Checklist production-ready
|
||||
- دستورات مفید
|
||||
- Pipeline flow diagram
|
||||
|
||||
### 🔄 Modified
|
||||
|
||||
#### Build & Deploy
|
||||
- **Makefile**: آپدیت برای Harbor registry
|
||||
- تغییر REGISTRY به `harbor.peikarband.ir`
|
||||
- اضافه شدن DOCKER_BUILDKIT flag
|
||||
- بهبود docker-build با build arguments
|
||||
- اضافه شدن docker-login command
|
||||
|
||||
#### Helm Charts
|
||||
- **helm/peikarband/values.yaml**:
|
||||
- آپدیت image repository به Harbor
|
||||
- اضافه شدن imagePullSecrets
|
||||
|
||||
#### ArgoCD Applications
|
||||
- **argocd/application.yaml** (Production):
|
||||
- اضافه شدن annotations برای notifications
|
||||
- اضافه شدن labels
|
||||
- تعیین targetRevision به `main`
|
||||
- اضافه شدن Helm parameters برای image
|
||||
- بهبود syncOptions
|
||||
|
||||
- **argocd/application-staging.yaml** (Staging):
|
||||
- اضافه شدن annotations و labels
|
||||
- targetRevision: `develop`
|
||||
- Helm parameters برای staging
|
||||
|
||||
### 🏗️ Infrastructure Changes
|
||||
|
||||
#### Registry Strategy
|
||||
- **Before**: `registry.example.com`
|
||||
- **After**: `harbor.peikarband.ir/peikarband/landing`
|
||||
- **Authentication**: Robot account با محدودیت دسترسی
|
||||
|
||||
#### Deployment Strategy
|
||||
- **GitOps**: ArgoCD برای automated sync
|
||||
- **CI/CD**: Woodpecker برای build و test
|
||||
- **Environments**:
|
||||
- Production: `main` branch → `peikarband.ir`
|
||||
- Staging: `develop` branch → `staging.peikarband.ir`
|
||||
|
||||
#### Security Improvements
|
||||
- Image scanning با Trivy
|
||||
- Secret scanning با Trufflehog
|
||||
- Dependency scanning با Safety
|
||||
- Code security با Bandit
|
||||
- Non-root containers
|
||||
- Network policies enabled
|
||||
- Pod security contexts configured
|
||||
|
||||
### 📊 Pipeline Metrics
|
||||
|
||||
- **Total Stages**: 11
|
||||
- **Estimated Time**: 10-15 minutes
|
||||
- **Parallelization**: Services (PostgreSQL, Redis)
|
||||
- **Matrix Build**: Multi-arch support (amd64, arm64)
|
||||
|
||||
### 🔐 Security Checklist
|
||||
|
||||
- [x] Non-root user در Docker
|
||||
- [x] Image vulnerability scanning
|
||||
- [x] Secret management با Kubernetes
|
||||
- [x] TLS/SSL با cert-manager
|
||||
- [x] Network policies
|
||||
- [x] Resource limits
|
||||
- [x] Pod security contexts
|
||||
- [x] Image pull secrets
|
||||
|
||||
### 📝 Configuration Files Summary
|
||||
|
||||
| File | Purpose | Status |
|
||||
|------|---------|--------|
|
||||
| woodpecker.yml | CI/CD Pipeline | ✅ Created |
|
||||
| .dockerignore | Build optimization | ✅ Created |
|
||||
| .env.example | Config template | ✅ Created |
|
||||
| .yamllint.yml | YAML validation | ✅ Created |
|
||||
| Dockerfile | Container image | ✅ Enhanced |
|
||||
| Makefile | Build commands | ✅ Updated |
|
||||
| k8s/secrets-template.yaml | K8s secrets | ✅ Created |
|
||||
| argocd/application.yaml | Production GitOps | ✅ Updated |
|
||||
| argocd/application-staging.yaml | Staging GitOps | ✅ Updated |
|
||||
| helm/peikarband/values.yaml | Helm values | ✅ Updated |
|
||||
|
||||
### 🎯 Prerequisites for Production
|
||||
|
||||
1. **Kubernetes Cluster**
|
||||
- Version: 1.24+
|
||||
- Nodes: 3+ workers
|
||||
- Resources: 6 CPU cores, 6GB RAM minimum
|
||||
|
||||
2. **External Services**
|
||||
- Harbor Registry
|
||||
- ArgoCD
|
||||
- Woodpecker CI
|
||||
- PostgreSQL 14+
|
||||
- Redis 7+
|
||||
|
||||
3. **DNS Configuration**
|
||||
- peikarband.ir
|
||||
- staging.peikarband.ir
|
||||
- harbor.peikarband.ir
|
||||
- argocd.peikarband.ir
|
||||
|
||||
4. **Secrets Required**
|
||||
- Harbor robot account
|
||||
- Database credentials
|
||||
- Redis password
|
||||
- JWT secrets
|
||||
- Cloud provider tokens
|
||||
- Payment gateway keys
|
||||
- Notification service tokens
|
||||
|
||||
### 🚀 Deployment Steps
|
||||
|
||||
1. Setup Harbor registry and create robot account
|
||||
2. Create Kubernetes secrets
|
||||
3. Install and configure ArgoCD
|
||||
4. Configure Woodpecker CI secrets
|
||||
5. Push code to trigger pipeline
|
||||
6. Verify deployment with health checks
|
||||
|
||||
### 📚 Documentation Structure
|
||||
|
||||
```
|
||||
docs/
|
||||
├── deployment/
|
||||
│ ├── PRODUCTION_DEPLOYMENT.md (50+ pages, complete guide)
|
||||
│ └── kubernetes.md (existing)
|
||||
├── DEPLOYMENT_QUICK_START.md (Quick reference)
|
||||
└── CHANGELOG-DEPLOYMENT.md (This file)
|
||||
```
|
||||
|
||||
### 🔗 References
|
||||
|
||||
- Harbor: https://goharbor.io
|
||||
- ArgoCD: https://argo-cd.readthedocs.io
|
||||
- Woodpecker: https://woodpecker-ci.org
|
||||
- Kubernetes: https://kubernetes.io
|
||||
|
||||
### ⚠️ Breaking Changes
|
||||
|
||||
- Image repository path changed from `registry.example.com` to `harbor.peikarband.ir`
|
||||
- Harbor authentication required
|
||||
- Kubernetes secrets must be created before deployment
|
||||
- Environment variables significantly expanded
|
||||
|
||||
### 🎉 Impact
|
||||
|
||||
این تغییرات پروژه را **کاملاً آماده برای دیپلوی Production** میکند با:
|
||||
- ✅ Automated CI/CD pipeline
|
||||
- ✅ Security scanning
|
||||
- ✅ GitOps deployment
|
||||
- ✅ Health monitoring
|
||||
- ✅ Comprehensive documentation
|
||||
- ✅ Production-grade Docker images
|
||||
- ✅ Scalability support
|
||||
- ✅ High availability configuration
|
||||
|
||||
---
|
||||
|
||||
**Approved By**: #اکسپت ApprovalToken:PROD-001
|
||||
**Implementation Date**: 2025-12-26
|
||||
**Status**: ✅ Complete
|
||||
**Next Steps**: Follow DEPLOYMENT_QUICK_START.md for deployment
|
||||
|
||||
@@ -1,451 +0,0 @@
|
||||
# ✅ Deployment Readiness Checklist - Peikarband
|
||||
|
||||
تاریخ بررسی: 2025-12-27
|
||||
وضعیت: **READY FOR DEPLOYMENT** 🚀
|
||||
|
||||
---
|
||||
|
||||
## 📊 خلاصه بررسی
|
||||
|
||||
| Category | Status | Details |
|
||||
|----------|--------|---------|
|
||||
| Assets & Static Files | ✅ FIXED | `.dockerignore` اصلاح شد |
|
||||
| Health Endpoints | ✅ FIXED | Endpoints متصل شدند |
|
||||
| Dependencies | ✅ COMPLETE | `psutil` اضافه شد |
|
||||
| Docker Build | ✅ READY | Multi-stage build optimized |
|
||||
| CI/CD Pipeline | ✅ READY | Woodpecker configured |
|
||||
| Kubernetes | ✅ READY | Helm charts + ArgoCD |
|
||||
| Documentation | ✅ COMPLETE | راهنماهای کامل |
|
||||
|
||||
---
|
||||
|
||||
## 🔧 مشکلات برطرف شده
|
||||
|
||||
### 1️⃣ Assets در Docker Image (CRITICAL) ✅
|
||||
|
||||
**مشکل**: فایلهای استاتیک (logo.png, banner-3.gif, custom.css) در `.dockerignore` exclude شده بودند.
|
||||
|
||||
**راهحل**:
|
||||
```diff
|
||||
# Before
|
||||
*.gif
|
||||
*.png
|
||||
*.svg
|
||||
!assets/logo.png
|
||||
|
||||
# After
|
||||
# Keep assets directory
|
||||
!assets/
|
||||
!src/presentation/web/assets/
|
||||
```
|
||||
|
||||
**تاثیر**: بدون این تغییر، صفحه landing بدون تصاویر نمایش داده میشد.
|
||||
|
||||
---
|
||||
|
||||
### 2️⃣ psutil Dependency (MEDIUM) ✅
|
||||
|
||||
**مشکل**: `psutil` برای metrics endpoint نیاز بود ولی در `requirements.txt` نبود.
|
||||
|
||||
**راهحل**: اضافه شد به requirements:
|
||||
```python
|
||||
psutil==5.9.6
|
||||
```
|
||||
|
||||
**تاثیر**: بدون این، `/metrics` endpoint crash میکرد.
|
||||
|
||||
---
|
||||
|
||||
### 3️⃣ Health Endpoints Integration (MEDIUM) ✅
|
||||
|
||||
**مشکل**: Health check endpoints تعریف شده بودند ولی به Reflex app متصل نبودند.
|
||||
|
||||
**راهحل**: `peikarband/peikarband.py` اصلاح شد:
|
||||
```python
|
||||
@rx.page(route="/ping")
|
||||
def ping():
|
||||
data = ping_endpoint()
|
||||
return rx.box(rx.text(str(data)))
|
||||
|
||||
# + /health, /ready, /live
|
||||
```
|
||||
|
||||
**تاثیر**: Kubernetes probes حالا کار میکنند.
|
||||
|
||||
---
|
||||
|
||||
## ✅ تایید شده
|
||||
|
||||
### Assets & Static Files ✅
|
||||
- ✅ `/logo.png` - در navbar
|
||||
- ✅ `/banner-3.gif` - در hero section
|
||||
- ✅ `/custom.css` - استایلهای سفارشی
|
||||
- ✅ `assets/` directory شامل میشود
|
||||
- ✅ `src/presentation/web/assets/` شامل میشود
|
||||
|
||||
### Reflex Configuration ✅
|
||||
- ✅ `rxconfig.py` صحیح است
|
||||
- ✅ Stylesheets (Vazirmatn, Inter) لود میشوند
|
||||
- ✅ Ports: Frontend 3000, Backend 8000
|
||||
|
||||
### Docker Build ✅
|
||||
- ✅ Multi-stage build (Builder + Runtime)
|
||||
- ✅ Non-root user (peikarband:1000)
|
||||
- ✅ Security hardening (tini, minimal runtime)
|
||||
- ✅ Health checks configured
|
||||
- ✅ Labels و metadata کامل
|
||||
- ✅ BuildKit enabled
|
||||
|
||||
### Dependencies ✅
|
||||
**Core:**
|
||||
- ✅ reflex==0.4.0
|
||||
- ✅ sqlalchemy==2.0.23
|
||||
- ✅ psycopg2-binary==2.9.9
|
||||
- ✅ redis==5.0.1
|
||||
- ✅ psutil==5.9.6 ⭐ (اضافه شد)
|
||||
|
||||
**Security:**
|
||||
- ✅ pyjwt==2.8.0
|
||||
- ✅ cryptography==41.0.7
|
||||
- ✅ passlib[bcrypt]==1.7.4
|
||||
|
||||
**Monitoring:**
|
||||
- ✅ sentry-sdk==1.38.0
|
||||
- ✅ prometheus-client==0.19.0
|
||||
- ✅ structlog==23.2.0
|
||||
|
||||
### Health Checks ✅
|
||||
- ✅ `/ping` - Basic health check
|
||||
- ✅ `/health` - Detailed with dependencies
|
||||
- ✅ `/ready` - Readiness probe
|
||||
- ✅ `/live` - Liveness probe
|
||||
- ✅ `/metrics` - System metrics (با psutil)
|
||||
|
||||
### Woodpecker CI Pipeline ✅
|
||||
**Active Stages:**
|
||||
- ✅ Lint (Python + YAML)
|
||||
- ✅ Docker Build
|
||||
- ✅ Helm Validation
|
||||
- ✅ Migration Check
|
||||
- ✅ ArgoCD Deployment
|
||||
- ✅ Health Verification
|
||||
- ✅ Notifications
|
||||
|
||||
**Temporarily Disabled** (برای سرعت اولیه):
|
||||
- ⏸️ Unit Tests (commented)
|
||||
- ⏸️ Integration Tests (commented)
|
||||
- ⏸️ Security Scans (commented)
|
||||
|
||||
**توصیه**: بعد از اولین deploy موفق، uncomment کنید.
|
||||
|
||||
### Harbor Registry ✅
|
||||
- ✅ URL: `harbor.peikarband.ir`
|
||||
- ✅ Project: `peikarband`
|
||||
- ✅ Image pull secrets configured
|
||||
- ✅ Makefile updated
|
||||
|
||||
### Kubernetes & Helm ✅
|
||||
- ✅ Helm chart validated
|
||||
- ✅ values.yaml با Harbor registry
|
||||
- ✅ values-production.yaml configured
|
||||
- ✅ Resource limits defined
|
||||
- ✅ HPA enabled (2-20 replicas)
|
||||
- ✅ PDB enabled
|
||||
- ✅ Network policies configured
|
||||
|
||||
### ArgoCD ✅
|
||||
- ✅ Production app: `argocd/application.yaml`
|
||||
- ✅ Staging app: `argocd/application-staging.yaml`
|
||||
- ✅ Auto-sync enabled
|
||||
- ✅ Notifications configured
|
||||
- ✅ Image parameters set
|
||||
|
||||
### Documentation ✅
|
||||
- ✅ `PRODUCTION_DEPLOYMENT.md` (50+ pages)
|
||||
- ✅ `DEPLOYMENT_QUICK_START.md` (10 minutes)
|
||||
- ✅ `CHANGELOG-DEPLOYMENT.md` (complete history)
|
||||
- ✅ This checklist
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Pre-Deployment Tests
|
||||
|
||||
### Local Testing:
|
||||
```bash
|
||||
# 1. Install dependencies
|
||||
pip install -r requirements.txt
|
||||
|
||||
# 2. Run app locally
|
||||
make dev
|
||||
# OR
|
||||
python3 -m reflex run
|
||||
|
||||
# 3. Test endpoints
|
||||
curl http://localhost:8000/ping
|
||||
curl http://localhost:8000/health
|
||||
|
||||
# 4. Kill processes
|
||||
make kill-dev
|
||||
```
|
||||
|
||||
### Docker Testing:
|
||||
```bash
|
||||
# 1. Build image
|
||||
make docker-build
|
||||
|
||||
# 2. Run container
|
||||
docker run -p 3000:3000 -p 8000:8000 peikarband/landing:latest
|
||||
|
||||
# 3. Test health
|
||||
curl http://localhost:8000/ping
|
||||
|
||||
# 4. Check logs
|
||||
docker logs <container_id>
|
||||
```
|
||||
|
||||
### Helm Testing:
|
||||
```bash
|
||||
# 1. Lint chart
|
||||
helm lint helm/peikarband
|
||||
|
||||
# 2. Dry run
|
||||
helm template peikarband helm/peikarband \
|
||||
--set image.tag=latest \
|
||||
--debug
|
||||
|
||||
# 3. Validate
|
||||
helm install peikarband helm/peikarband --dry-run
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Deployment Steps
|
||||
|
||||
### Quick Deploy (از commit تا production):
|
||||
|
||||
1. **Push to Git**
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "feat: production-ready deployment"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
2. **Woodpecker CI** (Automatic)
|
||||
- ✅ Lint code
|
||||
- ✅ Build Docker image
|
||||
- ✅ Push to Harbor
|
||||
- ✅ Update ArgoCD
|
||||
- ⏱️ ~5-8 minutes
|
||||
|
||||
3. **ArgoCD** (Automatic)
|
||||
- ✅ Sync Helm chart
|
||||
- ✅ Deploy to Kubernetes
|
||||
- ✅ Rolling update
|
||||
- ⏱️ ~2-3 minutes
|
||||
|
||||
4. **Verify**
|
||||
```bash
|
||||
# Check pods
|
||||
kubectl get pods -n peikarband
|
||||
|
||||
# Test endpoint
|
||||
curl https://peikarband.ir/ping
|
||||
|
||||
# Check ArgoCD
|
||||
argocd app get peikarband
|
||||
```
|
||||
|
||||
**Total Time**: ~10 minutes از push تا production! 🎉
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Known Issues & Notes
|
||||
|
||||
### 1. Tests Temporarily Disabled
|
||||
تستها در woodpecker.yml موقتاً comment شدند برای سرعت بیشتر.
|
||||
|
||||
**برای فعالسازی**:
|
||||
- Uncomment کردن test stages در `woodpecker.yml`
|
||||
- اطمینان از PostgreSQL و Redis در CI environment
|
||||
|
||||
### 2. Reflex Export در Dockerfile
|
||||
```dockerfile
|
||||
RUN python -m reflex init --template blank && \
|
||||
python -m reflex export --frontend-only --no-zip || true
|
||||
```
|
||||
|
||||
`|| true` اضافه شده تا در صورت fail شدن export، build متوقف نشود.
|
||||
|
||||
**نکته**: Reflex در runtime mode اجرا میشود، نه export mode.
|
||||
|
||||
### 3. Database در Production
|
||||
در حال حاضر از SQLite استفاده میشود. برای production:
|
||||
|
||||
```bash
|
||||
# Update rxconfig.py
|
||||
db_url="postgresql://USER:PASS@HOST:5432/peikarband"
|
||||
|
||||
# Run migrations
|
||||
kubectl exec -it POD_NAME -n peikarband -- alembic upgrade head
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 Performance Expectations
|
||||
|
||||
### Resource Usage:
|
||||
- **Memory**: 512MB - 1GB per pod
|
||||
- **CPU**: 0.5 - 1 core per pod
|
||||
- **Startup Time**: 30-60 seconds
|
||||
- **Response Time**: < 200ms
|
||||
|
||||
### Scaling:
|
||||
- **Min Replicas**: 2 (production), 1 (staging)
|
||||
- **Max Replicas**: 20 (production), 5 (staging)
|
||||
- **Target CPU**: 60% (production), 70% (staging)
|
||||
|
||||
### Availability:
|
||||
- **SLA Target**: 99.9% uptime
|
||||
- **RTO**: < 5 minutes (Recovery Time Objective)
|
||||
- **RPO**: < 1 hour (Recovery Point Objective)
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Post-Deployment Tasks
|
||||
|
||||
### Immediate (Day 1):
|
||||
- [ ] Verify all endpoints responding
|
||||
- [ ] Check logs for errors
|
||||
- [ ] Monitor resource usage
|
||||
- [ ] Test domain and SSL
|
||||
- [ ] Verify database connectivity
|
||||
|
||||
### Short-term (Week 1):
|
||||
- [ ] Enable monitoring (Prometheus/Grafana)
|
||||
- [ ] Set up alerting
|
||||
- [ ] Configure backup strategy
|
||||
- [ ] Enable security scans in CI
|
||||
- [ ] Uncomment tests in pipeline
|
||||
- [ ] Load testing
|
||||
|
||||
### Long-term (Month 1):
|
||||
- [ ] Performance optimization
|
||||
- [ ] Cost optimization
|
||||
- [ ] Disaster recovery testing
|
||||
- [ ] Security audit
|
||||
- [ ] Documentation updates
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Security Checklist
|
||||
|
||||
- [x] Non-root containers
|
||||
- [x] Image pull secrets configured
|
||||
- [x] TLS/SSL ready (cert-manager)
|
||||
- [x] Network policies enabled
|
||||
- [x] Resource limits set
|
||||
- [x] Pod security contexts
|
||||
- [x] Secrets in Kubernetes
|
||||
- [ ] Vulnerability scanning (enable after deploy)
|
||||
- [ ] RBAC configured
|
||||
- [ ] Audit logging enabled
|
||||
|
||||
---
|
||||
|
||||
## 📚 Quick References
|
||||
|
||||
### Essential Commands:
|
||||
```bash
|
||||
# Logs
|
||||
kubectl logs -f deployment/peikarband -n peikarband
|
||||
|
||||
# Scale
|
||||
kubectl scale deployment peikarband --replicas=5 -n peikarband
|
||||
|
||||
# Restart
|
||||
kubectl rollout restart deployment/peikarband -n peikarband
|
||||
|
||||
# Status
|
||||
kubectl get all -n peikarband
|
||||
|
||||
# Describe
|
||||
kubectl describe deployment peikarband -n peikarband
|
||||
```
|
||||
|
||||
### Troubleshooting:
|
||||
- **Pod CrashLoopBackOff**: Check logs with `--previous` flag
|
||||
- **ImagePullError**: Verify Harbor credentials
|
||||
- **Ingress 404**: Check DNS and ingress configuration
|
||||
- **Database Error**: Verify secrets and connectivity
|
||||
|
||||
---
|
||||
|
||||
## ✅ Final Status
|
||||
|
||||
```
|
||||
🎉 پروژه پیکربند آماده دیپلوی در Production است!
|
||||
|
||||
✅ Assets: FIXED
|
||||
✅ Dependencies: COMPLETE
|
||||
✅ Health Checks: WORKING
|
||||
✅ Docker: OPTIMIZED
|
||||
✅ CI/CD: CONFIGURED
|
||||
✅ Kubernetes: READY
|
||||
✅ Documentation: COMPLETE
|
||||
|
||||
📝 تغییرات اعمال شده:
|
||||
1. .dockerignore اصلاح شد (assets شامل میشوند)
|
||||
2. psutil به requirements اضافه شد
|
||||
3. Health endpoints به Reflex متصل شدند
|
||||
4. peikarband.py بروز شد
|
||||
|
||||
🚀 آماده برای: git push origin main
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**تایید شده توسط**: AI Code Review
|
||||
**تاریخ**: 2025-12-27
|
||||
**نسخه**: 1.0.0
|
||||
**Status**: ✅ PRODUCTION READY
|
||||
|
||||
---
|
||||
|
||||
## 🎁 Bonus
|
||||
|
||||
### VS Code Tasks (اختیاری):
|
||||
ایجاد فایل `.vscode/tasks.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Dev Server",
|
||||
"type": "shell",
|
||||
"command": "make dev",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Kill Dev Server",
|
||||
"type": "shell",
|
||||
"command": "make kill-dev"
|
||||
},
|
||||
{
|
||||
"label": "Docker Build",
|
||||
"type": "shell",
|
||||
"command": "make docker-build"
|
||||
},
|
||||
{
|
||||
"label": "Test Health",
|
||||
"type": "shell",
|
||||
"command": "curl http://localhost:8000/ping"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Happy Deploying! 🚀🎉**
|
||||
|
||||
@@ -1,259 +0,0 @@
|
||||
# راهنمای سریع دیپلوی - Peikarband
|
||||
|
||||
راهنمای سریع برای راهاندازی پروژه پیکربند در Production
|
||||
|
||||
## 🚀 دیپلوی سریع در 10 دقیقه
|
||||
|
||||
### 1️⃣ Harbor Registry Setup (2 دقیقه)
|
||||
|
||||
```bash
|
||||
# لاگین به Harbor
|
||||
docker login harbor.peikarband.ir
|
||||
|
||||
# ساخت project: peikarband
|
||||
# ساخت robot account: deployer
|
||||
```
|
||||
|
||||
### 2️⃣ Kubernetes Secrets (2 دقیقه)
|
||||
|
||||
```bash
|
||||
# Harbor pull secret
|
||||
kubectl create secret docker-registry harbor-registry-secret \
|
||||
--docker-server=harbor.peikarband.ir \
|
||||
--docker-username=robot\$peikarband+deployer \
|
||||
--docker-password="YOUR_TOKEN" \
|
||||
--namespace=peikarband
|
||||
|
||||
# Application secrets
|
||||
kubectl create secret generic peikarband-prod-secrets \
|
||||
--from-literal=db-password=YOUR_DB_PASS \
|
||||
--from-literal=redis-password=YOUR_REDIS_PASS \
|
||||
--from-literal=secret-key=YOUR_SECRET_KEY \
|
||||
--from-literal=jwt-secret-key=YOUR_JWT_KEY \
|
||||
--namespace=peikarband
|
||||
```
|
||||
|
||||
### 3️⃣ ArgoCD Setup (3 دقیقه)
|
||||
|
||||
```bash
|
||||
# نصب ArgoCD
|
||||
kubectl create namespace argocd
|
||||
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
|
||||
|
||||
# Deploy application
|
||||
kubectl apply -f argocd/application.yaml
|
||||
|
||||
# Sync
|
||||
argocd app sync peikarband
|
||||
```
|
||||
|
||||
### 4️⃣ Woodpecker CI Secrets (2 دقیقه)
|
||||
|
||||
در Woodpecker UI یا با CLI:
|
||||
|
||||
```bash
|
||||
woodpecker-cli secret add --name harbor_username --value "robot\$peikarband+deployer"
|
||||
woodpecker-cli secret add --name harbor_password --value "YOUR_TOKEN"
|
||||
woodpecker-cli secret add --name argocd_server --value "argocd.peikarband.ir"
|
||||
woodpecker-cli secret add --name argocd_token --value "YOUR_ARGOCD_TOKEN"
|
||||
```
|
||||
|
||||
### 5️⃣ Push & Deploy (1 دقیقه)
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "feat: production deployment setup"
|
||||
git push origin main
|
||||
|
||||
# Woodpecker به صورت خودکار:
|
||||
# ✅ Tests را اجرا میکند
|
||||
# ✅ Docker image را build میکند
|
||||
# ✅ به Harbor push میکند
|
||||
# ✅ ArgoCD را trigger میکند
|
||||
# ✅ در Kubernetes deploy میشود
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 Checklist قبل از Production
|
||||
|
||||
### Infrastructure
|
||||
- [ ] Kubernetes cluster آماده است (3+ nodes)
|
||||
- [ ] Harbor registry نصب شده
|
||||
- [ ] ArgoCD نصب شده
|
||||
- [ ] Woodpecker CI پیکربندی شده
|
||||
- [ ] cert-manager برای SSL نصب شده
|
||||
- [ ] Ingress NGINX نصب شده
|
||||
|
||||
### Database & Cache
|
||||
- [ ] PostgreSQL در دسترس است
|
||||
- [ ] Redis در دسترس است
|
||||
- [ ] Backup strategy تعریف شده
|
||||
|
||||
### DNS & SSL
|
||||
- [ ] Domain به cluster اشاره میکند
|
||||
- [ ] SSL certificate صادر شده (Let's Encrypt)
|
||||
- [ ] HTTPS کار میکند
|
||||
|
||||
### Secrets & Security
|
||||
- [ ] Harbor robot account ساخته شده
|
||||
- [ ] Kubernetes secrets ایجاد شده
|
||||
- [ ] ArgoCD token ساخته شده
|
||||
- [ ] Woodpecker secrets تنظیم شده
|
||||
|
||||
### Monitoring
|
||||
- [ ] Prometheus نصب شده (اختیاری)
|
||||
- [ ] Grafana پیکربندی شده (اختیاری)
|
||||
- [ ] Telegram/Slack notifications تنظیم شده
|
||||
|
||||
---
|
||||
|
||||
## 🧪 تست سریع
|
||||
|
||||
```bash
|
||||
# Health check
|
||||
curl https://peikarband.ir/ping
|
||||
# Expected: {"status":"ok",...}
|
||||
|
||||
# Kubernetes pods
|
||||
kubectl get pods -n peikarband
|
||||
# Expected: 3 pods در حالت Running
|
||||
|
||||
# ArgoCD status
|
||||
argocd app get peikarband
|
||||
# Expected: Health Status: Healthy, Sync Status: Synced
|
||||
|
||||
# Logs
|
||||
kubectl logs -f deployment/peikarband -n peikarband
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 CI/CD Pipeline Flow
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[Git Push] --> B[Woodpecker CI]
|
||||
B --> C[Run Tests]
|
||||
C --> D[Build Docker Image]
|
||||
D --> E[Push to Harbor]
|
||||
E --> F[Update ArgoCD]
|
||||
F --> G[Deploy to K8s]
|
||||
G --> H[Health Check]
|
||||
H --> I[Notify Team]
|
||||
```
|
||||
|
||||
### Pipeline Stages:
|
||||
|
||||
1. **Lint & Test** (2-3 min)
|
||||
- Python linting (flake8, black)
|
||||
- Unit tests
|
||||
- Integration tests
|
||||
|
||||
2. **Security Scan** (1-2 min)
|
||||
- Dependency vulnerabilities
|
||||
- Secret scanning
|
||||
- Code security analysis
|
||||
|
||||
3. **Build & Push** (3-5 min)
|
||||
- Docker build (multi-stage)
|
||||
- Trivy security scan
|
||||
- Push to Harbor
|
||||
|
||||
4. **Deploy** (2-3 min)
|
||||
- Update ArgoCD app
|
||||
- Kubernetes rolling update
|
||||
- Health verification
|
||||
|
||||
**Total Pipeline Time**: ~10-15 minutes
|
||||
|
||||
---
|
||||
|
||||
## 🔧 دستورات مفید
|
||||
|
||||
### Development
|
||||
|
||||
```bash
|
||||
# Local development
|
||||
make dev
|
||||
|
||||
# Run tests
|
||||
make test
|
||||
|
||||
# Build Docker image
|
||||
make docker-build
|
||||
|
||||
# Push to Harbor
|
||||
make docker-login
|
||||
make docker-push
|
||||
```
|
||||
|
||||
### Deployment
|
||||
|
||||
```bash
|
||||
# Full deploy
|
||||
make k8s-deploy
|
||||
|
||||
# Helm lint
|
||||
make helm-lint
|
||||
|
||||
# Helm upgrade
|
||||
make helm-upgrade
|
||||
```
|
||||
|
||||
### Monitoring
|
||||
|
||||
```bash
|
||||
# Watch pods
|
||||
kubectl get pods -n peikarband -w
|
||||
|
||||
# Tail logs
|
||||
kubectl logs -f deployment/peikarband -n peikarband
|
||||
|
||||
# Port forward to app
|
||||
kubectl port-forward svc/peikarband -n peikarband 8000:8000
|
||||
|
||||
# Describe deployment
|
||||
kubectl describe deployment peikarband -n peikarband
|
||||
```
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
```bash
|
||||
# Pod details
|
||||
kubectl describe pod POD_NAME -n peikarband
|
||||
|
||||
# Previous logs (if crashed)
|
||||
kubectl logs POD_NAME -n peikarband --previous
|
||||
|
||||
# Execute in pod
|
||||
kubectl exec -it POD_NAME -n peikarband -- /bin/bash
|
||||
|
||||
# Events
|
||||
kubectl get events -n peikarband --sort-by='.lastTimestamp'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📞 Support
|
||||
|
||||
- **Documentation**: [docs/deployment/PRODUCTION_DEPLOYMENT.md](docs/deployment/PRODUCTION_DEPLOYMENT.md)
|
||||
- **Issues**: راهنمای کامل عیبیابی در مستندات
|
||||
- **Team**: support@peikarband.ir
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Next Steps
|
||||
|
||||
بعد از دیپلوی موفق:
|
||||
|
||||
1. ✅ تنظیم monitoring و alerting
|
||||
2. ✅ پیکربندی backup strategy
|
||||
3. ✅ تست load testing
|
||||
4. ✅ تنظیم CI/CD برای سایر برنچها
|
||||
5. ✅ مستندسازی runbooks
|
||||
|
||||
---
|
||||
|
||||
**Happy Deploying! 🚀**
|
||||
|
||||
@@ -1,600 +0,0 @@
|
||||
# راهنمای کامل دیپلوی Production - پیکربند
|
||||
|
||||
این مستند شامل تمام مراحل لازم برای راهاندازی پروژه پیکربند در محیط Production با استفاده از Woodpecker CI، Harbor Registry و ArgoCD است.
|
||||
|
||||
## 📋 جدول محتویات
|
||||
|
||||
1. [پیشنیازها](#پیشنیازها)
|
||||
2. [تنظیمات Harbor Registry](#تنظیمات-harbor-registry)
|
||||
3. [تنظیمات Kubernetes](#تنظیمات-kubernetes)
|
||||
4. [تنظیمات ArgoCD](#تنظیمات-argocd)
|
||||
5. [تنظیمات Woodpecker CI](#تنظیمات-woodpecker-ci)
|
||||
6. [دیپلوی اولیه](#دیپلوی-اولیه)
|
||||
7. [مانیتورینگ و لاگ](#مانیتورینگ-و-لاگ)
|
||||
8. [عیبیابی](#عیبیابی)
|
||||
|
||||
---
|
||||
|
||||
## 🔧 پیشنیازها
|
||||
|
||||
### Infrastructure Requirements
|
||||
|
||||
- **Kubernetes Cluster**: نسخه 1.24+ با حداقل 3 worker nodes
|
||||
- **Harbor Registry**: نسخه 2.8+ برای نگهداری images
|
||||
- **ArgoCD**: نسخه 2.9+ برای GitOps deployment
|
||||
- **Woodpecker CI**: نسخه 2.0+ برای CI/CD pipeline
|
||||
- **PostgreSQL**: نسخه 14+ برای database
|
||||
- **Redis**: نسخه 7+ برای caching
|
||||
|
||||
### Resources مورد نیاز
|
||||
|
||||
**Production Environment:**
|
||||
- CPU: حداقل 6 cores (2 cores per pod × 3 replicas)
|
||||
- Memory: حداقل 6GB (2GB per pod × 3 replicas)
|
||||
- Storage: 50GB برای logs و uploads
|
||||
- Network: Load Balancer با IP عمومی
|
||||
|
||||
**Staging Environment:**
|
||||
- CPU: حداقل 3 cores
|
||||
- Memory: حداقل 3GB
|
||||
- Storage: 20GB
|
||||
|
||||
### Domain & SSL
|
||||
|
||||
- Domain اصلی: `peikarband.ir`
|
||||
- Staging: `staging.peikarband.ir`
|
||||
- Harbor: `harbor.peikarband.ir`
|
||||
- ArgoCD: `argocd.peikarband.ir`
|
||||
- SSL Certificate: Let's Encrypt (via cert-manager)
|
||||
|
||||
---
|
||||
|
||||
## 🐳 تنظیمات Harbor Registry
|
||||
|
||||
### 1. نصب Harbor
|
||||
|
||||
```bash
|
||||
# با Helm
|
||||
helm repo add harbor https://helm.goharbor.io
|
||||
helm repo update
|
||||
|
||||
helm install harbor harbor/harbor \
|
||||
--namespace harbor \
|
||||
--create-namespace \
|
||||
--set expose.type=ingress \
|
||||
--set expose.ingress.hosts.core=harbor.peikarband.ir \
|
||||
--set externalURL=https://harbor.peikarband.ir \
|
||||
--set persistence.enabled=true \
|
||||
--set harborAdminPassword="CHANGE_ME_STRONG_PASSWORD"
|
||||
```
|
||||
|
||||
### 2. ساخت Project در Harbor
|
||||
|
||||
1. لاگین به Harbor UI: `https://harbor.peikarband.ir`
|
||||
2. رفتن به **Projects** > **New Project**
|
||||
3. نام: `peikarband`
|
||||
4. Access Level: **Private**
|
||||
5. فعالسازی **Vulnerability Scanning**
|
||||
|
||||
### 3. ساخت Robot Account
|
||||
|
||||
```bash
|
||||
# از طریق Harbor UI:
|
||||
# Projects > peikarband > Robot Accounts > New Robot Account
|
||||
|
||||
Name: deployer
|
||||
Expiration: Never
|
||||
Permissions:
|
||||
- Push Repository
|
||||
- Pull Repository
|
||||
- Read Helm Chart
|
||||
- Create Helm Chart Version
|
||||
|
||||
# Token را کپی کنید (فقط یکبار نمایش داده میشود)
|
||||
```
|
||||
|
||||
### 4. تست دسترسی به Harbor
|
||||
|
||||
```bash
|
||||
# لاگین از local machine
|
||||
docker login harbor.peikarband.ir
|
||||
Username: robot$peikarband+deployer
|
||||
Password: [TOKEN]
|
||||
|
||||
# تست push image
|
||||
docker pull nginx:alpine
|
||||
docker tag nginx:alpine harbor.peikarband.ir/peikarband/test:latest
|
||||
docker push harbor.peikarband.ir/peikarband/test:latest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ☸️ تنظیمات Kubernetes
|
||||
|
||||
### 1. ایجاد Namespaces
|
||||
|
||||
```bash
|
||||
kubectl create namespace peikarband
|
||||
kubectl create namespace peikarband-staging
|
||||
kubectl create namespace argocd
|
||||
kubectl create namespace woodpecker
|
||||
```
|
||||
|
||||
### 2. نصب Cert-Manager (برای SSL)
|
||||
|
||||
```bash
|
||||
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
|
||||
|
||||
# ایجاد ClusterIssuer برای Let's Encrypt
|
||||
cat <<EOF | kubectl apply -f -
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: ClusterIssuer
|
||||
metadata:
|
||||
name: letsencrypt-prod
|
||||
spec:
|
||||
acme:
|
||||
server: https://acme-v02.api.letsencrypt.org/directory
|
||||
email: admin@peikarband.ir
|
||||
privateKeySecretRef:
|
||||
name: letsencrypt-prod
|
||||
solvers:
|
||||
- http01:
|
||||
ingress:
|
||||
class: nginx
|
||||
EOF
|
||||
```
|
||||
|
||||
### 3. نصب Ingress NGINX
|
||||
|
||||
```bash
|
||||
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
|
||||
helm repo update
|
||||
|
||||
helm install ingress-nginx ingress-nginx/ingress-nginx \
|
||||
--namespace ingress-nginx \
|
||||
--create-namespace \
|
||||
--set controller.service.type=LoadBalancer
|
||||
```
|
||||
|
||||
### 4. ایجاد Harbor Pull Secret
|
||||
|
||||
```bash
|
||||
# Production
|
||||
kubectl create secret docker-registry harbor-registry-secret \
|
||||
--docker-server=harbor.peikarband.ir \
|
||||
--docker-username=robot\$peikarband+deployer \
|
||||
--docker-password="YOUR_ROBOT_TOKEN" \
|
||||
--docker-email=admin@peikarband.ir \
|
||||
--namespace=peikarband
|
||||
|
||||
# Staging
|
||||
kubectl create secret docker-registry harbor-registry-secret \
|
||||
--docker-server=harbor.peikarband.ir \
|
||||
--docker-username=robot\$peikarband+deployer \
|
||||
--docker-password="YOUR_ROBOT_TOKEN" \
|
||||
--docker-email=admin@peikarband.ir \
|
||||
--namespace=peikarband-staging
|
||||
```
|
||||
|
||||
### 5. ایجاد Application Secrets
|
||||
|
||||
```bash
|
||||
# استفاده از template موجود در k8s/secrets-template.yaml
|
||||
# ابتدا مقادیر واقعی را جایگزین کنید
|
||||
|
||||
# For Production
|
||||
kubectl apply -f k8s/secrets-production.yaml -n peikarband
|
||||
|
||||
# For Staging
|
||||
kubectl apply -f k8s/secrets-staging.yaml -n peikarband-staging
|
||||
```
|
||||
|
||||
**نمونه ایجاد سریع:**
|
||||
|
||||
```bash
|
||||
kubectl create secret generic peikarband-prod-secrets \
|
||||
--from-literal=db-username=peikarband_prod \
|
||||
--from-literal=db-password=YOUR_DB_PASSWORD \
|
||||
--from-literal=redis-password=YOUR_REDIS_PASSWORD \
|
||||
--from-literal=secret-key=YOUR_SECRET_KEY \
|
||||
--from-literal=jwt-secret-key=YOUR_JWT_SECRET \
|
||||
--namespace=peikarband
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 تنظیمات ArgoCD
|
||||
|
||||
### 1. نصب ArgoCD
|
||||
|
||||
```bash
|
||||
kubectl create namespace argocd
|
||||
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
|
||||
|
||||
# دریافت پسورد اولیه admin
|
||||
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
|
||||
```
|
||||
|
||||
### 2. دسترسی به ArgoCD UI
|
||||
|
||||
```bash
|
||||
# Port forward برای دسترسی موقت
|
||||
kubectl port-forward svc/argocd-server -n argocd 8080:443
|
||||
|
||||
# یا ایجاد Ingress
|
||||
cat <<EOF | kubectl apply -f -
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: argocd-server-ingress
|
||||
namespace: argocd
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: argocd.peikarband.ir
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: argocd-server
|
||||
port:
|
||||
name: https
|
||||
tls:
|
||||
- hosts:
|
||||
- argocd.peikarband.ir
|
||||
secretName: argocd-tls
|
||||
EOF
|
||||
```
|
||||
|
||||
### 3. اضافه کردن Repository به ArgoCD
|
||||
|
||||
```bash
|
||||
# لاگین به ArgoCD
|
||||
argocd login argocd.peikarband.ir
|
||||
|
||||
# اضافه کردن Git repository
|
||||
argocd repo add https://git.peikarband.ir/ehsan-minadd/peikarband.git \
|
||||
--username YOUR_GIT_USERNAME \
|
||||
--password YOUR_GIT_TOKEN
|
||||
```
|
||||
|
||||
### 4. ایجاد Applications در ArgoCD
|
||||
|
||||
```bash
|
||||
# Production
|
||||
kubectl apply -f argocd/application.yaml
|
||||
|
||||
# Staging
|
||||
kubectl apply -f argocd/application-staging.yaml
|
||||
|
||||
# بررسی وضعیت
|
||||
argocd app list
|
||||
argocd app get peikarband
|
||||
```
|
||||
|
||||
### 5. تنظیم Notifications (اختیاری)
|
||||
|
||||
```bash
|
||||
# تنظیم Telegram notifications
|
||||
kubectl create secret generic argocd-notifications-secret \
|
||||
--from-literal=telegram-token=YOUR_BOT_TOKEN \
|
||||
--namespace=argocd
|
||||
|
||||
kubectl patch configmap argocd-notifications-cm -n argocd --patch '
|
||||
data:
|
||||
service.telegram: |
|
||||
token: $telegram-token
|
||||
template.app-deployed: |
|
||||
message: |
|
||||
✅ Application {{.app.metadata.name}} deployed successfully!
|
||||
Version: {{.app.status.sync.revision}}
|
||||
trigger.on-deployed: |
|
||||
- when: app.status.operationState.phase in ["Succeeded"]
|
||||
send: [app-deployed]
|
||||
'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 تنظیمات Woodpecker CI
|
||||
|
||||
### 1. نصب Woodpecker Server
|
||||
|
||||
```bash
|
||||
helm repo add woodpecker https://woodpecker-ci.org/
|
||||
helm repo update
|
||||
|
||||
helm install woodpecker woodpecker/woodpecker \
|
||||
--namespace woodpecker \
|
||||
--create-namespace \
|
||||
--set server.host=ci.peikarband.ir
|
||||
```
|
||||
|
||||
### 2. اتصال به Git Repository
|
||||
|
||||
در Woodpecker UI:
|
||||
1. لاگین با Git account
|
||||
2. Activate کردن repository
|
||||
3. تنظیم Webhooks
|
||||
|
||||
### 3. اضافه کردن Secrets به Woodpecker
|
||||
|
||||
از طریق Woodpecker UI یا CLI:
|
||||
|
||||
```bash
|
||||
woodpecker-cli secret add \
|
||||
--repository peikarband/landing \
|
||||
--name harbor_username \
|
||||
--value "robot\$peikarband+deployer"
|
||||
|
||||
woodpecker-cli secret add \
|
||||
--repository peikarband/landing \
|
||||
--name harbor_password \
|
||||
--value "YOUR_ROBOT_TOKEN"
|
||||
|
||||
woodpecker-cli secret add \
|
||||
--repository peikarband/landing \
|
||||
--name argocd_server \
|
||||
--value "argocd.peikarband.ir"
|
||||
|
||||
woodpecker-cli secret add \
|
||||
--repository peikarband/landing \
|
||||
--name argocd_token \
|
||||
--value "YOUR_ARGOCD_TOKEN"
|
||||
|
||||
woodpecker-cli secret add \
|
||||
--repository peikarband/landing \
|
||||
--name telegram_bot_token \
|
||||
--value "YOUR_BOT_TOKEN"
|
||||
|
||||
woodpecker-cli secret add \
|
||||
--repository peikarband/landing \
|
||||
--name telegram_chat_id \
|
||||
--value "YOUR_CHAT_ID"
|
||||
```
|
||||
|
||||
### 4. دریافت ArgoCD Token
|
||||
|
||||
```bash
|
||||
# ساخت token برای CI/CD
|
||||
argocd account generate-token --account ci-robot --id ci-robot
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 دیپلوی اولیه
|
||||
|
||||
### 1. آمادهسازی کد
|
||||
|
||||
```bash
|
||||
# کلون پروژه
|
||||
git clone https://git.peikarband.ir/ehsan-minadd/peikarband.git
|
||||
cd peikarband
|
||||
|
||||
# بررسی فایلهای مورد نیاز
|
||||
ls -la woodpecker.yml
|
||||
ls -la Dockerfile
|
||||
ls -la helm/peikarband/
|
||||
ls -la argocd/
|
||||
```
|
||||
|
||||
### 2. Build و Push اولیه Image
|
||||
|
||||
```bash
|
||||
# لاگین به Harbor
|
||||
docker login harbor.peikarband.ir
|
||||
|
||||
# Build
|
||||
make docker-build VERSION=v0.1.0
|
||||
|
||||
# Push
|
||||
make docker-push VERSION=v0.1.0
|
||||
```
|
||||
|
||||
### 3. تنظیم DNS
|
||||
|
||||
```
|
||||
peikarband.ir A YOUR_LOADBALANCER_IP
|
||||
www.peikarband.ir A YOUR_LOADBALANCER_IP
|
||||
staging.peikarband.ir A YOUR_LOADBALANCER_IP
|
||||
harbor.peikarband.ir A YOUR_LOADBALANCER_IP
|
||||
argocd.peikarband.ir A YOUR_LOADBALANCER_IP
|
||||
```
|
||||
|
||||
### 4. Sync اولیه با ArgoCD
|
||||
|
||||
```bash
|
||||
# Production
|
||||
argocd app sync peikarband
|
||||
argocd app wait peikarband --timeout 600
|
||||
|
||||
# Staging
|
||||
argocd app sync peikarband-staging
|
||||
argocd app wait peikarband-staging --timeout 600
|
||||
```
|
||||
|
||||
### 5. بررسی وضعیت Deployment
|
||||
|
||||
```bash
|
||||
# Pods
|
||||
kubectl get pods -n peikarband
|
||||
kubectl get pods -n peikarband-staging
|
||||
|
||||
# Services
|
||||
kubectl get svc -n peikarband
|
||||
|
||||
# Ingress
|
||||
kubectl get ingress -n peikarband
|
||||
|
||||
# Logs
|
||||
kubectl logs -f deployment/peikarband -n peikarband
|
||||
|
||||
# Events
|
||||
kubectl get events -n peikarband --sort-by='.lastTimestamp'
|
||||
```
|
||||
|
||||
### 6. تست Health Checks
|
||||
|
||||
```bash
|
||||
# Production
|
||||
curl https://peikarband.ir/ping
|
||||
curl https://peikarband.ir/health
|
||||
curl https://peikarband.ir/ready
|
||||
|
||||
# Staging
|
||||
curl https://staging.peikarband.ir/ping
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 مانیتورینگ و لاگ
|
||||
|
||||
### 1. نصب Prometheus & Grafana
|
||||
|
||||
```bash
|
||||
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
|
||||
helm repo update
|
||||
|
||||
helm install prometheus prometheus-community/kube-prometheus-stack \
|
||||
--namespace monitoring \
|
||||
--create-namespace
|
||||
```
|
||||
|
||||
### 2. فعالسازی ServiceMonitor
|
||||
|
||||
در `values-production.yaml`:
|
||||
|
||||
```yaml
|
||||
monitoring:
|
||||
serviceMonitor:
|
||||
enabled: true
|
||||
interval: 30s
|
||||
```
|
||||
|
||||
### 3. دسترسی به Grafana
|
||||
|
||||
```bash
|
||||
# Port forward
|
||||
kubectl port-forward svc/prometheus-grafana -n monitoring 3000:80
|
||||
|
||||
# Default credentials
|
||||
Username: admin
|
||||
Password: prom-operator
|
||||
```
|
||||
|
||||
### 4. مشاهده Logs
|
||||
|
||||
```bash
|
||||
# Real-time logs
|
||||
kubectl logs -f deployment/peikarband -n peikarband
|
||||
|
||||
# Logs از همه pods
|
||||
kubectl logs -l app.kubernetes.io/name=peikarband -n peikarband --tail=100
|
||||
|
||||
# Logs با timestamp
|
||||
kubectl logs deployment/peikarband -n peikarband --timestamps=true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 عیبیابی
|
||||
|
||||
### مشکلات متداول
|
||||
|
||||
#### 1. Image Pull Error
|
||||
|
||||
```bash
|
||||
# بررسی secret
|
||||
kubectl get secret harbor-registry-secret -n peikarband -o yaml
|
||||
|
||||
# تست دسترسی به Harbor
|
||||
docker login harbor.peikarband.ir
|
||||
|
||||
# بررسی logs
|
||||
kubectl describe pod POD_NAME -n peikarband
|
||||
```
|
||||
|
||||
#### 2. Database Connection Error
|
||||
|
||||
```bash
|
||||
# بررسی secrets
|
||||
kubectl get secret peikarband-prod-secrets -n peikarband -o yaml
|
||||
|
||||
# تست اتصال به database
|
||||
kubectl run -it --rm debug --image=postgres:14 --restart=Never -- \
|
||||
psql -h postgres-prod.default.svc.cluster.local -U peikarband_prod -d peikarband_prod
|
||||
```
|
||||
|
||||
#### 3. Pod در حالت CrashLoopBackOff
|
||||
|
||||
```bash
|
||||
# بررسی logs
|
||||
kubectl logs POD_NAME -n peikarband --previous
|
||||
|
||||
# بررسی events
|
||||
kubectl describe pod POD_NAME -n peikarband
|
||||
|
||||
# Debug container
|
||||
kubectl debug POD_NAME -it --image=busybox -n peikarband
|
||||
```
|
||||
|
||||
#### 4. Ingress کار نمیکند
|
||||
|
||||
```bash
|
||||
# بررسی ingress
|
||||
kubectl describe ingress peikarband -n peikarband
|
||||
|
||||
# بررسی certificate
|
||||
kubectl describe certificate peikarband-tls -n peikarband
|
||||
|
||||
# لاگ ingress controller
|
||||
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller
|
||||
```
|
||||
|
||||
#### 5. ArgoCD Sync Failed
|
||||
|
||||
```bash
|
||||
# بررسی وضعیت app
|
||||
argocd app get peikarband
|
||||
|
||||
# Sync دستی
|
||||
argocd app sync peikarband --force
|
||||
|
||||
# بررسی diff
|
||||
argocd app diff peikarband
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 منابع اضافی
|
||||
|
||||
- [Woodpecker CI Documentation](https://woodpecker-ci.org/docs)
|
||||
- [Harbor Documentation](https://goharbor.io/docs)
|
||||
- [ArgoCD Documentation](https://argo-cd.readthedocs.io)
|
||||
- [Kubernetes Best Practices](https://kubernetes.io/docs/concepts/configuration/overview/)
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Security Checklist
|
||||
|
||||
- [ ] تمام secrets در Kubernetes ایجاد شدهاند
|
||||
- [ ] Robot account در Harbor محدود است
|
||||
- [ ] SSL certificates نصب شدهاند
|
||||
- [ ] Network policies فعال هستند
|
||||
- [ ] Pod security contexts تنظیم شدهاند
|
||||
- [ ] Resource limits تعریف شدهاند
|
||||
- [ ] Vulnerability scanning فعال است
|
||||
- [ ] Backup استراتژی تعریف شده است
|
||||
|
||||
---
|
||||
|
||||
**نسخه**: 1.0.0
|
||||
**تاریخ**: 2025-12-26
|
||||
**نویسنده**: Peikarband DevOps Team
|
||||
|
||||
@@ -1,449 +0,0 @@
|
||||
# راهنمای Deployment روی Kubernetes با Helm
|
||||
|
||||
این راهنما نحوه deploy کردن پلتفرم Peikarband روی Kubernetes با استفاده از Helm Chart را توضیح میدهد.
|
||||
|
||||
## پیشنیازها
|
||||
|
||||
### 1. ابزارهای مورد نیاز
|
||||
|
||||
```bash
|
||||
# Kubectl (v1.24+)
|
||||
kubectl version --client
|
||||
|
||||
# Helm (v3.10+)
|
||||
helm version
|
||||
|
||||
# Docker (برای build local)
|
||||
docker --version
|
||||
```
|
||||
|
||||
### 2. دسترسی به Kubernetes Cluster
|
||||
|
||||
```bash
|
||||
# تست دسترسی
|
||||
kubectl cluster-info
|
||||
kubectl get nodes
|
||||
```
|
||||
|
||||
### 3. Namespace ها
|
||||
|
||||
```bash
|
||||
# ساخت namespace ها
|
||||
kubectl create namespace production
|
||||
kubectl create namespace staging
|
||||
```
|
||||
|
||||
## ساختار Helm Chart
|
||||
|
||||
```
|
||||
helm/peikarband/
|
||||
├── Chart.yaml # Metadata
|
||||
├── values.yaml # Default values
|
||||
├── values-production.yaml # Production overrides
|
||||
├── templates/
|
||||
│ ├── _helpers.tpl # Helper templates
|
||||
│ ├── deployment.yaml # Deployment
|
||||
│ ├── service.yaml # Service
|
||||
│ ├── ingress.yaml # Ingress
|
||||
│ ├── configmap.yaml # ConfigMap
|
||||
│ ├── serviceaccount.yaml
|
||||
│ ├── hpa.yaml # Horizontal Pod Autoscaler
|
||||
│ ├── pdb.yaml # Pod Disruption Budget
|
||||
│ ├── networkpolicy.yaml
|
||||
│ └── NOTES.txt
|
||||
└── .helmignore
|
||||
```
|
||||
|
||||
## مراحل Deployment
|
||||
|
||||
### 1. آمادهسازی Secrets
|
||||
|
||||
ابتدا باید secrets مورد نیاز را ایجاد کنید:
|
||||
|
||||
```bash
|
||||
# Database credentials
|
||||
kubectl create secret generic peikarband-secrets \
|
||||
--from-literal=db-username=peikarband \
|
||||
--from-literal=db-password=STRONG_PASSWORD_HERE \
|
||||
--from-literal=redis-password=REDIS_PASSWORD_HERE \
|
||||
-n production
|
||||
|
||||
# برای staging
|
||||
kubectl create secret generic peikarband-secrets \
|
||||
--from-literal=db-username=peikarband \
|
||||
--from-literal=db-password=STAGING_PASSWORD \
|
||||
--from-literal=redis-password=REDIS_PASSWORD \
|
||||
-n staging
|
||||
```
|
||||
|
||||
### 2. Build و Push Docker Image
|
||||
|
||||
#### روش اول: با GitHub Actions (توصیه میشود)
|
||||
|
||||
```bash
|
||||
# فقط یک tag بزنید و GitHub Actions خودکار build و deploy میکند
|
||||
git tag -a v0.1.0 -m "Release v0.1.0"
|
||||
git push origin v0.1.0
|
||||
```
|
||||
|
||||
#### روش دوم: Build دستی
|
||||
|
||||
```bash
|
||||
# Build image
|
||||
docker build -t peikarband/landing:0.1.0 .
|
||||
|
||||
# Tag for registry
|
||||
docker tag peikarband/landing:0.1.0 registry.example.com/peikarband/landing:0.1.0
|
||||
|
||||
# Push
|
||||
docker push registry.example.com/peikarband/landing:0.1.0
|
||||
```
|
||||
|
||||
### 3. Validate Helm Chart
|
||||
|
||||
قبل از deploy، chart را validate کنید:
|
||||
|
||||
```bash
|
||||
# Lint
|
||||
helm lint helm/peikarband
|
||||
|
||||
# Dry-run
|
||||
helm install peikarband-test ./helm/peikarband \
|
||||
--dry-run \
|
||||
--debug \
|
||||
--namespace production
|
||||
|
||||
# Template rendering
|
||||
helm template peikarband ./helm/peikarband > rendered.yaml
|
||||
```
|
||||
|
||||
### 4. Deploy به Staging
|
||||
|
||||
```bash
|
||||
helm upgrade --install peikarband-staging ./helm/peikarband \
|
||||
--namespace staging \
|
||||
--create-namespace \
|
||||
--set image.repository=registry.example.com/peikarband/landing \
|
||||
--set image.tag=0.1.0 \
|
||||
--set ingress.hosts[0].host=staging.peikarband.ir \
|
||||
--set replicaCount=2 \
|
||||
--wait \
|
||||
--timeout 5m
|
||||
```
|
||||
|
||||
### 5. تست Staging
|
||||
|
||||
```bash
|
||||
# چک کردن pods
|
||||
kubectl get pods -n staging
|
||||
|
||||
# چک کردن logs
|
||||
kubectl logs -f deployment/peikarband-staging -n staging
|
||||
|
||||
# Port forward برای تست local
|
||||
kubectl port-forward svc/peikarband-staging 3000:3000 -n staging
|
||||
|
||||
# تست health check
|
||||
curl http://localhost:8000/ping
|
||||
```
|
||||
|
||||
### 6. Deploy به Production
|
||||
|
||||
```bash
|
||||
helm upgrade --install peikarband-prod ./helm/peikarband \
|
||||
--namespace production \
|
||||
--create-namespace \
|
||||
--set image.repository=registry.example.com/peikarband/landing \
|
||||
--set image.tag=0.1.0 \
|
||||
--values helm/peikarband/values-production.yaml \
|
||||
--wait \
|
||||
--timeout 10m
|
||||
```
|
||||
|
||||
## پیکربندیهای مهم
|
||||
|
||||
### 1. تغییر تعداد Replicas
|
||||
|
||||
```bash
|
||||
# با Helm
|
||||
helm upgrade peikarband-prod ./helm/peikarband \
|
||||
--namespace production \
|
||||
--reuse-values \
|
||||
--set replicaCount=5
|
||||
|
||||
# یا با kubectl
|
||||
kubectl scale deployment peikarband-prod --replicas=5 -n production
|
||||
```
|
||||
|
||||
### 2. Update Image Version
|
||||
|
||||
```bash
|
||||
helm upgrade peikarband-prod ./helm/peikarband \
|
||||
--namespace production \
|
||||
--reuse-values \
|
||||
--set image.tag=0.2.0
|
||||
```
|
||||
|
||||
### 3. تغییر Resources
|
||||
|
||||
```bash
|
||||
helm upgrade peikarband-prod ./helm/peikarband \
|
||||
--namespace production \
|
||||
--reuse-values \
|
||||
--set resources.limits.cpu=2000m \
|
||||
--set resources.limits.memory=2Gi
|
||||
```
|
||||
|
||||
### 4. فعال/غیرفعال کردن Autoscaling
|
||||
|
||||
```bash
|
||||
# فعال کردن
|
||||
helm upgrade peikarband-prod ./helm/peikarband \
|
||||
--namespace production \
|
||||
--reuse-values \
|
||||
--set autoscaling.enabled=true \
|
||||
--set autoscaling.minReplicas=3 \
|
||||
--set autoscaling.maxReplicas=10
|
||||
|
||||
# غیرفعال کردن
|
||||
helm upgrade peikarband-prod ./helm/peikarband \
|
||||
--namespace production \
|
||||
--reuse-values \
|
||||
--set autoscaling.enabled=false \
|
||||
--set replicaCount=3
|
||||
```
|
||||
|
||||
## Ingress و SSL/TLS
|
||||
|
||||
### نصب cert-manager (برای Let's Encrypt)
|
||||
|
||||
```bash
|
||||
# نصب cert-manager
|
||||
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
|
||||
|
||||
# ساخت ClusterIssuer
|
||||
cat <<EOF | kubectl apply -f -
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: ClusterIssuer
|
||||
metadata:
|
||||
name: letsencrypt-prod
|
||||
spec:
|
||||
acme:
|
||||
server: https://acme-v02.api.letsencrypt.org/directory
|
||||
email: admin@peikarband.ir
|
||||
privateKeySecretRef:
|
||||
name: letsencrypt-prod
|
||||
solvers:
|
||||
- http01:
|
||||
ingress:
|
||||
class: nginx
|
||||
EOF
|
||||
```
|
||||
|
||||
### پیکربندی DNS
|
||||
|
||||
```bash
|
||||
# A Record برای domain اصلی
|
||||
peikarband.ir. A YOUR_CLUSTER_IP
|
||||
|
||||
# CNAME برای www
|
||||
www.peikarband.ir. CNAME peikarband.ir.
|
||||
```
|
||||
|
||||
## Monitoring و Logs
|
||||
|
||||
### 1. مشاهده Logs
|
||||
|
||||
```bash
|
||||
# تمام pods
|
||||
kubectl logs -f deployment/peikarband-prod -n production
|
||||
|
||||
# یک pod خاص
|
||||
kubectl logs -f peikarband-prod-xxxxx-yyyyy -n production
|
||||
|
||||
# تمام logs (از همه pods)
|
||||
kubectl logs -l app.kubernetes.io/name=peikarband -n production --tail=100
|
||||
```
|
||||
|
||||
### 2. مشاهده Events
|
||||
|
||||
```bash
|
||||
kubectl get events -n production --sort-by='.lastTimestamp'
|
||||
```
|
||||
|
||||
### 3. چک کردن Resource Usage
|
||||
|
||||
```bash
|
||||
# CPU و Memory
|
||||
kubectl top pods -n production
|
||||
|
||||
# Metrics از deployment
|
||||
kubectl top deployment peikarband-prod -n production
|
||||
```
|
||||
|
||||
### 4. HPA Status
|
||||
|
||||
```bash
|
||||
kubectl get hpa -n production
|
||||
kubectl describe hpa peikarband-prod -n production
|
||||
```
|
||||
|
||||
## Rollback
|
||||
|
||||
### 1. مشاهده History
|
||||
|
||||
```bash
|
||||
# Helm releases
|
||||
helm history peikarband-prod -n production
|
||||
|
||||
# Kubernetes rollout history
|
||||
kubectl rollout history deployment/peikarband-prod -n production
|
||||
```
|
||||
|
||||
### 2. Rollback با Helm
|
||||
|
||||
```bash
|
||||
# به نسخه قبلی
|
||||
helm rollback peikarband-prod -n production
|
||||
|
||||
# به نسخه خاص
|
||||
helm rollback peikarband-prod 3 -n production
|
||||
```
|
||||
|
||||
### 3. Rollback با Kubectl
|
||||
|
||||
```bash
|
||||
# به نسخه قبلی
|
||||
kubectl rollout undo deployment/peikarband-prod -n production
|
||||
|
||||
# به نسخه خاص
|
||||
kubectl rollout undo deployment/peikarband-prod --to-revision=2 -n production
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Pod در حالت Pending
|
||||
|
||||
```bash
|
||||
# بررسی events
|
||||
kubectl describe pod POD_NAME -n production
|
||||
|
||||
# چک کردن resources
|
||||
kubectl describe nodes
|
||||
```
|
||||
|
||||
### Pod در حالت CrashLoopBackOff
|
||||
|
||||
```bash
|
||||
# مشاهده logs
|
||||
kubectl logs POD_NAME -n production --previous
|
||||
|
||||
# مشاهده events
|
||||
kubectl describe pod POD_NAME -n production
|
||||
```
|
||||
|
||||
### Image Pull Error
|
||||
|
||||
```bash
|
||||
# چک کردن imagePullSecrets
|
||||
kubectl get secrets -n production
|
||||
|
||||
# بررسی pod
|
||||
kubectl describe pod POD_NAME -n production
|
||||
```
|
||||
|
||||
### Health Check Failing
|
||||
|
||||
```bash
|
||||
# تست مستقیم health endpoint
|
||||
kubectl exec -it POD_NAME -n production -- curl localhost:8000/ping
|
||||
|
||||
# بررسی liveness/readiness probes
|
||||
kubectl describe pod POD_NAME -n production
|
||||
```
|
||||
|
||||
## Clean Up
|
||||
|
||||
### حذف Release
|
||||
|
||||
```bash
|
||||
# حذف کامل
|
||||
helm uninstall peikarband-prod -n production
|
||||
|
||||
# با نگه داشتن history
|
||||
helm uninstall peikarband-prod -n production --keep-history
|
||||
```
|
||||
|
||||
### حذف Namespace
|
||||
|
||||
```bash
|
||||
kubectl delete namespace production
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Always use specific image tags
|
||||
```yaml
|
||||
image:
|
||||
tag: "v0.1.0" # ✅ Good
|
||||
# tag: "latest" # ❌ Bad
|
||||
```
|
||||
|
||||
### 2. Set resource limits
|
||||
```yaml
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1Gi
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 512Mi
|
||||
```
|
||||
|
||||
### 3. Enable autoscaling برای production
|
||||
```yaml
|
||||
autoscaling:
|
||||
enabled: true
|
||||
minReplicas: 3
|
||||
maxReplicas: 10
|
||||
```
|
||||
|
||||
### 4. استفاده از Pod Disruption Budget
|
||||
```yaml
|
||||
podDisruptionBudget:
|
||||
enabled: true
|
||||
minAvailable: 1
|
||||
```
|
||||
|
||||
### 5. NetworkPolicy برای امنیت
|
||||
```yaml
|
||||
networkPolicy:
|
||||
enabled: true
|
||||
```
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
workflow ما به صورت خودکار:
|
||||
|
||||
1. ✅ Build Docker image
|
||||
2. ✅ Push به registry
|
||||
3. ✅ Package Helm chart
|
||||
4. ✅ Deploy به staging (on push to main)
|
||||
5. ✅ Deploy به production (on tag)
|
||||
6. ✅ Create GitHub release
|
||||
|
||||
### Manual Trigger
|
||||
|
||||
```bash
|
||||
# از طریق GitHub UI: Actions → CD → Run workflow
|
||||
```
|
||||
|
||||
## Support
|
||||
|
||||
برای مشکلات و سوالات:
|
||||
- 📧 Email: support@peikarband.ir
|
||||
- 💬 Telegram: @peikarband_support
|
||||
- 📚 Docs: https://docs.peikarband.ir
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
# Quick Start - Deploy در 5 دقیقه
|
||||
|
||||
راهنمای سریع برای deploy کردن Peikarband روی Kubernetes.
|
||||
|
||||
## پیشنیاز
|
||||
|
||||
- Kubernetes cluster (v1.24+)
|
||||
- Helm 3 نصب شده
|
||||
- kubectl پیکربندی شده
|
||||
- دسترسی به یک Container Registry
|
||||
|
||||
## مراحل
|
||||
|
||||
### 1. Clone Repository
|
||||
|
||||
```bash
|
||||
git clone https://github.com/peikarband/landing.git
|
||||
cd landing
|
||||
```
|
||||
|
||||
### 2. Build Docker Image
|
||||
|
||||
```bash
|
||||
# تغییر REGISTRY به registry خودتون
|
||||
export REGISTRY=registry.example.com
|
||||
export IMAGE_NAME=peikarband/landing
|
||||
export VERSION=0.1.0
|
||||
|
||||
docker build -t ${REGISTRY}/${IMAGE_NAME}:${VERSION} .
|
||||
docker push ${REGISTRY}/${IMAGE_NAME}:${VERSION}
|
||||
```
|
||||
|
||||
### 3. ساخت Secrets
|
||||
|
||||
```bash
|
||||
kubectl create namespace production
|
||||
|
||||
kubectl create secret generic peikarband-secrets \
|
||||
--from-literal=db-username=peikarband \
|
||||
--from-literal=db-password=YOUR_STRONG_PASSWORD \
|
||||
--from-literal=redis-password=YOUR_REDIS_PASSWORD \
|
||||
-n production
|
||||
```
|
||||
|
||||
### 4. Deploy با Helm
|
||||
|
||||
```bash
|
||||
helm upgrade --install peikarband ./helm/peikarband \
|
||||
--namespace production \
|
||||
--set image.repository=${REGISTRY}/${IMAGE_NAME} \
|
||||
--set image.tag=${VERSION} \
|
||||
--set ingress.hosts[0].host=yourdomain.com \
|
||||
--wait
|
||||
```
|
||||
|
||||
### 5. چک کردن وضعیت
|
||||
|
||||
```bash
|
||||
# Pods
|
||||
kubectl get pods -n production
|
||||
|
||||
# Service
|
||||
kubectl get svc -n production
|
||||
|
||||
# Ingress
|
||||
kubectl get ingress -n production
|
||||
```
|
||||
|
||||
### 6. دسترسی به Application
|
||||
|
||||
```bash
|
||||
# Port forward برای تست
|
||||
kubectl port-forward svc/peikarband 3000:3000 -n production
|
||||
|
||||
# باز کردن در browser
|
||||
open http://localhost:3000
|
||||
```
|
||||
|
||||
## پیکربندی Production
|
||||
|
||||
برای production از `values-production.yaml` استفاده کنید:
|
||||
|
||||
```bash
|
||||
helm upgrade --install peikarband ./helm/peikarband \
|
||||
--namespace production \
|
||||
--set image.repository=${REGISTRY}/${IMAGE_NAME} \
|
||||
--set image.tag=${VERSION} \
|
||||
--values helm/peikarband/values-production.yaml \
|
||||
--wait
|
||||
```
|
||||
|
||||
## Uninstall
|
||||
|
||||
```bash
|
||||
helm uninstall peikarband -n production
|
||||
kubectl delete namespace production
|
||||
```
|
||||
|
||||
## بعدش چی؟
|
||||
|
||||
- [مستندات کامل Kubernetes](./kubernetes.md)
|
||||
- [راهنمای CI/CD](../development/ci-cd.md)
|
||||
- [Troubleshooting](./troubleshooting.md)
|
||||
|
||||
@@ -1,386 +0,0 @@
|
||||
# استانداردهای کدنویسی
|
||||
|
||||
## اصول کلی
|
||||
|
||||
### 1. کد تمیز (Clean Code)
|
||||
|
||||
کد باید:
|
||||
- خوانا باشد
|
||||
- ساده باشد
|
||||
- قابل فهم باشد
|
||||
- قابل نگهداری باشد
|
||||
|
||||
### 2. PEP 8 Compliance
|
||||
|
||||
**الزامی**: تمام کدها باید با PEP 8 مطابقت داشته باشند.
|
||||
|
||||
استفاده از ابزارها:
|
||||
```bash
|
||||
black src/ # Auto-formatting
|
||||
flake8 src/ # Linting
|
||||
isort src/ # Import sorting
|
||||
```
|
||||
|
||||
## قوانین Naming
|
||||
|
||||
### Classes
|
||||
|
||||
```python
|
||||
# ✅ GOOD: PascalCase
|
||||
class UserService:
|
||||
pass
|
||||
|
||||
class PaymentGateway:
|
||||
pass
|
||||
|
||||
class DatabaseConnection:
|
||||
pass
|
||||
|
||||
# ❌ BAD
|
||||
class user_service: # Wrong case
|
||||
class payment_gateway_service: # Too long
|
||||
class UServ: # Unclear abbreviation
|
||||
```
|
||||
|
||||
### Functions & Methods
|
||||
|
||||
```python
|
||||
# ✅ GOOD: snake_case, descriptive
|
||||
def calculate_total_price(items: List[Item]) -> Decimal:
|
||||
pass
|
||||
|
||||
def send_welcome_email(user: User) -> bool:
|
||||
pass
|
||||
|
||||
# ❌ BAD
|
||||
def calcTotPrice(): # Mixed case
|
||||
def cp(): # Not descriptive
|
||||
def calculate(): # Too vague
|
||||
```
|
||||
|
||||
### Variables
|
||||
|
||||
```python
|
||||
# ✅ GOOD
|
||||
user_email = "test@example.com"
|
||||
total_amount = Decimal("100.00")
|
||||
is_active = True
|
||||
MAX_ATTEMPTS = 3 # Constant
|
||||
|
||||
# ❌ BAD
|
||||
e = "test@example.com" # Too short
|
||||
userEmail = "test@example.com" # camelCase
|
||||
TOTAL = 100 # Constant style for variable
|
||||
```
|
||||
|
||||
## Type Hints
|
||||
|
||||
**الزامی**: همه function signatures باید type hints داشته باشند.
|
||||
|
||||
```python
|
||||
from typing import Optional, List, Dict, Any
|
||||
from decimal import Decimal
|
||||
|
||||
# ✅ GOOD
|
||||
def get_user(user_id: int) -> Optional[User]:
|
||||
pass
|
||||
|
||||
def create_invoice(
|
||||
user_id: int,
|
||||
amount: Decimal,
|
||||
items: List[InvoiceItem]
|
||||
) -> Invoice:
|
||||
pass
|
||||
|
||||
# ❌ BAD
|
||||
def get_user(user_id): # No types
|
||||
pass
|
||||
|
||||
def create_invoice(user_id, amount, items): # No types
|
||||
pass
|
||||
```
|
||||
|
||||
## Docstrings
|
||||
|
||||
**الزامی**: همه public functions, classes, و methods باید docstring داشته باشند.
|
||||
|
||||
### Google Style (استاندارد پروژه)
|
||||
|
||||
```python
|
||||
def create_user(
|
||||
email: str,
|
||||
password: str,
|
||||
full_name: str
|
||||
) -> User:
|
||||
"""Create a new user account.
|
||||
|
||||
Args:
|
||||
email: User's email address
|
||||
password: Plain text password
|
||||
full_name: User's full name
|
||||
|
||||
Returns:
|
||||
User: Created user object
|
||||
|
||||
Raises:
|
||||
EmailAlreadyExistsException: If email exists
|
||||
WeakPasswordException: If password is weak
|
||||
|
||||
Example:
|
||||
>>> user = create_user(
|
||||
... email="test@example.com",
|
||||
... password="SecurePass123!",
|
||||
... full_name="John Doe"
|
||||
... )
|
||||
"""
|
||||
pass
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Use Specific Exceptions
|
||||
|
||||
```python
|
||||
# ✅ GOOD
|
||||
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))
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.critical("unexpected_error", error=str(e))
|
||||
raise
|
||||
|
||||
# ❌ BAD
|
||||
try:
|
||||
user = get_user(user_id)
|
||||
except: # Never use bare except!
|
||||
pass
|
||||
|
||||
try:
|
||||
user = get_user(user_id)
|
||||
except Exception: # Too broad
|
||||
pass
|
||||
```
|
||||
|
||||
### Custom Exception Hierarchy
|
||||
|
||||
```python
|
||||
class PeikarbandException(Exception):
|
||||
"""Base exception."""
|
||||
pass
|
||||
|
||||
class DomainException(PeikarbandException):
|
||||
"""Domain layer exceptions."""
|
||||
pass
|
||||
|
||||
class UserNotFoundException(DomainException):
|
||||
"""User not found."""
|
||||
pass
|
||||
```
|
||||
|
||||
## Code Organization
|
||||
|
||||
### Imports
|
||||
|
||||
```python
|
||||
# 1. Standard library
|
||||
import os
|
||||
import sys
|
||||
from typing import Optional, List
|
||||
from decimal import Decimal
|
||||
|
||||
# 2. Third-party
|
||||
import redis
|
||||
from sqlalchemy import Column, Integer
|
||||
from pydantic import BaseModel
|
||||
|
||||
# 3. Local
|
||||
from src.config.settings import settings
|
||||
from src.core.domain.entities.user import User
|
||||
```
|
||||
|
||||
### Function Length
|
||||
|
||||
**Max 50 lines per function** (توصیه: 20-30 lines)
|
||||
|
||||
```python
|
||||
# ✅ GOOD: Short and focused
|
||||
def calculate_discount(amount: Decimal, user: User) -> Decimal:
|
||||
"""Calculate user discount."""
|
||||
if user.is_premium:
|
||||
return amount * Decimal("0.10")
|
||||
return Decimal("0.00")
|
||||
|
||||
# ❌ BAD: Too long (100+ lines)
|
||||
def process_order(order_data):
|
||||
# 100+ lines of code
|
||||
pass
|
||||
```
|
||||
|
||||
### Class Length
|
||||
|
||||
**Max 300 lines per class** (توصیه: 100-200 lines)
|
||||
|
||||
اگر class بزرگ شد، به چند class کوچکتر تقسیم کنید.
|
||||
|
||||
## Comments
|
||||
|
||||
### When to Comment
|
||||
|
||||
```python
|
||||
# ✅ GOOD: Explain WHY, not WHAT
|
||||
def calculate_tax(amount: Decimal) -> Decimal:
|
||||
# Iranian tax rate is 9% as of 2024
|
||||
TAX_RATE = Decimal("0.09")
|
||||
return amount * TAX_RATE
|
||||
|
||||
# ❌ BAD: States the obvious
|
||||
def add(a, b):
|
||||
# Add two numbers
|
||||
return a + b
|
||||
```
|
||||
|
||||
### TODO Comments
|
||||
|
||||
```python
|
||||
# TODO(username): Description of what needs to be done
|
||||
# TODO(john): Implement caching for this query
|
||||
# FIXME(jane): This breaks when amount is negative
|
||||
# HACK(bob): Temporary workaround until API is fixed
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Single Responsibility
|
||||
|
||||
```python
|
||||
# ✅ GOOD
|
||||
class UserRepository:
|
||||
def save(self, user: User) -> User:
|
||||
pass
|
||||
|
||||
class EmailService:
|
||||
def send_email(self, to: str, subject: str) -> bool:
|
||||
pass
|
||||
|
||||
# ❌ BAD
|
||||
class UserManager:
|
||||
def save_user(self, user):
|
||||
pass
|
||||
|
||||
def send_email(self, user):
|
||||
pass
|
||||
|
||||
def log_activity(self, user):
|
||||
pass
|
||||
```
|
||||
|
||||
### 2. DRY (Don't Repeat Yourself)
|
||||
|
||||
```python
|
||||
# ❌ BAD
|
||||
def get_user_name(user_id):
|
||||
db = connect_db()
|
||||
user = db.query(User).filter_by(id=user_id).first()
|
||||
db.close()
|
||||
return user.name
|
||||
|
||||
def get_user_email(user_id):
|
||||
db = connect_db()
|
||||
user = db.query(User).filter_by(id=user_id).first()
|
||||
db.close()
|
||||
return user.email
|
||||
|
||||
# ✅ GOOD
|
||||
def get_user(user_id: int) -> Optional[User]:
|
||||
with get_db_context() as db:
|
||||
return db.query(User).filter_by(id=user_id).first()
|
||||
|
||||
def get_user_name(user_id: int) -> Optional[str]:
|
||||
user = get_user(user_id)
|
||||
return user.name if user else None
|
||||
```
|
||||
|
||||
### 3. Early Return
|
||||
|
||||
```python
|
||||
# ✅ GOOD: Early return
|
||||
def process_payment(amount: Decimal) -> bool:
|
||||
if amount <= 0:
|
||||
return False
|
||||
|
||||
if not user.has_sufficient_balance(amount):
|
||||
return False
|
||||
|
||||
# Process payment
|
||||
return True
|
||||
|
||||
# ❌ BAD: Nested conditions
|
||||
def process_payment(amount):
|
||||
if amount > 0:
|
||||
if user.has_sufficient_balance(amount):
|
||||
# Process payment
|
||||
return True
|
||||
return False
|
||||
```
|
||||
|
||||
### 4. Use Constants
|
||||
|
||||
```python
|
||||
# ✅ GOOD
|
||||
MAX_LOGIN_ATTEMPTS = 3
|
||||
PASSWORD_MIN_LENGTH = 8
|
||||
SESSION_TIMEOUT_MINUTES = 30
|
||||
|
||||
if attempts >= MAX_LOGIN_ATTEMPTS:
|
||||
lock_account()
|
||||
|
||||
# ❌ BAD: Magic numbers
|
||||
if attempts >= 3: # What's 3?
|
||||
lock_account()
|
||||
```
|
||||
|
||||
### 5. Avoid Deep Nesting
|
||||
|
||||
```python
|
||||
# ✅ GOOD: Max 2-3 levels
|
||||
def process_order(order: Order) -> bool:
|
||||
if not order.is_valid():
|
||||
return False
|
||||
|
||||
if not user.can_order():
|
||||
return False
|
||||
|
||||
return save_order(order)
|
||||
|
||||
# ❌ BAD: Too nested
|
||||
def process_order(order):
|
||||
if order:
|
||||
if order.is_valid():
|
||||
if user:
|
||||
if user.can_order():
|
||||
if save_order(order):
|
||||
return True
|
||||
return False
|
||||
```
|
||||
|
||||
## Code Review Checklist
|
||||
|
||||
قبل از ارسال PR، این موارد را بررسی کنید:
|
||||
|
||||
- [ ] همه تستها pass میشوند
|
||||
- [ ] Code coverage کافی است (>80%)
|
||||
- [ ] تمام functions دارای type hints هستند
|
||||
- [ ] تمام public functions دارای docstring هستند
|
||||
- [ ] black, flake8, mypy بدون error
|
||||
- [ ] هیچ TODO/FIXME جدید بدون توضیح نیست
|
||||
- [ ] تغییرات در CHANGELOG.md ثبت شده
|
||||
- [ ] مستندات بهروز شده
|
||||
|
||||
---
|
||||
|
||||
**الزامات**: این استانداردها الزامی هستند و در code review بررسی میشوند.
|
||||
|
||||
@@ -1,433 +0,0 @@
|
||||
# Git Workflow
|
||||
|
||||
## Branch Strategy
|
||||
|
||||
### Main Branches
|
||||
|
||||
```
|
||||
main (production)
|
||||
└── develop (staging)
|
||||
```
|
||||
|
||||
- **main**: Production-ready code
|
||||
- **develop**: Integration branch for features
|
||||
|
||||
### Supporting Branches
|
||||
|
||||
```
|
||||
develop
|
||||
├── feature/user-authentication
|
||||
├── feature/billing-system
|
||||
├── bugfix/payment-timeout
|
||||
└── hotfix/security-patch
|
||||
```
|
||||
|
||||
## Branch Naming Convention
|
||||
|
||||
### Feature Branches
|
||||
```
|
||||
feature/short-description
|
||||
feature/user-auth
|
||||
feature/payment-gateway
|
||||
```
|
||||
|
||||
### Bugfix Branches
|
||||
```
|
||||
bugfix/issue-description
|
||||
bugfix/payment-timeout
|
||||
bugfix/email-sending
|
||||
```
|
||||
|
||||
### Hotfix Branches
|
||||
```
|
||||
hotfix/critical-issue
|
||||
hotfix/security-vuln
|
||||
hotfix/data-loss
|
||||
```
|
||||
|
||||
## Commit Message Format
|
||||
|
||||
### Structure
|
||||
|
||||
```
|
||||
<type>(<scope>): <subject>
|
||||
|
||||
<body>
|
||||
|
||||
<footer>
|
||||
```
|
||||
|
||||
### Type
|
||||
|
||||
- `feat`: ویژگی جدید
|
||||
- `fix`: رفع باگ
|
||||
- `docs`: تغییرات مستندات
|
||||
- `style`: فرمتبندی، فاصلهگذاری
|
||||
- `refactor`: بازنویسی کد
|
||||
- `perf`: بهبود performance
|
||||
- `test`: اضافه/اصلاح تست
|
||||
- `chore`: کارهای نگهداری
|
||||
- `build`: تغییرات build system
|
||||
- `ci`: تغییرات CI/CD
|
||||
|
||||
### Scope
|
||||
|
||||
بخشی از کد که تغییر کرده:
|
||||
- `auth`
|
||||
- `billing`
|
||||
- `api`
|
||||
- `database`
|
||||
- `ui`
|
||||
|
||||
### Examples
|
||||
|
||||
```bash
|
||||
feat(auth): add two-factor authentication
|
||||
|
||||
- Implement TOTP-based 2FA
|
||||
- Add QR code generation
|
||||
- Add backup codes
|
||||
|
||||
Closes #123
|
||||
```
|
||||
|
||||
```bash
|
||||
fix(payment): resolve timeout issue with zarinpal
|
||||
|
||||
The payment gateway was timing out due to long response time.
|
||||
Added retry logic with exponential backoff.
|
||||
|
||||
Fixes #456
|
||||
```
|
||||
|
||||
```bash
|
||||
docs(api): update authentication endpoints
|
||||
|
||||
Added examples for JWT token usage and refresh flow.
|
||||
```
|
||||
|
||||
## Workflow Steps
|
||||
|
||||
### 1. شروع کار روی Feature جدید
|
||||
|
||||
```bash
|
||||
# بروزرسانی develop
|
||||
git checkout develop
|
||||
git pull origin develop
|
||||
|
||||
# ایجاد branch جدید
|
||||
git checkout -b feature/my-feature
|
||||
|
||||
# شروع کدنویسی...
|
||||
```
|
||||
|
||||
### 2. Commit های منظم
|
||||
|
||||
```bash
|
||||
# بررسی تغییرات
|
||||
git status
|
||||
git diff
|
||||
|
||||
# Stage کردن
|
||||
git add src/specific/file.py
|
||||
# یا
|
||||
git add .
|
||||
|
||||
# Commit
|
||||
git commit -m "feat(scope): description"
|
||||
|
||||
# Push (اولین بار)
|
||||
git push -u origin feature/my-feature
|
||||
|
||||
# Push های بعدی
|
||||
git push
|
||||
```
|
||||
|
||||
### 3. نگهداری Branch بهروز
|
||||
|
||||
```bash
|
||||
# بروزرسانی از develop
|
||||
git checkout develop
|
||||
git pull origin develop
|
||||
|
||||
git checkout feature/my-feature
|
||||
git merge develop
|
||||
|
||||
# حل conflict ها (در صورت وجود)
|
||||
# ... edit files ...
|
||||
git add .
|
||||
git commit -m "merge: resolve conflicts with develop"
|
||||
```
|
||||
|
||||
### 4. ایجاد Pull Request
|
||||
|
||||
1. Push کردن همه commits
|
||||
2. رفتن به GitHub/GitLab
|
||||
3. Create Pull Request
|
||||
4. انتخاب base: `develop`, compare: `feature/my-feature`
|
||||
5. عنوان و توضیحات
|
||||
6. Request reviewers
|
||||
7. Link کردن issues
|
||||
|
||||
### 5. Code Review Process
|
||||
|
||||
**برای نویسنده**:
|
||||
- پاسخ به comments
|
||||
- انجام تغییرات درخواستی
|
||||
- Push کردن updates
|
||||
- Request re-review
|
||||
|
||||
**برای Reviewer**:
|
||||
- بررسی کد با دقت
|
||||
- Check کردن tests
|
||||
- بررسی code quality
|
||||
- Approve یا Request Changes
|
||||
|
||||
### 6. Merge
|
||||
|
||||
پس از approval:
|
||||
```bash
|
||||
# Squash and Merge (توصیه میشود)
|
||||
# یا
|
||||
# Merge Commit
|
||||
# یا
|
||||
# Rebase and Merge
|
||||
```
|
||||
|
||||
### 7. پاک کردن Branch
|
||||
|
||||
```bash
|
||||
# Local
|
||||
git branch -d feature/my-feature
|
||||
|
||||
# Remote (معمولا automatic)
|
||||
git push origin --delete feature/my-feature
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Commit های کوچک و مشخص
|
||||
|
||||
```bash
|
||||
# ✅ GOOD: Small, focused commits
|
||||
git commit -m "feat(auth): add email validation"
|
||||
git commit -m "test(auth): add tests for email validation"
|
||||
git commit -m "docs(auth): document email validation"
|
||||
|
||||
# ❌ BAD: Large, vague commit
|
||||
git commit -m "add stuff"
|
||||
```
|
||||
|
||||
### Commit منظم
|
||||
|
||||
```bash
|
||||
# Commit هر چند ساعت یکبار
|
||||
# نه خیلی کم (هر خط کد)
|
||||
# نه خیلی زیاد (روزی یک commit)
|
||||
```
|
||||
|
||||
### Push روزانه
|
||||
|
||||
```bash
|
||||
# حداقل یکبار در روز push کنید
|
||||
# از دست رفتن کد جلوگیری میکند
|
||||
```
|
||||
|
||||
### استفاده از .gitignore
|
||||
|
||||
```bash
|
||||
# اضافه نکردن فایلهای غیرضروری
|
||||
# - __pycache__
|
||||
# - .env
|
||||
# - venv/
|
||||
# - *.pyc
|
||||
```
|
||||
|
||||
## Git Commands Reference
|
||||
|
||||
### Basic
|
||||
|
||||
```bash
|
||||
# Status
|
||||
git status
|
||||
|
||||
# Log
|
||||
git log
|
||||
git log --oneline
|
||||
git log --graph
|
||||
|
||||
# Diff
|
||||
git diff
|
||||
git diff --staged
|
||||
```
|
||||
|
||||
### Branching
|
||||
|
||||
```bash
|
||||
# لیست branches
|
||||
git branch
|
||||
git branch -a # با remote
|
||||
|
||||
# ایجاد branch
|
||||
git branch feature/new-feature
|
||||
git checkout -b feature/new-feature # ایجاد + checkout
|
||||
|
||||
# تغییر branch
|
||||
git checkout develop
|
||||
|
||||
# حذف branch
|
||||
git branch -d feature/old-feature
|
||||
git branch -D feature/force-delete # Force
|
||||
```
|
||||
|
||||
### Stashing
|
||||
|
||||
```bash
|
||||
# ذخیره تغییرات موقت
|
||||
git stash
|
||||
|
||||
# با پیام
|
||||
git stash save "work in progress"
|
||||
|
||||
# لیست stash ها
|
||||
git stash list
|
||||
|
||||
# برگرداندن stash
|
||||
git stash apply
|
||||
git stash pop # apply + delete
|
||||
|
||||
# حذف stash
|
||||
git stash drop
|
||||
git stash clear # همه
|
||||
```
|
||||
|
||||
### Undoing Changes
|
||||
|
||||
```bash
|
||||
# Unstage file
|
||||
git reset HEAD file.py
|
||||
|
||||
# Discard changes
|
||||
git checkout -- file.py
|
||||
|
||||
# Undo last commit (keep changes)
|
||||
git reset --soft HEAD~1
|
||||
|
||||
# Undo last commit (discard changes)
|
||||
git reset --hard HEAD~1
|
||||
|
||||
# Revert commit (safe)
|
||||
git revert <commit-hash>
|
||||
```
|
||||
|
||||
### Rebasing
|
||||
|
||||
```bash
|
||||
# Rebase on develop
|
||||
git checkout feature/my-feature
|
||||
git rebase develop
|
||||
|
||||
# Interactive rebase
|
||||
git rebase -i HEAD~3 # آخرین 3 commits
|
||||
|
||||
# Abort rebase
|
||||
git rebase --abort
|
||||
|
||||
# Continue after resolving conflicts
|
||||
git rebase --continue
|
||||
```
|
||||
|
||||
### Tags
|
||||
|
||||
```bash
|
||||
# ایجاد tag
|
||||
git tag v1.0.0
|
||||
|
||||
# با پیام
|
||||
git tag -a v1.0.0 -m "Release version 1.0.0"
|
||||
|
||||
# Push tags
|
||||
git push origin v1.0.0
|
||||
git push origin --tags # همه tags
|
||||
|
||||
# حذف tag
|
||||
git tag -d v1.0.0
|
||||
git push origin --delete v1.0.0
|
||||
```
|
||||
|
||||
## Merge Conflicts
|
||||
|
||||
### حل Conflict
|
||||
|
||||
```bash
|
||||
# 1. مشاهده conflicts
|
||||
git status
|
||||
|
||||
# 2. باز کردن فایل و حل conflict
|
||||
# <<<<<<< HEAD
|
||||
# کد شما
|
||||
# =======
|
||||
# کد دیگران
|
||||
# >>>>>>> branch-name
|
||||
|
||||
# 3. Stage کردن
|
||||
git add resolved-file.py
|
||||
|
||||
# 4. Commit
|
||||
git commit -m "merge: resolve conflicts"
|
||||
```
|
||||
|
||||
### ابزارهای کمکی
|
||||
|
||||
```bash
|
||||
# استفاده از merge tool
|
||||
git mergetool
|
||||
|
||||
# استفاده از --ours یا --theirs
|
||||
git checkout --ours file.py
|
||||
git checkout --theirs file.py
|
||||
```
|
||||
|
||||
## Tips & Tricks
|
||||
|
||||
### Aliases
|
||||
|
||||
```bash
|
||||
# در ~/.gitconfig
|
||||
[alias]
|
||||
co = checkout
|
||||
br = branch
|
||||
ci = commit
|
||||
st = status
|
||||
lg = log --oneline --graph --decorate
|
||||
```
|
||||
|
||||
### Commit Templates
|
||||
|
||||
```bash
|
||||
# در ~/.gitmessage
|
||||
<type>(<scope>): <subject>
|
||||
|
||||
<body>
|
||||
|
||||
<footer>
|
||||
```
|
||||
|
||||
```bash
|
||||
git config --global commit.template ~/.gitmessage
|
||||
```
|
||||
|
||||
### Auto-completion
|
||||
|
||||
```bash
|
||||
# Bash
|
||||
source /usr/share/bash-completion/completions/git
|
||||
|
||||
# Zsh
|
||||
autoload -Uz compinit && compinit
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**مهم**: این workflow الزامی است و در code review بررسی میشود.
|
||||
|
||||
@@ -1,371 +0,0 @@
|
||||
# راهنمای راهاندازی محیط توسعه
|
||||
|
||||
## پیشنیازها
|
||||
|
||||
### نرمافزارهای مورد نیاز
|
||||
|
||||
| نرمافزار | نسخه مورد نیاز | لینک نصب |
|
||||
|-----------|----------------|----------|
|
||||
| Python | 3.11+ | [python.org](https://python.org) |
|
||||
| PostgreSQL | 14+ | [postgresql.org](https://postgresql.org) |
|
||||
| Redis | 7+ | [redis.io](https://redis.io) |
|
||||
| Node.js | 18+ | [nodejs.org](https://nodejs.org) |
|
||||
| Git | 2.x+ | [git-scm.com](https://git-scm.com) |
|
||||
|
||||
### بررسی نسخهها
|
||||
|
||||
```bash
|
||||
python --version # باید 3.11 یا بالاتر
|
||||
psql --version # باید 14 یا بالاتر
|
||||
redis-cli --version # باید 7 یا بالاتر
|
||||
node --version # باید 18 یا بالاتر
|
||||
git --version
|
||||
```
|
||||
|
||||
## نصب
|
||||
|
||||
### 1. Clone Repository
|
||||
|
||||
```bash
|
||||
git clone https://github.com/yourusername/peikarband.git
|
||||
cd peikarband
|
||||
```
|
||||
|
||||
### 2. Virtual Environment
|
||||
|
||||
```bash
|
||||
# ایجاد virtual environment
|
||||
python -m venv venv
|
||||
|
||||
# فعالسازی
|
||||
# Linux/Mac:
|
||||
source venv/bin/activate
|
||||
|
||||
# Windows:
|
||||
venv\Scripts\activate
|
||||
```
|
||||
|
||||
### 3. نصب Dependencies
|
||||
|
||||
```bash
|
||||
# Core dependencies
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Development dependencies
|
||||
pip install -r requirements-dev.txt
|
||||
|
||||
# تایید نصب
|
||||
pip list
|
||||
```
|
||||
|
||||
### 4. Pre-commit Hooks
|
||||
|
||||
```bash
|
||||
# نصب pre-commit hooks
|
||||
pre-commit install
|
||||
|
||||
# تست (اختیاری)
|
||||
pre-commit run --all-files
|
||||
```
|
||||
|
||||
## تنظیمات
|
||||
|
||||
### 1. Environment Variables
|
||||
|
||||
```bash
|
||||
# کپی فایل example
|
||||
cp .env.example .env
|
||||
|
||||
# ویرایش .env
|
||||
nano .env
|
||||
```
|
||||
|
||||
**متغیرهای ضروری**:
|
||||
|
||||
```env
|
||||
# Database
|
||||
DATABASE_URL=postgresql://username:password@localhost:5432/peikarband
|
||||
|
||||
# Redis
|
||||
REDIS_URL=redis://localhost:6379/0
|
||||
|
||||
# Security
|
||||
SECRET_KEY=generate-a-secure-random-key
|
||||
JWT_SECRET_KEY=generate-another-secure-random-key
|
||||
|
||||
# Celery
|
||||
CELERY_BROKER_URL=redis://localhost:6379/1
|
||||
CELERY_RESULT_BACKEND=redis://localhost:6379/2
|
||||
```
|
||||
|
||||
**تولید Secret Key**:
|
||||
```bash
|
||||
python -c "import secrets; print(secrets.token_urlsafe(32))"
|
||||
```
|
||||
|
||||
### 2. PostgreSQL Setup
|
||||
|
||||
```bash
|
||||
# ایجاد دیتابیس
|
||||
createdb peikarband
|
||||
|
||||
# یا با psql
|
||||
psql -U postgres
|
||||
CREATE DATABASE peikarband;
|
||||
CREATE USER peikarband_user WITH PASSWORD 'your_password';
|
||||
GRANT ALL PRIVILEGES ON DATABASE peikarband TO peikarband_user;
|
||||
\q
|
||||
```
|
||||
|
||||
### 3. Redis Setup
|
||||
|
||||
```bash
|
||||
# شروع Redis
|
||||
redis-server
|
||||
|
||||
# تست
|
||||
redis-cli ping
|
||||
# باید "PONG" برگرداند
|
||||
```
|
||||
|
||||
### 4. Database Migrations
|
||||
|
||||
```bash
|
||||
# اجرای migrations
|
||||
alembic upgrade head
|
||||
|
||||
# بررسی
|
||||
alembic current
|
||||
```
|
||||
|
||||
### 5. Seed Database (اختیاری)
|
||||
|
||||
```bash
|
||||
python scripts/seed_database.py
|
||||
```
|
||||
|
||||
## اجرای پروژه
|
||||
|
||||
### Development Mode
|
||||
|
||||
```bash
|
||||
# روش 1: با Reflex
|
||||
python -m reflex run
|
||||
|
||||
# روش 2: با auto-reload
|
||||
python -m reflex run --reload
|
||||
|
||||
# روش 3: با loglevel
|
||||
python -m reflex run --loglevel debug
|
||||
```
|
||||
|
||||
### Background Services
|
||||
|
||||
**Terminal 1**: Celery Worker
|
||||
```bash
|
||||
celery -A src.infrastructure.tasks.celery_app worker -l info
|
||||
```
|
||||
|
||||
**Terminal 2**: Celery Beat (برای scheduled tasks)
|
||||
```bash
|
||||
celery -A src.infrastructure.tasks.celery_app beat -l info
|
||||
```
|
||||
|
||||
**Terminal 3**: Flower (Celery monitoring)
|
||||
```bash
|
||||
celery -A src.infrastructure.tasks.celery_app flower
|
||||
# دسترسی: http://localhost:5555
|
||||
```
|
||||
|
||||
### دسترسی به Application
|
||||
|
||||
- **Frontend**: http://localhost:3000
|
||||
- **Backend API**: http://localhost:8000
|
||||
- **Flower (Celery)**: http://localhost:5555
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### 1. Branch جدید
|
||||
|
||||
```bash
|
||||
git checkout develop
|
||||
git pull origin develop
|
||||
git checkout -b feature/your-feature-name
|
||||
```
|
||||
|
||||
### 2. کدنویسی
|
||||
|
||||
```bash
|
||||
# قبل از commit
|
||||
black src/
|
||||
isort src/
|
||||
flake8 src/
|
||||
mypy src/
|
||||
|
||||
# یا با pre-commit
|
||||
pre-commit run --all-files
|
||||
```
|
||||
|
||||
### 3. Testing
|
||||
|
||||
```bash
|
||||
# همه تستها
|
||||
pytest
|
||||
|
||||
# با coverage
|
||||
pytest --cov=src tests/
|
||||
|
||||
# تستهای خاص
|
||||
pytest tests/unit/
|
||||
pytest tests/integration/
|
||||
|
||||
# تست یک فایل
|
||||
pytest tests/unit/test_user.py
|
||||
|
||||
# تست یک function
|
||||
pytest tests/unit/test_user.py::test_create_user
|
||||
```
|
||||
|
||||
### 4. Commit
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "feat(scope): description"
|
||||
git push origin feature/your-feature-name
|
||||
```
|
||||
|
||||
### 5. Pull Request
|
||||
|
||||
1. Create PR از feature branch به develop
|
||||
2. منتظر code review باشید
|
||||
3. اصلاحات لازم را انجام دهید
|
||||
4. Merge
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### مشکل: ModuleNotFoundError
|
||||
|
||||
```bash
|
||||
# مطمئن شوید که در virtual environment هستید
|
||||
which python
|
||||
# باید به venv اشاره کند
|
||||
|
||||
# نصب مجدد
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### مشکل: Database Connection
|
||||
|
||||
```bash
|
||||
# بررسی PostgreSQL
|
||||
sudo systemctl status postgresql
|
||||
|
||||
# شروع PostgreSQL
|
||||
sudo systemctl start postgresql
|
||||
|
||||
# تست connection
|
||||
psql -U username -d peikarband
|
||||
```
|
||||
|
||||
### مشکل: Redis Connection
|
||||
|
||||
```bash
|
||||
# بررسی Redis
|
||||
redis-cli ping
|
||||
|
||||
# شروع Redis
|
||||
redis-server
|
||||
|
||||
# بررسی port
|
||||
netstat -an | grep 6379
|
||||
```
|
||||
|
||||
### مشکل: Port Already in Use
|
||||
|
||||
```bash
|
||||
# پیدا کردن process
|
||||
lsof -i :3000
|
||||
lsof -i :8000
|
||||
|
||||
# Kill process
|
||||
kill -9 <PID>
|
||||
```
|
||||
|
||||
## ابزارهای مفید
|
||||
|
||||
### IDE Setup
|
||||
|
||||
**VS Code Extensions**:
|
||||
- Python
|
||||
- Pylance
|
||||
- Python Test Explorer
|
||||
- GitLens
|
||||
- Better Comments
|
||||
|
||||
**PyCharm**: تنظیمات پیشنهادی در `.idea/` موجود است.
|
||||
|
||||
### Database Tools
|
||||
|
||||
- **pgAdmin**: GUI برای PostgreSQL
|
||||
- **DBeaver**: Multi-database tool
|
||||
- **TablePlus**: Modern database GUI
|
||||
|
||||
### API Testing
|
||||
|
||||
- **httpie**: `pip install httpie`
|
||||
- **Postman**: Desktop app
|
||||
- **Insomnia**: Alternative to Postman
|
||||
|
||||
## بروزرسانی Dependencies
|
||||
|
||||
```bash
|
||||
# بررسی dependencies قدیمی
|
||||
pip list --outdated
|
||||
|
||||
# بروزرسانی یک package
|
||||
pip install --upgrade package-name
|
||||
|
||||
# بروزرسانی همه (با دقت!)
|
||||
pip install --upgrade -r requirements.txt
|
||||
|
||||
# ذخیره نسخههای جدید
|
||||
pip freeze > requirements.txt
|
||||
```
|
||||
|
||||
## مشکلات رایج
|
||||
|
||||
### Import Error
|
||||
|
||||
اطمینان حاصل کنید که:
|
||||
- Virtual environment فعال است
|
||||
- `PYTHONPATH` صحیح است
|
||||
- همه `__init__.py` ها موجودند
|
||||
|
||||
### Alembic Migration Error
|
||||
|
||||
```bash
|
||||
# Reset alembic
|
||||
alembic downgrade base
|
||||
alembic upgrade head
|
||||
|
||||
# ایجاد migration جدید
|
||||
alembic revision --autogenerate -m "description"
|
||||
```
|
||||
|
||||
### Test Failures
|
||||
|
||||
```bash
|
||||
# پاک کردن cache
|
||||
pytest --cache-clear
|
||||
|
||||
# اجرا با verbose
|
||||
pytest -vv
|
||||
|
||||
# اجرا با output کامل
|
||||
pytest -s
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**نکته**: این راهنما همیشه بهروز نگه داشته میشود. در صورت مشکل به team lead مراجعه کنید.
|
||||
|
||||
902
docs/handbook.md
902
docs/handbook.md
@@ -1,902 +0,0 @@
|
||||
# پروژه پیکربند - 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 prod
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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 باید همیشه بهروز نگه داشته شود.**
|
||||
|
||||
Reference in New Issue
Block a user