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]
CLI[⌨️ CLI Interface ✅<br/>─────────────<br/>• 21 comandos implementados<br/>• Procesamiento batch<br/>• Import/Export<br/>• Debugging y stats<br/>• audit-report GOB-11]
end
subgraph "Application Layer"
direction TB
UseCases[🎯 Use Cases<br/>─────────────<br/>• ProcessDocumentUseCase ✅<br/>• ExportExcelUseCase ✅<br/>• ImportExcelUseCase ✅<br/>• SearchDocumentsUseCase ⏳<br/>• ValidateEntityUseCase ⏳]
DTOs[📦 DTOs<br/>─────────────<br/>• ProcessDocumentRequest<br/>• ProcessDocumentResponse<br/>• ProcessingMetrics<br/>• ExportExcelRequest/Response<br/>• ImportExcelRequest/Response<br/>• SearchRequest<br/>• DuplicateCandidateDTO]
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]
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 ✅<br/>• EntityLinker ✅<br/>• RadicadoValidator ✅<br/>• DocumentStructureAnalyzer ✅<br/>• TemporalFeatures ✅<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
CLI --> UseCases
%% Application internal
UseCases --> DTOs
UseCases --> Container
Container --> UseCases
%% 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 -.uses.-> PersistenceModule
%% 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
style GUI fill:#f9d5e5
style CLI fill:#f9d5e5
style UseCases fill:#d5e5f9
style DTOs fill:#d5e5f9
style Container 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 21 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)
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
- SearchDocumentsUseCase ⏳: Búsqueda full-text con FTS5 (planificado, actualmente en Repository)
- ValidateEntityUseCase ⏳: Validación y corrección de entidades (planificado)
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)
Características: - Identidad única (UUID) - Validaciones de negocio - Inmutabilidad preferida
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 (Chain of Responsibility) ✅:
- 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)
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¶
- Presentation → Application: GUI/CLI usan Use Cases
- Application → Domain: Use Cases usan Entities y Value Objects
- Application → Infrastructure (via Ports): Use Cases dependen de interfaces, no implementaciones
- Infrastructure → Domain: Adapters usan Value Objects para retornar resultados
- Infrastructure ← Domain: Nunca (Domain no conoce Infrastructure)
Flujo de Datos Típico¶
Usuario → GUI → ProcessDocumentUseCase → OCRRouter → TesseractAdapter → Tesseract
↓
EntityResult ← SpaCyAdapter ← NERPort
↓
DuplicateDetectionResult ← HybridEnsembleDetector ← DuplicateDetectorPort
↓
Document → SQLiteDocumentRepository → SQLite DB
↓
ProcessDocumentResponse → GUI → Usuario
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
ProcessDocumentUseCase¶
OCRRouter¶
SpaCyAdapter¶
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¶
- Implementar
OCRPort - Crear adapter (e.g.,
EasyOCRAdapter) - Registrar en
OCRRouter - Sin cambios en Application Layer
Agregar Nuevo Nivel de Detección¶
- Crear matcher (e.g.,
SemanticMatcher) - Implementar interfaz de matching
- Registrar en
HybridEnsembleDetector - Sin cambios en Use Case
Cambiar Base de Datos¶
- Implementar
DocumentRepository - Crear adapter (e.g.,
PostgresDocumentRepository) - Configurar en
ServiceContainer - 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 | ~500 | 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) |
| TOTAL | ~4500 | 12 | Media Global |
Nota: NER Module aumentó en líneas pero redujo complejidad ciclomática gracias a Strategy + Chain of Responsibility.
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 (SearchDocuments, ValidateEntity use cases) |
Última actualización: 2026-03-06 (GOB-05 auth, GOB-06 AuditService, GOB-11 audit-report CLI, CLI 21 cmds, argparse)