# Arquitectura CBCFacil v9

## Resumen Ejecutivo

CBCFacil es un servicio de IA modular para procesamiento de documentos (audio, PDF, texto) con integracion a Nextcloud. Este documento describe la arquitectura actual, patrones de diseno utilizados y guia de extension del sistema.

## Evucion Arquitectonica

### Problema Original (v7)

El proyecto sufria de un archivo monolitico de 3167 lineas (`main.py`) que contenia todas las responsabilidades en un solo archivo.

### Solucion Actual (v9)

Arquitectura modular con separacion clara de responsabilidades en capas independientes.

```
                              FLUJO DE DATOS
                              =============

  1. MONITOREO              2. DESCARGA            3. PROCESAMIENTO
  +---------------+         +---------------+       +---------------+
  |   Nextcloud   |-------->|  Downloads/   |------>|  Processors   |
  |   (WebDAV)    |         |   Local       |       |  (Audio/PDF)  |
  +---------------+         +---------------+       +---------------+
         |                                                  |
         v                                                  v
  +---------------+                                +---------------+
  |   WebDAV      |                                |   AI Services |
  |   Service     |                                |   (Claude/    |
  +---------------+                                |    Gemini)    |
                                                     +---------------+
                                                             |
                                                             v
  4. GENERACION            5. REGISTRO            6. NOTIFICACION
  +---------------+         +---------------+       +---------------+
  |   Document    |-------->|   Processed   |------>|   Telegram    |
  |   Generators  |         |   Registry    |       |   Service     |
  +---------------+         +---------------+       +---------------+
         |                                                  |
         v                                                  v
  +---------------+                                +---------------+
  |   Nextcloud   |                                |   Dashboard   |
  |   (Upload)    |                                |   (Flask)     |
  +---------------+                                +---------------+
```

## Estructura de Directorios

```
cbcfacil/
├── main.py                      # Orquestador principal (149 lineas)
├── run.py                       # Script de ejecucion alternativo
├── config/                      # Configuracion centralizada
│   ├── __init__.py              # Exports: settings, validate_environment
│   ├── settings.py              # Configuracion desde variables de entorno
│   └── validators.py            # Validadores de configuracion
├── core/                        # Nucleo compartido
│   ├── __init__.py              # Exports: excepciones, Result
│   ├── exceptions.py            # Excepciones personalizadas
│   ├── result.py                # Patron Result/Error handling
│   └── base_service.py          # Clase base BaseService
├── services/                    # Servicios externos
│   ├── __init__.py              # Exports de servicios
│   ├── webdav_service.py        # WebDAV/Nextcloud operaciones
│   ├── vram_manager.py          # GPU memory management
│   ├── telegram_service.py      # Telegram notificaciones
│   ├── metrics_collector.py     # Metricas y estadisticas
│   ├── ai_service.py            # Servicio AI unificado
│   └── ai/                      # AI Providers
│       ├── __init__.py
│       ├── base_provider.py     # Interfaz BaseProvider
│       ├── claude_provider.py   # Claude (Z.ai) implementation
│       ├── gemini_provider.py   # Gemini API/CLI implementation
│       └── provider_factory.py  # Factory para proveedores
├── processors/                  # Procesadores de archivos
│   ├── __init__.py              # Exports de procesadores
│   ├── base_processor.py        # Clase base FileProcessor
│   ├── audio_processor.py       # Whisper transcription
│   ├── pdf_processor.py         # PDF OCR processing
│   └── text_processor.py        # Text summarization
├── document/                    # Generacion de documentos
│   ├── __init__.py
│   └── generators.py            # DOCX/PDF/Markdown generation
├── storage/                     # Persistencia y cache
│   ├── __init__.py
│   └── processed_registry.py    # Registro de archivos procesados
├── api/                         # API REST
│   ├── __init__.py
│   └── routes.py                # Flask routes y endpoints
├── tests/                       # Tests unitarios e integracion
│   ├── conftest.py              # Fixtures pytest
│   ├── test_config.py           # Tests de configuracion
│   ├── test_storage.py          # Tests de almacenamiento
│   ├── test_webdav.py           # Tests de WebDAV
│   ├── test_processors.py       # Tests de procesadores
│   ├── test_ai_providers.py     # Tests de AI providers
│   ├── test_vram_manager.py     # Tests de VRAM manager
│   └── test_main_integration.py # Tests de integracion main
├── docs/                        # Documentacion
│   ├── archive/                 # Documentacion historica
│   ├── SETUP.md                 # Guia de configuracion
│   ├── TESTING.md               # Guia de testing
│   └── DEPLOYMENT.md            # Guia de despliegue
├── requirements.txt             # Dependencias produccion
├── requirements-dev.txt         # Dependencias desarrollo
├── .env.example                 # Template de configuracion
├── .env.secrets                 # Configuracion local (no versionar)
└── Dockerfile                   # Container Docker
```

