[INIT-001] Initial project setup with Clean Architecture (feat)
Some checks failed
CD - Build & Deploy / build-and-push (push) Has been cancelled
CD - Build & Deploy / package-helm (push) Has been cancelled
CD - Build & Deploy / deploy-staging (push) Has been cancelled
CD - Build & Deploy / deploy-production (push) Has been cancelled
CD - Build & Deploy / release (push) Has been cancelled
CI / test (3.11) (push) Has been cancelled
CI / test (3.12) (push) Has been cancelled
CI / security (push) Has been cancelled

- Implemented Clean Architecture with Domain, Application, Infrastructure, Presentation layers
- Added comprehensive project structure following SOLID principles
- Created Kubernetes deployment with Helm charts (HPA, PDB, NetworkPolicy)
- Configured ArgoCD for automated deployment (production + staging)
- Implemented CI/CD pipeline with GitHub Actions
- Added comprehensive documentation (handbook, architecture, coding standards)
- Configured PostgreSQL, Redis, Celery for backend services
- Created modern landing page with Persian fonts (Vazirmatn)
- Added Docker multi-stage build for production
- Configured development tools (pytest, black, flake8, mypy, isort)
- Added pre-commit hooks for code quality
- Implemented Makefile for common operations
This commit is contained in:
Ehsan.Asadi
2025-12-26 15:52:50 +03:30
commit 8a924f6091
135 changed files with 8637 additions and 0 deletions

View File

@@ -0,0 +1,386 @@
# استانداردهای کدنویسی
## اصول کلی
### 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 بررسی می‌شوند.