From 5ca87ddab883d46315255193c95305f70653bfbc Mon Sep 17 00:00:00 2001 From: Caio Carvalho <21188280+ccrvlh@users.noreply.github.com> Date: Fri, 18 Oct 2024 20:50:00 -0300 Subject: [PATCH 1/2] feat: allow for URL pattern matching on funnels --- src/pages/api/reports/funnel.ts | 5 ++- src/queries/analytics/reports/getFunnel.ts | 42 +++++++++++++++++++--- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/pages/api/reports/funnel.ts b/src/pages/api/reports/funnel.ts index 35759a3030..f3ea41aa6e 100644 --- a/src/pages/api/reports/funnel.ts +++ b/src/pages/api/reports/funnel.ts @@ -31,7 +31,10 @@ const schema = { .of( yup.object().shape({ type: yup.string().required(), - value: yup.string().required(), + value: yup + .string() + .matches(/^[a-zA-Z0-9/*-_]+$/, 'Invalid URL pattern') + .required(), }), ) .min(2) diff --git a/src/queries/analytics/reports/getFunnel.ts b/src/queries/analytics/reports/getFunnel.ts index f9ceb85cd1..53f0899723 100644 --- a/src/queries/analytics/reports/getFunnel.ts +++ b/src/queries/analytics/reports/getFunnel.ts @@ -70,9 +70,26 @@ async function relationalQuery( (pv, cv, i) => { const levelNumber = i + 1; const startSum = i > 0 ? 'union ' : ''; - const operator = cv.type === 'url' && cv.value.endsWith('*') ? 'like' : '='; const column = cv.type === 'url' ? 'url_path' : 'event_name'; - const paramValue = cv.value.endsWith('*') ? cv.value.replace('*', '%') : cv.value; + + let operator: string; + let paramValue: string; + + if (cv.type === 'url') { + if (cv.value.includes('*')) { + operator = '~'; + paramValue = cv.value.replace(/\*/g, '.*'); + } else if (cv.value.endsWith('*')) { + operator = 'like'; + paramValue = cv.value.replace('*', '%'); + } else { + operator = '='; + paramValue = cv.value; + } + } else { + operator = '='; + paramValue = cv.value; + } if (levelNumber === 1) { pv.levelOneQuery = ` @@ -167,9 +184,26 @@ async function clickhouseQuery( const levelNumber = i + 1; const startSum = i > 0 ? 'union all ' : ''; const startFilter = i > 0 ? 'or' : ''; - const operator = cv.type === 'url' && cv.value.endsWith('*') ? 'like' : '='; const column = cv.type === 'url' ? 'url_path' : 'event_name'; - const paramValue = cv.value.endsWith('*') ? cv.value.replace('*', '%') : cv.value; + + let operator: string; + let paramValue: string; + + if (cv.type === 'url') { + if (cv.value.includes('*')) { + operator = 'match'; + paramValue = cv.value.replace(/\*/g, '.*'); + } else if (cv.value.endsWith('*')) { + operator = 'like'; + paramValue = cv.value.replace('*', '%'); + } else { + operator = '='; + paramValue = cv.value; + } + } else { + operator = '='; + paramValue = cv.value; + } if (levelNumber === 1) { pv.levelOneQuery = `\n From d99b8227c90741a2ccaf9ed7112e17ffe4d08ed1 Mon Sep 17 00:00:00 2001 From: Caio Carvalho <21188280+ccrvlh@users.noreply.github.com> Date: Thu, 21 Nov 2024 00:41:11 -0300 Subject: [PATCH 2/2] feat: refactor if statements --- src/queries/analytics/reports/getFunnel.ts | 27 ++++++++-------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/src/queries/analytics/reports/getFunnel.ts b/src/queries/analytics/reports/getFunnel.ts index 53f0899723..0a812d8a52 100644 --- a/src/queries/analytics/reports/getFunnel.ts +++ b/src/queries/analytics/reports/getFunnel.ts @@ -70,25 +70,18 @@ async function relationalQuery( (pv, cv, i) => { const levelNumber = i + 1; const startSum = i > 0 ? 'union ' : ''; - const column = cv.type === 'url' ? 'url_path' : 'event_name'; + const isURL = cv.type === 'url'; + const column = isURL ? 'url_path' : 'event_name'; - let operator: string; - let paramValue: string; + let operator = '='; + let paramValue = cv.value; - if (cv.type === 'url') { - if (cv.value.includes('*')) { - operator = '~'; - paramValue = cv.value.replace(/\*/g, '.*'); - } else if (cv.value.endsWith('*')) { - operator = 'like'; - paramValue = cv.value.replace('*', '%'); - } else { - operator = '='; - paramValue = cv.value; - } - } else { - operator = '='; - paramValue = cv.value; + if (isURL && cv.value.includes('*')) { + operator = '~'; + paramValue = cv.value.replace(/\*/g, '.*'); + } else if (isURL && cv.value.endsWith('*')) { + operator = 'like'; + paramValue = cv.value.replace('*', '%'); } if (levelNumber === 1) {