Commit b37910ec authored by Sean Arnold's avatar Sean Arnold

Add more validations and tweak index

- Max 10 rules for each policy
- One escalation for each rule/alert pair
- add ID to process_at index
- Change order of status column
parent 6249f4e3
...@@ -12,10 +12,10 @@ class CreateIncidentManagementPendingAlertEscalations < ActiveRecord::Migration[ ...@@ -12,10 +12,10 @@ class CreateIncidentManagementPendingAlertEscalations < ActiveRecord::Migration[
rule_id bigint, rule_id bigint,
alert_id bigint NOT NULL, alert_id bigint NOT NULL,
schedule_id bigint NOT NULL, schedule_id bigint NOT NULL,
status smallint NOT NULL,
process_at timestamp with time zone NOT NULL, process_at timestamp with time zone NOT NULL,
created_at timestamp with time zone NOT NULL, created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL,
status smallint NOT NULL,
PRIMARY KEY (id, process_at) PRIMARY KEY (id, process_at)
) PARTITION BY RANGE (process_at); ) PARTITION BY RANGE (process_at);
...@@ -28,8 +28,8 @@ class CreateIncidentManagementPendingAlertEscalations < ActiveRecord::Migration[ ...@@ -28,8 +28,8 @@ class CreateIncidentManagementPendingAlertEscalations < ActiveRecord::Migration[
CREATE INDEX index_incident_management_pending_alert_escalations_on_schedule_id CREATE INDEX index_incident_management_pending_alert_escalations_on_schedule_id
ON incident_management_pending_alert_escalations USING btree (schedule_id); ON incident_management_pending_alert_escalations USING btree (schedule_id);
CREATE INDEX index_incident_management_pending_alert_escalations_on_process_at CREATE INDEX index_incident_management_pending_alert_escalations_on_process_at_id
ON incident_management_pending_alert_escalations USING btree (process_at); ON incident_management_pending_alert_escalations USING btree (process_at, id);
ALTER TABLE incident_management_pending_alert_escalations ADD CONSTRAINT fk_rails_fcbfd9338b ALTER TABLE incident_management_pending_alert_escalations ADD CONSTRAINT fk_rails_fcbfd9338b
FOREIGN KEY (schedule_id) REFERENCES incident_management_oncall_schedules(id) ON DELETE CASCADE; FOREIGN KEY (schedule_id) REFERENCES incident_management_oncall_schedules(id) ON DELETE CASCADE;
......
...@@ -195,10 +195,10 @@ CREATE TABLE incident_management_pending_alert_escalations ( ...@@ -195,10 +195,10 @@ CREATE TABLE incident_management_pending_alert_escalations (
rule_id bigint, rule_id bigint,
alert_id bigint NOT NULL, alert_id bigint NOT NULL,
schedule_id bigint NOT NULL, schedule_id bigint NOT NULL,
status smallint NOT NULL,
process_at timestamp with time zone NOT NULL, process_at timestamp with time zone NOT NULL,
created_at timestamp with time zone NOT NULL, created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL updated_at timestamp with time zone NOT NULL,
status smallint NOT NULL
) )
PARTITION BY RANGE (process_at); PARTITION BY RANGE (process_at);
...@@ -23636,7 +23636,7 @@ CREATE INDEX index_incident_management_oncall_shifts_on_participant_id ON incide ...@@ -23636,7 +23636,7 @@ CREATE INDEX index_incident_management_oncall_shifts_on_participant_id ON incide
CREATE INDEX index_incident_management_pending_alert_escalations_on_alert_id ON ONLY incident_management_pending_alert_escalations USING btree (alert_id); CREATE INDEX index_incident_management_pending_alert_escalations_on_alert_id ON ONLY incident_management_pending_alert_escalations USING btree (alert_id);
CREATE INDEX index_incident_management_pending_alert_escalations_on_process_ ON ONLY incident_management_pending_alert_escalations USING btree (process_at); CREATE INDEX index_incident_management_pending_alert_escalations_on_process_ ON ONLY incident_management_pending_alert_escalations USING btree (process_at, id);
CREATE INDEX index_incident_management_pending_alert_escalations_on_rule_id ON ONLY incident_management_pending_alert_escalations USING btree (rule_id); CREATE INDEX index_incident_management_pending_alert_escalations_on_rule_id ON ONLY incident_management_pending_alert_escalations USING btree (rule_id);
...@@ -4,6 +4,8 @@ module IncidentManagement ...@@ -4,6 +4,8 @@ module IncidentManagement
class EscalationPolicy < ApplicationRecord class EscalationPolicy < ApplicationRecord
self.table_name = 'incident_management_escalation_policies' self.table_name = 'incident_management_escalation_policies'
MAX_RULE_COUNT = 10
belongs_to :project belongs_to :project
has_many :rules, class_name: 'EscalationRule', inverse_of: :policy, foreign_key: 'policy_id', index_errors: true has_many :rules, class_name: 'EscalationRule', inverse_of: :policy, foreign_key: 'policy_id', index_errors: true
...@@ -11,9 +13,16 @@ module IncidentManagement ...@@ -11,9 +13,16 @@ module IncidentManagement
validates :name, presence: true, uniqueness: { scope: [:project_id] }, length: { maximum: 72 } validates :name, presence: true, uniqueness: { scope: [:project_id] }, length: { maximum: 72 }
validates :description, length: { maximum: 160 } validates :description, length: { maximum: 160 }
validates :rules, presence: true validates :rules, presence: true
validate :rules_count_not_exceeded
accepts_nested_attributes_for :rules accepts_nested_attributes_for :rules
scope :with_rules, -> { includes(:rules) } scope :with_rules, -> { includes(:rules) }
private
def rules_count_not_exceeded
errors.add(:base, "cannot have more than #{MAX_RULE_COUNT} rules") if rules.size > MAX_RULE_COUNT
end
end end
end end
...@@ -25,6 +25,7 @@ module IncidentManagement ...@@ -25,6 +25,7 @@ module IncidentManagement
validates :process_at, presence: true validates :process_at, presence: true
validates :status, presence: true validates :status, presence: true
validates :rule_id, presence: true, uniqueness: { scope: [:alert_id] }
delegate :project, to: :alert delegate :project, to: :alert
end end
......
...@@ -21,5 +21,12 @@ RSpec.describe IncidentManagement::EscalationPolicy do ...@@ -21,5 +21,12 @@ RSpec.describe IncidentManagement::EscalationPolicy do
it { is_expected.to validate_uniqueness_of(:name).scoped_to(:project_id) } it { is_expected.to validate_uniqueness_of(:name).scoped_to(:project_id) }
it { is_expected.to validate_length_of(:name).is_at_most(72) } it { is_expected.to validate_length_of(:name).is_at_most(72) }
it { is_expected.to validate_length_of(:description).is_at_most(160) } it { is_expected.to validate_length_of(:description).is_at_most(160) }
it 'validates the number of rules' do
policy = build(:incident_management_escalation_policy, rule_count: 11)
expect(policy).not_to be_valid
expect(policy.errors).to contain_exactly("cannot have more than #{described_class::MAX_RULE_COUNT} rules")
end
end end
end end
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe IncidentManagement::PendingEscalations::Alert do RSpec.describe IncidentManagement::PendingEscalations::Alert do
subject { build(:incident_management_pending_alert_escalation) } subject { create(:incident_management_pending_alert_escalation) }
it { is_expected.to be_valid } it { is_expected.to be_valid }
...@@ -11,6 +11,7 @@ RSpec.describe IncidentManagement::PendingEscalations::Alert do ...@@ -11,6 +11,7 @@ RSpec.describe IncidentManagement::PendingEscalations::Alert do
it { is_expected.to validate_presence_of(:process_at) } it { is_expected.to validate_presence_of(:process_at) }
it { is_expected.to validate_presence_of(:status) } it { is_expected.to validate_presence_of(:status) }
it { is_expected.to delegate_method(:project).to(:alert) } it { is_expected.to delegate_method(:project).to(:alert) }
it { is_expected.to validate_uniqueness_of(:rule_id).scoped_to([:alert_id]) }
end end
describe 'associations' do describe 'associations' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment