import schemaDataRaw from '../lib/schema.json' assert { type: 'json' }; // El schema se usa para validar qué columnas existen realmente en la DB const schemaData = schemaDataRaw; /** * Formatea fechas a estándar ISO (YYYY-MM-DD) para MariaDB */ const fmt = (d) => (d instanceof Date && !isNaN(d.getTime()) ? d.toISOString().split('T')[0] : null); /** * Filtra y limpia las columnas según el schema.json */ const filterColumns = (tableName, rowData) => { const schema = schemaData[tableName]; if (!schema) return rowData; return Object.keys(rowData).reduce((cleanRow, col) => { const colDef = schema[col]; if (!colDef) return cleanRow; // Si la columna no existe en el JSON, se ignora let val = rowData[col]; const type = colDef.type || ''; // Usamos el campo 'type' generado por tu script anterior if (val != null) { // Lógica de fechas if (type.includes('date')) { try { const s = val.toString().trim(); const isISO = val instanceof Date || s.includes('T'); val = isISO ? fmt(new Date(val)) : /^\d{8}$/.test(s) ? `${s.slice(4, 8)}-${s.slice(2, 4)}-${s.slice(0, 2)}` : s.includes('.') ? s.split('.').reverse().join('-') : s.slice(0, 10); } catch { val = null; } } // Lógica de texto: trim y recorte por seguridad según definición else if (type === 'text' && typeof val === 'string') { val = val.trim().slice(0, 255); } } cleanRow[col] = val; return cleanRow; }, {}); }; /** * Orquestador para guardar datos transformados de SOAP a DB */ const saveSoap = async (db, raw, config) => { if (!raw || !raw.length) return 0; const rawArray = Array.isArray(raw) ? raw : [raw]; for (const [table, transform] of Object.entries(config)) { const data = rawArray.flatMap(item => { const res = transform ? transform(item) : item; if (!res) return []; return Array.isArray(res) ? res.map(sub => filterColumns(table, sub)) : [filterColumns(table, res)]; }); if (data.length) { await db.upsert(table, data, true); // true para INSERT IGNORE } } return rawArray.length; }; /** * Acciones exportables para el motor TRX * Estas funciones son llamadas dinámicamente según el nombre del servicio SOAP */ export const actions = { DescargaCompletaRecibos: async (db, { data }) => { const raw = data.ListaRecibos?.ReciboAmpliado || data || []; const total = await saveSoap(db, raw, { 'Recibos': null, 'RecibosEstados': null }); return { totalProcesado: total }; }, DescargaCartera: async (db, { data }) => { const raw = data.DatosCartera?.Cartera || data || []; const total = await saveSoap(db, raw, { 'Cartera': null }); return { totalProcesado: total }; }, DescargaSiniestros: async (db, { data }) => { const raw = data.ListaSiniestros?.SiniestroAmpliado || data || []; const total = await saveSoap(db, raw, { 'Siniestros': null, 'SiniestrosEstados': null }); return { totalProcesado: total }; }, ConsultaAgendaTramitacion: async (db, { data }) => { const raw = data.Datos?.DatosTramitacionResponse || data || []; const total = await saveSoap(db, raw, { 'SiniestrosTramites': null }); return { totalProcesado: total }; }, DescargaPolizas: async (db, { data }) => { const raw = data.ListaPolizas?.Poliza || data || []; const total = await saveSoap(db, raw, { 'Polizas': i => ({ ...i.DatosGenerales, Riesgo: [ i.DatosAccidentes?.NombreAsegurado, i.DatosAutos?.CodigoModelo && `${i.DatosAutos.CodigoModelo} ${i.DatosAutos.Matricula || ''}`.trim(), i.DatosMultirriesgos?.SituacionRiesgo ].filter(Boolean).join(' | ') }), 'PolizasDetalle': i => i.DatosGenerales ? { ...i.DatosGenerales.DatosTomador, ...i.DatosGenerales, CodigoPoliza: i.DatosGenerales.CodigoPoliza, CodigoSuplemento: i.DatosGenerales.CodigoSuplemento } : null, 'PolizasAutos': i => i.DatosAutos?.CodigoModelo ? { ...i.DatosAutos, CodigoPoliza: i.DatosGenerales.CodigoPoliza, CodigoSuplemento: i.DatosGenerales.CodigoSuplemento } : null, 'PolizasAutosConductor': i => { const { CodigoPoliza, CodigoSuplemento } = i.DatosGenerales || {}; const { DatosConductor: hab, DatosConductorOcasional: oca } = i.DatosAutos || {}; return [ hab?.Nombre ? { ...hab, CodigoPoliza, CodigoSuplemento, TipoConductor: 'Habitual' } : null, oca?.Nombre ? { ...oca, CodigoPoliza, CodigoSuplemento, TipoConductor: 'Ocasional' } : null ].filter(Boolean); }, 'PolizasMultirriesgos': i => i.DatosMultirriesgos ? { ...i.DatosMultirriesgos, CodigoPoliza: i.DatosGenerales.CodigoPoliza, CodigoSuplemento: i.DatosGenerales.CodigoSuplemento } : null, 'PolizasAccidentes': i => i.DatosAccidentes ? { ...i.DatosAccidentes, CodigoPoliza: i.DatosGenerales.CodigoPoliza, CodigoSuplemento: i.DatosGenerales.CodigoSuplemento } : null }); return { totalProcesado: total }; } };