Fix client identity when phone is added
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 58s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 58s
This commit is contained in:
@@ -568,6 +568,50 @@ test('getClientAnalytics returns opaque client tokens', async () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('getClientAnalytics groups phone-less history through the customer identity CTE', async () => {
|
||||
const originalQuery = pool.query;
|
||||
const calls = [];
|
||||
|
||||
pool.query = async (sql, params = []) => {
|
||||
calls.push({ sql, params });
|
||||
|
||||
if (sql.includes('INSERT INTO client_identity_tokens')) {
|
||||
return { rows: [] };
|
||||
}
|
||||
|
||||
return {
|
||||
rows: [
|
||||
{
|
||||
customer_key: '(16) 99999-9999',
|
||||
name: 'Cliente Com Historico',
|
||||
phone: '(16) 99999-9999',
|
||||
quantity_purchased: 1002,
|
||||
total_spent: 50000,
|
||||
order_count: 250,
|
||||
last_purchase_date: '2026-06-15'
|
||||
}
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
try {
|
||||
const clients = await getClientAnalytics({ start: '2026-05-01', end: '2026-06-15' });
|
||||
|
||||
assert.equal(calls.length, 2);
|
||||
assert.equal(clients.length, 1);
|
||||
assert.equal(clients[0].customerKey, '(16) 99999-9999');
|
||||
assert.equal(clients[0].phone, '(16) 99999-9999');
|
||||
assert.match(calls[0].sql, /WITH order_identity AS/);
|
||||
assert.match(calls[0].sql, /customer_phone_by_name AS/);
|
||||
assert.match(calls[0].sql, /ARRAY_AGG\(NULLIF\(cliente_fone, ''\) ORDER BY data_pedido_date DESC NULLS LAST, id DESC\)/);
|
||||
assert.match(calls[0].sql, /NULLIF\(order_identity\.cliente_fone, ''\),\s+customer_phone_by_name\.canonical_phone/s);
|
||||
assert.match(calls[0].sql, /FROM identity_orders/);
|
||||
assert.match(calls[0].sql, /GROUP BY customer_key/);
|
||||
} finally {
|
||||
pool.query = originalQuery;
|
||||
}
|
||||
});
|
||||
|
||||
test('getClientFilterOptions returns distinct date-scoped order metadata options', async () => {
|
||||
const originalQuery = pool.query;
|
||||
const calls = [];
|
||||
@@ -612,7 +656,7 @@ test('getClientFilterOptions returns distinct date-scoped order metadata options
|
||||
}
|
||||
});
|
||||
|
||||
test('getClientDetailsAnalytics fetches only the tokenized client and period rows', async () => {
|
||||
test('getClientDetailsAnalytics resolves legacy name tokens to the canonical phone client', async () => {
|
||||
const originalQuery = pool.query;
|
||||
const calls = [];
|
||||
const clientToken = createClientToken('name:Cliente Sem Fone');
|
||||
@@ -624,11 +668,15 @@ test('getClientDetailsAnalytics fetches only the tokenized client and period row
|
||||
return { rows: [{ customer_key: 'name:Cliente Sem Fone' }] };
|
||||
}
|
||||
|
||||
if (sql.includes('SELECT customer_key') && sql.includes('FROM identity_orders')) {
|
||||
return { rows: [{ customer_key: '(16) 99999-9999' }] };
|
||||
}
|
||||
|
||||
if (sql.includes('all_time_order_count')) {
|
||||
return {
|
||||
rows: [{
|
||||
name: 'Cliente Sem Fone',
|
||||
phone: null,
|
||||
phone: '(16) 99999-9999',
|
||||
all_time_order_count: 3
|
||||
}]
|
||||
};
|
||||
@@ -638,7 +686,7 @@ test('getClientDetailsAnalytics fetches only the tokenized client and period row
|
||||
rows: [
|
||||
{
|
||||
cliente_nome: 'Cliente Sem Fone',
|
||||
cliente_fone: null,
|
||||
cliente_fone: '',
|
||||
data_pedido: '10-06-2026',
|
||||
data_pedido_date: '2026-06-10',
|
||||
valor_pedido: 25,
|
||||
@@ -650,7 +698,7 @@ test('getClientDetailsAnalytics fetches only the tokenized client and period row
|
||||
},
|
||||
{
|
||||
cliente_nome: 'Cliente Sem Fone',
|
||||
cliente_fone: null,
|
||||
cliente_fone: '(16) 99999-9999',
|
||||
data_pedido: '10-06-2026',
|
||||
data_pedido_date: '2026-06-10',
|
||||
valor_pedido: 25,
|
||||
@@ -667,16 +715,19 @@ test('getClientDetailsAnalytics fetches only the tokenized client and period row
|
||||
try {
|
||||
const details = await getClientDetailsAnalytics(clientToken, { start: '2026-06-01', end: '2026-06-15' });
|
||||
|
||||
assert.equal(calls.length, 3);
|
||||
assert.equal(calls.length, 4);
|
||||
assert.match(calls[0].sql, /FROM client_identity_tokens/);
|
||||
assert.deepEqual(calls[0].params, [clientToken]);
|
||||
assert.match(calls[1].sql, /WHERE COALESCE\(NULLIF\(cliente_fone, ''\), 'name:' \|\| COALESCE\(NULLIF\(cliente_nome, ''\), 'Cliente Desconhecido'\)\) = \$1/);
|
||||
assert.deepEqual(calls[1].params, ['name:Cliente Sem Fone']);
|
||||
assert.match(calls[2].sql, /data_pedido_date >= \$2::date/);
|
||||
assert.match(calls[2].sql, /data_pedido_date <= \$3::date/);
|
||||
assert.deepEqual(calls[2].params, ['name:Cliente Sem Fone', '2026-06-01', '2026-06-15']);
|
||||
assert.match(calls[1].sql, /SELECT customer_key/);
|
||||
assert.deepEqual(calls[1].params, ['Cliente Sem Fone']);
|
||||
assert.match(calls[2].sql, /FROM identity_orders/);
|
||||
assert.match(calls[2].sql, /WHERE customer_key = \$1/);
|
||||
assert.deepEqual(calls[2].params, ['(16) 99999-9999']);
|
||||
assert.match(calls[3].sql, /data_pedido_date >= \$2::date/);
|
||||
assert.match(calls[3].sql, /data_pedido_date <= \$3::date/);
|
||||
assert.deepEqual(calls[3].params, ['(16) 99999-9999', '2026-06-01', '2026-06-15']);
|
||||
assert.equal(details.clientName, 'Cliente Sem Fone');
|
||||
assert.equal(details.clientPhone, '');
|
||||
assert.equal(details.clientPhone, '(16) 99999-9999');
|
||||
assert.equal(details.allTimeOrderCount, 3);
|
||||
assert.equal(details.periodSpent, 25);
|
||||
assert.equal(details.periodItems, 3);
|
||||
@@ -807,7 +858,8 @@ test('getRfmAnalytics classifies period buyers by history through the selected r
|
||||
|
||||
assert.match(calls[1].sql, /SET LOCAL statement_timeout/);
|
||||
assert.deepEqual(selectCalls[0].params, ['2026-06-09', '2026-06-15']);
|
||||
assert.doesNotMatch(selectCalls[0].sql, /cliente_fone IS NOT NULL/);
|
||||
assert.doesNotMatch(selectCalls[0].sql, /WHERE\s+cliente_fone IS NOT NULL/);
|
||||
assert.match(selectCalls[0].sql, /FROM identity_orders/);
|
||||
assert.match(selectCalls[1].sql, /\(\$1::date - MAX\(data_pedido_date\)\)::int/);
|
||||
assert.match(selectCalls[1].sql, /data_pedido_date <= \$1::date/);
|
||||
assert.match(selectCalls[1].sql, /WHEN frequency <= 1 THEN 1/);
|
||||
@@ -815,7 +867,8 @@ test('getRfmAnalytics classifies period buyers by history through the selected r
|
||||
assert.doesNotMatch(selectCalls[1].sql, /PERCENT_RANK\(\) OVER \(ORDER BY frequency\)/);
|
||||
assert.match(selectCalls[1].sql, /PERCENT_RANK\(\) OVER \(ORDER BY monetary\)/);
|
||||
assert.match(selectCalls[1].sql, /customer_key = ANY\(\$2::text\[\]\)/);
|
||||
assert.doesNotMatch(selectCalls[1].sql, /cliente_fone IS NOT NULL/);
|
||||
assert.doesNotMatch(selectCalls[1].sql, /WHERE\s+cliente_fone IS NOT NULL/);
|
||||
assert.match(selectCalls[1].sql, /FROM identity_orders/);
|
||||
assert.deepEqual(selectCalls[1].params, ['2026-06-15', ['1', '4', 'name:Cliente Sem Fone']]);
|
||||
assert.deepEqual(selectCalls[2].params, ['2026-06-14', '2026-06-14']);
|
||||
assert.deepEqual(selectCalls[3].params, ['2026-06-14', ['1', '4', 'name:Cliente Sem Fone']]);
|
||||
|
||||
Reference in New Issue
Block a user