Saltar a contenido

Diagrama de Componentes del Sistema

Descripción

Diagrama de componentes que muestra los módulos principales de Sherlock-docs, sus responsabilidades, interfaces públicas y dependencias entre componentes.

Vista arquitectónica de alto nivel siguiendo Clean Architecture.

Diagrama

graph TB
    subgraph "Presentation Layer"
        GUI[📱 Streamlit GUI ✅<br/>─────────────<br/>• 9 páginas implementadas<br/>• Upload, Process, Validate<br/>• Search, Duplicates, Stats<br/>• Detail, ManualEntry<br/>• ImportExcel<br/>─────────────<br/>Components S23-D1:<br/>• DuplicateRenderer ✅<br/>  Facade+Strategy compartido<br/>  process.py + duplicates.py]

        CLI[⌨️ CLI Interface ✅<br/>─────────────<br/>• 20 comandos implementados<br/>• Procesamiento batch<br/>• Import/Export<br/>• Debugging y stats<br/>• audit-report GOB-11]

        APIREST[🌐 API REST ✅<br/>─────────────<br/>• FastAPI 22 endpoints<br/>• JWT auth HS256<br/>• Swagger UI /docs<br/>• TaskManager async<br/>• Exception handler global<br/>─────────────<br/>Components:<br/>• 11 routers<br/>• 8 schema modules<br/>• result_mapper<br/>• Score: 9.2/10]
    end

    subgraph "Application Layer"
        direction TB

        UseCases[🎯 Use Cases<br/>─────────────<br/>• ProcessDocumentUseCase ✅<br/>• ExportExcelUseCase ✅<br/>• ImportExcelUseCase ✅ atomic txn]

        AppServices[🔧 Services S23 ✅<br/>─────────────<br/>• ValidationService<br/>• SearchService<br/>• StatisticsService<br/>• ManualEntryService<br/>• DedupConfigService<br/>─────────────<br/>Sin dependencia Streamlit]

        DTOs[📦 DTOs frozen<br/>─────────────<br/>• ProcessDocument Req/Resp<br/>• ProcessingMetrics<br/>• ExportExcel Req/Resp<br/>• ImportExcel Req/Resp<br/>• DuplicateCandidateDTO<br/>─── Fase 0 Pre-API ───<br/>• StatisticsResponse<br/>• SearchDocuments Req/Resp<br/>• ValidateDocument Req/Resp<br/>• CreateManualDocument Req/Resp<br/>• RecurringCheck Req/Resp<br/>• DedupConfig Resp/UpdateReq]

        Container[🔧 Service Container<br/>─────────────<br/>• Dependency Injection<br/>• Lazy Loading<br/>• Configuration Management]
    end

    subgraph "Domain Layer (Core)"
        direction LR

        Entities[🏛️ Entities<br/>─────────────<br/>• Document<br/>• DocumentType<br/>• DocumentStatus]

        ValueObjects[💎 Value Objects<br/>─────────────<br/>• OCRResult<br/>• EntityResult<br/>• DuplicateCandidate<br/>• LevelScore<br/>• NERFields ✅ S23<br/>• CSJMetadata ✅ S23<br/>• ProvisionalInfo ✅ S23<br/>• SectionsInfo ✅ S23]

        BusinessRules[📋 Business Rules<br/>─────────────<br/>• Validation Logic<br/>• Domain Events<br/>• Invariants]
    end

    subgraph "Infrastructure Layer - OCR"
        direction TB

        OCRModule[🔍 OCR Module<br/>─────────────<br/>Ports:<br/>• OCRPort<br/>─────────────<br/>Adapters:<br/>• BaseOCRAdapter ✅<br/>• TesseractAdapter<br/>• PaddleOCRAdapter<br/>• OCRRouter<br/>─────────────<br/>Services:<br/>• DocumentQualityAnalyzer<br/>• PDF to Image Converter]

        OCRDeps[Dependencies:<br/>• pytesseract<br/>• paddleocr<br/>• pdf2image<br/>• opencv-python]
    end

    subgraph "Infrastructure Layer - NER"
        direction TB

        NERModule[🏷️ NER Module<br/>─────────────<br/>Ports:<br/>• NERPort<br/>─────────────<br/>Adapters:<br/>• SpaCyAdapter ✅<br/>• EntityExtractorEnsemble ✅<br/>─────────────<br/>Extractors Strategy ✅:<br/>• EntityExtractor Protocol<br/>• MarkerExtractor pri=1<br/>• SpaCyNERExtractor pri=2<br/>• RegexExtractor pri=3<br/>• AddressExtractor pri=4<br/>• ContactExtractor pri=5<br/>─────────────<br/>Validators Chain ✅:<br/>• EntityValidator Protocol<br/>• ValidatorChain<br/>• StructuralValidator<br/>• TemporalValidator<br/>• RadicadoFormatValidator<br/>• DeduplicationValidator<br/>─────────────<br/>Active Learning ✅:<br/>• CorrectionRepository<br/>• Correction, CorrectionStats<br/>─────────────<br/>Detectors:<br/>• ActaRepartoExtractor ✅<br/>• SectionsDetector ✅<br/>• ProvisionalMeasureDetector ✅<br/>─────────────<br/>Utilities:<br/>• EntityTruncator ✅<br/>• ContextScorer ✅ S23-H2 fix<br/>• EntityLinker ✅<br/>• RadicadoValidator ✅<br/>• DocumentStructureAnalyzer ✅<br/>• TemporalFeatures ✅<br/>• CompoundSplitter ✅ S23-H4<br/>─────────────<br/>F1 Score: 85.3%]

        NERDeps[Dependencies:<br/>• spacy<br/>• es_core_news_lg<br/>• regex<br/>• unicodedata]
    end

    subgraph "Infrastructure Layer - Duplicate Detection"
        direction TB

        DedupModule[🔎 Dedup Module<br/>─────────────<br/>Ports:<br/>• DuplicateDetectorPort<br/>─────────────<br/>Adapters:<br/>• HybridEnsembleDetector<br/>─────────────<br/>Matchers:<br/>• ExactMatcher<br/>• MinHashMatcher<br/>• TFIDFMatcher<br/>• EntityMatcher<br/>─────────────<br/>Config:<br/>• EnsembleConfig<br/>• save/load JSON]

        DedupDeps[Dependencies:<br/>• datasketch<br/>• scikit-learn<br/>• numpy<br/>• scipy]
    end

    subgraph "Infrastructure Layer - Persistence"
        direction TB

        PersistenceModule[💾 Persistence Module<br/>─────────────<br/>Ports ISP:<br/>• DocumentReader ✅<br/>• DocumentWriter ✅<br/>• DocumentSearcher ✅<br/>• CorrectionRepository ✅<br/>• MetricsRepository ✅<br/>• DocumentRepository<br/>─────────────<br/>Adapters:<br/>• SQLiteDocumentRepository<br/>─────────────<br/>Mixins:<br/>• ConnectionMixin<br/>• CorrectionMixin<br/>• MetricsMixin<br/>─────────────<br/>Services:<br/>• FTS5 Search<br/>• Migration Manager]

        PersistenceDeps[Dependencies:<br/>• sqlite3<br/>• FTS5 extension]
    end

    subgraph "Cross-Cutting Concerns"
        direction LR

        Logging[📝 Logging<br/>─────────────<br/>• Structured logging<br/>• Performance metrics<br/>• Error tracking]

        Config[⚙️ Configuration<br/>─────────────<br/>• Environment vars<br/>• Config files<br/>• Defaults]

        Exceptions[⚠️ Exceptions<br/>─────────────<br/>• Custom exceptions<br/>• Error codes<br/>• Error messages]

        Audit[📋 Audit Service<br/>─────────────<br/>• GOB-06 audit_events<br/>• GOB-05 user tracking<br/>• GOB-11 CLI report]
    end

    %% Presentation → Application
    GUI --> UseCases
    GUI --> AppServices
    CLI --> UseCases
    APIREST --> UseCases
    APIREST --> AppServices
    APIREST --> Container

    %% Application internal
    UseCases --> DTOs
    UseCases --> Container
    AppServices --> Container
    Container --> UseCases
    Container --> AppServices

    %% Application → Domain
    UseCases --> Entities
    UseCases --> ValueObjects
    DTOs --> ValueObjects
    DTOs --> Entities
    BusinessRules --> Entities

    %% Application → Infrastructure (via Ports)
    UseCases -.uses.-> OCRModule
    UseCases -.uses.-> NERModule
    UseCases -.uses.-> DedupModule
    UseCases -."Result[T, AppError]".-> PersistenceModule
    AppServices -."Result[T, AppError]".-> PersistenceModule

    %% Document composition → Value Objects (Sprint 27)
    Entities -."delegates to".-> ValueObjects

    %% Infrastructure → Domain
    OCRModule --> ValueObjects
    NERModule --> ValueObjects
    DedupModule --> ValueObjects
    PersistenceModule --> Entities

    %% Infrastructure dependencies
    OCRModule -.depends on.-> OCRDeps
    NERModule -.depends on.-> NERDeps
    DedupModule -.depends on.-> DedupDeps
    PersistenceModule -.depends on.-> PersistenceDeps

    %% Cross-cutting → All layers
    Logging -.supports.-> UseCases
    Logging -.supports.-> OCRModule
    Logging -.supports.-> NERModule
    Logging -.supports.-> DedupModule
    Logging -.supports.-> PersistenceModule

    Config -.configures.-> Container
    Config -.configures.-> OCRModule
    Config -.configures.-> NERModule
    Config -.configures.-> DedupModule

    Exceptions -.used by.-> UseCases
    Exceptions -.used by.-> OCRModule
    Exceptions -.used by.-> NERModule
    Exceptions -.used by.-> DedupModule
    Exceptions -.used by.-> PersistenceModule

    Audit -.supports.-> UseCases
    Audit -.supports.-> GUI
    Audit -.supports.-> APIREST

    style GUI fill:#f9d5e5
    style CLI fill:#f9d5e5
    style APIREST fill:#f9d5e5
    style UseCases fill:#d5e5f9
    style DTOs fill:#d5e5f9
    style Container fill:#d5e5f9
    style AppServices fill:#d5e5f9
    style Entities fill:#d5f9e5
    style ValueObjects fill:#d5f9e5
    style BusinessRules fill:#d5f9e5
    style OCRModule fill:#fff4d4
    style NERModule fill:#fff4d4
    style DedupModule fill:#fff4d4
    style PersistenceModule fill:#fff4d4
    style Logging fill:#e5d5f9
    style Config fill:#e5d5f9
    style Exceptions fill:#e5d5f9
    style Audit fill:#e5d5f9

