Files

WealthWise Backend

Production-grade FastAPI backend for WealthWise financial analytics platform with self-hosted authentication.

Quick Start

Prerequisites

  • Python 3.11+
  • Poetry 1.7+
  • Docker & Docker Compose (recommended)
  • PostgreSQL 15+

The easiest way to get started with both database and backend:

cd backend

# Copy environment template
cp .env.example .env

# Start all services (database + backend)
docker-compose up -d

# View logs
docker-compose logs -f backend

# Stop services
docker-compose down

The API will be available at:

Option 2: Local Development with Docker Database

  1. Start the database:

    docker-compose up -d db
    
  2. Install dependencies:

    poetry install
    
  3. Set up environment:

    cp .env.example .env
    # Edit .env if needed (default should work with Docker DB)
    
  4. Run database migrations:

    # See ALEMBIC.md for detailed instructions
    poetry run alembic upgrade head
    
  5. Run the server:

    poetry run uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
    

Authentication System

WealthWise uses self-hosted JWT-based authentication with OAuth2 Password Flow.

Registration

curl -X POST http://localhost:8000/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@wealthwise.app",
    "password": "securepassword123"
  }'

Login

curl -X POST http://localhost:8000/api/v1/auth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=user@wealthwise.app&password=securepassword123"

Response:

{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "token_type": "bearer"
}

Access Protected Endpoint

curl -X GET http://localhost:8000/api/v1/users/me \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Using Swagger UI

  1. Open http://localhost:8000/api/v1/docs
  2. Click "Authorize" button (top right)
  3. Enter: Bearer <your-token> (replace with actual token)
  4. Or use the /auth/token endpoint to get a token, then use it

Testing

# Run all tests
poetry run pytest

# Run with coverage
poetry run pytest --cov=app --cov-report=html

# Run specific test file
poetry run pytest tests/test_auth.py -v

# Run auth tests only
poetry run pytest tests/test_auth.py -v

Database Migrations

See ALEMBIC.md for detailed migration instructions.

Quick commands:

# Create migration
poetry run alembic revision --autogenerate -m "Description"

# Apply migrations
poetry run alembic upgrade head

# View history
poetry run alembic history

Project Structure

backend/
├── app/
│   ├── api/
│   │   ├── v1/
│   │   │   ├── endpoints/
│   │   │   │   ├── auth.py       # Authentication endpoints
│   │   │   │   ├── health.py     # Health check endpoint
│   │   │   │   └── users.py      # User endpoints
│   │   │   └── api.py            # Router aggregation
│   │   └── deps.py               # Dependencies (DB session, auth)
│   ├── core/
│   │   ├── config.py             # Settings management
│   │   ├── db.py                 # Database engine & sessions
│   │   └── security.py           # Password hashing & JWT utilities
│   ├── models/
│   │   ├── __init__.py           # Model exports
│   │   ├── base.py               # Base SQLModel classes
│   │   ├── user.py               # User model
│   │   ├── portfolio.py          # Portfolio model
│   │   └── transaction.py        # Transaction model
│   ├── schemas/
│   │   ├── __init__.py           # Schema exports
│   │   ├── token.py              # Token schemas (legacy Supabase)
│   │   └── user.py               # User schemas
│   └── main.py                   # FastAPI application factory
├── tests/                        # Test suite
├── pyproject.toml                # Poetry configuration
├── Dockerfile                    # Multi-stage build
├── docker-compose.yml            # Docker Compose services
├── .env.example                  # Environment template
├── README.md                     # This file
└── ALEMBIC.md                    # Migration guide

Environment Variables

See .env.example for all available configuration options.

Required Variables

  • DATABASE_URL: PostgreSQL connection string
    • Local Docker: postgresql+asyncpg://postgres:postgres@localhost:5432/wealthwise
    • Production: postgresql+asyncpg://user:pass@host:5432/dbname
  • SECRET_KEY: JWT signing secret (generate with openssl rand -hex 32)
  • ALGORITHM: JWT algorithm (default: HS256)
  • ACCESS_TOKEN_EXPIRE_MINUTES: Token expiration (default: 30)

Docker Compose Configuration

The docker-compose.yml sets up:

  • PostgreSQL 15 with persistent volume
  • FastAPI backend with hot reload
  • Health checks for both services
  • Shared network for service communication

API Endpoints

Authentication

  • POST /api/v1/auth/register - Register new user
  • POST /api/v1/auth/token - Login (OAuth2 Password Flow)

Users (Protected)

  • GET /api/v1/users/me - Get current user info
  • GET /api/v1/users/me/active - Get current active user

Health Check

  • GET /api/v1/health - Comprehensive health check with DB connectivity
  • GET /api/v1/health/ready - Kubernetes readiness probe
  • GET /api/v1/health/live - Kubernetes liveness probe

Documentation

  • GET /api/v1/docs - Swagger UI
  • GET /api/v1/redoc - ReDoc UI
  • GET /api/v1/openapi.json - OpenAPI specification

Development Guidelines

Adding New Endpoints

  1. Create endpoint file in app/api/v1/endpoints/
  2. Add router to app/api/v1/api.py
  3. Write tests in tests/

Database Models

  1. Inherit from BaseModel in app/models/base.py
  2. Use SQLModel for type-safe ORM operations
  3. Create migration after model changes: poetry run alembic revision --autogenerate -m "Description"

Authentication in Endpoints

from fastapi import APIRouter, Depends
from app.api.deps import get_current_user
from app.models import User

router = APIRouter()

@router.get("/protected")
async def protected_route(current_user: User = Depends(get_current_user)):
    return {"message": f"Hello {current_user.email}"}

Code Quality

  • Format with Black: poetry run black app tests
  • Import sort with isort: poetry run isort app tests
  • Type check with mypy: poetry run mypy app

Security Notes

  • Passwords: Hashed using bcrypt (12 rounds by default)
  • JWT Tokens: HS256 algorithm, 30-minute expiration by default
  • SECRET_KEY: Must be changed in production! Use a strong random key.
  • HTTPS: Always use HTTPS in production to protect tokens
  • CORS: Configure CORS_ORIGINS to only allow your frontend domain

Migration from Supabase

This backend has been migrated from Supabase Auth to self-hosted authentication:

  • JWT validation uses local SECRET_KEY instead of Supabase
  • Password hashing with bcrypt
  • OAuth2 Password Flow endpoints
  • User, Portfolio, and Transaction models
  • Docker Compose for local development

License

Private - WealthWise Financial Technologies