From 082a10e3d0c2779670e1cadff8cc2454caa2ade5 Mon Sep 17 00:00:00 2001 From: Jorge Manrubia Date: Thu, 28 Aug 2025 11:20:28 +0200 Subject: [PATCH] Add notification settings model --- app/models/notification/settings.rb | 6 +++ app/models/user.rb | 6 +-- app/models/user/configurable.rb | 10 ++++ ...0828084732_create_notification_settings.rb | 12 +++++ db/schema.rb | 12 ++++- db/schema_cache.yml | 53 ++++++++++++++++++- test/fixtures/notification/settings.yml | 18 +++++++ test/models/user/configurable_test.rb | 8 +++ 8 files changed, 119 insertions(+), 6 deletions(-) create mode 100644 app/models/notification/settings.rb create mode 100644 app/models/user/configurable.rb create mode 100644 db/migrate/20250828084732_create_notification_settings.rb create mode 100644 test/fixtures/notification/settings.yml create mode 100644 test/models/user/configurable_test.rb diff --git a/app/models/notification/settings.rb b/app/models/notification/settings.rb new file mode 100644 index 000000000..e74f35041 --- /dev/null +++ b/app/models/notification/settings.rb @@ -0,0 +1,6 @@ +class Notification::Settings < ApplicationRecord + belongs_to :user + + enum :bundle_email_frequency, %i[ never every_few_hours daily weekly ], + default: :never, default: :never, prefix: :bundle_email +end diff --git a/app/models/user.rb b/app/models/user.rb index 676ce459a..229518ff3 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,6 +1,6 @@ class User < ApplicationRecord - include Accessor, Attachable, Assignee, Mentionable, Named, Notifiable, Role, Searcher, - SignalUser, Staff, Transferable, Conversational, AiQuota + include Accessor, Attachable, Assignee, Configurable, Mentionable, Named, Notifiable, Role, + Searcher, SignalUser, Staff, Transferable, Conversational, AiQuota include Timelined # Depends on Accessor has_one_attached :avatar @@ -15,8 +15,6 @@ class User < ApplicationRecord has_many :pins, dependent: :destroy has_many :pinned_cards, through: :pins, source: :card has_many :commands, dependent: :destroy - has_many :push_subscriptions, class_name: "Push::Subscription", dependent: :delete_all - has_many :period_activity_summaries, dependent: :destroy normalizes :email_address, with: ->(value) { value.strip.downcase } diff --git a/app/models/user/configurable.rb b/app/models/user/configurable.rb new file mode 100644 index 000000000..28e03a5e5 --- /dev/null +++ b/app/models/user/configurable.rb @@ -0,0 +1,10 @@ +module User::Configurable + extend ActiveSupport::Concern + + included do + has_one :notification_settings, class_name: "Notification::Settings", dependent: :destroy + has_many :push_subscriptions, class_name: "Push::Subscription", dependent: :delete_all + + after_create :create_notification_settings, unless: :system? + end +end diff --git a/db/migrate/20250828084732_create_notification_settings.rb b/db/migrate/20250828084732_create_notification_settings.rb new file mode 100644 index 000000000..cf414eb6e --- /dev/null +++ b/db/migrate/20250828084732_create_notification_settings.rb @@ -0,0 +1,12 @@ +class CreateNotificationSettings < ActiveRecord::Migration[8.1] + def change + create_table :notification_settings do |t| + t.references :user, null: false, foreign_key: true, index: true + t.integer :bundle_email_frequency, default: 0, null: false + + t.timestamps + + t.index %i[ user_id bundle_email_frequency ] + end + end +end diff --git a/db/schema.rb b/db/schema.rb index fa6dd112f..fdff4a4d2 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[8.1].define(version: 2025_08_27_072601) do +ActiveRecord::Schema[8.1].define(version: 2025_08_28_084732) do create_table "accesses", force: :cascade do |t| t.datetime "accessed_at" t.integer "collection_id", null: false @@ -319,6 +319,15 @@ ActiveRecord::Schema[8.1].define(version: 2025_08_27_072601) do t.index ["user_id", "status"], name: "index_notification_bundles_on_user_id_and_status" end + create_table "notification_settings", force: :cascade do |t| + t.integer "bundle_email_frequency", default: 0, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "user_id", null: false + t.index ["user_id", "bundle_email_frequency"], name: "idx_on_user_id_bundle_email_frequency_3ff75afaf4" + t.index ["user_id"], name: "index_notification_settings_on_user_id" + end + create_table "notifications", force: :cascade do |t| t.datetime "created_at", null: false t.integer "creator_id" @@ -477,6 +486,7 @@ ActiveRecord::Schema[8.1].define(version: 2025_08_27_072601) do add_foreign_key "mentions", "users", column: "mentionee_id" add_foreign_key "mentions", "users", column: "mentioner_id" add_foreign_key "notification_bundles", "users" + add_foreign_key "notification_settings", "users" add_foreign_key "notifications", "users" add_foreign_key "notifications", "users", column: "creator_id" add_foreign_key "pins", "cards" diff --git a/db/schema_cache.yml b/db/schema_cache.yml index 5ba56a0c4..cfb084665 100644 --- a/db/schema_cache.yml +++ b/db/schema_cache.yml @@ -989,6 +989,21 @@ columns: comment: - *9 - *18 + notification_settings: + - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column + auto_increment: + name: bundle_email_frequency + cast_type: *3 + sql_type_metadata: *4 + 'null': false + default: 0 + default_function: + collation: + comment: + - *5 + - *6 + - *9 + - *18 notifications: - *5 - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column @@ -1366,6 +1381,7 @@ primary_keys: filters_tags: mentions: id notification_bundles: id + notification_settings: id notifications: id pins: id push_subscriptions: id @@ -1416,6 +1432,7 @@ data_sources: filters_tags: true mentions: true notification_bundles: true + notification_settings: true notifications: true pins: true push_subscriptions: true @@ -2464,6 +2481,40 @@ indexes: nulls_not_distinct: comment: valid: true + notification_settings: + - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition + table: notification_settings + name: idx_on_user_id_bundle_email_frequency_3ff75afaf4 + unique: false + columns: + - user_id + - bundle_email_frequency + lengths: {} + orders: {} + opclasses: {} + where: + type: + using: + include: + nulls_not_distinct: + comment: + valid: true + - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition + table: notification_settings + name: index_notification_settings_on_user_id + unique: false + columns: + - user_id + lengths: {} + orders: {} + opclasses: {} + where: + type: + using: + include: + nulls_not_distinct: + comment: + valid: true notifications: - !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition table: notifications @@ -2941,4 +2992,4 @@ indexes: comment: valid: true workflows: [] -version: 20250827072601 +version: 20250828084732 diff --git a/test/fixtures/notification/settings.yml b/test/fixtures/notification/settings.yml new file mode 100644 index 000000000..5042d9463 --- /dev/null +++ b/test/fixtures/notification/settings.yml @@ -0,0 +1,18 @@ +_fixture: + model_class: Notification::Settings + +david_settings: + user: david + bundle_email_frequency: never + +jz_settings: + user: jz + bundle_email_frequency: never + +kevin_settings: + user: kevin + bundle_email_frequency: never + +system_settings: + user: system + bundle_email_frequency: never diff --git a/test/models/user/configurable_test.rb b/test/models/user/configurable_test.rb new file mode 100644 index 000000000..b62ac3e18 --- /dev/null +++ b/test/models/user/configurable_test.rb @@ -0,0 +1,8 @@ +require "test_helper" + +class Notification::ConfigurableTest < ActiveSupport::TestCase + test "should create a notification settings for new users" do + user = User.create! name: "Some new user", email_address: "some.new@user.com" + assert user.notification_settings.present? + end +end