# Anexo76 **Aplicación SaaS para gestión de comercio exterior conforme a Anexos 24, 30 y 22 del SAT** Anexo76 es una plataforma multi-tenant diseñada para maquilas, empresas IMMEX y agentes aduanales, que permite gestionar inventarios, pedimentos y facturas de importación/exportación con control de licencias y cumplimiento normativo. ## 🏗️ Arquitectura ### Backend - **Framework**: FastAPI 0.110+ - **Autenticación**: Keycloak (OpenID Connect) - **Base de Datos**: PostgreSQL con SQLAlchemy - **Modelo Multi-tenant**: Híbrido - BD compartida para tenants pequeños/medianos - BD dedicadas para clientes enterprise - **Estructura Modular**: Patrón similar a NestJS - `models.py`: Modelos ORM (SQLAlchemy) - `dto.py`: Data Transfer Objects (Pydantic) - `service.py`: Lógica de negocio - `routes.py`: Endpoints API ### Frontend - **Framework**: SvelteKit - **Autenticación**: keycloak-js - **UI**: Dashboard moderno y responsivo ### Infraestructura - **Containerización**: Docker / Docker Compose - **Orquestación**: Kubernetes (futuro) - **Monitoreo**: Prometheus + Grafana ## 📁 Estructura del Proyecto ``` anexo76/ ├── backend/ │ ├── main.py # Aplicación FastAPI principal │ ├── requirements.txt # Dependencias Python │ ├── .env.example # Variables de entorno de ejemplo │ ├── core/ # Módulos core │ │ ├── config.py # Configuración centralizada │ │ ├── paths.py # Rutas base y layout_path() para importación CSV │ │ ├── database.py # Configuración de BD multi-tenant │ │ ├── security.py # Autenticación y autorización │ │ └── middleware.py # Middlewares personalizados │ ├── layouts/ # Directorio de datos: temp y errors de importación CSV (creado al arranque) │ └── api/ │ └── v1/ │ ├── router.py # Router principal API v1 │ └── modules/ # Módulos de negocio │ └── a76/ │ ├── layouts_csv/ # Lógica centralizada de cargas por CSV (routes, tasks, validaciones por proceso) │ │ ├── facturas/ │ │ ├── customs_brokers/ │ │ ├── clients_and_providers/ │ │ └── ... # Una carpeta por proceso de importación │ ├── csv_templates/ │ └── ... │ ├── auth/ │ ├── tenants/ # Gestión de tenants │ ├── licenses/ # Control de licencias │ └── ... ├── frontend/ │ ├── src/ │ │ ├── routes/ │ │ ├── lib/ │ │ └── app.html │ ├── package.json │ └── svelte.config.js ├── docker-compose.yml └── README.md ``` ## 🚀 Inicio Rápido ### Requisitos Previos - Docker y Docker Compose - Python 3.11+ (para desarrollo local) - Node.js 18+ (para desarrollo frontend) ### 1. Clonar el repositorio ```bash git clone cd anexo76 ``` ### 2. Configurar variables de entorno ```bash cp backend/.env.example backend/.env # Editar backend/.env con tus configuraciones ``` ### 3. Iniciar con Docker Compose ```bash docker-compose up -d ``` Esto iniciará: - **PostgreSQL** en `localhost:5432` - **Keycloak** en `localhost:8080` - **Backend API** en `localhost:8000` - **Frontend** en `localhost:5173` ### 4. Configurar Keycloak 1. Acceder a Keycloak: http://localhost:8080 2. Login: `admin` / `admin` 3. Crear un nuevo realm o usar el realm `master` 4. Crear cliente para backend: - Client ID: `anexo76-backend` - Client Protocol: `openid-connect` - Access Type: `confidential` - Copiar el Secret y agregarlo a `.env` 5. Crear cliente para frontend: - Client ID: `anexo76-frontend` - Client Protocol: `openid-connect` - Access Type: `public` - Valid Redirect URIs: `http://localhost:5173/*` ### 5. Inicializar base de datos ```bash # Con Docker docker-compose exec backend python -c "from core.database import init_db; init_db()" # O localmente cd backend python -c "from core.database import init_db; init_db()" ``` ### 6. Acceder a la aplicación - **API Documentation**: http://localhost:8000/docs - **Frontend**: http://localhost:5173 - **Keycloak Admin**: http://localhost:8080 ## 🛠️ Produccion ``` docker build -t dev.aduanasoft.com/anexo76/backend:latest -f ./backend/Dockerfile ./backend ``` **Importación CSV y workers Celery**: La lógica de cargas por CSV está en `api/v1/modules/a76/layouts_csv/` (una carpeta por proceso). Los workers Celery deben cargar los módulos `api.v1.modules.a76.layouts_csv..tasks`. El directorio de trabajo del worker debe ser la raíz del backend para que `layout_path("imports", "temp")` y `layout_path("imports", "errors")` apunten a los mismos directorios que la API. Si API y worker comparten volumen, los archivos temporales y de errores se escriben en `backend/layouts/imports/temp` y `backend/layouts/imports/errors`. ``` docker build -t dev.aduanasoft.com/anexo76/backend:latest -f ./backend/Dockerfile ./backend docker build \ --build-arg VITE_API_URL=https://anexo76-dev.aduanasoft.com/api/ \ --build-arg VITE_KEYCLOAK_URL=https://anexo76-dev.aduanasoft.com/kcauth/ \ --build-arg INTERNAL_API_URL=http://backend:3467/api/ \ -t dev.aduanasoft.com/anexo76/frontend:latest \ -f ./frontend/Dockerfile.prod \ ./frontend ``` Publica en el registro (ajusta el registry si corresponde): ``` docker login dev.aduanasoft.com docker push dev.aduanasoft.com/anexo76/backend:latest docker push dev.aduanasoft.com/anexo76/frontend:latest ``` ## 🛠️ Desarrollo Local ### Backend ```bash cd backend python -m venv .venv source .venv/bin/activate # En Windows: .venv\Scripts\activate pip install -r requirements.txt uvicorn main:app --reload ``` Los directorios `backend/layouts/imports/temp` y `backend/layouts/imports/errors` se crean automáticamente al arrancar el backend para la importación CSV. ### Frontend ```bash cd frontend npm install npm run dev ``` ## 📦 Módulos Principales ### 1. **Auth** (`/v1/auth`) - Login con Keycloak - Refresh token - Logout - Información de usuario ### 2. **Tenants** (`/v1/tenants`) - Creación y gestión de tenants - Upgrade de BD compartida a dedicada - Gestión de realms de Keycloak ### 3. **Licenses** (`/v1/licenses`) - Control de planes (Free, Basic, Professional, Enterprise) - Validación de licencias activas - Tracking de uso (usuarios, storage, operaciones) - Límites por plan ## 🔐 Autenticación y Autorización ### Flujo de Autenticación 1. Usuario ingresa credenciales + tenant_slug 2. Backend valida contra Keycloak del realm del tenant 3. Keycloak retorna JWT con tenant_id y roles 4. Middleware valida tenant y licencia en cada request 5. Request procesado si todo es válido ### Roles Disponibles - `admin`: Administrador con acceso total - `user`: Usuario estándar - `auditor`: Solo lectura con acceso a reportes - `system`: Para integraciones y servicios ## 🎯 Multi-Tenancy ### Modelo Híbrido **BD Compartida** (tenants pequeños/medianos): - Tabla única con `tenant_id` como foreign key - Row-level security - Más económico para clientes con bajo volumen **BD Dedicada** (tenants enterprise): - Base de datos PostgreSQL independiente - Máximo aislamiento y performance - Configuración almacenada en `tenants.db_config` ### Migración de Shared a Dedicated ```python # Ejemplo de upgrade from api.v1.modules.tenants.service import TenantService db_config = { "host": "dedicated-db-host.example.com", "port": 5432, "name": "tenant_123_db", "user": "tenant_123_user", "password": "secure_password" } service = TenantService(db) service.upgrade_to_dedicated(tenant_id=123, db_config=db_config) ``` ## 📊 Control de Licencias ### Planes Disponibles | Plan | Usuarios | Storage | Operaciones/mes | Features | | ------------ | --------- | --------- | --------------- | -------------------------------- | | Free | 5 | 10 GB | 1,000 | API básica | | Basic | 20 | 50 GB | 10,000 | + Reportes | | Professional | 100 | 200 GB | 50,000 | + Integraciones | | Enterprise | Ilimitado | Ilimitado | Ilimitado | + Soporte dedicado + BD dedicada | ### Middleware de Validación El `LicenseValidationMiddleware` verifica en cada request: - ✅ Licencia activa - ✅ No expirada - ✅ Límites no excedidos - ✅ Features habilitadas ## 🧪 Testing ```bash # Backend cd backend pytest # Con cobertura pytest --cov=. --cov-report=html # Frontend cd frontend npm test ``` ## 📈 Monitoreo ### Prometheus Metrics El backend expone métricas en `/metrics`: - Request duration - Request count por endpoint - Error rate - Active connections ### Logging Logs estructurados con nivel configurable: - INFO: Operaciones normales - WARNING: Validaciones fallidas - ERROR: Errores de sistema - DEBUG: Información detallada (solo desarrollo) ## 🤝 Contribución 1. Fork el proyecto 2. Crear rama feature (`git checkout -b feature/AmazingFeature`) 3. Commit cambios (`git commit -m 'Add some AmazingFeature'`) 4. Push a la rama (`git push origin feature/AmazingFeature`) 5. Abrir Pull Request ## 📝 Licencia Este proyecto es privado y propietario. ## 📞 Soporte Para soporte técnico o consultas: - Email: soporte@anexo76.com - Documentación: https://docs.anexo76.com --- **Desarrollado con ❤️ para la industria de comercio exterior mexicana**