Componentes por Capa

1. Presentation Layer (Interfaces)

Streamlit GUI ✅

Responsabilidad: Interfaz web para operadores legales.

Estado: 9 páginas implementadas.

Páginas: | Página | Descripción | |--------|-------------| | Upload | Carga de documentos PDF (drag & drop) | | Process | Procesamiento OCR + NER | | Validate | Validación/corrección de entidades | | Search | Búsqueda full-text de documentos | | Duplicates | Visualización de duplicados detectados | | Stats | Dashboard de métricas y estadísticas | | Detail | Vista detallada de documento individual | | ManualEntry | Registro manual de documentos | | ImportExcel | Importación masiva desde Excel |

Tecnologías: Streamlit, Plotly (visualizaciones)

CLI Interface ✅

Responsabilidad: Comandos de línea para automatización.

Estado: Implementado con 20 comandos.

Funcionalidades: - Procesamiento batch de múltiples documentos - Import/Export de datos (Excel) - Debugging, stats y mantenimiento - Scripts de mantenimiento (rebuild índices, migraciones)

Tecnologías: argparse (stdlib)

API REST ✅ (Sprint 24 + 25 + 25.1)

Responsabilidad: Interfaz HTTP programática para consumidores externos.

Estado: 22 endpoints implementados (21 funcionales, 1 parcial). Score auditoría 9.2/10.