## Componentes Principales

### 1. Servicios (services/)

#### WebDAVService

**Archivo**: `services/webdav_service.py`

Responsabilidades:
- Conexion y operaciones con Nextcloud via WebDAV
- Download/upload de archivos
- Listado y creacion de directorios remotos
- Manejo de errores con reintentos configurables

```python
class WebDAVService:
    def initialize(self) -> None: ...
    def list(self, remote_path: str) -> List[str]: ...
    def download(self, remote_path: str, local_path: Path) -> None: ...
    def upload(self, local_path: Path, remote_path: str) -> None: ...
    def mkdir(self, remote_path: str) -> None: ...
```

#### VRAMManager

**Archivo**: `services/vram_manager.py`

Responsabilidades:
- Gestion de memoria GPU
- Carga/descarga de modelos (Whisper, OCR, TrOCR)
- Limpieza automatica de VRAM ociosa
- Fallback a CPU cuando GPU no disponible

```python
class VRAMManager:
    def initialize(self) -> None: ...
    def cleanup(self) -> None: ...
    def should_cleanup(self) -> bool: ...
    def lazy_cleanup(self) -> None: ...
```

#### TelegramService

**Archivo**: `services/telegram_service.py`

Responsabilidades:
- Envio de notificaciones a Telegram
- Throttling de errores para evitar spam
- Notificaciones de inicio/parada del servicio

```python
class TelegramService:
    def configure(self, token: str, chat_id: str) -> None: ...
    def send_message(self, message: str) -> None: ...
    def send_error_notification(self, context: str, error: str) -> None: ...
    def send_start_notification(self) -> None: ...
```

### 2. Procesadores (processors/)

#### AudioProcessor

**Archivo**: `processors/audio_processor.py`

Responsabilidades:
- Transcripcion de audio usando Whisper
- Modelo: medium (optimizado para espanol)
- Soporte GPU/CPU automatico
- Post-procesamiento de texto transcrito

#### PDFProcessor

**Archivo**: `processors/pdf_processor.py`

Responsabilidades:
- Extraccion de texto de PDFs
- OCR con EasyOCR + Tesseract + TrOCR en paralelo
- Correccion de texto con IA
- Generacion de documentos DOCX

#### TextProcessor

**Archivo**: `processors/text_processor.py`

Responsabilidades:
- Resumenes usando IA (Claude/Gemini)
- Clasificacion de contenido
- Generacion de quizzes opcionales

### 3. AI Services (services/ai/)

#### ProviderFactory

**Archivo**: `services/ai/provider_factory.py`

Patron Factory para seleccion dinamica de proveedor de IA:
```python
class ProviderFactory:
    def get_provider(self, provider_type: str = "auto") -> BaseProvider: ...
```

Proveedores disponibles:
- `claude`: Claude via Z.ai API
- `gemini`: Google Gemini API
- `gemini_cli`: Gemini CLI local
- `auto`: Seleccion automatica basada en disponibilidad

