@@ -84,53 +84,6 @@ const getDailyUsageByTypeQuery = () => `
8484 ORDER BY date ASC, event_category ASC
8585` ;
8686
87- const getEventTypeBreakdownQuery = ( ) => `
88- WITH all_events AS (
89- SELECT 'event' as event_category
90- FROM analytics.events
91- WHERE client_id IN {websiteIds:Array(String)}
92- AND time >= parseDateTimeBestEffort({startDate:String})
93- AND time <= parseDateTimeBestEffort({endDate:String})
94-
95- UNION ALL
96-
97- SELECT 'error' as event_category
98- FROM analytics.errors
99- WHERE client_id IN {websiteIds:Array(String)}
100- AND timestamp >= parseDateTimeBestEffort({startDate:String})
101- AND timestamp <= parseDateTimeBestEffort({endDate:String})
102-
103- UNION ALL
104-
105- SELECT 'web_vitals' as event_category
106- FROM analytics.web_vitals
107- WHERE client_id IN {websiteIds:Array(String)}
108- AND timestamp >= parseDateTimeBestEffort({startDate:String})
109- AND timestamp <= parseDateTimeBestEffort({endDate:String})
110-
111- UNION ALL
112-
113- SELECT 'custom_event' as event_category
114- FROM analytics.custom_events
115- WHERE client_id IN {websiteIds:Array(String)}
116- AND timestamp >= parseDateTimeBestEffort({startDate:String})
117- AND timestamp <= parseDateTimeBestEffort({endDate:String})
118-
119- UNION ALL
120-
121- SELECT 'outgoing_link' as event_category
122- FROM analytics.outgoing_links
123- WHERE client_id IN {websiteIds:Array(String)}
124- AND timestamp >= parseDateTimeBestEffort({startDate:String})
125- AND timestamp <= parseDateTimeBestEffort({endDate:String})
126- )
127- SELECT
128- event_category,
129- count() as event_count
130- FROM all_events
131- GROUP BY event_category
132- ORDER BY event_count DESC
133- ` ;
13487
13588export const billingRouter = createTRPCRouter ( {
13689 getUsage : protectedProcedure
@@ -186,28 +139,26 @@ export const billingRouter = createTRPCRouter({
186139 } ;
187140 }
188141
189- // Execute both queries in parallel - ClickHouse does all aggregation
190- const [ dailyUsageByTypeResults , eventTypeBreakdownResults ] =
191- await Promise . all ( [
192- chQuery < DailyUsageByTypeRow > ( getDailyUsageByTypeQuery ( ) , {
193- websiteIds,
194- startDate,
195- endDate,
196- } ) ,
197- chQuery < EventTypeBreakdown > ( getEventTypeBreakdownQuery ( ) , {
198- websiteIds,
199- startDate,
200- endDate,
201- } ) ,
202- ] ) ;
203-
204- // Calculate daily usage totals and total events from detailed breakdown
142+ const dailyUsageByTypeResults = await chQuery < DailyUsageByTypeRow > (
143+ getDailyUsageByTypeQuery ( ) ,
144+ {
145+ websiteIds,
146+ startDate,
147+ endDate,
148+ }
149+ ) ;
150+
205151 const dailyUsageMap = new Map < string , number > ( ) ;
152+ const eventTypeBreakdownMap = new Map < string , number > ( ) ;
206153 let totalEvents = 0 ;
207154
208155 for ( const row of dailyUsageByTypeResults ) {
209156 const currentDaily = dailyUsageMap . get ( row . date ) || 0 ;
210157 dailyUsageMap . set ( row . date , currentDaily + row . event_count ) ;
158+
159+ const currentTypeTotal = eventTypeBreakdownMap . get ( row . event_category ) || 0 ;
160+ eventTypeBreakdownMap . set ( row . event_category , currentTypeTotal + row . event_count ) ;
161+
211162 totalEvents += row . event_count ;
212163 }
213164
@@ -217,6 +168,12 @@ export const billingRouter = createTRPCRouter({
217168 . map ( ( [ date , event_count ] ) => ( { date, event_count } ) )
218169 . sort ( ( a , b ) => a . date . localeCompare ( b . date ) ) ;
219170
171+ const eventTypeBreakdownResults : EventTypeBreakdown [ ] = Array . from (
172+ eventTypeBreakdownMap . entries ( )
173+ )
174+ . map ( ( [ event_category , event_count ] ) => ( { event_category, event_count } ) )
175+ . sort ( ( a , b ) => b . event_count - a . event_count ) ;
176+
220177 logger . info (
221178 `Billing usage calculated for user ${ ctx . user . id } : ${ totalEvents } events across ${ websiteIds . length } websites` ,
222179 {
0 commit comments