Files
IPSExtractor/docs/database.dbml
T

205 lines
7.4 KiB
Plaintext

// IPSExtractor — esquema de integración PostgreSQL
// Fuente autoritativa: services/extraction/infrastructure/database.py
// services/extraction/alembic/versions/
//
// Visualizar en https://dbdiagram.io (importar este archivo)
// o con la CLI de dbml: npx @dbml/cli dbml2sql docs/database.dbml
Project ipsextractor {
database_type: 'PostgreSQL'
Note: '''
Base de datos compartida entre todos los microservicios (extraction, cleaning,
count-facturas). Cada servicio accede directamente a las tablas que necesita.
Las migraciones se gestionan con Alembic (services/extraction/alembic/).
Cada servicio es desacoplado; comparten solo la DB como fuente de verdad.
'''
}
// ---------------------------------------------------------------------------
// Grupos de tablas
// ---------------------------------------------------------------------------
TableGroup orchestration {
jobs
tasks
}
TableGroup pipeline {
extraction_batches
extraction_rows
cleaning_jobs
cleaned_rows
}
TableGroup counting {
count_job_files
}
// ---------------------------------------------------------------------------
// Orchestration — trabajo multimodular del usuario
// ---------------------------------------------------------------------------
Table jobs {
id varchar(36) [pk, note: 'UUID v4']
status varchar(32) [not null, default: 'pending', note: 'pending | running | completed | failed']
title text [note: 'Nombre descriptivo del trabajo']
metadata jsonb [not null, default: '{}', note: 'Datos adicionales específicos por tipo de trabajo']
created_at timestamptz [not null]
updated_at timestamptz [not null]
indexes {
status
}
Note: '''
Contenedor de trabajo del usuario. Un job puede tener múltiples tasks
(una por servicio/módulo utilizado). Permite agrupar conteo + extracción
+ limpieza de un mismo conjunto de documentos.
'''
}
Table tasks {
id varchar(36) [pk, note: 'UUID v4']
job_id varchar(36) [ref: > jobs.id, note: 'FK nullable — compat. con tasks anteriores']
type varchar(64) [not null, note: 'counting | extraction | cleaning']
status varchar(32) [not null, default: 'pending', note: 'pending | running | completed | failed']
title text
request jsonb [not null, default: '{}', note: 'Payload de la petición que originó la tarea']
result jsonb [not null, default: '{}', note: 'Al completar incluye extraction_batch_id o conteos']
error text
owner_id varchar(36) [note: 'Reservado para multi-usuario']
created_at timestamptz [not null]
updated_at timestamptz [not null]
started_at timestamptz
finished_at timestamptz
indexes {
job_id
type
status
owner_id
}
Note: '''
Módulo/resultado dentro de un Job. Una task representa la ejecución
de un servicio específico (conteo, extracción, limpieza).
job_id es nullable para compatibilidad con tasks creadas antes de jobs.
'''
}
// ---------------------------------------------------------------------------
// Counting — resultados del servicio de conteo de facturas médicas
// ---------------------------------------------------------------------------
Table count_job_files {
id varchar(36) [pk, note: 'UUID v4']
job_module_id varchar(36) [not null, ref: > tasks.id]
radicado varchar(255) [note: 'Identificador del radicado / carpeta de origen']
filename varchar(512) [not null, note: 'Nombre del archivo PDF']
file_path text [note: 'Ruta del archivo en el volumen montado (/data/...)']
doc_type varchar(128) [note: 'Tipo de documento (ej. Factura, Historia_Clinica)']
service_count integer [note: 'Número de servicios detectados por el modelo ML']
services jsonb [not null, default: '[]', note: 'Lista de ServiceRow detectados por el modelo']
status varchar(32) [not null, default: 'ok', note: 'ok | error']
is_valid boolean [note: 'null=sin revisar | true=válido | false=rechazado por el usuario']
error text [note: 'Mensaje de error si status=error']
created_at timestamptz [not null]
indexes {
job_module_id
radicado
status
is_valid
}
Note: '''
Resultado del servicio Go (services-count-facturas-medicas-serving) para
un PDF individual. El campo file_path permite que el servicio de extracción
procese el archivo directamente sin necesidad de re-subirlo.
is_valid=null hasta que el usuario revise; el umbral min_service_count
se aplica en el endpoint POST /tasks/extraction/from-count.
'''
}
// ---------------------------------------------------------------------------
// Extracción
// ---------------------------------------------------------------------------
Table extraction_batches {
id varchar(36) [pk, note: 'UUID v4']
job_module_id varchar(36) [ref: > tasks.id, note: 'FK nullable — tarea que origino este lote']
status varchar(32) [not null, default: 'pending', note: 'pending | running | completed | failed']
root_path text [note: 'Ruta raíz de documentos (IPS_DOCUMENT_ROOT o "count://" si viene de conteo)']
request jsonb [not null, default: '{}', note: 'ExtractionRequest serializado']
error text
created_at timestamptz [not null]
updated_at timestamptz [not null]
indexes {
job_module_id
status
}
Note: 'Lote creado al iniciar una extracción; agrupa todas las filas extraídas.'
}
Table extraction_rows {
id integer [pk, increment]
batch_id varchar(36) [not null, ref: > extraction_batches.id]
radicado varchar(255) [note: 'Identificador del radicado IPS']
source_pdf text [note: 'Ruta del PDF origen dentro del volumen montado']
row_index integer [not null, default: 0, note: 'Orden estable dentro del lote']
row_json jsonb [not null, default: '{}', note: 'Fila aplanada con campos solicitados']
raw_json jsonb [not null, default: '{}', note: 'Resultado bruto del procesador por radicado']
created_at timestamptz [not null]
indexes {
batch_id
radicado
}
Note: 'Una o más filas por radicado según flatten_extraction_result().'
}
// ---------------------------------------------------------------------------
// Limpieza
// ---------------------------------------------------------------------------
Table cleaning_jobs {
id varchar(36) [pk, note: 'UUID v4']
extraction_batch_id varchar(36) [null, ref: > extraction_batches.id, note: 'Null si source=csv']
job_id varchar(36) [null, ref: > jobs.id, note: 'Trabajo Desktop al que pertenece']
source varchar(32) [not null, default: 'extraction', note: 'extraction | csv']
status varchar(32) [not null, default: 'pending', note: 'pending | running | completed | failed']
request jsonb [not null, default: '{}', note: 'CleaningRequest (rules_per_column, etc.)']
log jsonb [not null, default: '[]', note: 'Lista de mensajes de auditoría del job']
error text
created_at timestamptz [not null]
updated_at timestamptz [not null]
indexes {
extraction_batch_id
job_id
source
status
}
Note: 'Ejecución de reglas de limpieza sobre filas de extracción o CSV subido.'
}
Table cleaned_rows {
id integer [pk, increment]
cleaning_job_id varchar(36) [not null, ref: > cleaning_jobs.id]
extraction_batch_id varchar(36) [null, ref: > extraction_batches.id]
row_index integer [not null, default: 0, note: 'Conserva el orden del lote original']
row_json jsonb [not null, default: '{}', note: 'Fila tras aplicar reglas de limpieza']
created_at timestamptz [not null]
indexes {
cleaning_job_id
extraction_batch_id
}
Note: 'Salida del servicio de limpieza.'
}