UNPKG

@opengis/fastify-table

Version:

core-plugins

145 lines (142 loc) 5.46 kB
import { createHash } from "node:crypto"; import getTemplate from "../../../table/funcs/getTemplate.js"; import metaFormat from "../../../table/funcs/metaFormat/index.js"; const defaultTitles = { editor_date: "Дата оновлення", editor_id: "Редактор", сdate: "Дата створення", uid: "Автор", body: "Зміст", entity_id: "ID Сутності", entity_type: "Таблиця сутності", file_path: "Шлях до файлу", uploaded_name: "Назва файлу", size: "Розмір файлу", ext: "Розширення файлу", }; function getValue(val, tableName) { if (!val) return null; if (["crm.files"].includes(tableName)) { return typeof val === "object" ? JSON.stringify(val) : val; } return typeof val === "object" ? JSON.stringify(val)?.substring?.(0, 30) : val?.toString?.()?.substring?.(0, 30); } // extract titles and cls from form schema // alt: extract table template from referer -> form export default async function logChanges({ pg, table: table1, tokenData, referer, id, data, uid = 1, type, }) { const table = table1.replace(/"/g, ""); if (!id) { console.error("param id is required"); return null; } if (!table || !pg.pk?.[table]) { console.error("table not found"); return null; } if (!pg.pk?.["log.table_changes"] || !pg.pk?.["log.table_changes_data"]) { console.error("log table not found"); return null; } if (!type) { console.error("invalid type"); return null; } try { const { change_id: changeId } = await pg .query(`insert into log.table_changes(change_date,change_type,change_user_id,entity_type,entity_id) values(CURRENT_DATE, $1, $2, $3, $4) returning change_id`, [type, uid, table, id]) .then((el) => el.rows?.[0] || {}); const q = `select json_object_agg(entity_key, value_hash) from ( select entity_key, value_hash, ( rank() over (partition by entity_key order by cdate desc) = 1 ) as is_latest from log.table_changes_data where change_id in ( select change_id from log.table_changes where entity_id=$1 and entity_type=$2 ) )q where is_latest`; // console.log(q, type, id); const old = type !== "INSERT" ? await pg .query(q, [id, table]) .then((el) => el.rows?.[0]?.json_object_agg || {}) : {}; const body = await getTemplate("form", tokenData?.form); const schema = body?.schema || body || {}; const titles = Object.keys(schema).reduce((acc, curr) => Object.assign(acc, { [curr]: schema[curr].title || schema[curr].ua }), {}); const cls = Object.keys(schema) .filter((el) => schema[el]?.data) .reduce((acc, curr) => Object.assign(acc, { [curr]: schema[curr].data }), {}); const data1 = data ? await metaFormat({ rows: [data], cls, sufix: false, reassign: false, }, pg) : null; const newObj = Object.fromEntries(Object.entries(data1?.[0] || {}).map((el) => [ [titles[el[0]] || defaultTitles[el[0]] || el[0]], el[1], ])); const changesData = Object.keys(newObj || {}) .map((el) => ({ change_id: changeId, entity_key: el, value_old: getValue(old?.[el], table), value_new: type === "DELETE" ? null : getValue(newObj?.[el], table), value_hash: newObj?.[el] ? createHash("md5").update(JSON.stringify(newObj?.[el])).digest("hex") : null, uid, })) .filter((el) => old?.[el.entity_key] !== el.value_hash); const res = await Promise.all(changesData.map(async (el) => { const insertQuery = `insert into log.table_changes_data (${Object.entries(el) ?.map((key) => `"${key[0]}"`) .join(",")}) values (${Object.entries(el) ?.map((key, i) => `$${i + 1}`) .join(",")}) returning *`; const { rows = [] } = (await pg.query(insertQuery, [ ...Object.entries(el).map((el1) => el1[1] && typeof el1[1] === "object" && (!Array.isArray(el1[1]) || typeof el1[1]?.[0] === "object") ? JSON.stringify(el1[1]) : el1[1]), ])) || {}; return rows[0]; })); const newData = type === "DELETE" ? {} : (Array.isArray(res) ? res : [res]).reduce((acc, curr) => Object.assign(acc, { [curr.entity_key]: curr.value_new }), {}); // console.log('logChanges OK', type); return { change_id: changeId, entity_type: table, entity_id: id, uid, change_type: type, old, new: newData, }; } catch (err) { console.error("logChanges error", type, table, id, data, err.toString()); return { error: err.toString(), entity_type: table, entity_id: id, uid, change_type: type, }; } }