# 🏗️ ARQUITECTURA TÉCNICA
## 📊 Diagrama General
```
USUARIO FINAL
↓
[Cliente Web / Script / API]
↓
[HTTPS POST: datosrut.codepyme.com/procesar]
↓
[FastAPI - app.py]
├── Validación de archivo PDF
├── Lectura binaria
└── Envío a Claude Vision API
↓
[Claude Vision API]
├── Análisis de imagen/PDF
├── Extracción con IA
└── Retorna JSON
↓
[RUT Extractor - rut_extractor.py]
├── Parse de respuesta JSON
├── Validación de datos
└── Mapeo a modelos Pydantic
↓
[Modelos - models.py]
├── DatosRUT
├── Identificacion
├── Ubicacion
└── ... más 10 clases
↓
[Respuesta JSON Formateada]
↓
[Usuario recibe JSON estructurado]
```
---
## 🔧 Componentes Principales
### 1. **FastAPI (app.py)**
**Responsabilidad:** Servidor web HTTP
```python
- GET / → Interfaz HTML
- POST /procesar → Procesar RUT
- GET /health → Health check
- POST /extraer-rut (api) → Endpoint alternativo
```
**Características:**
- Manejo de multipart/form-data
- CORS habilitado
- Timeout de 120 segundos
- Validación de archivos
### 2. **RUT Extractor (rut_extractor.py)**
**Responsabilidad:** Lógica de extracción
```
Flujo:
1. Leer archivo PDF → Base64
2. Enviar a Claude Vision API
3. Parsear respuesta JSON
4. Validar estructura
5. Mapear a modelos
6. Retornar datos
```
**Características:**
- Reintentos automáticos (3 intentos)
- Prompt optimizado para todas las páginas
- Manejo robusto de errores
- Validación de datos
### 3. **Modelos Pydantic (models.py)**
**Responsabilidad:** Estructura de datos
```python
DatosRUT
├── tipo_persona: Literal["natural", "juridica"]
├── identificacion: Identificacion
├── datos_personales: DatosPersonales
├── datos_juridicos: DatosJuridicos
├── ubicacion: Ubicacion
├── actividad_economica: ActividadEconomica
├── responsabilidades: Responsabilidades
├── representante_legal: RepresentanteLegal
├── revisor_fiscal: RevisorFiscal
├── contador: Contador
├── socios: List[Socio]
├── establecimientos: List[Establecimiento]
```
**Características:**
- Validación automática
- Conversión de tipos
- Serialización JSON
- Documentación de campos
### 4. **Claude Vision API**
**Responsabilidad:** Extracción IA
- Analiza PDF/Imágenes
- Lee texto automáticamente
- Interpreta estructura
- Retorna datos estructurados
---
## 🔄 Flujo de Solicitud Completo
```
1. ENTRADA
└─ Usuario sube PDF a través de:
- Cliente HTML
- Script Python
- Solicitud cURL
- Aplicación web
2. TRANSMISIÓN
└─ Navegador/Client → FastAPI (HTTPS)
- Multipart form data
- Campo: file (PDF binario)
- Timeout: 120 segundos
3. VALIDACIÓN (FastAPI)
└─ app.py verifica:
✓ Archivo existe
✓ Content-type = PDF
✓ Tamaño < 10MB
✓ Archivo no vacío
4. PROCESAMIENTO
└─ rut_extractor.py:
a. Leer archivo → bytes
b. Codificar → Base64
c. Crear prompt (instrucciones)
d. Enviar a Claude Vision API
5. ANÁLISIS IA
└─ Claude Vision:
a. Decodificar PDF/imagen
b. Analizar página por página
c. Extraer información
d. Estructurar JSON
6. VALIDACIÓN (Parser)
└─ rut_extractor.py:
a. Parse JSON
b. Limpiar valores especiales
c. Validar estructura
d. Mapear a modelos
7. SERIALIZACIÓN
└─ models.py:
a. Convertir tipos
b. Validar restricciones
c. Convertir a JSON
8. RESPUESTA
└─ FastAPI retorna:
{
"archivo": "rut.pdf",
"exito": true,
"datos": { ... JSON estructurado ... }
}
9. SALIDA
└─ Cliente recibe JSON y:
- Procesa datos
- Muestra en UI
- Guarda en BD
- Exporta a otro sistema
```
---
## 📈 Flujo de Datos
```
Archivo PDF (binario)
↓ [Leer]
Bytes
↓ [Codificar Base64]
String Base64
↓ [Claude Vision]
Raw JSON (sin validar)
↓ [Parse JSON]
Dict Python
↓ [Limpieza de valores]
Dict limpio
↓ [Validación Pydantic]
Objeto DatosRUT (validado)
↓ [Serialización]
JSON estructurado (respuesta)
↓
Cliente
```
---
## 🔐 Seguridad
### **Punto de entrada:**
- ✅ HTTPS obligatorio
- ✅ CORS configurado
- ✅ Validación de tipo de archivo
- ✅ Límite de tamaño
### **Procesamiento:**
- ✅ Archivo temporal eliminado
- ✅ No se almacenan datos
- ✅ Timeout de 120s
- ✅ Manejo de excepciones
### **Punto de salida:**
- ✅ JSON estructurado
- ✅ Sin información sensible extra
- ✅ Respuesta validada
---
## 🚀 Escalabilidad
### **Actual (Single Server):**
```
Railway dyno único
├── CPU: Compartido
├── Memoria: 512 MB
├── Conexiones: ~50 simultaneas
└── RUTs/hora: ~120
```
### **Si necesitas más capacidad:**
**Opción 1: Railway Pro**
```
- Dyno de pago
- CPU + memoria dedicados
- RUTs/hora: ~500
```
**Opcion 2: Múltiples instancias**
```
Railroad + Load Balancer
├── 3+ instancias
├── Auto-scaling
└── RUTs/hora: 1000+
```
**Opción 3: Queue/Batch**
```
Entrada → Redis Queue → Workers
├── Procesar en background
├── Reintentos automáticos
└── RUTs/hora: Ilimitados
```
---
## 💾 Base de Datos (Opcional)
Si quieres guardar resultados:
### **PostgreSQL (Recomendado)**
```sql
CREATE TABLE ruts (
id SERIAL PRIMARY KEY,
nit VARCHAR(20) UNIQUE,
razon_social VARCHAR(255),
email VARCHAR(255),
telefono VARCHAR(20),
datos JSONB,
fecha_extraccion TIMESTAMP DEFAULT NOW(),
estado VARCHAR(50) DEFAULT 'activo'
);
CREATE INDEX idx_nit ON ruts(nit);
CREATE INDEX idx_fecha ON ruts(fecha_extraccion);
```
### **SQLite (Simple)**
```sql
CREATE TABLE ruts (
id INTEGER PRIMARY KEY,
nit TEXT UNIQUE,
razon_social TEXT,
email TEXT,
telefono TEXT,
datos TEXT, -- JSON como texto
fecha_extraccion DATETIME DEFAULT CURRENT_TIMESTAMP
);
```
### **MongoDB (Flexible)**
```javascript
db.ruts.insertOne({
nit: "9015648075",
razon_social: "CODEPYME SAS",
email: "contabilidad@codepyme.com",
datos: { ... },
fecha_extraccion: new Date()
});
```
---
## 🔄 Reintentos y Errores
### **Estrategia de Reintentos:**
```
Intento 1 → OK → Retornar
Intento 1 → Error → Esperar 1s
Intento 2 → OK → Retornar
Intento 2 → Error → Esperar 2s
Intento 3 → OK → Retornar
Intento 3 → Error → Fallar y reportar
```
### **Tipos de Error:**
- **HTTP 400:** Archivo inválido
- **HTTP 413:** Archivo muy grande
- **HTTP 408:** Timeout
- **HTTP 500:** Error del servidor
- **Custom:** Errores de parseo
---
## 📊 Monitoreo
### **Métricas a considerar:**
```
- Tiempo promedio: ~15s
- Éxito rate: >95%
- Error rate: <5%
- Timeout rate: <1%
- Tamaño promedio PDF: 2-5 MB
```
### **Logging recomendado:**
```python
import logging
logger = logging.getLogger(__name__)
logger.info(f"Procesando: {archivo}")
logger.info(f"Éxito en: {tiempo}s")
logger.error(f"Error: {detalle}")
logger.warning(f"Timeout después de {segundos}s")
```
---
## 🔗 Integraciones
### **Posibles integraciones:**
```
RUT Extractor
├── Salesforce CRM
├── ERP (SAP, Odoo)
├── Contabilidad (SIIGo, Alegra)
├── Base de datos propia
├── Webhook a otro sistema
├── Notificaciones (Email, WhatsApp)
└── Analytics dashboard
```
### **Ejemplo de webhook:**
```python
# Después de extraer, enviar a sistema tercero
import requests
datos = extraer_rut(archivo)
requests.post(
'https://tu-sistema.com/webhook/rut',
json=datos,
headers={'Authorization': f'Bearer {token}'}
)
```
---
## 🎯 Optimizaciones
### **Actual:**
- ✅ Prompt optimizado (página por página)
- ✅ Caché de respuestas (en desarrollo)
- ✅ Reintentos automáticos
- ✅ Timeout configurado
### **Potenciales mejoras:**
- [ ] Caché Redis para PDFs idénticos
- [ ] Procesamiento paralelo de páginas
- [ ] OCR para PDFs escaneados
- [ ] Validación offline de algunos campos
- [ ] Machine Learning para mejorar precisión
---
## 🔄 Ciclo de vida de datos
```
1. INGESTA
└─ PDF → Servidor
2. PROCESAMIENTO
└─ IA → Extracción
3. VALIDACIÓN
└─ Parser → Estructura
4. ENTREGA
└─ JSON → Cliente
5. CONSUMO
└─ Cliente → Usa datos
6. ALMACENAMIENTO (Opcional)
└─ BD → Historial
7. EXPIRACIÓN
└─ Datos temporales → Borrar
└─ Datos importantes → Archivar
```
---
## 📝 Tecnologías Usadas
```
Backend:
├── FastAPI (Framework web)
├── Anthropic SDK (Claude API)
├── Pydantic (Validación)
├── Python 3.11+ (Lenguaje)
└── Railway (Hosting)
Frontend:
├── HTML/CSS/JS (Web)
├── Fetch API (HTTP)
└── Navegador (Ejecución)
Cliente:
├── Python/requests
├── JavaScript/Fetch
├── Node.js/axios
├── cURL
└── Otros lenguajes
```
---
## 🎓 Conclusión
La arquitectura es:
- ✅ **Simple:** FastAPI → Claude → JSON
- ✅ **Escalable:** Dyno → Load Balancer → Workers
- ✅ **Segura:** HTTPS, validación, sin almacenamiento
- ✅ **Flexible:** Múltiples clientes soportados
- ✅ **Mantenible:** Código modular, bien documentado
Para más detalles, consulta el README o contacta al equipo.
---
**¡Ahora entiendes cómo funciona el sistema! 🎉**