Endpoints (11 routers): | Router | Endpoints | Descripción | |--------|:---------:|-------------| | health | 1 | Status del sistema + 4 componentes | | auth | 4 | Login, me, refresh, logout | | documents | 3 | List, get, delete (CRUD) | | search | 1 | FTS5 full-text search | | process | 1 | Async OCR+NER processing (202 → poll) | | validate | 1 | Save NER corrections | | recurring | 1 | Check recurring entities | | manual | 1 | Manual document creation | | duplicates | 2 | Detect by doc + verify text | | import_export | 2 | Excel import/export | | config | 3 | Dedup config, NER config, stats | | tasks | 1 | Task polling |

Componentes internos: - main.py: App factory + lifespan + exception handler global - config.py: ApiSettings (Pydantic BaseSettings, env prefix SHERLOCK_) - auth.py: JWT encode/decode + credential loading (YAML) - dependencies.py: get_container, get_current_user, get_task_manager - result_mapper.py: Result[T,E] → JSONResponse con error classification - tasks.py: TaskManager (ThreadPoolExecutor + polling) - schemas/: 8 módulos Pydantic (common, auth, documents, health, tasks, validation, duplicates, config)

Seguridad: JWT HS256, 8h expiry, max 5 refreshes, path traversal prevention, temp cleanup, file size validation, XSS sanitization (HTML tags + entities), CORS configurable.

