Skip to content

Commit c2acd8f

Browse files
committed
chore: create notification model and schema
1 parent 99f4ce3 commit c2acd8f

3 files changed

Lines changed: 77 additions & 0 deletions

File tree

app/models/notification.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
class Notification < ApplicationRecord
2+
# Associations
3+
belongs_to :user
4+
5+
# Validations
6+
validates :title, presence: true, length: { maximum: 200 }
7+
validates :message, presence: true
8+
validates :type, presence: true, inclusion: {
9+
in: %w[info success warning error match schedule system],
10+
message: "%{value} is not a valid notification type"
11+
}
12+
13+
# Scopes
14+
scope :unread, -> { where(is_read: false) }
15+
scope :read, -> { where(is_read: true) }
16+
scope :recent, -> { order(created_at: :desc) }
17+
scope :by_type, ->(type) { where(type: type) }
18+
19+
# Callbacks
20+
before_create :set_default_channels
21+
22+
# Instance methods
23+
def mark_as_read!
24+
update!(is_read: true, read_at: Time.current)
25+
end
26+
27+
def unread?
28+
!is_read
29+
end
30+
31+
private
32+
33+
def set_default_channels
34+
self.channels ||= ['in_app']
35+
end
36+
end

app/models/user.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class User < ApplicationRecord
1010
has_many :created_vod_timestamps, class_name: 'VodTimestamp', foreign_key: 'created_by_id', dependent: :nullify
1111
has_many :assigned_goals, class_name: 'TeamGoal', foreign_key: 'assigned_to_id', dependent: :nullify
1212
has_many :created_goals, class_name: 'TeamGoal', foreign_key: 'created_by_id', dependent: :nullify
13+
has_many :notifications, dependent: :destroy
1314
has_many :audit_logs, dependent: :destroy
1415

1516
# Validations
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
class CreateNotifications < ActiveRecord::Migration[7.1]
2+
def change
3+
create_table :notifications, id: :uuid do |t|
4+
t.references :user, type: :uuid, null: false, foreign_key: true
5+
6+
t.string :title, limit: 200, null: false
7+
t.text :message, null: false
8+
t.string :type, null: false
9+
10+
# Linking
11+
t.text :link_url
12+
t.string :link_type, limit: 20
13+
t.uuid :link_id
14+
15+
# Status
16+
t.boolean :is_read, default: false
17+
t.timestamp :read_at
18+
19+
# Delivery channels
20+
t.text :channels, array: true, default: ['in_app']
21+
t.boolean :email_sent, default: false
22+
t.boolean :discord_sent, default: false
23+
24+
t.jsonb :metadata, default: {}
25+
26+
t.timestamps null: false
27+
end
28+
29+
add_index :notifications, :user_id
30+
add_index :notifications, :is_read
31+
add_index :notifications, :created_at, order: { created_at: :desc }
32+
33+
# Add check constraint for notification type
34+
execute <<-SQL
35+
ALTER TABLE notifications
36+
ADD CONSTRAINT notifications_type_check
37+
CHECK (type IN ('info', 'success', 'warning', 'error', 'match', 'schedule', 'system'));
38+
SQL
39+
end
40+
end

0 commit comments

Comments
 (0)