# Anexo76 - Resumen de Arquitectura Técnica ## 📋 Índice 1. [Visión General](#visión-general) 2. [Stack Tecnológico](#stack-tecnológico) 3. [Arquitectura del Sistema](#arquitectura-del-sistema) 4. [Estructura del Proyecto](#estructura-del-proyecto) 5. [Flujos Principales](#flujos-principales) 6. [Seguridad](#seguridad) 7. [Base de Datos](#base-de-datos) 8. [API Reference](#api-reference) --- ## Visión General Anexo76 es una aplicación SaaS multi-tenant para gestión de comercio exterior en México, enfocada en cumplir con los Anexos 24, 31 y 22 del SAT. ### Objetivos de Negocio - Gestión de inventarios para maquilas e IMMEX - Control de pedimentos aduanales - Manejo de facturas de importación/exportación - Cumplimiento normativo SAT - Licenciamiento flexible por planes --- ## Stack Tecnológico ### Backend - **Framework**: FastAPI 0.110+ (Python 3.11+) - **ORM**: SQLAlchemy 2.0 - **Autenticación**: Keycloak (OpenID Connect) - **Base de Datos**: PostgreSQL 15+ - **Validación**: Pydantic 2.6+ - **Testing**: Pytest ### Frontend - **Framework**: SvelteKit 2.0+ (Svelte 5) - **Lenguaje**: TypeScript - **Auth Client**: keycloak-js - **Estilos**: TailwindCSS 4.1+ - **Build**: Vite 7+ ### Infraestructura - **Containerización**: Docker / Docker Compose - **Orquestación**: Kubernetes (futuro) - **CI/CD**: GitHub Actions / GitLab CI - **Monitoreo**: Prometheus + Grafana --- ## Arquitectura del Sistema ### Patrón Arquitectónico: Modular Layered (estilo NestJS) ``` ┌─────────────────────────────────────────────────────────┐ │ FRONTEND │ │ SvelteKit + Keycloak-js + TailwindCSS │ └────────────────┬────────────────────────────────────────┘ │ HTTP/REST + JWT ┌────────────────▼────────────────────────────────────────┐ │ API GATEWAY (FastAPI) │ │ Middleware: Tenant | License | Logging | CORS │ └────────────────┬────────────────────────────────────────┘ │ ┌────────┴────────┐ │ │ ┌───────▼──────┐ ┌──────▼────────┐ │ MODULES │ │ CORE LAYER │ │ │ │ │ │ • auth │ │ • config.py │ │ • tenants │ │ • database.py │ │ • licenses │ │ • security.py │ │ • ... │ │ • middleware │ └───────┬──────┘ └───────────────┘ │ ┌───────▼──────────────────────────┐ │ DATABASE LAYER (Multi-tenant) │ │ │ │ ┌──────────┐ ┌──────────────┐ │ │ │ Core DB │ │ Tenant 1 DB │ │ │ │ (shared) │ │ (dedicated) │ │ │ └──────────┘ └──────────────┘ │ └───────────────────────────────────┘ ``` ### Estructura Modular (por módulo) Cada módulo sigue el patrón: ``` modules/{module_name}/ ├── models.py # ORM Models (SQLAlchemy) ├── dto.py # Data Transfer Objects (Pydantic) ├── service.py # Business Logic Layer ├── routes.py # API Endpoints (FastAPI) └── __init__.py # Module exports ``` #### Responsabilidades por Capa 1. **models.py**: Representación de entidades en BD - Define tablas con SQLAlchemy - Relaciones entre entidades - Constraints y validaciones a nivel DB 2. **dto.py**: Contratos de entrada/salida de datos - DTOs de request (CreateDTO, UpdateDTO) - DTOs de response (ResponseDTO) - Validaciones de Pydantic 3. **service.py**: Lógica de negocio - Operaciones CRUD - Validaciones de negocio - Orquestación de operaciones complejas 4. **routes.py**: Exposición HTTP - Definición de endpoints - Documentación OpenAPI automática - Manejo de dependencias (auth, db) --- ## Estructura del Proyecto ``` anexo76/ ├── backend/ │ ├── main.py # Aplicación FastAPI principal │ ├── requirements.txt # Dependencias │ ├── init_db.py # Script de inicialización │ ├── Dockerfile │ │ │ ├── core/ # Capa core (shared) │ │ ├── config.py # Configuración (Pydantic Settings) │ │ ├── database.py # Gestión de BD multi-tenant │ │ ├── security.py # Auth Keycloak + JWT │ │ ├── middleware.py # Middlewares personalizados │ │ └── __init__.py │ │ │ └── api/ │ └── v1/ │ ├── router.py # Router principal v1 │ └── modules/ # Módulos de negocio │ ├── auth/ # Autenticación │ ├── tenants/ # Gestión de tenants │ ├── licenses/ # Control de licencias │ └── ... # Futuros módulos │ ├── frontend/ │ ├── src/ │ │ ├── routes/ # Páginas SvelteKit │ │ │ ├── +layout.svelte # Layout global con Keycloak │ │ │ ├── +page.svelte # Dashboard principal │ │ │ └── callback/ # OAuth callback │ │ │ │ │ └── lib/ │ │ ├── auth.ts # Servicio de autenticación │ │ └── api.ts # Cliente API │ │ │ ├── static/ │ │ └── silent-check-sso.html │ ├── package.json │ └── Dockerfile │ ├── docs/ │ ├── KEYCLOAK_SETUP.md # Guía de configuración │ └── ARCHITECTURE.md # Este documento │ ├── docker-compose.yml # Orquestación completa ├── start.sh # Script de inicio rápido ├── README.md # Documentación principal └── .gitignore ``` --- ## Flujos Principales ### 1. Flujo de Autenticación ``` ┌──────────┐ ┌──────────┐ ┌──────────┐ │ Frontend │ │ Keycloak │ │ Backend │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ │ │ 1. Clic "Login" │ │ ├────────────────────────────>│ │ │ │ │ │ 2. Formulario de login │ │ │<────────────────────────────┤ │ │ │ │ │ 3. Credenciales │ │ ├────────────────────────────>│ │ │ │ │ │ 4. Redirigir + auth code │ │ │<────────────────────────────┤ │ │ │ │ │ 5. Intercambiar code x token│ │ ├────────────────────────────>│ │ │ │ │ │ 6. JWT (access + refresh) │ │ │<────────────────────────────┤ │ │ │ │ │ 7. Request con Bearer token │ │ ├─────────────────────────────┼──────────────────────────>│ │ │ │ │ │ 8. Validar token │ │ │<──────────────────────────┤ │ │ │ │ │ 9. Public key │ │ ├──────────────────────────>│ │ │ │ │ 10. Respuesta con datos │ │ │<─────────────────────────────┼───────────────────────────┤ │ │ │ ``` ### 2. Flujo de Request Multi-tenant ``` Request con JWT ↓ TenantMiddleware ├─ Extrae tenant_id del token ├─ Valida tenant existe y está activo └─ Agrega tenant_id a request.state ↓ LicenseValidationMiddleware ├─ Consulta licencia del tenant ├─ Valida estado (active/expired) ├─ Valida fecha de vigencia └─ Agrega license_info a request.state ↓ Endpoint Handler ├─ Obtiene tenant_id de request.state ├─ Selecciona BD (shared o dedicated) └─ Procesa request ↓ Response ``` ### 3. Flujo de Selección de Base de Datos ```python # Pseudocódigo tenant_id = request.state.tenant_id tenant = db.query(Tenant).filter(Tenant.id == tenant_id).first() if tenant.type == "SHARED": # Usar BD compartida (core_db) db_session = CoreSessionLocal() # Queries incluyen tenant_id en WHERE elif tenant.type == "DEDICATED": # Usar BD dedicada del tenant db_config = json.loads(tenant.db_config) db_session = get_tenant_db(tenant_id, db_config) # No necesita filtrar por tenant_id ``` --- ## Seguridad ### Autenticación - **Keycloak** como Identity Provider - **OpenID Connect** (OIDC) - **JWT** con RS256 (firma asimétrica) - **Refresh tokens** para renovación ### Autorización - **RBAC** (Role-Based Access Control) - Roles: `admin`, `user`, `auditor`, `system` - Middleware `has_role()` para proteger endpoints ### Multi-tenancy - **Aislamiento por tenant_id** en JWT - **Row-level security** en BD compartida - **BD dedicada** para mayor aislamiento (enterprise) ### Validación de Licencias - Middleware verifica en cada request: - ✓ Licencia activa - ✓ No expirada - ✓ Límites no excedidos --- ## Base de Datos ### Modelo Híbrido Multi-tenant #### BD Core (Compartida) Tablas principales: - `tenants`: Información de clientes - `licenses`: Control de licencias por tenant - `license_usage`: Métricas de uso - `users` (futuro): Usuarios por tenant Todas las tablas operacionales incluyen `tenant_id` para segmentación. #### BD Dedicadas (Enterprise) - Una BD PostgreSQL por tenant - Configuración almacenada en `tenants.db_config` - Migración automática desde BD compartida ### Ejemplo de Tabla Multi-tenant ```sql CREATE TABLE inventories ( id SERIAL PRIMARY KEY, tenant_id INTEGER NOT NULL REFERENCES tenants(id), product_code VARCHAR(50) NOT NULL, quantity INTEGER NOT NULL, created_at TIMESTAMP DEFAULT NOW(), -- Índice compuesto para queries eficientes INDEX idx_tenant_product (tenant_id, product_code) ); ``` ### Migración y Upgrade ```python # Tenant en BD compartida → BD dedicada tenant_service.upgrade_to_dedicated( tenant_id=123, db_config={ "host": "dedicated-postgres.example.com", "port": 5432, "name": "tenant_123_db", "user": "tenant_123_user", "password": "secure_password" } ) ``` --- ## API Reference ### Módulo: Authentication (`/v1/auth`) | Endpoint | Método | Descripción | Auth | |----------|--------|-------------|------| | `/auth/login` | POST | Login con Keycloak | Público | | `/auth/refresh` | POST | Renovar access token | Público | | `/auth/me` | GET | Info del usuario actual | Bearer | | `/auth/logout` | POST | Cerrar sesión | Bearer | | `/auth/health` | GET | Health check | Público | ### Módulo: Tenants (`/v1/tenants`) | Endpoint | Método | Descripción | Rol Requerido | |----------|--------|-------------|---------------| | `/tenants` | POST | Crear tenant | admin | | `/tenants` | GET | Listar tenants | admin | | `/tenants/{id}` | GET | Obtener tenant | user | | `/tenants/{id}` | PUT | Actualizar tenant | admin | | `/tenants/{id}` | DELETE | Eliminar tenant | admin | | `/tenants/slug/{slug}` | GET | Obtener por slug | user | ### Módulo: Licenses (`/v1/licenses`) | Endpoint | Método | Descripción | Rol Requerido | |----------|--------|-------------|---------------| | `/licenses` | POST | Crear licencia | admin | | `/licenses/tenant/{id}` | GET | Obtener licencia | user | | `/licenses/tenant/{id}` | PUT | Actualizar licencia | admin | | `/licenses/validate/{id}` | GET | Validar licencia | user | | `/licenses/usage/{id}` | GET | Uso de licencia | user | | `/licenses/my-license` | GET | Mi licencia | user | ### Planes de Licencia | 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 | ∞ | ∞ | ∞ | + Soporte + BD dedicada | --- ## Próximas Implementaciones ### Backend - [ ] Módulo de inventarios - [ ] Módulo de pedimentos - [ ] Módulo de facturas - [ ] Webhooks para integraciones - [ ] Reportes avanzados - [ ] Export/Import de datos ### Frontend - [ ] Dashboard con gráficas - [ ] Gestión de inventarios UI - [ ] Formularios de pedimentos - [ ] Panel de administración - [ ] Reportes interactivos ### DevOps - [ ] CI/CD pipeline - [ ] Tests automatizados - [ ] Monitoreo con Prometheus - [ ] Dashboards de Grafana - [ ] Deploy a Kubernetes - [ ] Backup automatizado --- **Última actualización**: Octubre 2025 **Versión del documento**: 1.0