Files
fast-next-template/backend
Felipe Cardoso 065e43c5a9 fix(tests): use delay variables in retry delay test
The delay2 and delay3 variables were calculated but never asserted,
causing lint warnings. Added assertions to verify all delays are
positive and within max bounds.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:19:54 +01:00
..
2025-11-27 09:12:30 +01:00
2025-11-27 09:12:30 +01:00

Syndarix Backend API

The pragmatic, production-ready FastAPI backend for Syndarix.

Overview

Opinionated, secure, and fast. This backend provides the solid foundation you need to ship features, not boilerplate.

Features:

  • Authentication: JWT with refresh tokens, session management, device tracking
  • Database: Async PostgreSQL with SQLAlchemy 2.0, Alembic migrations
  • Security: Rate limiting, CORS, CSP headers, password hashing (bcrypt)
  • Multi-tenancy: Organization-based access control with roles (Owner/Admin/Member)
  • Testing: 97%+ coverage with security-focused test suite
  • Performance: Async throughout, connection pooling, optimized queries
  • Modern Tooling: uv for dependencies, Ruff for linting/formatting, mypy for type checking

Quick Start

Prerequisites

  • Python 3.12+
  • PostgreSQL 14+ (or SQLite for development)
  • uv - Modern Python package manager (replaces pip)

Installation

# Install uv (if not already installed)
curl -LsSf https://astral.sh/uv/install.sh | sh

# Install all dependencies (production + dev)
cd backend
uv sync --extra dev

# Or use the Makefile
make install-dev

# Copy environment template
cp .env.example .env
# Edit .env with your configuration

Why uv?

  • 🚀 10-100x faster than pip
  • 🔒 Reproducible builds via uv.lock lockfile
  • 📦 Better dependency resolution
  • Built by Astral (creators of Ruff)

Database Setup

# Run migrations
python migrate.py apply

# Or use Alembic directly
alembic upgrade head

Run Development Server

# Using uv
uv run uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

# Or activate environment first
source .venv/bin/activate  # On Windows: .venv\Scripts\activate
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

API will be available at:


Dependency Management with uv

Understanding uv

uv is the modern standard for Python dependency management, built in Rust for speed and reliability.

Key files:

  • pyproject.toml - Declares dependencies and tool configurations
  • uv.lock - Locks exact versions for reproducible builds (commit to git)

Common Commands

Installing Dependencies

# Install all dependencies from lockfile
uv sync --extra dev

# Install only production dependencies (no dev tools)
uv sync

# Or use the Makefile
make install-dev    # Install with dev dependencies
make sync           # Sync from lockfile

Adding Dependencies

# Add a production dependency
uv add httpx

# Add a development dependency
uv add --dev pytest-mock

# Add with version constraint
uv add "fastapi>=0.115.0,<0.116.0"

# Add exact version
uv add "pydantic==2.10.6"

After adding dependencies, commit both pyproject.toml and uv.lock to git.

Removing Dependencies

# Remove a package
uv remove httpx

# Remove a dev dependency
uv remove --dev pytest-mock

Updating Dependencies

# Update all packages to latest compatible versions
uv sync --upgrade

# Update a specific package
uv add --upgrade fastapi

# Check for outdated packages
uv pip list --outdated

Running Commands in uv Environment

# Run any Python command via uv (no activation needed)
uv run python script.py
uv run pytest
uv run mypy app/

# Or activate the virtual environment
source .venv/bin/activate
python script.py
pytest

Makefile Commands

We provide convenient Makefile commands that use uv:

# Setup
make install-dev   # Install all dependencies (prod + dev)
make sync          # Sync from lockfile

# Code Quality
make lint          # Run Ruff linter (check only)
make lint-fix      # Run Ruff with auto-fix
make format        # Format code with Ruff
make format-check  # Check if code is formatted
make type-check    # Run mypy type checking
make validate      # Run all checks (lint + format + types)

# Testing
make test          # Run all tests
make test-cov      # Run tests with coverage report

# Utilities
make clean         # Remove cache and build artifacts
make help          # Show all commands

Dependency Workflow Example

# 1. Clone repository
git clone <repo-url>
cd backend

# 2. Install dependencies
make install-dev

# 3. Make changes, add a new dependency
uv add httpx

# 4. Test your changes
make test

