Backend reference (FastAPI)¶
Verze¶
Python: 3.12 (prod) / 3.13 (dev)
FastAPI: 0.136.0
SQLAlchemy: 2.0.49
Alembic: 1.18.4
Pydantic: 2.13.3
Spuštění (dev server)¶
cd ~/avax-platform/backend
source ~/avax-venv/bin/activate
uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
Bare uvicorn 8000 je primární dev backend (viz docs/infrastructure/dev-server.md).
Adresářová struktura¶
backend/app/
├── main.py ← FastAPI app, middleware, CORS
├── core/
│ ├── config.py ← Settings (pydantic-settings, čte .env)
│ ├── database.py ← AsyncSession, get_db dependency
│ ├── security.py ← JWT (HS256 + RS256), bcrypt, decode_token()
│ ├── s3.py ← get_s3_client(), get_presigned_url()
│ └── redis.py ← Redis klient
├── models/ ← SQLAlchemy ORM (user.py, backup.py, company.py, ...)
├── schemas/ ← Pydantic request/response modely
├── routers/ ← HTTP endpointy (auth.py, org.py, catalog.py, storage.py, shares.py, ...)
├── services/ ← business logika (peer_sharing.py, notifications.py, ...)
└── workers/ ← Celery tasky
Environment variables (.env)¶
DATABASE_URL=postgresql+asyncpg://avaxis:avaxis_dev_pass@localhost:5432/avaxis_dev
REDIS_URL=redis://localhost:6379/0
S3_ENDPOINT=https://s3.avaxis.cz
S3_PUBLIC_ENDPOINT=https://s3.avaxis.cz
S3_BUCKET=claudeai
S3_ACCESS_KEY=N0ZWGSW26GENWNQ1UDKD
S3_SECRET_KEY=6u4o0KBNe6SQ6lXoLVFSGX5CM74Ovwv8TC24RsIq
S3_REGION=us-east-1
S3_KEY_ENCRYPTION_KEY=fjpkNOGlrPJdfmcKxuUuL6pb9bF56JV-eBJQvaeBRUE=
S3_KEY_IMPORT_PREFIX=s3klic/
JWT_SECRET=dev-secret-avaxis-platform-2026-change-in-prod
JWT_ALGORITHM=HS256
JWT_PRIVATE_KEY_PATH=keys/jwt_private.pem
JWT_PUBLIC_KEY_PATH=keys/jwt_public.pem
ENVIRONMENT=development
Databáze (PostgreSQL 16)¶
host: 192.168.1.55 (Docker container na dev serveru)
port: 5432
db: avaxis_dev
user: avaxis
password: avaxis_dev_pass
url: postgresql+asyncpg://avaxis:avaxis_dev_pass@localhost:5432/avaxis_dev
ORM: SQLAlchemy 2.0 (async), Alembic migrace v backend/migrations/versions/
Migrace (Alembic)¶
# Na dev serveru
cd ~/avax-platform/backend && source ~/avax-venv/bin/activate
# Nová migrace (autogenerate)
alembic revision --autogenerate -m "popis_zmeny"
# Aplikovat
alembic upgrade head
# Aktuální stav
alembic current
# History
alembic history
Formát nové migrace:
# backend/migrations/versions/XXX_NNN_popis.py
revision = 'XXXXXXXXXX'
down_revision = 'PŘEDCHOZÍ_REVISION'
branch_labels = None
depends_on = None
def upgrade() -> None:
op.create_table('table_name', ...)
def downgrade() -> None:
op.drop_table('table_name')
Před commitem migrace spusť /review-migration — slash command zavolá migration-reviewer subagenta a zkontroluje FK constraints, NOT NULL, indexy, downgrade.
Historické migrace (přehled):
| ID | Soubor | Obsah |
|----|--------|-------|
| 001 | 624b62381ad6_001_... | companies, users, audit_log, gdpr_consents |
| 002 | ...002_... | roles, 2FA, contacts |
| 003 | ...003_... | apps, versions, subscriptions |
| 004 | ...004_... | backup, storage, S3 keys |
| 005 | ...005_... | chat, conversations |
| 006 | ...006_... | support, KB articles |
| 007 | ...007_... | devices, sync_dirs, GC |
| 008 | e5f6a7b8c9d0_... | sync_dir_shares (peer sharing) |
Redis 7¶
url: redis://localhost:6379/0
použití: Celery broker, WebSocket fan-out (broadcast skupiny), session cache
S3 (MinIO-compatible, vlastní server)¶
Endpoint, credentials → viz docs/infrastructure/dev-server.md.
S3 prefixová struktura (bucket claudeai):
claudeai/
├── companies/{company_id}/users/{user_id}/sync/{dir_slug}/ ← sync adresáře
├── companies/{company_id}/apps/{slug}/ ← app zálohy
├── apps/{slug}/{version}/ ← app distribuce
│ ├── manifest.json
│ └── files/{platform}/...
├── s3klic/ ← šifrované S3 klíče
└── avax/launcher/ ← launcher update
├── latest.json
└── avax-launcher-{version}.exe
Python přístup:
import boto3
s3 = boto3.client(
's3',
endpoint_url='https://s3.avaxis.cz',
aws_access_key_id='N0ZWGSW26GENWNQ1UDKD',
aws_secret_access_key='6u4o0KBNe6SQ6lXoLVFSGX5CM74Ovwv8TC24RsIq',
region_name='us-east-1',
)
Konvence kódu (backend)¶
- Python: snake_case, žádné type hints na triviální místa
- API funkce: synchronní (
requestsna launcher side), backend async (SQLAlchemy 2.0 async) - Routery:
from app.core import ...,router = APIRouter(prefix=..., tags=[...]) - Schémata: explicitní
Request/ResponsePydantic modely,response_modelna routě - Service vrstva: thin funkce, router ji jen volá; žádná DB logika v routeru
- Komentáře: minimálně, jen kde WHY není zřejmé
- Migrace: prefix číslem
NNN_+ slug,down_revisionmusí být správně, FK vždy s explicitnímondelete