-
Notifications
You must be signed in to change notification settings - Fork 0
Added materialized view and duplicated v2 Tinybird endpoints #37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: coderabbit_combined_20260121_augment_sentry_coderabbit_1_base_added_materialized_view_and_duplicated_v2_tinybird_endpoints_pr232
Are you sure you want to change the base?
Changes from all commits
a592045
2f1abc3
658ebdd
59adc0f
2a1fac5
2e055bf
90f1ae9
b274c27
272e5b4
85270a1
1df55c5
b611cee
4bc9eeb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -13,7 +13,11 @@ export const getStatEndpointUrl = (config?: StatsConfig | null, endpointName?: s | |||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||
| baseUrl = config.endpoint || ''; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| return `${baseUrl}/v0/pipes/${endpointName}.json?${params}`; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Append version suffix if provided (e.g., "v2" -> "api_kpis_v2") | ||||||||||||||||||||||||||
| const finalEndpointName = config.version ? `${config.version}_${endpointName}` : endpointName; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| return `${baseUrl}/v0/pipes/${finalEndpointName}.json?${params}`; | ||||||||||||||||||||||||||
|
Comment on lines
+17
to
+20
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Guard against undefined endpoint names when version is set. With 🔧 Proposed fix- // Append version suffix if provided (e.g., "v2" -> "api_kpis_v2")
- const finalEndpointName = config.version ? `${config.version}_${endpointName}` : endpointName;
-
- return `${baseUrl}/v0/pipes/${finalEndpointName}.json?${params}`;
+ if (!endpointName) {
+ return '';
+ }
+
+ // Append version suffix if provided (e.g., "v2" -> "api_kpis_v2")
+ const finalEndpointName = config.version ? `${config.version}_${endpointName}` : endpointName;
+
+ return `${baseUrl}/v0/pipes/${finalEndpointName}.json?${params}`;📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| export const getToken = () => { | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| SCHEMA > | ||
| `site_uuid` LowCardinality(String), | ||
| `session_id` String, | ||
| `pageviews` AggregateFunction(count, UInt64), | ||
| `first_pageview` AggregateFunction(min, DateTime), | ||
| `last_pageview` AggregateFunction(max, DateTime), | ||
| `source` AggregateFunction(argMin, String, DateTime), | ||
| `device` AggregateFunction(argMin, String, DateTime), | ||
| `utm_source` AggregateFunction(argMin, String, DateTime), | ||
| `utm_medium` AggregateFunction(argMin, String, DateTime), | ||
| `utm_campaign` AggregateFunction(argMin, String, DateTime), | ||
| `utm_term` AggregateFunction(argMin, String, DateTime), | ||
| `utm_content` AggregateFunction(argMin, String, DateTime) | ||
|
|
||
| ENGINE "AggregatingMergeTree" | ||
| ENGINE_SORTING_KEY "site_uuid, session_id" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,7 +7,7 @@ | |
| Ghost analytics distinguishes between two types of attributes: | ||
|
|
||
| #### Session-Level Attributes | ||
| These are captured from the **first hit** (earliest timestamp) in a session using `argMin(field, timestamp)` in the `mv_session_data` materialized view: | ||
| These are captured from the **first hit** (earliest timestamp) in a session using `argMinState(field, timestamp)` in the `_mv_session_data` materialized view (an `AggregatingMergeTree` table): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: rg -n "_mv_session_data_v2|_mv_session_data\b" ghost/core/core/server/data/tinybird -g '*.pipe' -g '*.datasource'Repository: qodo-benchmark/Ghost-combined-coderabbit Length of output: 1127 🏁 Script executed: cat -n ghost/core/core/server/data/tinybird/endpoints/README.md | head -50Repository: qodo-benchmark/Ghost-combined-coderabbit Length of output: 2406 🏁 Script executed: find ghost/core/core/server/data/tinybird -name "*.pipe" | grep -E "(filtered_sessions|mv_session_data)" | head -20Repository: qodo-benchmark/Ghost-combined-coderabbit Length of output: 349 🏁 Script executed: head -30 ghost/core/core/server/data/tinybird/pipes/filtered_sessions.pipeRepository: qodo-benchmark/Ghost-combined-coderabbit Length of output: 1672 🏁 Script executed: head -30 ghost/core/core/server/data/tinybird/pipes/filtered_sessions_v2.pipeRepository: qodo-benchmark/Ghost-combined-coderabbit Length of output: 1664 🏁 Script executed: grep -A 10 "sessions_filtered_by_session_attributes" ghost/core/core/server/data/tinybird/pipes/filtered_sessions.pipe | head -20Repository: qodo-benchmark/Ghost-combined-coderabbit Length of output: 474 🏁 Script executed: grep -A 10 "sessions_filtered_by_session_attributes" ghost/core/core/server/data/tinybird/pipes/filtered_sessions_v2.pipe | head -20Repository: qodo-benchmark/Ghost-combined-coderabbit Length of output: 459 🏁 Script executed: grep -A 20 "sessions_filtered_by_session_attributes" ghost/core/core/server/data/tinybird/pipes/filtered_sessions_v2.pipe | head -30Repository: qodo-benchmark/Ghost-combined-coderabbit Length of output: 914 🏁 Script executed: cat -n ghost/core/core/server/data/tinybird/pipes/mv_session_data.pipe | head -30Repository: qodo-benchmark/Ghost-combined-coderabbit Length of output: 1424 🏁 Script executed: cat -n ghost/core/core/server/data/tinybird/pipes/mv_session_data_v2.pipe | head -30Repository: qodo-benchmark/Ghost-combined-coderabbit Length of output: 960 Clarify v1 vs v2 datasources and correct function name. Lines 10 and 42 describe 🤖 Prompt for AI Agents |
||
|
|
||
| - `source` - Referring domain | ||
| - `utm_source` - UTM source parameter | ||
|
|
@@ -39,7 +39,7 @@ Finds sessions where **at least one hit** matches the hit-level filter criteria | |
| ```sql | ||
| NODE sessions_filtered_by_session_attributes | ||
| ``` | ||
| Further filters by session-level attributes (source, utm_*) by joining with `mv_session_data`. These filters check attributes from the **first hit only**. | ||
| Further filters by session-level attributes (source, utm_*) by reading from `_mv_session_data` using `-Merge` combinators (e.g., `argMinMerge(source)`). These filters check attributes from the **first hit only**. | ||
|
|
||
| **Stage 3: Final Output** | ||
| ```sql | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| TOKEN "stats_page" READ | ||
| TOKEN "axis" READ | ||
|
|
||
| NODE _active_visitors_0 | ||
| SQL > | ||
| % | ||
| select | ||
| uniqExact(session_id) as active_visitors | ||
| from _mv_hits | ||
| where | ||
| site_uuid = {{String(site_uuid, 'mock_site_uuid', description="Site UUID", required=True)}} | ||
| and timestamp >= (now() - interval 5 minute) | ||
| {% if defined(post_uuid) %} and post_uuid = {{ String(post_uuid, description="Post UUID to filter on", required=False) }} {% end %} | ||
|
|
||
| TYPE ENDPOINT |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,162 @@ | ||||||
| TOKEN "stats_page" READ | ||||||
| TOKEN "axis" READ | ||||||
|
|
||||||
| NODE timeseries | ||||||
| SQL > | ||||||
|
|
||||||
| % | ||||||
| {% set _single_day = defined(date_from) and day_diff(date_from, date_to) == 0 %} | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: find . -name "api_kpis_v2.pipe" -o -name "*.pipe" | head -20Repository: qodo-benchmark/Ghost-combined-coderabbit Length of output: 224 🏁 Script executed: git ls-files | grep -E "(tinybird|pipe)" | head -20Repository: qodo-benchmark/Ghost-combined-coderabbit Length of output: 1267 🏁 Script executed: git ls-files | grep "api_kpis_v2.pipe"Repository: qodo-benchmark/Ghost-combined-coderabbit Length of output: 147 🏁 Script executed: cat -n ghost/core/core/server/data/tinybird/endpoints/api_kpis_v2.pipe | head -50Repository: qodo-benchmark/Ghost-combined-coderabbit Length of output: 2196 🏁 Script executed: cat -n ghost/core/core/server/data/tinybird/endpoints/api_kpis_v2.pipeRepository: qodo-benchmark/Ghost-combined-coderabbit Length of output: 7570 🏁 Script executed: # Search for day_diff usage in tinybird files to understand its behavior
rg "day_diff" --type-list | head -5Repository: qodo-benchmark/Ghost-combined-coderabbit Length of output: 473 🏁 Script executed: rg "day_diff" ghost/core/core/server/data/tinybird/ -A 2 -B 2Repository: qodo-benchmark/Ghost-combined-coderabbit Length of output: 4660 Guard Line 8: Since both Suggested change- {% set _single_day = defined(date_from) and day_diff(date_from, date_to) == 0 %}
+ {% set _single_day = defined(date_from) and defined(date_to) and day_diff(date_from, date_to) == 0 %}Note: The same issue appears in multiple locations in this file (lines 84, 124, 132). 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
| with | ||||||
| {% if defined(date_from) %} | ||||||
| toStartOfDay( | ||||||
| toDate( | ||||||
| {{ | ||||||
| Date( | ||||||
| date_from, | ||||||
| description="Starting day for filtering a date range", | ||||||
| required=False, | ||||||
| ) | ||||||
| }} | ||||||
| ) | ||||||
| ) as start, | ||||||
| {% else %} toStartOfDay(timestampAdd(today(), interval -7 day)) as start, | ||||||
| {% end %} | ||||||
| {% if defined(date_to) %} | ||||||
| toStartOfDay( | ||||||
| toDate( | ||||||
| {{ | ||||||
| Date( | ||||||
| date_to, | ||||||
| description="Finishing day for filtering a date range", | ||||||
| required=False, | ||||||
| ) | ||||||
| }} | ||||||
| ) | ||||||
| ) as end | ||||||
| {% else %} toStartOfDay(today()) as end | ||||||
| {% end %} | ||||||
| {% if _single_day %} | ||||||
| select | ||||||
| arrayJoin( | ||||||
| arrayMap( | ||||||
| x -> toDateTime(toString(toDateTime(x)), {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}), | ||||||
| range( | ||||||
| toUInt32(toDateTime(start)), toUInt32(timestampAdd(end, interval 1 day)), 3600 | ||||||
| ) | ||||||
| ) | ||||||
| ) as date | ||||||
| {% else %} | ||||||
| select | ||||||
| arrayJoin( | ||||||
| arrayMap( | ||||||
| x -> toDate(x), | ||||||
| range(toUInt32(start), toUInt32(timestampAdd(end, interval 1 day)), 24 * 3600) | ||||||
| ) | ||||||
| ) as date | ||||||
| {% end %} | ||||||
|
|
||||||
|
|
||||||
| NODE session_data | ||||||
| DESCRIPTION > | ||||||
| Read session data from AggregatingMergeTree MV using -Merge combinators | ||||||
|
|
||||||
| SQL > | ||||||
| % | ||||||
| SELECT | ||||||
| site_uuid, | ||||||
| session_id, | ||||||
| countMerge(pageviews) as pageviews, | ||||||
| minMerge(first_pageview) as first_pageview, | ||||||
| maxMerge(last_pageview) as last_pageview | ||||||
| FROM _mv_session_data_v2 | ||||||
| WHERE site_uuid = {{ String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True) }} | ||||||
| GROUP BY site_uuid, session_id | ||||||
|
|
||||||
| NODE session_metrics | ||||||
| DESCRIPTION > | ||||||
| Calculate session-level metrics (visits, pageviews, bounce rate, avg session duration) | ||||||
|
|
||||||
| SQL > | ||||||
|
|
||||||
| % | ||||||
| select | ||||||
| site_uuid, | ||||||
| {% if defined(date_from) and day_diff(date_from, date_to) == 0 %} | ||||||
| toStartOfHour(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) as date, | ||||||
| {% else %} | ||||||
| toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) as date, | ||||||
| {% end %} | ||||||
| sd.session_id, | ||||||
| pageviews, | ||||||
| pageviews = 1 as is_bounce, | ||||||
| last_pageview - first_pageview as session_sec | ||||||
| from session_data sd | ||||||
| inner join filtered_sessions_v2 fs | ||||||
| on fs.session_id = sd.session_id | ||||||
|
|
||||||
|
|
||||||
| NODE data | ||||||
| DESCRIPTION > | ||||||
| Calculate KPIs per time period | ||||||
|
|
||||||
| SQL > | ||||||
|
|
||||||
| select | ||||||
| a.date, | ||||||
| uniq(distinct s.session_id) as visits, | ||||||
| sum(s.pageviews) as pageviews, | ||||||
| truncate(avg(s.is_bounce), 2) as bounce_rate, | ||||||
| truncate(avg(s.session_sec), 2) as avg_session_sec | ||||||
|
Comment on lines
+104
to
+109
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # First, let's check if the file exists and examine the context
find . -name "api_kpis_v2.pipe" -type fRepository: qodo-benchmark/Ghost-combined-coderabbit Length of output: 224 🌐 Web query:
💡 Result: Short answer: uniq itself does not take a DISTINCT keyword parameter. Use uniq(x[, ...]) (or an alternative uniq* variant) to count distinct values; ClickHouse supports COUNT(DISTINCT ...) (which is implemented by a chosen uniq* function) and also aggregate-function DISTINCT combinator for other aggregates (e.g., sum(DISTINCT x)). See ClickHouse docs. [1][2][3] Sources:
🏁 Script executed: # Also search for similar patterns in the codebase to understand how distinct counts are being done
rg "uniq|countDistinct" --type sql --max-count 20Repository: qodo-benchmark/Ghost-combined-coderabbit Length of output: 224
Line 106: Replace with Suggested change- uniq(distinct s.session_id) as visits,
+ uniqExact(s.session_id) as visits,🤖 Prompt for AI Agents |
||||||
| from timeseries a | ||||||
| inner join session_metrics s on a.date = s.date | ||||||
| group by a.date | ||||||
| order by a.date | ||||||
|
|
||||||
|
|
||||||
| NODE pathname_pageviews | ||||||
| DESCRIPTION > | ||||||
| Calculate pageviews for specific pathname with time granularity handling | ||||||
|
|
||||||
| SQL > | ||||||
|
|
||||||
| % | ||||||
| select | ||||||
| {% if defined(date_from) and day_diff(date_from, date_to) == 0 %} | ||||||
| toStartOfHour(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) as date, | ||||||
| {% else %} | ||||||
| toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) as date, | ||||||
| {% end %} | ||||||
| count() pageviews | ||||||
| from timeseries a | ||||||
| inner join _mv_hits h on | ||||||
| {% if defined(date_from) and day_diff(date_from, date_to) == 0 %} | ||||||
| a.date = toStartOfHour(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) | ||||||
| {% else %} | ||||||
| a.date = toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) | ||||||
| {% end %} | ||||||
| inner join filtered_sessions_v2 fs | ||||||
| on fs.session_id = h.session_id | ||||||
| where | ||||||
| site_uuid = {{ String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True) }} | ||||||
| {% if defined(member_status) %} and member_status IN {{ Array(member_status, "'undefined', 'free', 'paid'", description="Member status to filter on", required=False) }} {% end %} | ||||||
| {% if defined(location) %} and location = {{ String(location, description="Location to filter on", required=False) }} {% end %} | ||||||
| {% if defined(pathname) %} and pathname = {{ String(pathname, description="Pathname to filter on", required=False) }} {% end %} | ||||||
| {% if defined(post_uuid) %} and post_uuid = {{String(post_uuid, description="Post UUID to filter on", required=False) }} {% end %} | ||||||
| group by date | ||||||
| order by date | ||||||
|
|
||||||
|
|
||||||
| NODE finished_data | ||||||
| SQL > | ||||||
|
|
||||||
| % | ||||||
| select | ||||||
| a.date as date, | ||||||
| coalesce(b.visits, 0) as visits, | ||||||
| {% if defined(pathname) or defined(post_uuid) %}coalesce(c.pageviews, 0){% else %}coalesce(b.pageviews, 0){% end %} as pageviews, | ||||||
| coalesce(b.bounce_rate, 0) as bounce_rate, | ||||||
| coalesce(b.avg_session_sec, 0) as avg_session_sec | ||||||
| from timeseries a | ||||||
| left join data b on a.date = b.date | ||||||
| {% if defined(pathname) or defined(post_uuid) %}left join pathname_pageviews c on a.date = c.date{% end %} | ||||||
| TYPE ENDPOINT | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| TOKEN "stats_page" READ | ||
| TOKEN "axis" READ | ||
|
|
||
| NODE _post_visitor_counts_0 | ||
| SQL > | ||
| % | ||
| select | ||
| post_uuid, | ||
| uniqExact(session_id) as visits | ||
| from _mv_hits | ||
| where | ||
| site_uuid = {{String(site_uuid, 'mock_site_uuid', description="Site UUID", required=True)}} | ||
| and post_uuid IN {{ Array(post_uuids, description="Array of post UUIDs to get visitor counts for", required=True) }} | ||
| group by post_uuid | ||
| order by visits desc | ||
|
|
||
| TYPE ENDPOINT |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,28 @@ | ||||||||||||||||||||||||||||||||||||||
| TOKEN "stats_page" READ | ||||||||||||||||||||||||||||||||||||||
| TOKEN "axis" READ | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| NODE session_data | ||||||||||||||||||||||||||||||||||||||
| SQL > | ||||||||||||||||||||||||||||||||||||||
| % | ||||||||||||||||||||||||||||||||||||||
| SELECT | ||||||||||||||||||||||||||||||||||||||
| site_uuid, | ||||||||||||||||||||||||||||||||||||||
| session_id, | ||||||||||||||||||||||||||||||||||||||
| argMinMerge(device) as device | ||||||||||||||||||||||||||||||||||||||
| FROM _mv_session_data_v2 | ||||||||||||||||||||||||||||||||||||||
| WHERE site_uuid = {{ String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True) }} | ||||||||||||||||||||||||||||||||||||||
| GROUP BY site_uuid, session_id | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| NODE top_devices | ||||||||||||||||||||||||||||||||||||||
| SQL > | ||||||||||||||||||||||||||||||||||||||
| % | ||||||||||||||||||||||||||||||||||||||
| select | ||||||||||||||||||||||||||||||||||||||
| device, | ||||||||||||||||||||||||||||||||||||||
| count() as visits | ||||||||||||||||||||||||||||||||||||||
| from session_data sd | ||||||||||||||||||||||||||||||||||||||
| inner join filtered_sessions_v2 fs | ||||||||||||||||||||||||||||||||||||||
| on fs.session_id = sd.session_id | ||||||||||||||||||||||||||||||||||||||
| group by device | ||||||||||||||||||||||||||||||||||||||
| order by visits desc | ||||||||||||||||||||||||||||||||||||||
| limit {{ Int32(skip, 0) }},{{ Int32(limit, 50) }} | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+18
to
+26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: find . -name "api_top_devices_v2.pipe" -type fRepository: qodo-benchmark/Ghost-combined-coderabbit Length of output: 224 🌐 Web query:
💡 Result: Short answer: use a stable, deterministic ORDER BY (include a unique tie‑breaker) or switch to keyset (cursor) pagination. OFFSET+LIMIT without a deterministic ORDER BY can return inconsistent pages. Recommended options:
References:
🌐 Web query:
💡 Result: Short answer: Yes — if you need deterministic ordering from a Tinybird .pipe (SELECT ... ORDER BY), include a unique secondary/tie-breaker key (e.g. a unique id or monotonic timestamp). Tinybird pipes run on ClickHouse semantics, and ClickHouse returns rows with identical ORDER BY values in arbitrary/non‑deterministic order unless you break ties with additional expressions. [1][2] Recommendation: ORDER BY primary_col, tie_breaker_col (e.g. ORDER BY event_time DESC, id ASC) to guarantee stable results. [2] Sources:
Add tie-breaker to stabilize pagination ordering for deterministic results. Line 25: When multiple devices have the same visit count, rows are returned in arbitrary order without a deterministic secondary sort key. This causes inconsistent pagination across pages when using OFFSET/LIMIT. Add Suggested change- order by visits desc
+ order by visits desc, device asc📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| TYPE ENDPOINT | ||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,31 @@ | ||||||||||||||||
| TOKEN "stats_page" READ | ||||||||||||||||
| TOKEN "axis" READ | ||||||||||||||||
|
|
||||||||||||||||
| NODE _top_locations_0 | ||||||||||||||||
| SQL > | ||||||||||||||||
|
|
||||||||||||||||
| % | ||||||||||||||||
| select | ||||||||||||||||
| location, | ||||||||||||||||
| uniqExact(session_id) as visits | ||||||||||||||||
| from _mv_hits h | ||||||||||||||||
| inner join filtered_sessions_v2 fs | ||||||||||||||||
| on fs.session_id = h.session_id | ||||||||||||||||
| where | ||||||||||||||||
| site_uuid = {{String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True)}} | ||||||||||||||||
| {% if defined(member_status) %} | ||||||||||||||||
| and member_status IN ( | ||||||||||||||||
| select arrayJoin( | ||||||||||||||||
| {{ Array(member_status, "'undefined', 'free', 'paid'", description="Member status to filter on", required=False) }} | ||||||||||||||||
| || if('paid' IN {{ Array(member_status) }}, ['comped'], []) | ||||||||||||||||
| ) | ||||||||||||||||
| ) | ||||||||||||||||
| {% end %} | ||||||||||||||||
| {% if defined(location) %} and location = {{ String(location, description="Location to filter on", required=False) }} {% end %} | ||||||||||||||||
| {% if defined(pathname) %} and pathname = {{ String(pathname, description="Pathname to filter on", required=False) }} {% end %} | ||||||||||||||||
| {% if defined(post_uuid) %} and post_uuid = {{ String(post_uuid, description="Post UUID to filter on", required=False) }} {% end %} | ||||||||||||||||
|
Comment on lines
+24
to
+26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing The test file Add the device filter condition: {% if defined(post_uuid) %} and post_uuid = {{ String(post_uuid, description="Post UUID to filter on", required=False) }} {% end %}
+ {% if defined(device) %} and device = {{ String(device, description="Device type to filter on", required=False) }} {% end %}
group by location📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||
| group by location | ||||||||||||||||
| order by visits desc | ||||||||||||||||
| limit {{ Int32(skip, 0) }},{{ Int32(limit, 50) }} | ||||||||||||||||
|
|
||||||||||||||||
| TYPE ENDPOINT | ||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| TOKEN "stats_page" READ | ||
| TOKEN "axis" READ | ||
|
|
||
| NODE _top_pages_0 | ||
| SQL > | ||
|
|
||
| % | ||
| select | ||
| case when post_uuid = 'undefined' then '' else post_uuid end as post_uuid, | ||
| pathname, | ||
| uniqExact(session_id) as visits | ||
| from _mv_hits h | ||
| inner join filtered_sessions_v2 fs | ||
| on fs.session_id = h.session_id | ||
| where | ||
| site_uuid = {{String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True)}} | ||
| {% if defined(member_status) %} | ||
| and member_status IN ( | ||
| select arrayJoin( | ||
| {{ Array(member_status, "'undefined', 'free', 'paid'", description="Member status to filter on", required=False) }} | ||
| || if('paid' IN {{ Array(member_status) }}, ['comped'], []) | ||
| ) | ||
| ) | ||
| {% end %} | ||
| {% if defined(location) %} and location = {{ String(location, description="Location to filter on", required=False) }} {% end %} | ||
| {% if defined(pathname) %} and pathname = {{ String(pathname, description="Pathname to filter on", required=False) }} {% end %} | ||
| {% if defined(post_uuid) %} and post_uuid = {{ String(post_uuid, description="Post UUID to filter on", required=False) }} {% end %} | ||
| {% if defined(post_type) %} | ||
| {% if post_type == 'post' %} | ||
| and post_type = 'post' | ||
| {% else %} | ||
| and (post_type != 'post' or post_type is null) | ||
| {% end %} | ||
| {% end %} | ||
| group by post_uuid, pathname | ||
| order by visits desc | ||
| limit {{ Int32(skip, 0) }},{{ Int32(limit, 50) }} | ||
|
|
||
| TYPE ENDPOINT |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: qodo-benchmark/Ghost-combined-coderabbit
Length of output: 224
🏁 Script executed:
# Check file size to understand how to read it wc -l apps/admin-x-framework/src/providers/framework-provider.tsxRepository: qodo-benchmark/Ghost-combined-coderabbit
Length of output: 146
🏁 Script executed:
Repository: qodo-benchmark/Ghost-combined-coderabbit
Length of output: 547
🏁 Script executed:
Repository: qodo-benchmark/Ghost-combined-coderabbit
Length of output: 96
🏁 Script executed:
# Examine the Biome configuration cat biome.jsonRepository: qodo-benchmark/Ghost-combined-coderabbit
Length of output: 1858
🏁 Script executed:
Repository: qodo-benchmark/Ghost-combined-coderabbit
Length of output: 66
🏁 Script executed:
Repository: qodo-benchmark/Ghost-combined-coderabbit
Length of output: 99
🏁 Script executed:
Repository: qodo-benchmark/Ghost-combined-coderabbit
Length of output: 478
🏁 Script executed:
# Let's check the actual imports and React version to understand context head -30 apps/admin-x-framework/src/providers/framework-provider.tsxRepository: qodo-benchmark/Ghost-combined-coderabbit
Length of output: 981
🏁 Script executed:
Repository: qodo-benchmark/Ghost-combined-coderabbit
Length of output: 8166
🏁 Script executed:
# Check the ESLint configuration for the admin-x-framework cat apps/admin-x-framework/.eslintrc.cjsRepository: qodo-benchmark/Ghost-combined-coderabbit
Length of output: 1066
🏁 Script executed:
Repository: qodo-benchmark/Ghost-combined-coderabbit
Length of output: 531
🏁 Script executed:
Repository: qodo-benchmark/Ghost-combined-coderabbit
Length of output: 609
Use nested children instead of passing via prop.
ESLint's
react/no-children-proprule (from thereact/recommendedconfiguration) flags this pattern. Pass children as nested JSX content instead of as a prop.🔧 Proposed fix
📝 Committable suggestion
🧰 Tools
🪛 Biome (2.1.2)
[error] 90-90: Avoid passing children using a prop
The canonical way to pass children in React is to use JSX elements
(lint/correctness/noChildrenProp)
🤖 Prompt for AI Agents