# 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 <repository-url>
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.<proceso>.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 \
--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**
