Optimize product detail analytics loading
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 43s

This commit is contained in:
Cauê Faleiros
2026-06-22 15:49:40 -03:00
parent 3cd4bfc426
commit 62e0239ee4
7 changed files with 280 additions and 60 deletions

View File

@@ -452,6 +452,98 @@ const getProductAnalytics = async (range = {}) => {
}));
};
const getProductDetailsAnalytics = async (productId, range = {}) => {
const normalizedProductId = String(productId || '').trim();
if (!normalizedProductId) return null;
const normalizedStart = normalizeDateParam(range.start);
const normalizedEnd = normalizeDateParam(range.end);
const periodParams = [normalizedProductId];
const periodFilters = [
'produto_id = $1',
'data_pedido_date IS NOT NULL'
];
if (normalizedStart) {
periodParams.push(normalizedStart);
periodFilters.push(`data_pedido_date >= $${periodParams.length}::date`);
}
if (normalizedEnd) {
periodParams.push(normalizedEnd);
periodFilters.push(`data_pedido_date <= $${periodParams.length}::date`);
}
const [summaryResult, periodResult] = await Promise.all([
pool.query(`
WITH selected_product AS (
SELECT $1::text as id
),
stock_info AS (
SELECT
produto_id as id,
MAX(NULLIF(nome, '')) as name
FROM stock
WHERE produto_id = $1
GROUP BY produto_id
),
order_info AS (
SELECT
produto_id as id,
(ARRAY_AGG(COALESCE(NULLIF(produto_descricao, ''), 'Unknown') ORDER BY data_pedido_date DESC NULLS LAST, data_pedido DESC NULLS LAST))[1] as name,
(ARRAY_AGG(valor_unitario ORDER BY data_pedido_date DESC NULLS LAST, data_pedido DESC NULLS LAST))[1] as price
FROM orders
WHERE produto_id = $1
GROUP BY produto_id
)
SELECT
selected_product.id,
COALESCE(stock_info.name, order_info.name, 'Unknown') as name,
COALESCE(order_info.price, 0) as price
FROM selected_product
LEFT JOIN stock_info ON stock_info.id = selected_product.id
LEFT JOIN order_info ON order_info.id = selected_product.id
WHERE stock_info.id IS NOT NULL OR order_info.id IS NOT NULL;
`, [normalizedProductId]),
pool.query(`
SELECT
data_pedido_date,
MAX(data_pedido) as date_label,
COALESCE(SUM(quantidade), 0) as quantity_sold,
COALESCE(SUM(quantidade * valor_unitario), 0) as revenue
FROM orders
WHERE ${periodFilters.join(' AND ')}
GROUP BY data_pedido_date
ORDER BY data_pedido_date ASC;
`, periodParams)
]);
const summary = summaryResult.rows[0];
if (!summary) return null;
const chartData = periodResult.rows.map(row => ({
date: row.date_label || getDateOnly(row.data_pedido_date) || '',
value: toNumber(row.quantity_sold)
}));
const totalSold = periodResult.rows.reduce((sum, row) => sum + toNumber(row.quantity_sold), 0);
const totalRevenue = periodResult.rows.reduce((sum, row) => sum + toNumber(row.revenue), 0);
return {
range: {
start: normalizedStart,
end: normalizedEnd
},
productInfo: {
id: summary.id,
name: summary.name,
price: toNumber(summary.price)
},
chartData,
totalSold,
totalRevenue
};
};
const getClientAnalytics = async (range = {}) => {
const { params, whereClause } = buildDateFilter(range);
const result = await pool.query(`
@@ -837,6 +929,7 @@ module.exports = {
getRfmSegment,
getClientAnalytics,
getDashboardAnalytics,
getProductDetailsAnalytics,
getProductAnalytics,
normalizeDateParam,
scoreTertile