# 5. Commit (includes uv.lock)
git add pyproject.toml uv.lock
git commit -m "Add httpx dependency"

# 6. Other developers pull and sync
git pull
make sync  # Uses the committed uv.lock

Troubleshooting uv

Dependencies not found after install:

# Make sure you're using uv run or activated environment
uv run pytest          # Option 1: Run via uv
source .venv/bin/activate  # Option 2: Activate first
pytest

Lockfile out of sync:

# Regenerate lockfile
uv lock

# Force reinstall from lockfile
uv sync --reinstall

uv not found:

# Install uv globally
curl -LsSf https://astral.sh/uv/install.sh | sh

# Add to PATH if needed
export PATH="$HOME/.cargo/bin:$PATH"

Development

Project Structure

app/
├── api/              # API routes and dependencies
│   ├── routes/       # Endpoint implementations
│   └── dependencies/ # Auth, permissions, etc.
├── core/             # Core functionality
│   ├── config.py     # Settings management
│   ├── database.py   # Database engine setup
│   ├── auth.py       # JWT token handling
│   └── exceptions.py # Custom exceptions
├── crud/             # Database operations
├── models/           # SQLAlchemy ORM models
├── schemas/          # Pydantic request/response schemas
├── services/         # Business logic layer
└── utils/            # Utility functions

See docs/ARCHITECTURE.md for detailed architecture documentation.

Configuration

Environment variables (.env):

# Database
POSTGRES_USER=postgres
POSTGRES_PASSWORD=your_password
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_DB=app_db

# Security (IMPORTANT: Change these!)
SECRET_KEY=your-secret-key-min-32-chars-change-in-production
ENVIRONMENT=development  # development | production

# Optional
BACKEND_CORS_ORIGINS=["http://localhost:3000"]
CSP_MODE=relaxed  # strict | relaxed | disabled

# First superuser (auto-created on startup)
FIRST_SUPERUSER_EMAIL=admin@example.com
FIRST_SUPERUSER_PASSWORD=SecurePass123!

⚠️ Security Note: Never commit .env files. Use strong, unique values in production.

Database Migrations

We use Alembic for database migrations with a helper script:

# Generate migration from model changes
python migrate.py generate "add user preferences"

# Apply migrations
python migrate.py apply

# Generate and apply in one step
python migrate.py auto "add user preferences"

# Check current version
python migrate.py current

# List all migrations
python migrate.py list

Manual Alembic usage:

# Generate migration
alembic revision --autogenerate -m "description"

# Apply migrations
alembic upgrade head

# Rollback one migration
alembic downgrade -1

Testing

# Using Makefile (recommended)
make test              # Run all tests
make test-cov          # Run with coverage report

# Using uv directly
IS_TEST=True uv run pytest
IS_TEST=True uv run pytest --cov=app --cov-report=term-missing -n 0

# Run specific test file
IS_TEST=True uv run pytest tests/api/test_auth.py -v

# Run single test
IS_TEST=True uv run pytest tests/api/test_auth.py::TestLogin::test_login_success -v

# Generate HTML coverage report
IS_TEST=True uv run pytest --cov=app --cov-report=html -n 0
open htmlcov/index.html

Test Environment: Uses SQLite in-memory database. Tests run in parallel via pytest-xdist.

Code Quality

# Using Makefile (recommended)
make lint          # Ruff linting
make format        # Ruff formatting
make type-check    # mypy type checking
make validate      # All checks at once

# Using uv directly
uv run ruff check app/ tests/
uv run ruff format app/ tests/
uv run mypy app/

Tools:

  • Ruff: All-in-one linting, formatting, and import sorting (replaces Black, Flake8, isort)
  • mypy: Static type checking with Pydantic plugin

All configurations are in pyproject.toml.


API Documentation

Once the server is running, interactive API documentation is available:


Authentication

Token-Based Authentication

The API uses JWT tokens for authentication:

  1. Login: POST /api/v1/auth/login

    • Returns access token (15 min expiry) and refresh token (7 day expiry)
    • Session tracked with device information
  2. Refresh: POST /api/v1/auth/refresh

    • Exchange refresh token for new access token
    • Validates session is still active
  3. Logout: POST /api/v1/auth/logout

    • Invalidates current session
    • Use logout-all to invalidate all user sessions

Using Protected Endpoints

Include access token in Authorization header:

curl -H "Authorization: Bearer <access_token>" \
  http://localhost:8000/api/v1/users/me

