Skip to content

FlacSy/SaaS-Skeleton

Repository files navigation

🚀 SaaS Skeleton

Production-ready SaaS backend на FastAPI

Auth, multi-tenant, billing, admin — всё необходимое для старта.

Python 3.12+ FastAPI Docker PostgreSQL License: MIT

FeaturesInstallationQuick StartDockerSecurityAPI


✨ Возможности

SaaS Skeleton — готовый бэкенд для мультитенантного SaaS-продукта.

  • 🔐 Auth: JWT (access + refresh), bcrypt для паролей
  • 🏢 Multi-tenant: изоляция данных по tenant_id
  • 👑 Admin: CRUD tenants/users (только admin)
  • 💳 Billing: подписки, trial, Stripe/Mock
  • 📊 Monitoring: health, readiness, Prometheus metrics

📦 Установка

pip install -r requirements.txt

Переменные окружения (см. .env.example):

Переменная Описание
DATABASE_URL PostgreSQL (async): postgresql+asyncpg://user:pass@localhost:5432/demo_saas
JWT_SECRET Секрет для JWT (min 32 символа)
REDIS_URL Redis: redis://localhost:6379

⚡ Быстрый старт

1. Миграции и seed

export DATABASE_URL="postgresql+asyncpg://user:pass@localhost:5432/demo_saas"
export JWT_SECRET="your-secret-min-32-chars"
export REDIS_URL="redis://localhost:6379"

# Миграции (dev)
python -c "import asyncio; from core.database import init_db; asyncio.run(init_db())"

# Seed (dev)
python scripts/seed_dev.py

2. Запуск

uvicorn main:app --host 0.0.0.0 --port 8000

🐳 Docker

Запуск через Docker Compose (PostgreSQL, Redis, app + frontend):

docker compose up --build -d

Фронтенд собирается в образ и отдаётся с http://localhost:8000.

Сервисы и порты:

Сервис Порт Описание
app 8000 FastAPI backend + статика фронтенда
postgres 5433 (внешний 5432) PostgreSQL 16
redis 6380 (внешний 6379) Redis 7

Демо-данные и сброс

Для загрузки фиксированного набора данных (подходит для публичного демо):

docker compose --profile seed run --rm seed

Этот скрипт очищает БД и создаёт:

Email Пароль Роль Tenant Подписка
admin@example.com admin123 admin Demo free
user@example.com user123 user Demo free
alice@acme.com user123 user Acme trial
bob@acme.com user123 user Acme trial
pro@example.com user123 user Pro Showcase pro

Чтобы вернуть данные в «чистое» демо-состояние — снова выполните команду выше. Скрипт идемпотентен.

Автосброс каждые 15 минут (в Docker уже включён): переменная DEMO_AUTO_RESET_MINUTES=15. Можно изменить или отключить (0).

Миграции/seed с хоста:

export DATABASE_URL="postgresql+asyncpg://postgres:postgres@localhost:5433/demo_saas"
python -c "import asyncio; from core.database import init_db; asyncio.run(init_db())"
python scripts/seed_demo.py   # демо-набор
python scripts/seed_dev.py    # только admin

API: http://localhost:8000 • Docs: http://localhost:8000/api/docs • UI: http://localhost:8000


🖥 Frontend

В Docker — фронт уже включён: http://localhost:8000.

Локальная разработка (с hot-reload):

cd frontend
npm install
npm run dev

Открой http://localhost:5173. Vite проксирует /api на backend (localhost:8000).


📂 Структура проекта

app/
  auth/       # Логин, refresh, JWT
  admin/      # CRUD tenants/users (admin only)
  billing/    # Подписки, trial
  users/      # /users/me
  tenants/    # (пусто, резерв)
  monitoring/ # Health, metrics
core/
  config/     # Конфигурация (YAML + env)
  database/   # SQLAlchemy async
  redis/      # Redis client
  security/   # Security headers middleware
  utils/      # password, sanitize

🛡 Безопасность

  • Пароли: bcrypt
  • JWT: HS256, access 30 мин, refresh 7 дней
  • Security headers: HSTS, X-Frame-Options, CSP, X-Content-Type-Options
  • CORS: настраивается в config.yaml
  • Multi-tenant: tenant_id из JWT, нет кросс-доступа

Production

  1. Обязательно задать JWT_SECRET (min 32 символа)
  2. Задать ENV=production
  3. Настроить allow_origins в CORS
  4. Использовать HTTPS

Документация: docs/ARCHITECTURE.md (архитектура, БД, инструменты) • docs/SECURITY_RISKS.mddocs/SECURITY_REFACTOR_AUDIT_REPORT.md


🧪 Тесты

Все тесты (57):

# Unit (моки) + интеграционные (БД)
createdb demo_saas_test  # для интеграционных
TESTING=1 pytest tests/ app/auth/tests app/billing/tests app/monitoring/tests -v

Только unit-тесты (без БД):

TESTING=1 pytest tests/unit app/auth/tests app/billing/tests app/monitoring/tests -v

Только интеграционные (требуется PostgreSQL):

createdb demo_saas_test
TESTING=1 pytest tests/integration/ -v

Другой URL: TEST_DATABASE_URL=postgresql+asyncpg://... pytest tests/ -v


📐 Форматирование

black app core main.py
isort app core main.py

📡 API

Endpoint Описание
/api/docs Swagger UI
/api/redoc ReDoc
/api/openapi.json OpenAPI schema
/health Health check
/ready Readiness
/metrics Prometheus metrics

Developed with ❤️ by FlacSy