Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedThe pull request is closed. 📝 WalkthroughWalkthroughExtends client session filters by adding "pathname" and refactors server-side filter construction to support configurable session-level parameters and field mappings, replacing ad-hoc string replacements with composable mapping passed into getFilterStatement. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as Client UI
participant API as Analytics API
participant Filter as getFilterStatement
participant DB as Database / ClickHouse
rect rgba(200,200,255,0.5)
Client->>API: Request sessions/funnel (filters, site, time)
end
rect rgba(200,255,200,0.5)
API->>Filter: getFilterStatement(filters, site, time, { sessionLevelParams, fieldMappings })
Filter->>Filter: Build session-level subqueries for configured params\nApply regex/numeric handling\nApply fieldMappings remap
Filter-->>API: SQL filter fragment (CTE-aware)
end
rect rgba(255,200,200,0.5)
API->>DB: Execute composed query with filter fragment and CTEs (including utm_* columns)
DB-->>API: Rows
API-->>Client: Results
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…ters and field mappings - Introduced options for session-level parameters and field mappings in getFilterStatement, allowing for more flexible filter configurations. - Updated getSessions and getFunnelStepSessions to utilize the new field mappings for UTM parameters, improving query efficiency. - Enhanced unit tests for getFilterStatement to ensure correct handling of various filter types and conditions.
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
server/src/api/analytics/funnels/getFunnelStepSessions.ts (1)
145-146:filterStatementwith mapped field names fails at line 145 when applied to theeventstable in theSessionActionsCTE.The
filterStatementis constructed once (line 68) withfieldMappingsthat replaceurl_parameters['utm_source'], etc., withutm_sourcecolumn references. This mapping works correctly at line 251 where the final SELECT queriesAggregatedSessions(which extracts UTM parameters as separate columns at lines 222-226). However, at line 145, the samefilterStatementis applied to theSessionActionsCTE, which selects directly from theeventstable without extracting UTM parameters. Theeventstable stores UTM data in theurl_parametersmap, not as individual columns. When the mapped filter referencesutm_source, it will fail because that column does not exist in theeventstable.Solution: Either build separate filter statements for each CTE context, or apply field mappings conditionally only for the aggregated query.
🧹 Nitpick comments (3)
server/src/api/analytics/utils/getFilterStatement.ts (2)
101-121: Session-level subquery uses rawparaminstead ofgetSqlParam(param).When
buildSessionLevelSubqueryis called with a parameter fromsessionLevelParams, it uses the rawparamdirectly in the SQL condition (line 111). However, parameters likepathnamedon't need transformation, but if someone adds a parameter likereferrer(which maps todomainWithoutWWW(referrer)) tosessionLevelParams, the SQL would be incorrect.Consider using
getSqlParam(param)for consistency, or document thatsessionLevelParamsmust only contain parameters that don't require SQL transformation.♻️ Suggested fix
const buildSessionLevelSubquery = ( param: FilterParameter, filterType: FilterType, values: (string | number)[], wildcardPrefix: string ): string => { const whereClause = [siteIdFilter, timeFilter].filter(Boolean).join(" AND "); + const sqlParam = getSqlParam(param); const condition = values.length === 1 - ? `${param} ${filterTypeToOperator(filterType)} ${SqlString.escape(wildcardPrefix + values[0] + wildcardPrefix)}` - : `(${values.map(value => `${param} ${filterTypeToOperator(filterType)} ${SqlString.escape(wildcardPrefix + value + wildcardPrefix)}`).join(" OR ")})`; + ? `${sqlParam} ${filterTypeToOperator(filterType)} ${SqlString.escape(wildcardPrefix + values[0] + wildcardPrefix)}` + : `(${values.map(value => `${sqlParam} ${filterTypeToOperator(filterType)} ${SqlString.escape(wildcardPrefix + value + wildcardPrefix)}`).join(" OR ")})`;
304-311: Consider usingreplaceAll()instead of regex to avoid static analysis warnings.The static analysis tool flagged a potential ReDoS vulnerability on line 308. While this is likely a false positive (since
fieldMappingsare developer-controlled constants, not user input), you can silence the warning and simplify the code by usingString.prototype.replaceAll():♻️ Suggested fix using replaceAll
// Apply field mappings if provided (for CTEs that extract fields to different column names) if (options?.fieldMappings) { for (const [from, to] of Object.entries(options.fieldMappings)) { - // Escape special regex characters in the 'from' string - const escapedFrom = from.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); - result = result.replace(new RegExp(escapedFrom, "g"), to); + result = result.replaceAll(from, to); } }server/src/api/analytics/getSessions.ts (1)
60-67: Consider extracting sharedSESSION_FIELD_MAPPINGSto avoid duplication.This constant is identical to the one defined inline in
getFunnelStepSessions.ts(lines 69-75). Consider extracting it to a shared location (e.g.,utils/getFilterStatement.tsor a constants file) to maintain consistency and reduce duplication.♻️ Example shared constant in getFilterStatement.ts
// In server/src/api/analytics/utils/getFilterStatement.ts export const UTM_FIELD_MAPPINGS: Record<string, string> = { "url_parameters['utm_source']": "utm_source", "url_parameters['utm_medium']": "utm_medium", "url_parameters['utm_campaign']": "utm_campaign", "url_parameters['utm_term']": "utm_term", "url_parameters['utm_content']": "utm_content", };Then import and use in both
getSessions.tsandgetFunnelStepSessions.ts.
…ile display - Redesigned the SessionCard component to support a mobile-first layout, featuring a two-row design for better usability on smaller screens. - Added tooltips and badges for session details, including country, browser, and device type, enhancing the information presented to users. - Updated the SessionCardSkeleton to match the new layout, ensuring a consistent loading experience across devices. - Simplified the desktop layout while maintaining essential session information visibility.
* better filters * Refactor getFilterStatement to support customizable session-level filters and field mappings - Introduced options for session-level parameters and field mappings in getFilterStatement, allowing for more flexible filter configurations. - Updated getSessions and getFunnelStepSessions to utilize the new field mappings for UTM parameters, improving query efficiency. - Enhanced unit tests for getFilterStatement to ensure correct handling of various filter types and conditions. * Enhance SessionCard component with responsive layout and improved mobile display - Redesigned the SessionCard component to support a mobile-first layout, featuring a two-row design for better usability on smaller screens. - Added tooltips and badges for session details, including country, browser, and device type, enhancing the information presented to users. - Updated the SessionCardSkeleton to match the new layout, ensuring a consistent loading experience across devices. - Simplified the desktop layout while maintaining essential session information visibility.
Summary by CodeRabbit
New Features
Refactor
✏️ Tip: You can customize this high-level summary in your review settings.