Fix duplicate top campaign clients by phone
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m22s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m22s
This commit is contained in:
@@ -25,24 +25,6 @@ const WHATSAPP_CUSTOMER_PHONE_SQL = `
|
||||
ELSE ${NORMALIZED_CUSTOMER_PHONE_SQL}
|
||||
END
|
||||
`;
|
||||
const CANONICAL_CAMPAIGN_CUSTOMER_NAME_SQL = `
|
||||
NULLIF(TRIM(regexp_replace(
|
||||
regexp_replace(
|
||||
regexp_replace(
|
||||
regexp_replace(LOWER(COALESCE(cliente_nome, '')), '[^[:alnum:][:space:]]+', ' ', 'g'),
|
||||
'(^|[[:space:]])[0-9]{2,14}([[:space:]]|$)',
|
||||
' ',
|
||||
'g'
|
||||
),
|
||||
'(^|[[:space:]])(ltda|me|eireli|epp)([[:space:]]|$)',
|
||||
' ',
|
||||
'g'
|
||||
),
|
||||
'[[:space:]]+',
|
||||
' ',
|
||||
'g'
|
||||
)), '')
|
||||
`;
|
||||
const CUSTOMER_IDENTITY_CTE = `
|
||||
WITH customer_phone_by_name AS (
|
||||
SELECT
|
||||
@@ -177,7 +159,6 @@ const getTopClientsForCampaign = async ({ days, limit, start, end } = {}) => {
|
||||
WITH campaign_orders AS (
|
||||
SELECT
|
||||
orders.*,
|
||||
${CANONICAL_CAMPAIGN_CUSTOMER_NAME_SQL} as canonical_customer_name,
|
||||
${WHATSAPP_CUSTOMER_PHONE_SQL} as whatsapp_phone
|
||||
FROM orders
|
||||
)
|
||||
@@ -199,7 +180,9 @@ const getTopClientsForCampaign = async ({ days, limit, start, end } = {}) => {
|
||||
WHERE data_pedido_date >= $1::date
|
||||
AND data_pedido_date <= $2::date
|
||||
AND whatsapp_phone IS NOT NULL
|
||||
GROUP BY COALESCE(canonical_customer_name, whatsapp_phone)
|
||||
-- A campaign recipient is a WhatsApp destination, so each normalized
|
||||
-- phone number must produce exactly one exported customer.
|
||||
GROUP BY whatsapp_phone
|
||||
ORDER BY total_gasto DESC
|
||||
LIMIT $3;
|
||||
`, [range.start, range.end, normalizedLimit]);
|
||||
|
||||
@@ -75,7 +75,8 @@ test('getTopClientsForCampaign returns top clients for an explicit date range',
|
||||
|
||||
assert.equal(queries.length, 1);
|
||||
assert.deepEqual(queries[0].params, ['2026-06-28', '2026-07-27', 1000]);
|
||||
assert.match(queries[0].sql, /GROUP BY COALESCE\(canonical_customer_name, whatsapp_phone\)/);
|
||||
assert.match(queries[0].sql, /GROUP BY whatsapp_phone/);
|
||||
assert.doesNotMatch(queries[0].sql, /GROUP BY COALESCE\(canonical_customer_name, whatsapp_phone\)/);
|
||||
assert.match(queries[0].sql, /ARRAY_AGG\(DISTINCT whatsapp_phone\)/);
|
||||
assert.match(queries[0].sql, /ORDER BY total_gasto DESC/);
|
||||
});
|
||||
@@ -95,7 +96,7 @@ test('getTopClientsForCampaign derives an inclusive 30 day range from the end da
|
||||
});
|
||||
});
|
||||
|
||||
test('getTopClientsForCampaign normalizes phones and ranks one row per canonical client name', async () => {
|
||||
test('getTopClientsForCampaign normalizes phones and groups one row per WhatsApp number', async () => {
|
||||
await withCampaignService(async () => ({ rows: [] }), async ({ getTopClientsForCampaign }, queries) => {
|
||||
await getTopClientsForCampaign({
|
||||
days: '30',
|
||||
@@ -105,6 +106,6 @@ test('getTopClientsForCampaign normalizes phones and ranks one row per canonical
|
||||
assert.match(queries[0].sql, /regexp_replace\(COALESCE\(cliente_fone, ''\), '\\D', '', 'g'\)/);
|
||||
assert.match(queries[0].sql, /WHEN length\(/);
|
||||
assert.match(queries[0].sql, /'55' \|\|/);
|
||||
assert.match(queries[0].sql, /canonical_customer_name/);
|
||||
assert.match(queries[0].sql, /GROUP BY whatsapp_phone/);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user