Módulo Bancario — Documentación de Base de Datos
Módulo encargado de gestionar los formularios XLS de los bancos, parametrizar el mapeo de variables y generar los archivos pre-llenados con los datos del informe de tasación.
Flujo general
Informe de tasación (catched_fields)
↓
Servicio resuelve semantic_field → field concreto del formato
↓
Inyecta valores en named ranges del XLS base (bank_template activo)
↓
Formulario de revisión — producción confirma o corrige valores
↓
XLS final generado → se guarda en report_bank_exports
Tablas
banks — Catálogo de bancos
Registro único por institución financiera. Independiente de los formatos o versiones de su formulario.
| Campo | Descripción | Tipo | Nullable |
|---|---|---|---|
| id | Identificador único del banco | INTEGER (PK) | ✗ |
| name | Nombre del banco | VARCHAR(255) | ✗ |
Ejemplos:
| id | name |
|---|---|
| 1 | Scotiabank |
| 2 | Banreservas |
| 3 | APAP |
| 4 | BHD |
bank_templates — Versiones del formulario XLS por banco
Cada vez que un banco actualiza su formato, se sube un nuevo template. El activo es el que usarán todos los informes nuevos. Los anteriores quedan en historial para poder regenerar informes viejos con el formato que correspondía en ese momento.
| Campo | Descripción | Tipo | Nullable |
|---|---|---|---|
| id | Identificador único del template | INTEGER (PK) | ✗ |
| bank_id | Banco al que pertenece este template | INTEGER (FK → banks) | ✗ |
| name | Etiqueta descriptiva de la versión | VARCHAR(255) | ✗ |
| xls_path | Ruta al archivo XLS base en storage | VARCHAR(500) | ✗ |
| version | Número de versión correlativo por banco | INTEGER | ✗ |
| active | Si es el template vigente para nuevos informes | BOOLEAN | ✗ |
| uploaded_by | Usuario que subió este template | INTEGER (FK → users) | ✗ |
| uploaded_at | Fecha y hora de carga | TIMESTAMP | ✗ |
Ejemplo — historial Scotiabank:
| id | bank_id | name | version | active |
|---|---|---|---|---|
| 1 | 1 | Formato enero 2025 | 1 | false |
| 2 | 1 | Formato agosto 2025 | 2 | false |
| 3 | 1 | Formato marzo 2026 | 3 | true |
Al subir el template v3, el sistema desactiva automáticamente el v2. Los informes generados antes siguen referenciando el v2 en su
report_bank_exports.
bank_variable_groups — Grupos de variables relacionadas
Agrupa named ranges que forman una unidad lógica dentro del formulario. Hay dos patrones principales que justifican un grupo:
radio— varias celdas mutuamente excluyentes donde solo una se marca conXo1(ej: quién habita el inmueble)indexed— variables repetitivas con sufijo numérico que corresponden a una lista (ej: comparables 1, 2, 3…)single— agrupación visual/semántica sin lógica especial
| Campo | Descripción | Tipo | Nullable |
|---|---|---|---|
| id | Identificador único del grupo | INTEGER (PK) | ✗ |
| bank_template_id | Template al que pertenece este grupo | INTEGER (FK → bank_templates) | ✗ |
| name | Nombre descriptivo del grupo | VARCHAR(255) | ✗ |
| group_type | Tipo de comportamiento del grupo | ENUM(radio, indexed, single) | ✗ |
Ejemplos:
| id | bank_template_id | name | group_type |
|---|---|---|---|
| 1 | 3 | Quién habita el inmueble | radio |
| 2 | 3 | Uso del inmueble | radio |
| 3 | 3 | Comparable 1 | indexed |
| 4 | 3 | Comparable 2 | indexed |
| 5 | 3 | Datos generales | single |
bank_variable_mappings — Mapeo de cada named range
Corazón del módulo. Define exactamente qué valor va en cada named range del XLS y cómo obtenerlo. El mapeo se define una vez por banco y funciona para todos los formatos de Passos porque apunta a semantic_fields, no a un field concreto.
| Campo | Descripción | Tipo | Nullable |
|---|---|---|---|
| id | Identificador único del mapeo | INTEGER (PK) | ✗ |
| bank_template_id | Template al que pertenece | INTEGER (FK → bank_templates) | ✗ |
| group_id | Grupo al que pertenece (si aplica) | INTEGER (FK → bank_variable_groups) | ✓ |
| named_range | Nombre exacto de la variable en el XLS | VARCHAR(255) | ✗ |
| source_type | De dónde viene el valor | ENUM(field, static, comparable) | ✗ |
| semantic_field_id | Campo semántico del informe que provee el valor | INTEGER (FK → semantic_fields) | ✓ |
| static_value | Valor fijo a inyectar (si source_type = static) | VARCHAR(255) | ✓ |
| radio_match_value | Valor del field que activa este named range con X/1 | VARCHAR(255) | ✓ |
| comparable_index | Índice 0-based del comparable (si source_type = comparable) | INTEGER | ✓ |
| comparable_field | Atributo del comparable a usar (ubicacion, precio, area…) | VARCHAR(100) | ✓ |
Ejemplos de mapeos:
| named_range | source_type | semantic_field_id | static_value | radio_match_value | comparable_index | comparable_field |
|---|---|---|---|---|---|---|
nombre_cliente | field | 1 (nombre_propietario) | — | — | — | — |
area_construccion | field | 8 (area_construccion) | — | — | — | — |
habitado_propietario | field | 12 (habitado_por) | — | Propietario | — | — |
habitado_inquilino | field | 12 (habitado_por) | — | Inquilino | — | — |
habitado_familia | field | 12 (habitado_por) | — | Familia | — | — |
nombre_banco | static | — | Scotiabank | — | — | — |
comp1_ubicacion | comparable | — | — | — | 0 | ubicacion |
comp1_precio | comparable | — | — | — | 0 | precio |
comp2_ubicacion | comparable | — | — | — | 1 | ubicacion |
Lógica radio: el servicio lee el valor de
habitado_pordel informe. Si es “Propietario”, escribeXenhabitado_propietarioy deja vacíos los demás del grupo.
semantic_fields — Vocabulario canónico de Passos
Identidades estables que representan conceptos del informe independientemente del formato. Un mismo concepto (ej: área de construcción) puede existir como field #47 en Unidad Funcional y como field #183 en Solar y Mejoras — ambos apuntan al mismo semantic_field.
| Campo | Descripción | Tipo | Nullable |
|---|---|---|---|
| id | Identificador único | INTEGER (PK) | ✗ |
| key | Clave legible en snake_case | VARCHAR(100) | ✗ |
| description | Descripción del dato que representa | VARCHAR(255) | ✗ |
Ejemplos:
| id | key | description |
|---|---|---|
| 1 | nombre_propietario | Nombre completo del propietario del inmueble |
| 2 | cedula_propietario | Cédula o documento de identidad del propietario |
| 3 | direccion_inmueble | Dirección física completa del inmueble tasado |
| 4 | municipio | Municipio donde se ubica el inmueble |
| 5 | provincia | Provincia donde se ubica el inmueble |
| 6 | valor_tasado | Valor comercial final de la tasación |
| 7 | valor_tasado_letras | Valor comercial en letras |
| 8 | area_construccion | Área total de construcción en m² |
| 9 | area_terreno | Área total del terreno en m² |
| 10 | antiguedad | Antigüedad del inmueble en años |
| 11 | estado_conservacion | Estado de conservación del inmueble |
| 12 | habitado_por | Quién habita actualmente el inmueble |
| 13 | uso_inmueble | Uso actual del inmueble (residencial, comercial…) |
| 14 | certificado_matricula | Número de certificado de matrícula del título |
| 15 | nombre_tasador | Nombre del tasador responsable del informe |
| 16 | numero_servicio | Número de servicio del informe |
| 17 | fecha_inspeccion | Fecha en que se realizó la inspección |
| 18 | fecha_informe | Fecha de emisión del informe |
field_semantic_field — Mapeo fields concretos ↔ semántica
Tabla pivote que conecta los fields de cada formato de Passos con su semantic_field. Se llena al parametrizar cada formato. Los fields que no tienen equivalente bancario simplemente no se registran aquí.
| Campo | Descripción | Tipo | Nullable |
|---|---|---|---|
| id | Identificador único | INTEGER (PK) | ✗ |
| field_id | Campo concreto del formato Passos | INTEGER (FK → fields) | ✗ |
| semantic_field_id | Concepto semántico que representa | INTEGER (FK → semantic_fields) | ✗ |
Ejemplo — cómo el servicio resuelve en runtime:
Informe tipo "Solar y Mejoras" necesita inyectar "area_construccion" en Scotiabank
1. bank_variable_mappings → semantic_field_id = 8 (area_construccion)
2. field_semantic_field → busca field_id donde semantic_field_id = 8
Y ese field pertenece al report_type del informe
3. Resultado → field #183 del formato Solar y Mejoras
4. catched_fields → busca el valor capturado para field #183 en este informe
5. Inyecta ese valor en el named range del XLS
report_bank_exports — Historial de formularios generados
Registra cada vez que se genera un formulario bancario para un informe. Guarda qué versión del template se usó, quién lo generó y dónde está el archivo resultante.
| Campo | Descripción | Tipo | Nullable |
|---|---|---|---|
| id | Identificador único | INTEGER (PK) | ✗ |
| report_id | Informe de tasación | INTEGER (FK → reports) | ✗ |
| bank_id | Banco para el que se generó | INTEGER (FK → banks) | ✗ |
| bank_template_id | Versión exacta del XLS usado | INTEGER (FK → bank_templates) | ✗ |
| generated_xls_path | Ruta al archivo XLS con datos inyectados | VARCHAR(500) | ✗ |
| generated_by | Usuario que generó el formulario | INTEGER (FK → users) | ✗ |
| generated_at | Fecha y hora de generación | TIMESTAMP | ✗ |
Un mismo informe puede tener múltiples exports del mismo banco (si se regenera tras correcciones) y exports de diferentes bancos (si el cliente necesita Scotiabank y Banreservas simultáneamente).
Relaciones clave
banks ──< bank_templates ──< bank_variable_mappings >── bank_variable_groups
│
↓
semantic_fields >──< fields (via field_semantic_field)
reports >──< report_bank_exports >── bank_templates
Notas de implementación
- El mapeo (
bank_variable_mappings) se define porbank_template_id, no porbank_id, porque distintas versiones del mismo banco podrían tener named ranges diferentes. - Si el banco cambia un named range entre versiones, se actualiza el mapeo del nuevo template. El template viejo y su mapeo permanecen intactos para historial.
- Los
semantic_fieldsson globales al sistema — no pertenecen a ningún banco ni formato específico. field_semantic_fieldpuede tener múltiples registros porsemantic_field_id(uno por cada formato de Passos que tenga ese campo). El servicio filtra por elreport_typedel informe activo para saber cuál usar.