# 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.