Optimize products list analytics loading
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 54s

This commit is contained in:
Cauê Faleiros
2026-06-22 15:30:54 -03:00
parent bd98348989
commit 3cd4bfc426
7 changed files with 204 additions and 28 deletions

View File

@@ -11,6 +11,7 @@ const {
getClientAnalytics,
getClientDetailsAnalytics,
getPreviousDate,
getProductAnalytics,
getRecencyScore,
getRfmAnalytics,
getRfmSegment,
@@ -330,6 +331,67 @@ test('buildRfmClients applies lifecycle protections to new, hibernating, at-risk
assert.equal(byKey.get('lost').rfmScore, '113');
});
test('getProductAnalytics returns exact product rows with stock and latest price', async () => {
const originalQuery = pool.query;
const calls = [];
pool.query = async (sql, params = []) => {
calls.push({ sql, params });
return {
rows: [
{
id: '919483307',
name: 'BASE LISA CAMISETA COR PRETO TAMANHO - G',
quantity_sold: 9513,
revenue: 113216.83,
order_line_count: 100,
last_price: 11.9,
stock: 11731,
first_sale_date: '2026-06-01',
last_sale_date: '2026-06-22'
},
{
id: 'stock-only',
name: 'Produto sem venda no período',
quantity_sold: 0,
revenue: 0,
order_line_count: 0,
last_price: 0,
stock: 12,
first_sale_date: null,
last_sale_date: null
}
]
};
};
try {
const products = await getProductAnalytics({ start: '2026-06-01', end: '2026-06-22' });
assert.equal(calls.length, 1);
assert.match(calls[0].sql, /WITH period_sales AS/);
assert.match(calls[0].sql, /FULL OUTER JOIN stock_rows/);
assert.doesNotMatch(calls[0].sql, /GROUP BY name/);
assert.deepEqual(calls[0].params, ['2026-06-01', '2026-06-22']);
assert.deepEqual(products[0], {
id: '919483307',
name: 'BASE LISA CAMISETA COR PRETO TAMANHO - G',
quantitySold: 9513,
revenue: 113216.83,
orderLineCount: 100,
lastPrice: 11.9,
stock: 11731,
firstSaleDate: '2026-06-01',
lastSaleDate: '2026-06-22'
});
assert.equal(products[1].id, 'stock-only');
assert.equal(products[1].stock, 12);
} finally {
pool.query = originalQuery;
}
});
test('getClientAnalytics returns opaque client tokens', async () => {
const originalQuery = pool.query;
const calls = [];