### 4. Document Generation (document/)

#### DocumentGenerator

**Archivo**: `document/generators.py`

Responsabilidades:
- Creacion de documentos DOCX
- Conversion a PDF
- Formateo Markdown
- Plantillas de documentos

### 5. Storage (storage/)

#### ProcessedRegistry

**Archivo**: `storage/processed_registry.py`

Responsabilidades:
- Registro persistente de archivos procesados
- Cache en memoria con TTL
- File locking para thread-safety

```python
class ProcessedRegistry:
    def initialize(self) -> None: ...
    def load(self) -> Set[str]: ...
    def save(self, file_path: str) -> None: ...
    def is_processed(self, file_path: str) -> bool: ...
    def mark_for_reprocess(self, file_path: str) -> None: ...
```

### 6. API (api/)

#### Flask Routes

**Archivo**: `api/routes.py`

Endpoints REST disponibles:
- `GET /api/files` - Listado de archivos
- `POST /api/reprocess` - Reprocesar archivo
- `POST /api/mark-unprocessed` - Resetear estado
- `GET /api/refresh` - Sincronizar con Nextcloud
- `GET /health` - Health check

## Patrones de Diseno Utilizados

### 1. Repository Pattern

```python
# storage/processed_registry.py
class ProcessedRegistry:
    def save(self, file_path: str) -> None: ...
    def load(self) -> Set[str]: ...
    def is_processed(self, file_path: str) -> bool: ...
```

### 2. Factory Pattern

```python
# services/ai/provider_factory.py
class ProviderFactory:
    def get_provider(self, provider_type: str = "auto") -> BaseProvider: ...
```

### 3. Strategy Pattern

```python
# services/vram_manager.py
class VRAMManager:
    def cleanup(self) -> None: ...
    def should_cleanup(self) -> bool: ...
    def lazy_cleanup(self) -> None: ...
```

### 4. Service Layer Pattern

```python
# services/webdav_service.py
class WebDAVService:
    def list(self, remote_path: str) -> List[str]: ...
    def download(self, remote_path: str, local_path: Path) -> None: ...
    def upload(self, local_path: Path, remote_path: str) -> None: ...
```

### 5. Singleton Pattern

Servicios implementados como singletons para compartir estado:
```python
# services/webdav_service.py
webdav_service = WebDAVService()

# services/vram_manager.py
vram_manager = VRAMManager()
```

### 6. Result Pattern

```python
# core/result.py
class Result:
    @staticmethod
    def success(value): ...
    @staticmethod
    def failure(error): ...
```

## Decisiones Arquitectonicas (ADR)

### ADR-001: Arquitectura Modular

**Decision**: Separar el monolito en modulos independientes.

**Contexto**: El archivo main.py de 3167 lineas era dificil de mantener y testar.

**Decision**: Separar en capas: config/, core/, services/, processors/, document/, storage/, api/.

**Consecuencias**:
- Positivo: Codigo mas mantenible y testeable
- Positivo: Reutilizacion de componentes
- Negativo: Mayor complejidad inicial

### ADR-002: Configuracion Centralizada

**Decision**: Usar clase Settings con variables de entorno.

**Contexto**: Credenciales hardcodeadas representan riesgo de seguridad.

**Decision**: Todas las configuraciones via variables de entorno con .env.secrets.

**Consecuencias**:
- Positivo: Seguridad mejorada
- Positivo: Facil despliegue en diferentes entornos
- Negativo: Requiere documentacion de variables

### ADR-003: GPU-First con CPU Fallback

**Decision**: Optimizar para GPU pero soportar CPU.

**Contexto**: No todos los usuarios tienen GPU disponible.

**Decision**: VRAMManager con lazy loading y cleanup automatico.

**Consecuencias**:
- Positivo: Performance optimo en GPU
- Positivo: Funciona sin GPU
- Negativo: Complejidad adicional en gestion de memoria

