@@ -99,40 +99,67 @@ GROUP BY users.id, username, avatar_url
99
99
ORDER BY user_id ASC ;
100
100
101
101
-- name: GetTemplateInsights :one
102
- -- GetTemplateInsights has a granularity of 5 minutes where if a session/app was
103
- -- in use during a minute, we will add 5 minutes to the total usage for that
104
- -- session/app (per user).
105
- WITH agent_stats_by_interval_and_user AS (
106
- SELECT
107
- date_trunc(' minute' , was .created_at ),
108
- was .user_id ,
109
- array_agg(was .template_id ) AS template_ids,
110
- CASE WHEN SUM (was .session_count_vscode ) > 0 THEN 60 ELSE 0 END AS usage_vscode_seconds,
111
- CASE WHEN SUM (was .session_count_jetbrains ) > 0 THEN 60 ELSE 0 END AS usage_jetbrains_seconds,
112
- CASE WHEN SUM (was .session_count_reconnecting_pty ) > 0 THEN 60 ELSE 0 END AS usage_reconnecting_pty_seconds,
113
- CASE WHEN SUM (was .session_count_ssh ) > 0 THEN 60 ELSE 0 END AS usage_ssh_seconds
114
- FROM workspace_agent_stats was
115
- WHERE
116
- was .created_at >= @start_time::timestamptz
117
- AND was .created_at < @end_time::timestamptz
118
- AND was .connection_count > 0
119
- AND CASE WHEN COALESCE(array_length(@template_ids::uuid[], 1 ), 0 ) > 0 THEN was .template_id = ANY(@template_ids::uuid[]) ELSE TRUE END
120
- GROUP BY date_trunc(' minute' , was .created_at ), was .user_id
121
- ), template_ids AS (
122
- SELECT array_agg(DISTINCT template_id) AS ids
123
- FROM agent_stats_by_interval_and_user, unnest(template_ids) template_id
124
- WHERE template_id IS NOT NULL
125
- )
102
+ -- GetTemplateInsights returns the aggregate user-produced usage of all
103
+ -- workspaces in a given timeframe. The template IDs, active users, and
104
+ -- usage_seconds all reflect any usage in the template, including apps.
105
+ --
106
+ -- When combining data from multiple templates, we must make a guess at
107
+ -- how the user behaved for the 30 minute interval. In this case we make
108
+ -- the assumption that if the user used two workspaces for 15 minutes,
109
+ -- they did so sequentially, thus we sum the usage up to a maximum of
110
+ -- 30 minutes with LEAST(SUM(n), 30).
111
+ WITH
112
+ insights AS (
113
+ SELECT
114
+ user_id,
115
+ -- See motivation in GetTemplateInsights for LEAST(SUM(n), 30).
116
+ LEAST(SUM (usage_mins), 30 ) AS usage_mins,
117
+ LEAST(SUM (ssh_mins), 30 ) AS ssh_mins,
118
+ LEAST(SUM (sftp_mins), 30 ) AS sftp_mins,
119
+ LEAST(SUM (reconnecting_pty_mins), 30 ) AS reconnecting_pty_mins,
120
+ LEAST(SUM (vscode_mins), 30 ) AS vscode_mins,
121
+ LEAST(SUM (jetbrains_mins), 30 ) AS jetbrains_mins
122
+ FROM
123
+ template_usage_stats
124
+ WHERE
125
+ start_time >= @start_time::timestamptz
126
+ AND end_time <= @end_time::timestamptz
127
+ AND CASE WHEN COALESCE(array_length(@template_ids::uuid[], 1 ), 0 ) > 0 THEN template_id = ANY(@template_ids::uuid[]) ELSE TRUE END
128
+ GROUP BY
129
+ start_time, user_id
130
+ ),
131
+ templates AS (
132
+ SELECT
133
+ array_agg(DISTINCT template_id) AS template_ids,
134
+ array_agg(DISTINCT template_id) FILTER (WHERE ssh_mins > 0 ) AS ssh_template_ids,
135
+ array_agg(DISTINCT template_id) FILTER (WHERE sftp_mins > 0 ) AS sftp_template_ids,
136
+ array_agg(DISTINCT template_id) FILTER (WHERE reconnecting_pty_mins > 0 ) AS reconnecting_pty_template_ids,
137
+ array_agg(DISTINCT template_id) FILTER (WHERE vscode_mins > 0 ) AS vscode_template_ids,
138
+ array_agg(DISTINCT template_id) FILTER (WHERE jetbrains_mins > 0 ) AS jetbrains_template_ids
139
+ FROM
140
+ template_usage_stats
141
+ WHERE
142
+ start_time >= @start_time::timestamptz
143
+ AND end_time <= @end_time::timestamptz
144
+ AND CASE WHEN COALESCE(array_length(@template_ids::uuid[], 1 ), 0 ) > 0 THEN template_id = ANY(@template_ids::uuid[]) ELSE TRUE END
145
+ )
126
146
127
147
SELECT
128
- COALESCE((SELECT ids FROM template_ids), ' {}' )::uuid[] AS template_ids,
129
- -- Return IDs so we can combine this with GetTemplateAppInsights.
130
- COALESCE(array_agg(DISTINCT user_id), ' {}' )::uuid[] AS active_user_ids,
131
- COALESCE(SUM (usage_vscode_seconds), 0 )::bigint AS usage_vscode_seconds,
132
- COALESCE(SUM (usage_jetbrains_seconds), 0 )::bigint AS usage_jetbrains_seconds,
133
- COALESCE(SUM (usage_reconnecting_pty_seconds), 0 )::bigint AS usage_reconnecting_pty_seconds,
134
- COALESCE(SUM (usage_ssh_seconds), 0 )::bigint AS usage_ssh_seconds
135
- FROM agent_stats_by_interval_and_user;
148
+ COALESCE((SELECT template_ids FROM templates), ' {}' )::uuid[] AS template_ids, -- Includes app usage.
149
+ COALESCE((SELECT ssh_template_ids FROM templates), ' {}' )::uuid[] AS ssh_template_ids,
150
+ COALESCE((SELECT sftp_template_ids FROM templates), ' {}' )::uuid[] AS sftp_template_ids,
151
+ COALESCE((SELECT reconnecting_pty_template_ids FROM templates), ' {}' )::uuid[] AS reconnecting_pty_template_ids,
152
+ COALESCE((SELECT vscode_template_ids FROM templates), ' {}' )::uuid[] AS vscode_template_ids,
153
+ COALESCE((SELECT jetbrains_template_ids FROM templates), ' {}' )::uuid[] AS jetbrains_template_ids,
154
+ COALESCE(COUNT (DISTINCT user_id), 0 )::bigint AS active_users, -- Includes app usage.
155
+ COALESCE(SUM (usage_mins) * 60 , 0 )::bigint AS usage_total_seconds, -- Includes app usage.
156
+ COALESCE(SUM (ssh_mins) * 60 , 0 )::bigint AS usage_ssh_seconds,
157
+ COALESCE(SUM (sftp_mins) * 60 , 0 )::bigint AS usage_sftp_seconds,
158
+ COALESCE(SUM (reconnecting_pty_mins) * 60 , 0 )::bigint AS usage_reconnecting_pty_seconds,
159
+ COALESCE(SUM (vscode_mins) * 60 , 0 )::bigint AS usage_vscode_seconds,
160
+ COALESCE(SUM (jetbrains_mins) * 60 , 0 )::bigint AS usage_jetbrains_seconds
161
+ FROM
162
+ insights;
136
163
137
164
-- name: GetTemplateInsightsByTemplate :many
138
165
WITH agent_stats_by_interval_and_user AS (
0 commit comments