audit and sync
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { refreshProductByWooId } from "../../shared/wooSnapshot.js";
|
||||
import { getTenantByKey } from "../db/repo.js";
|
||||
import { insertAuditLog } from "../../0-ui/db/repo.js";
|
||||
|
||||
function unauthorized(res) {
|
||||
res.setHeader("WWW-Authenticate", 'Basic realm="woo-webhook"');
|
||||
@@ -18,11 +19,25 @@ function checkBasicAuth(req) {
|
||||
return { ok: false, reason: "invalid_creds" };
|
||||
}
|
||||
|
||||
function parseWooId(payload) {
|
||||
function parseWooPayload(payload) {
|
||||
const id = payload?.id || payload?.data?.id || null;
|
||||
const parentId = payload?.parent_id || payload?.data?.parent_id || null;
|
||||
const resource = payload?.resource || payload?.topic || null;
|
||||
return { id: id ? Number(id) : null, parentId: parentId ? Number(parentId) : null, resource };
|
||||
const action = payload?.action || null; // 'created' | 'updated' | 'deleted'
|
||||
|
||||
// Extraer campos relevantes para audit
|
||||
const name = payload?.name || null;
|
||||
const price = payload?.price || null;
|
||||
const stockStatus = payload?.stock_status || null;
|
||||
const stockQty = payload?.stock_quantity ?? null;
|
||||
|
||||
return {
|
||||
id: id ? Number(id) : null,
|
||||
parentId: parentId ? Number(parentId) : null,
|
||||
resource,
|
||||
action,
|
||||
changes: { name, price, stockStatus, stockQty }
|
||||
};
|
||||
}
|
||||
|
||||
export function makeWooProductWebhook() {
|
||||
@@ -30,7 +45,7 @@ export function makeWooProductWebhook() {
|
||||
const auth = checkBasicAuth(req);
|
||||
if (!auth.ok) return unauthorized(res);
|
||||
|
||||
const { id, parentId, resource } = parseWooId(req.body || {});
|
||||
const { id, parentId, resource, action, changes } = parseWooPayload(req.body || {});
|
||||
if (!id) return res.status(400).json({ ok: false, error: "missing_id" });
|
||||
|
||||
// Determinar tenant por query ?tenant_key=...
|
||||
@@ -42,17 +57,55 @@ export function makeWooProductWebhook() {
|
||||
const parentForVariation =
|
||||
resource && String(resource).includes("variation") ? parentId || null : null;
|
||||
|
||||
const updated = await refreshProductByWooId({
|
||||
tenantId: tenant.id,
|
||||
wooId: id,
|
||||
parentId: parentForVariation,
|
||||
});
|
||||
// Determinar acción para audit
|
||||
let auditAction = 'update';
|
||||
if (action === 'created' || resource?.includes('created')) {
|
||||
auditAction = 'create';
|
||||
} else if (action === 'deleted' || resource?.includes('deleted')) {
|
||||
auditAction = 'delete';
|
||||
}
|
||||
|
||||
let updated = null;
|
||||
|
||||
// Si es delete, no podemos refresh (el producto ya no existe en Woo)
|
||||
if (auditAction !== 'delete') {
|
||||
try {
|
||||
updated = await refreshProductByWooId({
|
||||
tenantId: tenant.id,
|
||||
wooId: id,
|
||||
parentId: parentForVariation,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("[wooWebhook] Error refreshing product:", err.message);
|
||||
// Si falla el refresh (ej: producto eliminado), registramos igual en audit
|
||||
}
|
||||
}
|
||||
|
||||
// Registrar en audit_log
|
||||
try {
|
||||
await insertAuditLog({
|
||||
tenantId: tenant.id,
|
||||
entityType: 'product',
|
||||
entityId: String(id),
|
||||
action: auditAction,
|
||||
changes: {
|
||||
...changes,
|
||||
resource,
|
||||
woo_action: action,
|
||||
refreshed: updated != null
|
||||
},
|
||||
actor: 'webhook'
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("[wooWebhook] Error inserting audit log:", err.message);
|
||||
}
|
||||
|
||||
return res.status(200).json({
|
||||
ok: true,
|
||||
woo_id: updated?.woo_id || id,
|
||||
type: updated?.type || null,
|
||||
parent_id: updated?.parent_id || null,
|
||||
action: auditAction,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user