75 lines
2.3 KiB
JavaScript
75 lines
2.3 KiB
JavaScript
import { readFile } from 'node:fs/promises';
|
|
import { parseLine } from './parsing.mjs';
|
|
import { buildIntervalsCrossDay } from './intervals.mjs';
|
|
import { exportCSV } from './csv.mjs';
|
|
import { NamesServiceProxy } from './namesProxy.mjs';
|
|
|
|
class GenericDriver {
|
|
constructor(){
|
|
if (GenericDriver._instance) return GenericDriver._instance;
|
|
/** @type {Array<Object>} */ this.parsedRows = [];
|
|
/** @type {Array<Object>} */ this.payloadDB = [];
|
|
/** @type {Array<Object>} */ this.pairs = [];
|
|
GenericDriver._instance = this;
|
|
}
|
|
|
|
// Orquesta el proceso a partir de texto plano
|
|
async processText(text, { fetchNamesForDocs } = {}){
|
|
const lines = String(text||'').split(/\n/);
|
|
const rows = [];
|
|
for (const line of lines) {
|
|
const r = parseLine(line);
|
|
if (r) rows.push(r);
|
|
}
|
|
this.parsedRows = rows;
|
|
|
|
const uniqueDocs = [...new Set(this.parsedRows.map(r => r.doc))];
|
|
|
|
const namesProxy = new NamesServiceProxy(fetchNamesForDocs);
|
|
const map = await namesProxy.get(uniqueDocs);
|
|
|
|
const missingDocs = uniqueDocs.filter(d => {
|
|
const hit = map?.[d];
|
|
if (!hit) return true;
|
|
if (typeof hit.found === 'boolean') return !hit.found;
|
|
return !(hit?.nombre||'').trim() && !(hit?.apellido||'').trim();
|
|
});
|
|
|
|
// sobreescribir nombre cuando DB provee
|
|
this.parsedRows.forEach(r => {
|
|
const hit = map?.[r.doc];
|
|
if (hit && (hit.nombre || hit.apellido)) {
|
|
r.name = `${hit.nombre || ''} ${hit.apellido || ''}`.trim();
|
|
}
|
|
});
|
|
|
|
// Pairs (permitiendo cruce de medianoche)
|
|
this.pairs = buildIntervalsCrossDay(this.parsedRows);
|
|
|
|
// Payload crudo para insertar
|
|
this.payloadDB = this.parsedRows.map(r => ({
|
|
doc: r.doc,
|
|
isoDate: r.isoDate,
|
|
time: r.time,
|
|
mode: r.mode || null
|
|
}));
|
|
|
|
return { parsedRows: this.parsedRows, pairs: this.pairs, payloadDB: this.payloadDB, missingDocs };
|
|
}
|
|
|
|
// Conveniencia: leer desde ruta en disco
|
|
async processFileFromPath(filePath, opts = {}){
|
|
const txt = await readFile(filePath, 'utf8');
|
|
return await this.processText(txt, opts);
|
|
}
|
|
|
|
// CSV server-side (devuelve string)
|
|
exportCSV(pairs = this.pairs){
|
|
return exportCSV(pairs);
|
|
}
|
|
}
|
|
|
|
const instance = new GenericDriver();
|
|
export default instance;
|
|
export { GenericDriver };
|