Tecnologías: FastAPI, Pydantic v2, python-jose (JWT), PyYAML

2. Application Layer

Use Cases

Responsabilidad: Orquestación de lógica de negocio.

Casos de uso: - ProcessDocumentUseCase ✅: Pipeline completo OCR → NER → Dedup → Persist - ExportExcelUseCase ✅: Exportación masiva a Excel con filtros por fecha/tipo - ImportExcelUseCase ✅: Importación masiva desde Excel con validación - SearchService ✅: Búsqueda FTS5 + filtros client-side (extraído de search.py, Sprint 23) - ValidationService ✅: Correcciones + entidades recurrentes (extraído de validate.py, Sprint 23) - StatisticsService ✅: Dashboard stats (extraído de stats.py, Sprint 23) - ManualEntryService ✅: Ingreso manual con validación (extraído de manual_entry.py, Sprint 23) - DedupConfigService ✅: Configuración ensemble dedup (extraído de duplicates.py, Sprint 23)

Patrón: Railway-Oriented Programming con Result pattern.

DTOs (Data Transfer Objects)

Responsabilidad: Transferencia de datos entre capas.

Características: - Inmutables (@dataclass(frozen=True)) - Type hints completos - Sin lógica de negocio

Service Container

Responsabilidad: Inyección de dependencias.

Características: - Lazy loading de recursos costosos - Singleton pattern para configuraciones - Context manager para manejo de recursos

3. Domain Layer (Core)

Entities

Responsabilidad: Objetos con identidad del dominio.

Entidades principales: - Document: Documento legal con metadatos - DocumentType: Enum de tipos (TUTELA, HABEAS_CORPUS) - DocumentStatus: Enum de estados (PENDING, PROCESSING, PROCESSED, VALIDATED, ERROR)

Composición de Document (Sprint 27): La entidad Document delega sus datos estructurados a Value Objects tipados en lugar de almacenar diccionarios planos: - Document.ner_fieldsNERFields: Campos NER extraídos (accionante, demandado, radicado, juzgado, etc.) - Document.csj_metadataCSJMetadata: Metadatos del Consejo Superior de la Judicatura - Document.provisional_infoProvisionalInfo: Información de medida provisional (detectada, tipo, descripción) - Document.sections_infoSectionsInfo: Secciones detectadas del documento (hechos, pretensiones, etc.)

Esta composición reemplaza el acceso directo a diccionarios dict[str, Any], aportando type safety y validación en frontera.