### ADR-004: Factory para AI Providers

**Decision**: Abstraer proveedores de IA detras de interfaz comun.

**Contexto**: Multiples proveedores (Claude, Gemini) con diferentes APIs.

**Decision**: BaseProvider con implementaciones concretas y ProviderFactory.

**Consecuencias**:
- Positivo: Facilidad para agregar nuevos proveedores
- Positivo: Fallback entre proveedores
- Negativo: Sobrecarga de abstraccion

## Guia de Extension del Sistema

### Agregar Nuevo Procesador

1. Crear archivo en `processors/`:
```python
from processors.base_processor import FileProcessor

class NuevoProcessor(FileProcessor):
    def process(self, file_path: str) -> None:
        # Implementar procesamiento
        pass
```

2. Registrar en `processors/__init__.py`:
```python
from processors.nuevo_processor import NuevoProcessor

__all__ = ['NuevoProcessor', ...]
```

3. Integrar en `main.py`:
```python
from processors.nuevo_processor import NuevoProcessor

nuevo_processor = NuevoProcessor()
```

### Agregar Nuevo AI Provider

1. Crear clase en `services/ai/`:
```python
from services.ai.base_provider import BaseProvider

class NuevoProvider(BaseProvider):
    def summarize(self, text: str) -> str:
        # Implementar
        pass
```

2. Registrar en `provider_factory.py`:
```python
PROVIDERS = {
    'nuevo': NuevoProvider,
    ...
}
```

3. Usar:
```python
provider = factory.get_provider('nuevo')
```

### Agregar Nuevo Servicio

1. Crear archivo en `services/`:
```python
from core.base_service import BaseService

class NuevoService(BaseService):
    def initialize(self) -> None:
        pass

nuevo_service = NuevoService()
```

2. Inicializar en `main.py`:
```python
from services.nuevo_service import nuevo_service

nuevo_service.initialize()
```

### Agregar Nuevo Endpoint API

1. Editar `api/routes.py`:
```python
@app.route('/api/nuevo', methods=['GET'])
def nuevo_endpoint():
    return {'status': 'ok'}, 200
```

## Configuracion Detallada

### Variables de Entorno Principales

| Variable | Requerido | Default | Descripcion |
|----------|-----------|---------|-------------|
| NEXTCLOUD_URL | Si | - | URL de Nextcloud WebDAV |
| NEXTCLOUD_USER | Si | - | Usuario Nextcloud |
| NEXTCLOUD_PASSWORD | Si | - | Contrasena Nextcloud |
| ANTHROPIC_AUTH_TOKEN | No | - | Token Claude/Z.ai |
| GEMINI_API_KEY | No | - | API Key Gemini |
| TELEGRAM_TOKEN | No | - | Token Bot Telegram |
| TELEGRAM_CHAT_ID | No | - | Chat ID Telegram |
| CUDA_VISIBLE_DEVICES | No | "all" | GPU a usar |
| POLL_INTERVAL | No | 5 | Segundos entre polls |
| LOG_LEVEL | No | "INFO" | Nivel de logging |

## Metricas y Benchmarks

| Metrica | Valor |
|---------|-------|
| Lineas main.py | 149 (antes 3167) |
| Modulos independientes | 8+ |
| Cobertura tests | ~60%+ |
| Tiempo inicio | 5-10s |
| Transcripcion Whisper | ~1x tiempo audio (GPU) |
| OCR PDF | 0.5-2s/pagina |

## Beneficios de la Arquitectura

1. **Mantenibilidad**: Cada responsabilidad en su propio modulo
2. **Testabilidad**: Servicios independientes y testeables
3. **Escalabilidad**: Facil agregar nuevos procesadores/servicios
4. **Reutilizacion**: Componentes desacoplados
5. **Legibilidad**: Codigo organizado y documentado
6. **Seguridad**: Configuracion centralizada sin hardcoding

## Licencia

MIT License - Ver LICENSE para detalles.
