@opengis/fastify-table
Version:
core-plugins
145 lines (142 loc) • 5.46 kB
JavaScript
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,
};
}
}