Características: - Identidad única (UUID) - Validaciones de negocio - Inmutabilidad preferida - Composición con Value Objects tipados (frozen dataclasses)

Value Objects

Responsabilidad: Objetos sin identidad, comparables por valor.

Value Objects: - OCRResult: Resultado de extracción OCR - EntityResult: Entidades extraídas - DuplicateCandidate: Candidato de duplicado - LevelScore: Score de nivel de detección

Características: - Inmutables (frozen=True) - Sin identidad - Comparación por valor

Business Rules

Responsabilidad: Reglas de negocio puras.

Ejemplos: - Validación de que un documento debe tener contenido - Invariante: status PROCESSED requiere OCR confidence > 0 - Evento: "Documento marcado como duplicado"

4. Infrastructure Layer

OCR Module

Responsabilidad: Extracción de texto de PDFs.

Componentes: - Ports: OCRPort (interfaz abstracta) - Adapters: - BaseOCRAdapter ✅: Template Method base class (skeleton algorithm) - TesseractAdapter: Hereda de BaseOCRAdapter, Tesseract-OCR (CER 3.2%) - PaddleOCRAdapter: Hereda de BaseOCRAdapter, PaddleOCR (CER 4.5%) - OCRRouter: Routing inteligente con fallback - Services: - DocumentQualityAnalyzer: Analiza calidad para routing - pdf_to_images: Conversión PDF → imágenes

Dependencias externas: pytesseract, paddleocr, pdf2image, opencv-python

NER Module

Responsabilidad: Extracción de entidades legales.

Refactoring completado (2026-02-04): SpaCyAdapter reducido de 722 a 342 líneas (53%).

Componentes: - Ports: NERPort (interfaz abstracta) - Adapters: - SpaCyAdapter ✅: Orquestador de extracción (342 líneas) - EntityExtractorEnsemble ✅: Votación ponderada de extractores

Extractors (Strategy Pattern) ✅: - EntityExtractor (Protocol): Interfaz para estrategias - BaseExtractor (ABC): Clase base con logging - MarkerExtractor (priority=1): Extrae de ACCIONANTE:, DEMANDADO:, etc. - SpaCyNERExtractor (priority=2): Extracción neuronal con POS validation - RegexExtractor (priority=3): Patrones para radicados, fechas, juzgados - AddressExtractor (priority=4): Direcciones de demandante y demandado - ContactExtractor (priority=5): Correo electrónico y cédula (CC/CE/NIT)

Validators (Pipeline) ✅: - EntityValidator (Protocol): Interfaz para validadores - BaseValidator (ABC): Clase base con logging - ValidatorChain: Orquesta ejecución secuencial - ValidationContext: Contexto compartido (full_text, doc, sections) - StructuralValidator: Boost +10-15% por sección correcta - TemporalValidator: Consistencia de fechas/años - RadicadoFormatValidator: Valida formato 23 dígitos, filtra T-/SU- - DeduplicationValidator: Fuzzy dedup con EntityLinker

Detectors ✅: - ActaRepartoExtractor: Extracción de datos desde actas de reparto - SectionsDetector: Detección de secciones (hechos, pretensiones) - ProvisionalMeasureDetector: Detección de medida provisional

Utilities: - EntityTruncator ✅: Truncamiento inteligente por tipo de entidad - ContextScorer ✅: Pesos configurables para clasificación - EntityLinker ✅: Agrupación fuzzy de menciones similares - RadicadoValidator ✅: Validación de radicados colombianos - DocumentStructureAnalyzer ✅: Detección de secciones del documento - TemporalFeatures ✅: Normalización y validación de fechas - POS Filtering ✅: Filtrado por Part-of-Speech

Precisión actual: F1 85.3% (5 extractores + 4 validadores en ensemble)

Dependencias externas: spacy, es_core_news_lg (340MB), regex, unicodedata

Duplicate Detection Module

Responsabilidad: Detección de documentos duplicados.

