/** * Repositorio para el volcado de lineas de objenious en intranet * solo para uso en el volcado. */ import { createHash } from "node:crypto"; import { PoolClient } from "pg"; import { CreateObjeniousLineDTO, ObjeniousLineDb } from "sim-shared/domain/objeniousLine.js"; import { PgClient } from "sim-shared/infrastructure/PgClient.js"; export class ObjeniousLinesRepository { constructor( private pgClient: PgClient ) { } private generateLineHash(data: CreateObjeniousLineDTO) { try { const lineStr = JSON.stringify(data) const hash = createHash("sha256").update(lineStr).digest("base64url") return hash } catch (e) { console.error("[x] Error generando el hash de la linea", data) return undefined } } /** * Hay que hacer la query un poco mas general */ public async getLinesByStatus(query: { status?: string | undefined }, pagination: { limit: number, offset: number }) { // $1 y $2 se reservan para paginación const values: (string | number)[] = [ pagination.limit, pagination.offset, ] const paginationStr = ` LIMIT $1 OFFSET $2 ` const conditionsStr = ` WHERE raw -> 'status' ->> 'networkStatus' = $3 ` let queryStr = ` SELECT * FROM objenious_lines ` if (query.status != undefined) { queryStr = queryStr + conditionsStr values.push(query.status) } queryStr = queryStr + ` ${paginationStr}; ` let client: PoolClient | undefined = undefined; try { client = await this.pgClient.connect(); const res = await client.query(queryStr, values); return { data: res.rows, offset: pagination.offset, rowCount: res.rowCount ?? 0, } } catch (err) { console.error('Error en la query:', err); throw err; } finally { if (client != undefined) { client.release() } } } public async insertOrUpdate(data: CreateObjeniousLineDTO) { const query = ` INSERT INTO objenious_lines ( simId, iccid, msisdn, imei, imeiChangeDate, offerCode, status, preactivationDate, activationDate, commercialStatus, commercialStatusDate, billingStatus, billingStatusChangeDate, billingActivationDate, createDate, raw, hash ) VALUES ( $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17 ) ON CONFLICT (simId) DO UPDATE SET iccid = EXCLUDED.iccid, msisdn = EXCLUDED.msisdn, imei = EXCLUDED.imei, imeiChangeDate = EXCLUDED.imeiChangeDate, offerCode = EXCLUDED.offerCode, status = EXCLUDED.status, preactivationDate = EXCLUDED.preactivationDate, activationDate = EXCLUDED.activationDate, commercialStatus = EXCLUDED.commercialStatus, commercialStatusDate = EXCLUDED.commercialStatusDate, billingStatus = EXCLUDED.billingStatus, billingStatusChangeDate = EXCLUDED.billingStatusChangeDate, billingActivationDate = EXCLUDED.billingActivationDate, raw = EXCLUDED.raw, hash = EXCLUDED.hash WHERE objenious_lines.hash IS DISTINCT FROM EXCLUDED.hash RETURNING id; `; const lineHash = this.generateLineHash(data) if (lineHash == undefined) { console.error("[x] Ignorando linea ", data) return; } const values = [ data.simId, data.iccid, data.msisdn, data.imei, data.imeiChangeDate, data.offerCode, data.status, data.preactivationDate, data.activationDate, data.commercialStatus, data.commercialStatusDate, data.billingStatus, data.billingStatusChangeDate, data.billingActivationDate, data.createDate || new Date(), // Default a ahora si no viene JSON.stringify(data.raw), // El driver de pg requiere string o el objeto directo para JSONB lineHash ]; let client: PoolClient | undefined = undefined; try { client = await this.pgClient.connect(); const res = await client.query<{ id: number }>(query, values); return res.rows[0]; } catch (err) { console.error('Error en la inserción:', err); throw err; } finally { if (client != undefined) { client.release() } } } }