88} from '@roo-code/types' ;
99
1010import type { AnyTimePeriod } from '@/types' ;
11+ import type { Filter } from '@/types/analytics' ;
12+ import { buildFilterConditions } from '@/types/analytics' ;
1113import { analytics } from '@/lib/server' ;
1214import { tokenSumSql } from '@/lib' ;
1315import { type User , getUsersById } from '@roo-code-cloud/db/server' ;
@@ -178,10 +180,12 @@ export const getDeveloperUsage = async ({
178180 orgId,
179181 timePeriod = 90 ,
180182 userId,
183+ filters = [ ] ,
181184} : {
182185 orgId ?: string | null ;
183186 timePeriod ?: AnyTimePeriod ;
184187 userId ?: string | null ;
188+ filters ?: Filter [ ] ;
185189} ) : Promise < DeveloperUsage [ ] > => {
186190 await authorizeAnalytics ( {
187191 requestedOrgId : orgId ,
@@ -207,6 +211,9 @@ export const getDeveloperUsage = async ({
207211 queryParams . userId = userId ;
208212 }
209213
214+ // Build filter conditions using shared helper
215+ const filterClause = buildFilterConditions ( filters , queryParams ) ;
216+
210217 const results = await analytics . query ( {
211218 query : `
212219 SELECT
@@ -221,6 +228,7 @@ export const getDeveloperUsage = async ({
221228 AND timestamp >= toUnixTimestamp(now() - INTERVAL {timePeriod: Int32} DAY)
222229 AND type IN ({types: Array(String)})
223230 ${ userFilter }
231+ ${ filterClause }
224232 GROUP BY 1
225233 ` ,
226234 format : 'JSONEachRow' ,
@@ -245,10 +253,12 @@ export const getRepositoryUsage = async ({
245253 orgId,
246254 timePeriod = 90 ,
247255 userId,
256+ filters = [ ] ,
248257} : {
249258 orgId ?: string | null ;
250259 timePeriod ?: AnyTimePeriod ;
251260 userId ?: string | null ;
261+ filters ?: Filter [ ] ;
252262} ) : Promise < RepositoryUsage [ ] > => {
253263 await authorizeAnalytics ( {
254264 requestedOrgId : orgId ,
@@ -274,6 +284,9 @@ export const getRepositoryUsage = async ({
274284 queryParams . userId = userId ;
275285 }
276286
287+ // Build filter conditions using shared helper
288+ const filterClause = buildFilterConditions ( filters , queryParams ) ;
289+
277290 const results = await analytics . query ( {
278291 query : `
279292 SELECT
@@ -291,6 +304,7 @@ export const getRepositoryUsage = async ({
291304 AND type IN ({types: Array(String)})
292305 AND repositoryName IS NOT NULL
293306 ${ userFilter }
307+ ${ filterClause }
294308 GROUP BY repositoryName
295309 ` ,
296310 format : 'JSONEachRow' ,
@@ -318,10 +332,12 @@ export const getModelUsage = async ({
318332 orgId,
319333 timePeriod = 90 ,
320334 userId,
335+ filters = [ ] ,
321336} : {
322337 orgId ?: string | null ;
323338 timePeriod ?: AnyTimePeriod ;
324339 userId ?: string | null ;
340+ filters ?: Filter [ ] ;
325341} ) : Promise < ModelUsage [ ] > => {
326342 await authorizeAnalytics ( {
327343 requestedOrgId : orgId ,
@@ -349,6 +365,9 @@ export const getModelUsage = async ({
349365 queryParams . userId = userId ;
350366 }
351367
368+ // Build filter conditions using shared helper
369+ const filterClause = buildFilterConditions ( filters , queryParams ) ;
370+
352371 const results = await analytics . query ( {
353372 query : `
354373 SELECT
@@ -364,6 +383,7 @@ export const getModelUsage = async ({
364383 AND type IN ({types: Array(String)})
365384 AND modelId IS NOT NULL
366385 ${ userFilter }
386+ ${ filterClause }
367387 GROUP BY 1, 2
368388 ` ,
369389 format : 'JSONEachRow' ,
@@ -409,8 +429,7 @@ export const getTasks = async ({
409429 skipAuth = false ,
410430 limit = 20 ,
411431 cursor,
412- filterType,
413- filterValue,
432+ filters = [ ] ,
414433} : {
415434 orgId ?: string | null ;
416435 userId ?: string | null ;
@@ -419,8 +438,7 @@ export const getTasks = async ({
419438 skipAuth ?: boolean ;
420439 limit ?: number ;
421440 cursor ?: number ;
422- filterType ?: 'userId' | 'model' | 'repositoryName' ;
423- filterValue ?: string ;
441+ filters ?: Filter [ ] ;
424442} ) : Promise < TasksResult > => {
425443 let effectiveUserId = userId ;
426444
@@ -480,27 +498,8 @@ export const getTasks = async ({
480498 queryParams . cursor = cursor ;
481499 }
482500
483- // Add filter parameters
484- if ( filterType && filterValue ) {
485- if ( filterType === 'userId' ) {
486- queryParams . filterUserId = filterValue ;
487- } else if ( filterType === 'model' ) {
488- queryParams . filterModel = filterValue ;
489- } else if ( filterType === 'repositoryName' ) {
490- queryParams . filterRepository = filterValue ;
491- }
492- }
493-
494- // Build filter conditions
495- const filterConditions = [ ] ;
496- if ( filterType === 'userId' && filterValue ) {
497- filterConditions . push ( 'AND e.userId = {filterUserId: String}' ) ;
498- } else if ( filterType === 'model' && filterValue ) {
499- filterConditions . push ( 'AND e.modelId = {filterModel: String}' ) ;
500- } else if ( filterType === 'repositoryName' && filterValue ) {
501- filterConditions . push ( 'AND e.repositoryName = {filterRepository: String}' ) ;
502- }
503- const filterClause = filterConditions . join ( ' ' ) ;
501+ // Build filter conditions using shared helper
502+ const filterClause = buildFilterConditions ( filters , queryParams , 'e' ) ;
504503
505504 // TODO: Handle same-timestamp edge cases
506505 // Currently using only timestamp as cursor, but this can miss/duplicate tasks
@@ -600,10 +599,12 @@ export const getHourlyUsageByUser = async ({
600599 orgId,
601600 timePeriod = 90 ,
602601 userId,
602+ filters = [ ] ,
603603} : {
604604 orgId ?: string | null ;
605605 timePeriod ?: AnyTimePeriod ;
606606 userId ?: string | null ;
607+ filters ?: Filter [ ] ;
607608} ) : Promise < HourlyUsageByUser [ ] > => {
608609 const { effectiveUserId } = await authorizeAnalytics ( {
609610 requestedOrgId : orgId ,
@@ -637,6 +638,9 @@ export const getHourlyUsageByUser = async ({
637638 queryParams . userId = effectiveUserId ;
638639 }
639640
641+ // Build filter conditions using shared helper
642+ const filterClause = buildFilterConditions ( filters , queryParams ) ;
643+
640644 const results = await analytics . query ( {
641645 query : `
642646 SELECT
@@ -651,6 +655,7 @@ export const getHourlyUsageByUser = async ({
651655 AND timestamp >= toUnixTimestamp(now() - INTERVAL {timePeriod: Int32} DAY)
652656 AND type IN ({types: Array(String)})
653657 ${ userFilter }
658+ ${ filterClause }
654659 GROUP BY 1, 2
655660 ORDER BY hour_utc DESC, userId
656661 ` ,
0 commit comments