Roles & Permissions

  • Superuser: Full system access (user/org management)
  • Organization Roles:
    • Owner: Full control of organization
    • Admin: Can manage members (except owners)
    • Member: Read-only access

Common Tasks

Create a Superuser

Superusers are created automatically on startup using FIRST_SUPERUSER_EMAIL and FIRST_SUPERUSER_PASSWORD from .env.

To create additional superusers, update a user via SQL or admin API.

Add a New API Endpoint

See docs/FEATURE_EXAMPLE.md for step-by-step guide.

Quick overview:

  1. Create Pydantic schemas in app/schemas/
  2. Create CRUD operations in app/crud/
  3. Create route in app/api/routes/
  4. Register router in app/api/main.py
  5. Write tests in tests/api/

Database Health Check

# Check database connection
python migrate.py check

# Health endpoint
curl http://localhost:8000/health

Docker Support

The Dockerfile uses uv for fast, reproducible builds:

# Development with hot reload
docker-compose -f docker-compose.dev.yml up

# Production
docker-compose up -d

# Rebuild after changes
docker-compose build backend

Docker features:

  • Multi-stage builds (development + production)
  • uv for fast dependency installation
  • uv.lock ensures exact versions in containers
  • Development stage includes dev dependencies
  • Production stage optimized for size and security

Troubleshooting

Common Issues

Module Import Errors

# Ensure dependencies are installed
make install-dev

# Or sync from lockfile
make sync

# Verify Python environment
uv run python --version

uv command not found

# Install uv globally
curl -LsSf https://astral.sh/uv/install.sh | sh

# Add to PATH (add to ~/.bashrc or ~/.zshrc)
export PATH="$HOME/.cargo/bin:$PATH"

Database Connection Failed

# Check PostgreSQL is running
sudo systemctl status postgresql

# Verify credentials in .env
cat .env | grep POSTGRES

Migration Conflicts

# Check migration history
python migrate.py list

# Downgrade and retry
alembic downgrade -1
alembic upgrade head

Tests Failing

# Run with verbose output
make test

# Run single test to isolate issue
IS_TEST=True uv run pytest tests/api/test_auth.py::TestLogin::test_login_success -vv

Dependencies out of sync

# Regenerate lockfile from pyproject.toml
uv lock

# Reinstall everything
make install-dev

Getting Help

See our detailed documentation:


Performance

Database Connection Pooling

Configured in app/core/config.py:

  • Pool size: 20 connections
  • Max overflow: 50 connections
  • Pool timeout: 30 seconds
  • Connection recycling: 1 hour

Async Operations

  • All I/O operations use async/await
  • CPU-intensive operations (bcrypt) run in thread pool
  • No blocking calls in request handlers

Query Optimization

  • N+1 query prevention via eager loading
  • Bulk operations for admin actions
  • Indexed foreign keys and common lookups

Security

Built-in Security Features

  • Password Security: bcrypt hashing, strength validation, common password blocking
  • Token Security: HMAC-SHA256 signed, short-lived access tokens, algorithm validation
  • Session Management: Database-backed, device tracking, revocation support
  • Rate Limiting: Per-endpoint limits on auth/sensitive operations
  • CORS: Explicit origins, methods, and headers only
  • Security Headers: CSP, HSTS, X-Frame-Options, etc.
  • Input Validation: Pydantic schemas, SQL injection prevention (ORM)

Security Best Practices

  1. Never commit secrets: Use .env files (git-ignored)
  2. Strong SECRET_KEY: Min 32 chars, cryptographically random
  3. HTTPS in production: Required for token security
  4. Regular updates: Keep dependencies current (uv sync --upgrade)
  5. Audit logs: Monitor authentication events

Monitoring

Health Check

curl http://localhost:8000/health

Returns:

  • API version
  • Environment
  • Database connectivity
  • Timestamp

Logging

Logs are written to stdout with structured format:

# Configure log level
logging.basicConfig(level=logging.INFO)

# In production, use JSON logs for log aggregation

Additional Resources

Official Documentation

Our Documentation


Built with modern Python tooling:

  • 🚀 uv - 10-100x faster dependency management
  • Ruff - 10-100x faster linting & formatting
  • 🔍 mypy - Static type checking
  • pytest - Comprehensive test suite

All configured in a single pyproject.toml file!