Componentes: - Ports: DuplicateDetectorPort - Adapters: HybridEnsembleDetector - Matchers: - ExactMatcher: Hash SHA-256 (100% match) - MinHashMatcher: MinHash LSH (70-95% similarity) - TFIDFMatcher: TF-IDF cosine (60-80% similarity) - EntityMatcher: Boost por entidades legales (+20%)

Dependencias externas: datasketch, scikit-learn, numpy, scipy

Persistence Module

Responsabilidad: Almacenamiento y recuperación de documentos.

Componentes: - Ports (ISP) ✅: - DocumentReader: Operaciones de lectura (find_by_id, find_by_hash, get_all, count) - DocumentWriter: Operaciones de escritura (save) - DocumentSearcher: Búsqueda full-text (search) - CorrectionRepository: Gestión de correcciones - MetricsRepository: Métricas de procesamiento - DocumentRepository: Interfaz combinada (hereda las 5 anteriores) - Adapters: SQLiteDocumentRepository - Services: - FTS5Search: Búsqueda full-text - MigrationManager: Migraciones de esquema - ConnectionPool: Pool de conexiones (futuro)

Métodos con Result types (Sprint 27): Los siguientes métodos de persistencia ahora retornan Result[T, AppError] en lugar de lanzar excepciones o retornar valores desnudos: - delete(doc_id)Result[None, AppError] - update_status(doc_id, status)Result[None, AppError] - update_document_field(doc_id, field, value)Result[None, AppError] - save_processing_metrics(metrics)Result[None, AppError]

Esto permite que la capa de aplicación maneje errores con Railway-Oriented Programming (bind/map) sin try/except anidados.

Dependencias externas: sqlite3 (stdlib), FTS5 extension

5. Cross-Cutting Concerns

Logging

Responsabilidad: Trazabilidad y debugging.

Características: - Structured logging (JSON) - Niveles: DEBUG, INFO, WARNING, ERROR - Performance metrics (latencia por etapa) - Error tracking con stack traces

Configuration

Responsabilidad: Gestión de configuración.

Fuentes: - Variables de entorno (.env) - Archivos de configuración (TOML, YAML) - Defaults hardcodeados

Configuraciones: - Paths de modelos OCR/NER - Umbrales de detección de duplicados - Conexión a base de datos

Exceptions

Responsabilidad: Manejo de errores.

Jerarquía: - SherlockException (base) - OCRError - NERError - DuplicateDetectionError - PersistenceError

Características: - Códigos de error únicos - Mensajes descriptivos - Contexto adicional (stage, details)

Dependencias entre Componentes

Reglas de Dependencias

  1. Presentation → Application: GUI/CLI/API usan Use Cases y Services
  2. Application → Domain: Use Cases usan Entities y Value Objects
  3. Application → Infrastructure (via Ports): Use Cases dependen de interfaces, no implementaciones
  4. Infrastructure → Domain: Adapters usan Value Objects para retornar resultados
  5. Infrastructure ← Domain: Nunca (Domain no conoce Infrastructure)

Flujo de Datos Típico (GUI)

Usuario → GUI → ProcessDocumentUseCase → OCRRouter → TesseractAdapter → Tesseract
                  EntityResult ← SpaCyAdapter ← NERPort
          DuplicateDetectionResult ← HybridEnsembleDetector ← DuplicateDetectorPort
                  Document → SQLiteDocumentRepository → SQLite DB
           ProcessDocumentResponse → GUI → Usuario

Flujo de Datos API REST

HTTP POST /api/v1/documents/process (JWT Bearer token)
FastAPI → Depends(get_current_user) → auth.decode_access_token()
Depends(get_container) → ServiceContainer
TaskManager.submit(_process_document_sync, file, container)
    ↓ (ThreadPoolExecutor)
ProcessDocumentUseCase.execute(ProcessDocumentRequest) → Result[Response, Error]
202 Accepted {task_id: "..."}  →  GET /tasks/{task_id} (polling)
200 {status: "completed", result: {...}}

