@@ -2822,7 +2822,134 @@ func (q *FakeQuerier) GetUserActivityInsights(ctx context.Context, arg database.
2822
2822
return nil , err
2823
2823
}
2824
2824
2825
- panic ("not implemented" )
2825
+ q .mutex .RLock ()
2826
+ defer q .mutex .RUnlock ()
2827
+
2828
+ type uniqueKey struct {
2829
+ TemplateID uuid.UUID
2830
+ UserID uuid.UUID
2831
+ }
2832
+
2833
+ combinedStats := make (map [uniqueKey ]map [time.Time ]int64 )
2834
+
2835
+ // Get application stats
2836
+ for _ , s := range q .workspaceAppStats {
2837
+ if ! (((s .SessionStartedAt .After (arg .StartTime ) || s .SessionStartedAt .Equal (arg .StartTime )) && s .SessionStartedAt .Before (arg .EndTime )) ||
2838
+ (s .SessionEndedAt .After (arg .StartTime ) && s .SessionEndedAt .Before (arg .EndTime )) ||
2839
+ (s .SessionStartedAt .Before (arg .StartTime ) && (s .SessionEndedAt .After (arg .EndTime ) || s .SessionEndedAt .Equal (arg .EndTime )))) {
2840
+ continue
2841
+ }
2842
+
2843
+ w , err := q .getWorkspaceByIDNoLock (ctx , s .WorkspaceID )
2844
+ if err != nil {
2845
+ return nil , err
2846
+ }
2847
+
2848
+ if len (arg .TemplateIDs ) > 0 && ! slices .Contains (arg .TemplateIDs , w .TemplateID ) {
2849
+ continue
2850
+ }
2851
+
2852
+ key := uniqueKey {
2853
+ TemplateID : w .TemplateID ,
2854
+ UserID : s .UserID ,
2855
+ }
2856
+ if combinedStats [key ] == nil {
2857
+ combinedStats [key ] = make (map [time.Time ]int64 )
2858
+ }
2859
+
2860
+ t := s .SessionStartedAt .Truncate (5 * time .Minute )
2861
+ if t .Before (arg .StartTime ) {
2862
+ t = arg .StartTime
2863
+ }
2864
+ for t .Before (s .SessionEndedAt ) && t .Before (arg .EndTime ) {
2865
+ combinedStats [key ][t ] = 60
2866
+ t = t .Add (1 * time .Minute )
2867
+ }
2868
+ }
2869
+
2870
+ // Get session stats
2871
+ for _ , s := range q .workspaceAgentStats {
2872
+ if s .CreatedAt .Before (arg .StartTime ) || s .CreatedAt .Equal (arg .EndTime ) || s .CreatedAt .After (arg .EndTime ) {
2873
+ continue
2874
+ }
2875
+ if len (arg .TemplateIDs ) > 0 && ! slices .Contains (arg .TemplateIDs , s .TemplateID ) {
2876
+ continue
2877
+ }
2878
+ if s .ConnectionCount == 0 {
2879
+ continue
2880
+ }
2881
+
2882
+ key := uniqueKey {
2883
+ TemplateID : s .TemplateID ,
2884
+ UserID : s .UserID ,
2885
+ }
2886
+
2887
+ if combinedStats [key ] == nil {
2888
+ combinedStats [key ] = make (map [time.Time ]int64 )
2889
+ }
2890
+
2891
+ if s .SessionCountJetBrains > 0 || s .SessionCountVSCode > 0 || s .SessionCountReconnectingPTY > 0 || s .SessionCountSSH > 0 {
2892
+ t := s .CreatedAt .Truncate (time .Minute )
2893
+ combinedStats [key ][t ] = 60
2894
+ }
2895
+ }
2896
+
2897
+ // Use temporary maps for aggregation purposes
2898
+ mUserIDTemplateIDs := map [uuid.UUID ]map [uuid.UUID ]struct {}{}
2899
+ mUserIDUsageSeconds := map [uuid.UUID ]int64 {}
2900
+
2901
+ for key , times := range combinedStats {
2902
+ if mUserIDTemplateIDs [key .UserID ] == nil {
2903
+ mUserIDTemplateIDs [key .UserID ] = make (map [uuid.UUID ]struct {})
2904
+ mUserIDUsageSeconds [key .UserID ] = 0
2905
+ }
2906
+
2907
+ if _ , ok := mUserIDTemplateIDs [key.UserID ][key.TemplateID ]; ! ok {
2908
+ mUserIDTemplateIDs [key.UserID ][key.TemplateID ] = struct {}{}
2909
+ }
2910
+
2911
+ for _ , t := range times {
2912
+ mUserIDUsageSeconds [key .UserID ] += t
2913
+ }
2914
+ }
2915
+
2916
+ userIDs := make ([]uuid.UUID , 0 , len (mUserIDUsageSeconds ))
2917
+ for userID := range mUserIDUsageSeconds {
2918
+ userIDs = append (userIDs , userID )
2919
+ }
2920
+ sort .Slice (userIDs , func (i , j int ) bool {
2921
+ return userIDs [i ].String () < userIDs [j ].String ()
2922
+ })
2923
+
2924
+ // Finally, select stats
2925
+ var rows []database.GetUserActivityInsightsRow
2926
+
2927
+ for _ , userID := range userIDs {
2928
+ user , err := q .getUserByIDNoLock (userID )
2929
+ if err != nil {
2930
+ return nil , err
2931
+ }
2932
+
2933
+ tids := mUserIDTemplateIDs [userID ]
2934
+ templateIDs := make ([]uuid.UUID , 0 , len (tids ))
2935
+ for key := range tids {
2936
+ templateIDs = append (templateIDs , key )
2937
+ }
2938
+ sort .Slice (templateIDs , func (i , j int ) bool {
2939
+ return templateIDs [i ].String () < templateIDs [j ].String ()
2940
+ })
2941
+
2942
+ row := database.GetUserActivityInsightsRow {
2943
+ UserID : user .ID ,
2944
+ Username : user .Username ,
2945
+ AvatarURL : user .AvatarURL ,
2946
+ TemplateIDs : templateIDs ,
2947
+ UsageSeconds : mUserIDUsageSeconds [userID ],
2948
+ }
2949
+
2950
+ rows = append (rows , row )
2951
+ }
2952
+ return rows , nil
2826
2953
}
2827
2954
2828
2955
func (q * FakeQuerier ) GetUserByEmailOrUsername (_ context.Context , arg database.GetUserByEmailOrUsernameParams ) (database.User , error ) {
0 commit comments