@@ -3692,90 +3692,61 @@ func (q *FakeQuerier) GetTemplateInsightsByTemplate(_ context.Context, arg datab
3692
3692
q .mutex .RLock ()
3693
3693
defer q .mutex .RUnlock ()
3694
3694
3695
- // map time.Time x TemplateID x UserID x <usage>
3696
- appUsageByTemplateAndUser := map [time.Time ]map [uuid.UUID ]map [uuid.UUID ]database.GetTemplateInsightsByTemplateRow {}
3697
-
3698
- // Review agent stats in terms of usage
3699
- templateIDSet := make (map [uuid.UUID ]struct {})
3695
+ /*
3696
+ SELECT
3697
+ template_id,
3698
+ COUNT(DISTINCT user_id) AS active_users,
3699
+ (SUM(usage_mins) * 60)::bigint AS usage_total_seconds, -- Includes app usage.
3700
+ (SUM(ssh_mins) * 60)::bigint AS usage_ssh_seconds,
3701
+ (SUM(sftp_mins) * 60)::bigint AS usage_sftp_seconds,
3702
+ (SUM(reconnecting_pty_mins) * 60)::bigint AS usage_reconnecting_pty_seconds,
3703
+ (SUM(vscode_mins) * 60)::bigint AS usage_vscode_seconds,
3704
+ (SUM(jetbrains_mins) * 60)::bigint AS usage_jetbrains_seconds
3705
+ FROM
3706
+ template_usage_stats
3707
+ WHERE
3708
+ start_time >= @start_time::timestamptz
3709
+ AND end_time <= @end_time::timestamptz
3710
+ GROUP BY template_id;
3711
+ */
3700
3712
3701
- for _ , s := range q .workspaceAgentStats {
3702
- if s .CreatedAt .Before (arg .StartTime ) || s .CreatedAt .Equal (arg .EndTime ) || s .CreatedAt .After (arg .EndTime ) {
3703
- continue
3704
- }
3705
- if s .ConnectionCount == 0 {
3713
+ type grouped struct {
3714
+ database.GetTemplateInsightsByTemplateRow
3715
+ activeUserIDs map [uuid.UUID ]struct {}
3716
+ }
3717
+ groupedByTemplateID := make (map [uuid.UUID ]grouped )
3718
+ for _ , tus := range q .templateUsageStats {
3719
+ if tus .StartTime .Before (arg .StartTime ) || tus .EndTime .After (arg .EndTime ) {
3706
3720
continue
3707
3721
}
3708
-
3709
- t := s .CreatedAt .Truncate (time .Minute )
3710
- templateIDSet [s .TemplateID ] = struct {}{}
3711
-
3712
- if _ , ok := appUsageByTemplateAndUser [t ]; ! ok {
3713
- appUsageByTemplateAndUser [t ] = make (map [uuid.UUID ]map [uuid.UUID ]database.GetTemplateInsightsByTemplateRow )
3714
- }
3715
-
3716
- if _ , ok := appUsageByTemplateAndUser [t ][s.TemplateID ]; ! ok {
3717
- appUsageByTemplateAndUser [t ][s.TemplateID ] = make (map [uuid.UUID ]database.GetTemplateInsightsByTemplateRow )
3718
- }
3719
-
3720
- if _ , ok := appUsageByTemplateAndUser [t ][s.TemplateID ][s .UserID ]; ! ok {
3721
- appUsageByTemplateAndUser [t ][s.TemplateID ][s .UserID ] = database.GetTemplateInsightsByTemplateRow {}
3722
- }
3723
-
3724
- u := appUsageByTemplateAndUser [t ][s.TemplateID ][s .UserID ]
3725
- if s .SessionCountJetBrains > 0 {
3726
- u .UsageJetbrainsSeconds = 60
3727
- }
3728
- if s .SessionCountVSCode > 0 {
3729
- u .UsageVscodeSeconds = 60
3730
- }
3731
- if s .SessionCountReconnectingPTY > 0 {
3732
- u .UsageReconnectingPtySeconds = 60
3733
- }
3734
- if s .SessionCountSSH > 0 {
3735
- u .UsageSshSeconds = 60
3722
+ row , ok := groupedByTemplateID [tus .TemplateID ]
3723
+ if ! ok {
3724
+ row = grouped {
3725
+ GetTemplateInsightsByTemplateRow : database.GetTemplateInsightsByTemplateRow {
3726
+ TemplateID : tus .TemplateID ,
3727
+ },
3728
+ activeUserIDs : make (map [uuid.UUID ]struct {}),
3729
+ }
3736
3730
}
3737
- appUsageByTemplateAndUser [t ][s.TemplateID ][s .UserID ] = u
3731
+ row .activeUserIDs [tus .UserID ] = struct {}{}
3732
+ row .ActiveUsers = int64 (len (row .activeUserIDs ))
3733
+ row .UsageTotalSeconds += int64 (tus .UsageMins ) * 60
3734
+ row .UsageSshSeconds += int64 (tus .SshMins ) * 60
3735
+ row .UsageSftpSeconds += int64 (tus .SftpMins ) * 60
3736
+ row .UsageReconnectingPtySeconds += int64 (tus .ReconnectingPtyMins ) * 60
3737
+ row .UsageVscodeSeconds += int64 (tus .VscodeMins ) * 60
3738
+ row .UsageJetbrainsSeconds += int64 (tus .JetbrainsMins ) * 60
3739
+ groupedByTemplateID [tus .TemplateID ] = row
3738
3740
}
3739
3741
3740
- // Sort used templates
3741
- templateIDs := make ([]uuid.UUID , 0 , len (templateIDSet ))
3742
- for templateID := range templateIDSet {
3743
- templateIDs = append (templateIDs , templateID )
3742
+ var rows []database.GetTemplateInsightsByTemplateRow
3743
+ for _ , row := range groupedByTemplateID {
3744
+ rows = append (rows , row .GetTemplateInsightsByTemplateRow )
3744
3745
}
3745
- slices .SortFunc (templateIDs , func (a , b uuid. UUID ) int {
3746
- return slice .Ascending (a .String (), b .String ())
3746
+ slices .SortFunc (rows , func (a , b database. GetTemplateInsightsByTemplateRow ) int {
3747
+ return slice .Ascending (a .TemplateID . String (), b . TemplateID .String ())
3747
3748
})
3748
-
3749
- // Build result
3750
- var result []database.GetTemplateInsightsByTemplateRow
3751
- for _ , templateID := range templateIDs {
3752
- r := database.GetTemplateInsightsByTemplateRow {
3753
- TemplateID : templateID ,
3754
- }
3755
-
3756
- uniqueUsers := map [uuid.UUID ]struct {}{}
3757
-
3758
- for _ , mTemplateUserUsage := range appUsageByTemplateAndUser {
3759
- mUserUsage , ok := mTemplateUserUsage [templateID ]
3760
- if ! ok {
3761
- continue // template was not used in this time window
3762
- }
3763
-
3764
- for userID , usage := range mUserUsage {
3765
- uniqueUsers [userID ] = struct {}{}
3766
-
3767
- r .UsageJetbrainsSeconds += usage .UsageJetbrainsSeconds
3768
- r .UsageVscodeSeconds += usage .UsageVscodeSeconds
3769
- r .UsageReconnectingPtySeconds += usage .UsageReconnectingPtySeconds
3770
- r .UsageSshSeconds += usage .UsageSshSeconds
3771
- }
3772
- }
3773
-
3774
- r .ActiveUsers = int64 (len (uniqueUsers ))
3775
-
3776
- result = append (result , r )
3777
- }
3778
- return result , nil
3749
+ return rows , nil
3779
3750
}
3780
3751
3781
3752
func (q * FakeQuerier ) GetTemplateParameterInsights (ctx context.Context , arg database.GetTemplateParameterInsightsParams ) ([]database.GetTemplateParameterInsightsRow , error ) {
0 commit comments