Interfaces Públicas (API de Componentes)

ServiceContainer

def get_container(db_path: str) -> ServiceContainer
container.process_document_use_case -> ProcessDocumentUseCase
container.ocr_router -> OCRRouter
container.ner_adapter -> SpaCyAdapter
container.duplicate_detector -> HybridEnsembleDetector
container.repository -> DocumentRepository
container.audit_service -> AuditService
# Fase 0 Pre-API services:
container.statistics_service -> StatisticsService
container.search_service -> SearchService
container.validation_service -> ValidationService
container.manual_entry_service -> ManualEntryService
container.dedup_config_service -> DedupConfigService

ProcessDocumentUseCase

def execute(request: ProcessDocumentRequest) -> Result[ProcessDocumentResponse, ProcessingError]

OCRRouter

def extract_text(file_path: Path) -> OCRResult

SpaCyAdapter

def extract_entities(text: str) -> EntityResult

HybridEnsembleDetector

def detect_duplicates(content: str, doc_id: str, doc_type: str) -> DuplicateDetectionResult
def index_document(doc_id: str, content: str) -> None
def index_corpus(corpus: Dict[str, str]) -> None

SQLiteDocumentRepository

def save(document: Document) -> Document
def get_by_id(id: str) -> Optional[Document]
def get_all() -> List[Document]
def find_by_hash(hash: str) -> Optional[Document]
def search(query: str, limit: int) -> List[SearchResult]

Extensibilidad del Sistema

Agregar Nuevo Motor OCR

  1. Implementar OCRPort
  2. Crear adapter (e.g., EasyOCRAdapter)
  3. Registrar en OCRRouter
  4. Sin cambios en Application Layer

Agregar Nuevo Nivel de Detección

  1. Crear matcher (e.g., SemanticMatcher)
  2. Implementar interfaz de matching
  3. Registrar en HybridEnsembleDetector
  4. Sin cambios en Use Case

Cambiar Base de Datos

  1. Implementar DocumentRepository
  2. Crear adapter (e.g., PostgresDocumentRepository)
  3. Configurar en ServiceContainer
  4. Sin cambios en Use Cases

Métricas de Complejidad

Componente Líneas de Código Dependencias Externas Complejidad Ciclomática
Domain Layer ~300 0 Baja (1-5)
Application Layer ~800 1 (returns) Media (5-10)
OCR Module ~800 4 (tesseract, paddle, pdf2image, cv2) Alta (10-20)
NER Module ~1100 2 (spacy, regex) Baja (1-5) ✅
├─ SpaCyAdapter 342 - Baja (orquestación)
├─ Extractors ~280 - Baja (SRP)
├─ Validators ~320 - Baja (SRP)
└─ Utilities ~160 - Baja
Dedup Module ~1200 4 (datasketch, sklearn, numpy, scipy) Alta (10-25)
Persistence Module ~600 1 (sqlite3) Media (5-10)
GUI Layer ~4800 1 (streamlit) Media (0 bypasses)
API Layer ~1200 3 (fastapi, pydantic, jose) Baja (delegación a Services)
TOTAL ~10800 16 Media Global

Nota: Los 16 bypasses legacy GUI→Repository fueron eliminados en Sprint 23.1 (Fase 1.5). La API REST no tiene bypasses — todas las operaciones pasan por Services/UseCases.

Nota: NER Module aumentó en líneas pero redujo complejidad ciclomática gracias a Strategy + Pipeline.

Notas de Implementación

  • Todos los componentes tienen tests unitarios (coverage >80%)
  • Infrastructure Layer usa lazy loading para optimizar memoria
  • Cross-cutting concerns implementados con decoradores Python
  • Configuración externalizada (12-factor app)
  • Logging estructurado para análisis con herramientas (ELK, Grafana)

Leyenda de Estados

Símbolo Significado
Implementado y funcional
Planificado para fase futura

Última actualización: 2026-03-27 (Sprint 28: composición Document→VOs, Result[T, AppError] en persistencia, 1707 tests, 88% coverage)