# 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+ ### Option 1: Docker Compose (Recommended) The easiest way to get started with both database and backend: ```bash 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: - API Docs: http://localhost:8000/api/v1/docs - Health Check: http://localhost:8000/api/v1/health ### Option 2: Local Development with Docker Database 1. **Start the database:** ```bash docker-compose up -d db ``` 2. **Install dependencies:** ```bash poetry install ``` 3. **Set up environment:** ```bash cp .env.example .env # Edit .env if needed (default should work with Docker DB) ``` 4. **Run database migrations:** ```bash # See ALEMBIC.md for detailed instructions poetry run alembic upgrade head ``` 5. **Run the server:** ```bash 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 ```bash curl -X POST http://localhost:8000/api/v1/auth/register \ -H "Content-Type: application/json" \ -d '{ "email": "user@wealthwise.app", "password": "securepassword123" }' ``` ### Login ```bash 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: ```json { "access_token": "eyJhbGciOiJIUzI1NiIs...", "token_type": "bearer" } ``` ### Access Protected Endpoint ```bash 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 ` (replace with actual token) 4. Or use the `/auth/token` endpoint to get a token, then use it ## Testing ```bash # 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](ALEMBIC.md) for detailed migration instructions. Quick commands: ```bash # 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 ```python 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