Přeskočit obsah

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í (requests na launcher side), backend async (SQLAlchemy 2.0 async)
  • Routery: from app.core import ..., router = APIRouter(prefix=..., tags=[...])
  • Schémata: explicitní Request/Response Pydantic modely, response_model na 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_revision musí být správně, FK vždy s explicitním ondelete