Anexo Risk
Refined FastAPI risk-analysis backend with JWT authentication, role-based access, and a clean, tested codebase.
Context
Anexo Risk is a refined FastAPI backend for risk-analysis workflows with JWT authentication. The codebase was cleaned of legacy debug scripts, organized around a zero-ORM SQLite data layer, and documented for portfolio review. The public repository is the canonical version.
The project evolved from a research prototype to a structured API with proper authentication, data validation, and deployment configuration.
Challenges
- Authentication implementation: Designing a JWT-based auth system that is both secure and developer-friendly
- Code sanitization: Removing redundant files, debugging scripts, and temporary artifacts from the history
- Dependency management: Establishing lean production dependencies via
requirements.prod.txt - Docker configuration: Multi-stage build with Node 20 for frontend + Python 3.12-slim for backend
- API design: Creating intuitive endpoints that balance flexibility with strict contract validation
Solution
Architecture
The system uses a FastAPI backend with Pydantic v2 data contracts, JWT authentication for API access, and SQLite via a zero-ORM data layer for persistence. A multi-stage Docker build keeps the runtime image lean.
┌────────────────────────────────────────────────────────────┐
│ ANEXO_RISK LIMPO - ARCHITECTURE │
└────────────────────────────────────────────────────────────┘
[MULTI-STAGE DOCKER BUILD] [PRODUCTION DEPLOY]
Node 20 (frontend) ┌─────────────────┐
│ FastAPI │
──────────────────── ────────────▶│ (Python) │
Frontend build ───────────────────────────▶│ API Endpoints│
│ /api/auth/* │
│ /api/risk/* │
└─────────────────┘
▲ ▲
│ │
docker compose docker run
│ --port
Key Endpoints
| Endpoint | Description | Auth |
|---|---|---|
/api/auth/jwt |
Obtener token JWT | Pública |
/api/auth/refresh |
Renovar token | Pública |
/api/risk/analyze |
Analizar riesgo en celda H3 | Requerido |
/api/risk/profile |
Perfil de riesgo por zona | Requerido |
/api/docs |
Documentación interactiva Swagger | Pública |
JWT Authentication Flow
- Login: POST
/api/auth/jwtwith credentials → receive signed JWT - Access: Include JWT in
Authorization: Bearer <token>header - Refresh: POST
/api/auth/refreshwith refresh token → new access token - Validate: All protected endpoints verify JWT before processing
Data Model
- Users: email, hashed password, created_at, last_login
- Risk Cells: h3_index, risk_profile (K-Means cluster), severity score, metadata
- Analysis Sessions: user_id, cell_id, analysis_type, results, created_at
Production Deployment
# Docker Compose (development + development)
docker compose up --build
# Production single service
docker run -p 8000:8000 juandelaf1/anexo_risk_limpio
API Documentation
Swagger UI automatically generated at /api/docs. All endpoints have OpenAPI 3.0 specification with request/response validation via Pydantic v2 models.
Implementation
The most significant refactoring was the authentication layer. The original project had no auth; the limpio version introduces JWT with refresh token rotation. This involved:
- Designing the user model with email uniqueness and password hashing
- Creating token issuance with access/refresh token pair
- Implementing middleware that validates JWT on all protected endpoints
- Adding endpoint contracts with Pydantic models for request/response
The code cleanup removed 8+ temporary scripts, debug files, and redundant configurations that were tracked in the original git history. The .gitignore was expanded to exclude *.env, *.db, temp_*.py, and debug_*.py files.
The Docker configuration uses a multi-stage build:
- Stage 1: Node 20 builds the frontend (if applicable)
- Stage 2: Python 3.12-slim runs the FastAPI application
- Combined via
docker composefor development ordocker runfor production
The requirements.prod.txt contains only the lean production dependencies, separate from the full ML stack in requirements.txt.
Testing
- 50+ unit tests covering auth flow, endpoint validation, and data processing
- pytest runs on every GitHub Actions push
- Test coverage includes edge cases for token expiration, invalid credentials, and rate limiting
- Integration tests verify the complete auth → analyze → response pipeline
Results
- JWT authentication functional with access and refresh token flow
- Codebase cleaned: redundant files and debug scripts removed from active tracking
- Docker multi-stage build validated for production deployment
- Lean production dependencies via
requirements.prod.txt(vs. full ML stack) - API docs auto-generated with Swagger/OpenAPI 3.0 specification
- 50+ unit tests defined covering auth and analysis paths; the latest GitHub Actions run on this repo is failing — treat CI as not currently green
License
MIT. See repository for full license text.
Lessons Learned
-
Authentication from scratch is non-trivial. Designing a JWT system that handles token rotation, refresh, and revocation requires careful consideration of security edge cases. Off-the-shelf solutions (like Auth0) can simplify this but may not match the project’s integration requirements.
-
Code history cleanup improves presentational value. Removing 8+ years of debug scripts, temporary analyses, and redundant configurations from the “active” view makes the repository more navigable and professional.
-
Separate production requirements files prevent accidental deployment of development-only dependencies (ML libraries, test tools, debugging scripts). The
.gitignoreworking in concert withrequirements.prod.txtprovides defense-in-depth. -
Docker multi-stage builds require careful layer ordering. The build order determines what’s preserved in the final image. Placing the Python stage after the Node stage ensures the smallest possible footprint for a Python-only backend.
-
Swagger/OpenAPI generation is valuable even for internal APIs. It serves as living documentation and enables automatic client generation for consumers of the API.
Future Work
- Multi-tenant projects/portfolios support
- Additional risk analysis models (actuarial, probabilistic)
- GraphQL API alternative to REST
- OpenID Connect integration instead of custom JWT
- Rate limiting and abuse prevention middleware