- Added data table component for displaying clients and providers with infinite scroll functionality. - Created dropdown actions for each client/provider including copy ID, copy RFC, view details, edit, toggle status, and delete. - Implemented dialogs for creating, editing, viewing details, and deleting clients/providers. - Integrated API calls for fetching, creating, editing, deleting, and toggling status of clients/providers. - Enhanced error handling and loading states for better user experience. - Updated server-side logic to handle pagination and company selection for client/provider data retrieval.
21 KiB
Anexo76 - Resumen de Arquitectura Técnica
đ Ăndice
- VisiĂłn General
- Stack TecnolĂłgico
- Arquitectura del Sistema
- Arquitectura de Schemas y MĂłdulos
- Estructura del Proyecto
- Flujos Principales
- Seguridad
- Base de Datos
- 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
-
models.py: RepresentaciĂłn de entidades en BD
- Define tablas con SQLAlchemy
- Relaciones entre entidades
- Constraints y validaciones a nivel DB
-
dto.py: Contratos de entrada/salida de datos
- DTOs de request (CreateDTO, UpdateDTO)
- DTOs de response (ResponseDTO)
- Validaciones de Pydantic
-
service.py: LĂłgica de negocio
- Operaciones CRUD
- Validaciones de negocio
- OrquestaciĂłn de operaciones complejas
-
routes.py: ExposiciĂłn HTTP
- DefiniciĂłn de endpoints
- DocumentaciĂłn OpenAPI automĂĄtica
- Manejo de dependencias (auth, db)
Arquitectura de Schemas y MĂłdulos
Estructura de Schemas en Base de Datos
La aplicaciĂłn utiliza una arquitectura de schemas para organizar lĂłgicamente las tablas segĂșn su funcionalidad y alcance:
Schema a24 (Anexo 24)
Contiene todas las tablas relacionadas con el Anexo 24 del SAT (control de inventarios para empresas IMMEX):
- GestiĂłn de inventarios
- Control de entradas y salidas de mercancĂas
- Reportes de existencias
- Cumplimiento de obligaciones fiscales del Anexo 24
Schema a76 (Anexo 76)
Contiene todas las tablas relacionadas con el Anexo 76 del SAT (comercio exterior):
- Pedimentos aduanales
- Facturas de importaciĂłn/exportaciĂłn
- DocumentaciĂłn de comercio exterior
- Cumplimiento normativo de comercio exterior
Schema public (CatĂĄlogos Fijos)
Contiene catĂĄlogos compartidos y datos de referencia que no cambian frecuentemente:
- CatĂĄlogos del SAT (tipos de material, unidades de medida, etc.)
- CĂłdigos de paĂs
- CatĂĄlogos de aduanas
- Tipos de documento
- Datos maestros compartidos entre mĂłdulos
ConvenciĂłn de Prefijos de Tablas
Para mantener claridad y trazabilidad, las tablas utilizan prefijos que identifican su mĂłdulo funcional:
Prefijo inv_ (Inventarios)
Tablas relacionadas con el control de inventarios:
inv_products: Productos en inventarioinv_movements: Movimientos de entrada/salidainv_warehouses: Almacenesinv_balances: Saldos de inventario
Nota histĂłrica: Anteriormente se utilizaba el prefijo s (SCAII - Sistema de aduanas e Inventarios).
Prefijo fa_ (Fixed Assets / Activos Fijos)
Tablas relacionadas con la gestiĂłn de activos fijos:
fa_assets: Registro de activos fijosfa_depreciation: DepreciaciĂłn de activosfa_maintenance: Mantenimiento de activosfa_transfers: Transferencias de activos
Nota histĂłrica: Anteriormente se utilizaba el prefijo q (SCAF - Sistema de Control de Activos Fijos).
Diagrama de Arquitectura de Schemas
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â DATABASE: anexo76_db â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ€
â â
â ââââââââââââââââââ ââââââââââââââââââ âââââââââââââââââ â
â â Schema: a24 â â Schema: a76 â âSchema: public â â
â â (Anexo 24) â â (Anexo 76) â â (CatĂĄlogos) â â
â âââââââââââââââââ†âââââââââââââââââ†ââââââââââââââââ†â
â â â â â â â â
â â inv_products â â pedimentos â â material_typesâ â
â â inv_movements â â facturas â â uom_codes â â
â â inv_warehouses â â customs_docs â â countries â â
â â inv_balances â â export_ops â â customs_list â â
â â â â â â document_typesâ â
â â fa_assets â â â â â â
â â fa_depreciationâ â â â â â
â â fa_maintenance â â â â â â
â â fa_transfers â â â â â â
â â â â â â â â
â ââââââââââââââââââ ââââââââââââââââââ âââââââââââââââââ â
â â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
Ventajas de esta Arquitectura
- SeparaciĂłn LĂłgica: Cada schema representa un dominio especĂfico del negocio
- Escalabilidad: Facilita la adiciĂłn de nuevos mĂłdulos sin afectar los existentes
- Seguridad: Permite aplicar permisos a nivel de schema
- Mantenibilidad: CĂłdigo y migraciones organizados por dominio
- Claridad: Los prefijos hacen evidente la funcionalidad de cada tabla
- MigraciĂłn Gradual: Permite actualizar sistemas legados (SCAII/SCAF) sin interrupciones
Mapeo de Sistemas Legados
| Sistema Legacy | Prefijo Antiguo | Sistema Nuevo | Prefijo Nuevo | Schema |
|---|---|---|---|---|
| SCAII (Inventarios) | s |
Inventarios | inv_ |
a24 |
| SCAF (Activos Fijos) | q |
Fixed Assets | fa_ |
a24 |
| Winsaii (Pedimentos) | w |
- | - | a22 |
| - | g |
Comercio Exterior | - | a76 |
| - | g |
CatĂĄlogos SAT | - | public |
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
â âââ common/ # Utilidades compartidas
â â âââ base_models.py
â â âââ crud_routes.py
â â âââ dto_mixins.py
â â âââ tenant_crud_routes.py
â â
â âââ modules/ # MĂłdulos de negocio por schema
â âââ a24/ # MĂłdulo Anexo 24 (Inventarios)
â â âââ inventarios/
â â âââ activos_fijos/
â â
â âââ a76/ # MĂłdulo Anexo 76 (Comercio Exterior)
â â âââ pedimentos/
â â âââ facturas/
â â
â âââ public/ # CatĂĄlogos compartidos
â âââ material_types/
â âââ uom_codes/
â âââ countries/
â
âââ 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
# 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 clienteslicenses: Control de licencias por tenantlicense_usage: Métricas de usousers(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
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
# 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