diff --git a/app/models/check_notification.rb b/app/models/check_notification.rb new file mode 100644 index 0000000..789280b --- /dev/null +++ b/app/models/check_notification.rb @@ -0,0 +1,46 @@ +# == Schema Information +# +# Table name: check_notifications +# +# id :bigint(8) not null, primary key +# sent_at :datetime +# status :integer default("pending"), not null +# created_at :datetime not null +# updated_at :datetime not null +# check_id :bigint(8) +# notification_id :bigint(8) +# +# Indexes +# +# index_check_notifications_on_check_id (check_id) +# index_check_notifications_on_notification_id (notification_id) +# +# Foreign Keys +# +# fk_rails_... (check_id => checks.id) +# fk_rails_... (notification_id => notifications.id) +# + +# Copyright (C) 2018 Colin Darie , 2018 Evolix +# License: GNU AGPL-3+ (see full text in LICENSE file) + +class CheckNotification < ApplicationRecord + belongs_to :check + belongs_to :notification, counter_cache: :checks_count + + enum status: [:pending, :ongoing, :succeed, :failed] + + scope :active_check, -> { Check.active } + scope :check_last_run_failed, -> { Check.last_run_failed } + + def pending! + self.sent_at = nil + super + end + alias reset! pending! + + def ongoing! + self.sent_at = Time.now + super + end +end diff --git a/app/models/notification.rb b/app/models/notification.rb index 860f67e..cec38ce 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -1,27 +1,29 @@ # Copyright (C) 2018 Colin Darie , 2018 Jeremy Lecour , 2018 Evolix # License: GNU AGPL-3+ (see full text in LICENSE file) - # == Schema Information # # Table name: notifications # -# id :bigint(8) not null, primary key -# channel :integer default("email"), not null -# interval :integer not null -# recipient :string(255) not null -# sent_at :datetime -# status :integer default("pending"), not null -# created_at :datetime not null -# updated_at :datetime not null -# check_id :bigint(8) +# id :bigint(8) not null, primary key +# channel :integer default("email"), not null +# checks_count :integer default(0), not null +# interval :integer not null +# label :string(255) +# recipient :string(255) not null +# created_at :datetime not null +# updated_at :datetime not null +# check_id :bigint(8) +# user_id :bigint(8) # # Indexes # # index_notifications_on_check_id (check_id) +# index_notifications_on_user_id (user_id) # # Foreign Keys # # fk_rails_... (check_id => checks.id) +# fk_rails_... (user_id => users.id) # class Notification < ApplicationRecord diff --git a/db/migrate/20180801072038_add_consecutive_failures_to_checks.rb b/db/migrate/20180801072038_add_consecutive_failures_to_checks.rb index dbf038b..02c6faa 100644 --- a/db/migrate/20180801072038_add_consecutive_failures_to_checks.rb +++ b/db/migrate/20180801072038_add_consecutive_failures_to_checks.rb @@ -1,3 +1,6 @@ +# Copyright (C) 2018 Colin Darie , 2018 Evolix +# License: GNU AGPL-3+ (see full text in LICENSE file) + class AddConsecutiveFailuresToChecks < ActiveRecord::Migration[5.2] def change add_column :checks, :consecutive_failures, :integer, default: 0, null: false diff --git a/db/migrate/20180829073920_create_check_notifications.rb b/db/migrate/20180829073920_create_check_notifications.rb new file mode 100644 index 0000000..0522c80 --- /dev/null +++ b/db/migrate/20180829073920_create_check_notifications.rb @@ -0,0 +1,15 @@ +# Copyright (C) 2018 Colin Darie , 2018 Evolix +# License: GNU AGPL-3+ (see full text in LICENSE file) + +class CreateCheckNotifications < ActiveRecord::Migration[5.2] + def change + create_table :check_notifications do |t| + t.references :check, foreign_key: true + t.references :notification, foreign_key: true + t.integer :status, null: false, default: 0, limit: 1 + t.datetime :sent_at + + t.timestamps + end + end +end diff --git a/db/migrate/20180829164227_add_fields_to_notifications.rb b/db/migrate/20180829164227_add_fields_to_notifications.rb new file mode 100644 index 0000000..52fdbc3 --- /dev/null +++ b/db/migrate/20180829164227_add_fields_to_notifications.rb @@ -0,0 +1,41 @@ +# Copyright (C) 2018 Colin Darie , 2018 Evolix +# License: GNU AGPL-3+ (see full text in LICENSE file) + +class AddFieldsToNotifications < ActiveRecord::Migration[5.2] + def change + add_reference :notifications, :user, foreign_key: true + add_column :notifications, :label, :string + add_column :notifications, :checks_count, :integer, default: 0, null: false + + reversible do |dir| + dir.up do + # first set user & label for *all* notifications + Notification.find_each do |notification| + check = Check.find(notification.check_id) # check relation does not exist anymore + + notification.user_id = check.user_id + notification.save! + end + + # then build the equivalent check notification + Notification.find_each do |notification| + assoc_notification = Notification.where( + user_id: notification.user_id, + recipient: notification.recipient, + interval: notification.interval, + ).order(checks_count: :desc).limit(1).first + + CheckNotification.create!( + check_id: notification.check_id, + notification: assoc_notification, + status: notification.status, + sent_at: notification.sent_at + ) + end + + # last delete duplicate notification templates not used + Notification.where(checks_count: 0).destroy_all + end + end + end +end diff --git a/db/migrate/20180830083927_remove_obsolete_fields_to_notifications.rb b/db/migrate/20180830083927_remove_obsolete_fields_to_notifications.rb new file mode 100644 index 0000000..f4454b3 --- /dev/null +++ b/db/migrate/20180830083927_remove_obsolete_fields_to_notifications.rb @@ -0,0 +1,9 @@ +# Copyright (C) 2018 Colin Darie , 2018 Evolix +# License: GNU AGPL-3+ (see full text in LICENSE file) + +class RemoveObsoleteFieldsToNotifications < ActiveRecord::Migration[5.2] + def change + remove_column :notifications, :status, :integer, null: false, limit: 1, default: 0 + remove_column :notifications, :sent_at, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index 6957dbb..7da2aa0 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.define(version: 2018_08_29_134404) do +ActiveRecord::Schema.define(version: 2018_08_30_083927) do create_table "check_logs", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| t.bigint "check_id" @@ -24,6 +24,17 @@ ActiveRecord::Schema.define(version: 2018_08_29_134404) do t.index ["check_id"], name: "index_check_logs_on_check_id" end + create_table "check_notifications", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| + t.bigint "check_id" + t.bigint "notification_id" + t.integer "status", limit: 1, default: 0, null: false + t.datetime "sent_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["check_id"], name: "index_check_notifications_on_check_id" + t.index ["notification_id"], name: "index_check_notifications_on_notification_id" + end + create_table "checks", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| t.bigint "user_id" t.integer "kind", null: false @@ -49,11 +60,13 @@ ActiveRecord::Schema.define(version: 2018_08_29_134404) do t.integer "channel", default: 0, null: false t.string "recipient", null: false t.integer "interval", null: false - t.integer "status", default: 0, null: false - t.datetime "sent_at" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.bigint "user_id" + t.string "label" + t.integer "checks_count", default: 0, null: false t.index ["check_id"], name: "index_notifications_on_check_id" + t.index ["user_id"], name: "index_notifications_on_user_id" end create_table "users", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| @@ -82,6 +95,9 @@ ActiveRecord::Schema.define(version: 2018_08_29_134404) do end add_foreign_key "check_logs", "checks" + add_foreign_key "check_notifications", "checks" + add_foreign_key "check_notifications", "notifications" add_foreign_key "checks", "users" add_foreign_key "notifications", "checks" + add_foreign_key "notifications", "users" end diff --git a/test/factories/check_notifications.rb b/test/factories/check_notifications.rb new file mode 100644 index 0000000..3167933 --- /dev/null +++ b/test/factories/check_notifications.rb @@ -0,0 +1,44 @@ +# == Schema Information +# +# Table name: check_notifications +# +# id :bigint(8) not null, primary key +# sent_at :datetime +# status :integer default("pending"), not null +# created_at :datetime not null +# updated_at :datetime not null +# check_id :bigint(8) +# notification_id :bigint(8) +# +# Indexes +# +# index_check_notifications_on_check_id (check_id) +# index_check_notifications_on_notification_id (notification_id) +# +# Foreign Keys +# +# fk_rails_... (check_id => checks.id) +# fk_rails_... (notification_id => notifications.id) +# + +FactoryBot.define do + factory :check_notification do + check + notification + status :pending + sent_at nil + + trait :ongoing do + status :ongoing + end + + trait :succeed do + status :succeed + sent_at { 1.day.ago } + end + + trait :failed do + status :failed + end + end +end diff --git a/test/factories/notifications.rb b/test/factories/notifications.rb index b851774..de8052c 100644 --- a/test/factories/notifications.rb +++ b/test/factories/notifications.rb @@ -1,27 +1,29 @@ # Copyright (C) 2018 Colin Darie , 2018 Jeremy Lecour , 2018 Evolix # License: GNU AGPL-3+ (see full text in LICENSE file) - # == Schema Information # # Table name: notifications # -# id :bigint(8) not null, primary key -# channel :integer default("email"), not null -# interval :integer not null -# recipient :string(255) not null -# sent_at :datetime -# status :integer default("pending"), not null -# created_at :datetime not null -# updated_at :datetime not null -# check_id :bigint(8) +# id :bigint(8) not null, primary key +# channel :integer default("email"), not null +# checks_count :integer default(0), not null +# interval :integer not null +# label :string(255) +# recipient :string(255) not null +# created_at :datetime not null +# updated_at :datetime not null +# check_id :bigint(8) +# user_id :bigint(8) # # Indexes # # index_notifications_on_check_id (check_id) +# index_notifications_on_user_id (user_id) # # Foreign Keys # # fk_rails_... (check_id => checks.id) +# fk_rails_... (user_id => users.id) # FactoryBot.define do diff --git a/test/models/check_notification_test.rb b/test/models/check_notification_test.rb new file mode 100644 index 0000000..dca5c8f --- /dev/null +++ b/test/models/check_notification_test.rb @@ -0,0 +1,30 @@ +# == Schema Information +# +# Table name: check_notifications +# +# id :bigint(8) not null, primary key +# sent_at :datetime +# status :integer default("pending"), not null +# created_at :datetime not null +# updated_at :datetime not null +# check_id :bigint(8) +# notification_id :bigint(8) +# +# Indexes +# +# index_check_notifications_on_check_id (check_id) +# index_check_notifications_on_notification_id (notification_id) +# +# Foreign Keys +# +# fk_rails_... (check_id => checks.id) +# fk_rails_... (notification_id => notifications.id) +# + +require 'test_helper' + +class CheckNotificationTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/notification_test.rb b/test/models/notification_test.rb index 05e9c46..a542799 100644 --- a/test/models/notification_test.rb +++ b/test/models/notification_test.rb @@ -1,27 +1,29 @@ # Copyright (C) 2018 Colin Darie , 2018 Jeremy Lecour , 2018 Evolix # License: GNU AGPL-3+ (see full text in LICENSE file) - # == Schema Information # # Table name: notifications # -# id :bigint(8) not null, primary key -# channel :integer default("email"), not null -# interval :integer not null -# recipient :string(255) not null -# sent_at :datetime -# status :integer default("pending"), not null -# created_at :datetime not null -# updated_at :datetime not null -# check_id :bigint(8) +# id :bigint(8) not null, primary key +# channel :integer default("email"), not null +# checks_count :integer default(0), not null +# interval :integer not null +# label :string(255) +# recipient :string(255) not null +# created_at :datetime not null +# updated_at :datetime not null +# check_id :bigint(8) +# user_id :bigint(8) # # Indexes # # index_notifications_on_check_id (check_id) +# index_notifications_on_user_id (user_id) # # Foreign Keys # # fk_rails_... (check_id => checks.id) +# fk_rails_... (user_id => users.id) # require "test_helper"