From 962afad2e0eff4fe116d0a970a434c92c0926fc2 Mon Sep 17 00:00:00 2001 From: yuenmichelle1 Date: Wed, 23 Aug 2023 09:45:43 -0500 Subject: [PATCH] Classification user groups migrations and models (#23) * add migration daily group counts and routes * create migrations * models associated with continuous aggregates and update error message on user classification count controller * add migrations for daily group count and time per user per project/workflow * add models for daily group user per project/workflow counts * initial logic of user group classifications report * Update user_group_classification_count_controller.rb * update migrations with frozen string literal comment and other hound sniffs --- .../daily_group_classification_count.rb | 14 ++++++++ ...aily_group_project_classification_count.rb | 15 +++++++++ .../daily_group_user_classification_count.rb | 15 +++++++++ ...group_user_project_classification_count.rb | 16 ++++++++++ ...roup_user_workflow_classification_count.rb | 16 ++++++++++ ...ily_group_workflow_classification_count.rb | 15 +++++++++ ...ly_group_classifications_count_and_time.rb | 21 ++++++++++++ ...p_project_classification_count_and_time.rb | 22 +++++++++++++ ..._workflow_classification_count_and_time.rb | 22 +++++++++++++ ...roup_user_classification_count_and_time.rb | 30 +++++++++++++++++ ...daily_group_user_project_count_and_time.rb | 32 +++++++++++++++++++ ...aily_group_user_workflow_count_and_time.rb | 32 +++++++++++++++++++ db/schema.rb | 2 +- 13 files changed, 251 insertions(+), 1 deletion(-) create mode 100644 app/models/user_group_classification_counts/daily_group_classification_count.rb create mode 100644 app/models/user_group_classification_counts/daily_group_project_classification_count.rb create mode 100644 app/models/user_group_classification_counts/daily_group_user_classification_count.rb create mode 100644 app/models/user_group_classification_counts/daily_group_user_project_classification_count.rb create mode 100644 app/models/user_group_classification_counts/daily_group_user_workflow_classification_count.rb create mode 100644 app/models/user_group_classification_counts/daily_group_workflow_classification_count.rb create mode 100644 db/migrate/20230725185947_create_daily_group_classifications_count_and_time.rb create mode 100644 db/migrate/20230725193600_create_daily_group_project_classification_count_and_time.rb create mode 100644 db/migrate/20230725194157_create_daily_group_workflow_classification_count_and_time.rb create mode 100644 db/migrate/20230725194325_create_daily_group_user_classification_count_and_time.rb create mode 100644 db/migrate/20230801163815_create_daily_group_user_project_count_and_time.rb create mode 100644 db/migrate/20230801163827_create_daily_group_user_workflow_count_and_time.rb diff --git a/app/models/user_group_classification_counts/daily_group_classification_count.rb b/app/models/user_group_classification_counts/daily_group_classification_count.rb new file mode 100644 index 0000000..53f6073 --- /dev/null +++ b/app/models/user_group_classification_counts/daily_group_classification_count.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module UserGroupClassificationCounts + class DailyGroupClassificationCount < ApplicationRecord + self.table_name = 'daily_group_classification_count_and_time' + attribute :classification_count, :integer + attribute :total_session_time, :integer + attribute :user_group_id, :integer + + def readonly? + true + end + end +end diff --git a/app/models/user_group_classification_counts/daily_group_project_classification_count.rb b/app/models/user_group_classification_counts/daily_group_project_classification_count.rb new file mode 100644 index 0000000..5641df9 --- /dev/null +++ b/app/models/user_group_classification_counts/daily_group_project_classification_count.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module UserGroupClassificationCounts + class DailyGroupProjectClassificationCount < ApplicationRecord + self.table_name = 'daily_group_classification_count_and_time_per_project' + attribute :classification_count, :integer + attribute :total_session_time, :integer + attribute :project_id, :integer + attribute :user_group_id, :integer + + def readonly? + true + end + end +end diff --git a/app/models/user_group_classification_counts/daily_group_user_classification_count.rb b/app/models/user_group_classification_counts/daily_group_user_classification_count.rb new file mode 100644 index 0000000..f936545 --- /dev/null +++ b/app/models/user_group_classification_counts/daily_group_user_classification_count.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module UserGroupClassificationCounts + class DailyGroupUserClassificationCount < ApplicationRecord + self.table_name = 'daily_group_classification_count_and_time_per_user' + attribute :classification_count, :integer + attribute :total_session_time, :integer + attribute :user_id, :integer + attribute :user_group_id, :integer + + def readonly? + true + end + end +end diff --git a/app/models/user_group_classification_counts/daily_group_user_project_classification_count.rb b/app/models/user_group_classification_counts/daily_group_user_project_classification_count.rb new file mode 100644 index 0000000..9678ded --- /dev/null +++ b/app/models/user_group_classification_counts/daily_group_user_project_classification_count.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module UserGroupClassificationCounts + class DailyGroupUserProjectClassificationCount < ApplicationRecord + self.table_name = 'daily_group_classification_count_and_time_per_user_per_project' + attribute :classification_count, :integer + attribute :total_session_time, :integer + attribute :user_id, :integer + attribute :project_id, :integer + attribute :user_group_id, :integer + + def readonly? + true + end + end +end diff --git a/app/models/user_group_classification_counts/daily_group_user_workflow_classification_count.rb b/app/models/user_group_classification_counts/daily_group_user_workflow_classification_count.rb new file mode 100644 index 0000000..06e3302 --- /dev/null +++ b/app/models/user_group_classification_counts/daily_group_user_workflow_classification_count.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module UserGroupClassificationCounts + class DailyGroupUserWorkflowClassificationCount < ApplicationRecord + self.table_name = 'daily_group_classification_count_and_time_per_user_per_workflow' + attribute :classification_count, :integer + attribute :total_session_time, :integer + attribute :user_id, :integer + attribute :workflow_id, :integer + attribute :user_group_id, :integer + + def readonly? + true + end + end +end diff --git a/app/models/user_group_classification_counts/daily_group_workflow_classification_count.rb b/app/models/user_group_classification_counts/daily_group_workflow_classification_count.rb new file mode 100644 index 0000000..0dc7de1 --- /dev/null +++ b/app/models/user_group_classification_counts/daily_group_workflow_classification_count.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module UserGroupClassificationCounts + class DailyGroupWorkflowClassificationCount < ApplicationRecord + self.table_name = 'daily_group_classification_count_and_time_per_workflow' + attribute :classification_count, :integer + attribute :total_session_time, :integer + attribute :workflow_id, :integer + attribute :user_group_id, :integer + + def readonly? + true + end + end +end diff --git a/db/migrate/20230725185947_create_daily_group_classifications_count_and_time.rb b/db/migrate/20230725185947_create_daily_group_classifications_count_and_time.rb new file mode 100644 index 0000000..02d441e --- /dev/null +++ b/db/migrate/20230725185947_create_daily_group_classifications_count_and_time.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class CreateDailyGroupClassificationsCountAndTime < ActiveRecord::Migration[7.0] + # we have to disable the migration transaction because creating materialized views within it is not allowed. + disable_ddl_transaction! + def change + execute <<~SQL + create materialized view daily_group_classification_count_and_time + with ( + timescaledb.continuous + ) as + select + time_bucket('1d', event_time) as day, + user_group_id, + count(*) as classification_count, + sum(session_time) as total_session_time + from classification_user_groups + group by day, user_group_id; + SQL + end +end diff --git a/db/migrate/20230725193600_create_daily_group_project_classification_count_and_time.rb b/db/migrate/20230725193600_create_daily_group_project_classification_count_and_time.rb new file mode 100644 index 0000000..f4bbe00 --- /dev/null +++ b/db/migrate/20230725193600_create_daily_group_project_classification_count_and_time.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +class CreateDailyGroupProjectClassificationCountAndTime < ActiveRecord::Migration[7.0] + # we have to disable the migration transaction because creating materialized views within it is not allowed. + disable_ddl_transaction! + def change + execute <<~SQL + create materialized view daily_group_classification_count_and_time_per_project + with ( + timescaledb.continuous + ) as + select + time_bucket('1d', event_time) as day, + user_group_id, + project_id, + count(*) as classification_count, + sum(session_time) as total_session_time + from classification_user_groups + group by day, user_group_id, project_id; + SQL + end +end diff --git a/db/migrate/20230725194157_create_daily_group_workflow_classification_count_and_time.rb b/db/migrate/20230725194157_create_daily_group_workflow_classification_count_and_time.rb new file mode 100644 index 0000000..9ca5629 --- /dev/null +++ b/db/migrate/20230725194157_create_daily_group_workflow_classification_count_and_time.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +class CreateDailyGroupWorkflowClassificationCountAndTime < ActiveRecord::Migration[7.0] + # we have to disable the migration transaction because creating materialized views within it is not allowed. + disable_ddl_transaction! + def change + execute <<~SQL + create materialized view daily_group_classification_count_and_time_per_workflow + with ( + timescaledb.continuous + ) as + select + time_bucket('1d', event_time) as day, + user_group_id, + workflow_id, + count(*) as classification_count, + sum(session_time) as total_session_time + from classification_user_groups + group by day, user_group_id, workflow_id; + SQL + end +end diff --git a/db/migrate/20230725194325_create_daily_group_user_classification_count_and_time.rb b/db/migrate/20230725194325_create_daily_group_user_classification_count_and_time.rb new file mode 100644 index 0000000..6f58c5a --- /dev/null +++ b/db/migrate/20230725194325_create_daily_group_user_classification_count_and_time.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +class CreateDailyGroupUserClassificationCountAndTime < ActiveRecord::Migration[7.0] + # we have to disable the migration transaction because creating materialized views within it is not allowed. + disable_ddl_transaction! + ## We should note that this view looks very similar to the daily_user_classification_count_and_time (where the columns of that table are day, user_id, classification_count, total_session_time). + ## The only difference between this view and daily_user_classification_count_and_time is that we are grouping by user_group_id (i.e. user_group_id is a column in this view). + ## Even though the view are very similar we cannot query from just daily_user_classification_count_and_time to get stats info of that user for that group. + ## Reason being: + ## A) daily_user_classification_count_and_time does not consider when a user has joined a group. + ## (So if we queried for all time for the user group, the user's old classifications [when he/she/they were not part of the group] would be counted towards the user group) + ## [Vice versa if a user LEAVES a user group] + ## B) On the flip side, we cannot query from just daily_group_classification_count_and_time_per_user, because not every user belongs to a group. + def change + execute <<~SQL + create materialized view daily_group_classification_count_and_time_per_user + with ( + timescaledb.continuous + ) as + select + time_bucket('1d', event_time) as day, + user_group_id, + user_id, + count(*) as classification_count, + sum(session_time) as total_session_time + from classification_user_groups + group by day, user_group_id, user_id; + SQL + end +end diff --git a/db/migrate/20230801163815_create_daily_group_user_project_count_and_time.rb b/db/migrate/20230801163815_create_daily_group_user_project_count_and_time.rb new file mode 100644 index 0000000..0d8caf3 --- /dev/null +++ b/db/migrate/20230801163815_create_daily_group_user_project_count_and_time.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +class CreateDailyGroupUserProjectCountAndTime < ActiveRecord::Migration[7.0] + # we have to disable the migration transaction because creating materialized views within it is not allowed. + disable_ddl_transaction! + ## We should note that this view looks very similar to the daily_user_classification_count_and_time_per_project + ## (where the columns of that table are day, user_id, classification_count, total_session_time, project_id). + ## The only difference between this view and daily_user_classification_count_and_time_per_project is that we are grouping by user_group_id (i.e. user_group_id is a column in this view). + ## Even though the views are very similar we cannot query from just daily_user_classification_count_and_time_per_project to get stats info of that user for that group. + ## Reason being: + ## A) daily_user_classification_count_and_time_per_project does not consider WHEN a user has joined a group. + ## (So if we queried for all time for the user group, the user's old classifications [when he/she/they were not part of the group] would be counted towards the user group) + ## [Vice versa if a user LEAVES a user group] + ## B) On the flip side, we cannot query from just daily_group_classification_count_and_time_per_user_per_prject when querying for just user stats, because not every user belongs to a group. + def change + execute <<~SQL + create materialized view daily_group_classification_count_and_time_per_user_per_project + with ( + timescaledb.continuous + ) as + select + time_bucket('1d', event_time) as day, + user_group_id, + user_id, + project_id, + count(*) as classification_count, + sum(session_time) as total_session_time + from classification_user_groups + group by day, user_group_id, user_id, project_id; + SQL + end +end diff --git a/db/migrate/20230801163827_create_daily_group_user_workflow_count_and_time.rb b/db/migrate/20230801163827_create_daily_group_user_workflow_count_and_time.rb new file mode 100644 index 0000000..368938b --- /dev/null +++ b/db/migrate/20230801163827_create_daily_group_user_workflow_count_and_time.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +class CreateDailyGroupUserWorkflowCountAndTime < ActiveRecord::Migration[7.0] + # we have to disable the migration transaction because creating materialized views within it is not allowed. + disable_ddl_transaction! + ## We should note that this view looks very similar to the daily_user_classification_count_and_time_per_workflow + ## (where the columns of that table are day, user_id, classification_count, total_session_time, workflow_id). + ## The only difference between this view and daily_user_classification_count_and_time_per_workflow is that we are grouping by user_group_id (i.e. user_group_id is a column in this view). + ## Even though the views are very similar we cannot query from just daily_user_classification_count_and_time_per_workflow to get stats info of that user for that group. + ## Reason being: + ## A) daily_user_classification_count_and_time_per_workflow does not consider WHEN a user has joined a group. + ## (So if we queried for all time for the user group, the user's old classifications [when he/she/they were not part of the group] would be counted towards the user group) + ## [Vice versa if a user LEAVES a user group] + ## B) On the flip side, we cannot query from just daily_group_classification_count_and_time_per_user_per_workflow when querying for just user stats, because not every user belongs to a group. + def change + execute <<~SQL + create materialized view daily_group_classification_count_and_time_per_user_per_workflow + with ( + timescaledb.continuous + ) as + select + time_bucket('1d', event_time) as day, + user_group_id, + user_id, + workflow_id, + count(*) as classification_count, + sum(session_time) as total_session_time + from classification_user_groups + group by day, user_group_id, user_id, workflow_id; + SQL + end +end diff --git a/db/schema.rb b/db/schema.rb index cea8239..0ddb226 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2023_07_12_142126) do +ActiveRecord::Schema[7.0].define(version: 2023_08_01_163827) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" enable_extension "timescaledb"