Commit f411615d authored by Alper Akgun's avatar Alper Akgun

History log for gitlab subscriptions table

Gitlab_subscriptions table currently doesn't keep history. That makes
blocks data team from measuring some growth KPIs. This MR adds a
history log table
parent 691c54ad
# frozen_string_literal: true
class CreateGitlabSubscriptionHistories < ActiveRecord::Migration[5.2]
DOWNTIME = false
def up
create_table :gitlab_subscription_histories do |t|
t.datetime_with_timezone :gitlab_subscription_created_at
t.datetime_with_timezone :gitlab_subscription_updated_at
t.date :start_date
t.date :end_date
t.date :trial_ends_on
t.integer :namespace_id, null: true
t.integer :hosted_plan_id, null: true
t.integer :max_seats_used
t.integer :seats
t.boolean :trial
t.integer :change_type, limit: 2
t.bigint :gitlab_subscription_id, null: false
t.datetime_with_timezone :created_at
end
add_index :gitlab_subscription_histories, :gitlab_subscription_id
end
def down
drop_table :gitlab_subscription_histories
end
end
......@@ -1828,6 +1828,23 @@ ActiveRecord::Schema.define(version: 2019_12_02_031812) do
t.index ["upload_id"], name: "index_geo_upload_deleted_events_on_upload_id"
end
create_table "gitlab_subscription_histories", force: :cascade do |t|
t.datetime_with_timezone "gitlab_subscription_created_at"
t.datetime_with_timezone "gitlab_subscription_updated_at"
t.date "start_date"
t.date "end_date"
t.date "trial_ends_on"
t.integer "namespace_id"
t.integer "hosted_plan_id"
t.integer "max_seats_used"
t.integer "seats"
t.boolean "trial"
t.integer "change_type", limit: 2
t.bigint "gitlab_subscription_id", null: false
t.datetime_with_timezone "created_at"
t.index ["gitlab_subscription_id"], name: "index_gitlab_subscription_histories_on_gitlab_subscription_id"
end
create_table "gitlab_subscriptions", force: :cascade do |t|
t.datetime_with_timezone "created_at", null: false
t.datetime_with_timezone "updated_at", null: false
......
......@@ -2,6 +2,9 @@
class GitlabSubscription < ApplicationRecord
default_value_for(:start_date) { Date.today }
after_create_commit :log_previous_state_for_create
before_update :log_previous_state_for_update
after_destroy_commit :log_previous_state_for_destroy
belongs_to :namespace
belongs_to :hosted_plan, class_name: 'Plan'
......@@ -56,6 +59,32 @@ class GitlabSubscription < ApplicationRecord
private
def log_previous_state_for_create
log_previous_state_to_history(:gitlab_subscription_created)
end
def log_previous_state_for_update
attrs = self.attributes.merge(self.attributes_in_database)
log_previous_state_to_history(:gitlab_subscription_updated, attrs)
end
def log_previous_state_for_destroy
attrs = self.attributes
log_previous_state_to_history(:gitlab_subscription_destroyed, attrs)
end
def log_previous_state_to_history(change_type, attrs = {})
attrs['gitlab_subscription_created_at'] = attrs['created_at']
attrs['gitlab_subscription_updated_at'] = attrs['updated_at']
attrs['gitlab_subscription_id'] = self.id
attrs['change_type'] = change_type
omitted_attrs = %w(id created_at updated_at)
attrs.reject! { |k, v| omitted_attrs.include?(k) }
GitlabSubscriptionHistory.create(attrs)
end
def hosted?
namespace_id.present?
end
......
# frozen_string_literal: true
class GitlabSubscriptionHistory < ApplicationRecord
enum change_type: [:gitlab_subscription_created,
:gitlab_subscription_updated,
:gitlab_subscription_destroyed]
end
---
title: Log history for gitlab_subscriptions table
merge_request: 19694
author:
type: added
......@@ -231,4 +231,68 @@ describe GitlabSubscription do
end
end
end
describe 'callbacks' do
it 'gitlab_subscription columns are contained in gitlab_subscription_history columns' do
diff_attrs = %w(updated_at)
expect(described_class.attribute_names - GitlabSubscriptionHistory.attribute_names).to eq(diff_attrs)
end
it 'gitlab_subscription_history columns have some extra columns over gitlab_subscription' do
diff_attrs = %w(gitlab_subscription_created_at gitlab_subscription_updated_at change_type gitlab_subscription_id)
expect(GitlabSubscriptionHistory.attribute_names - described_class.attribute_names).to eq(diff_attrs)
end
context 'after_create_commit' do
it 'logs previous state to gitlab subscription history' do
subject.save
expect(GitlabSubscriptionHistory.count).to eq(1)
expected_attrs = {
'gitlab_subscription_id' => subject.id,
'change_type' => 'gitlab_subscription_created'
}
expect(GitlabSubscriptionHistory.last.attributes).to include(expected_attrs)
end
end
context 'before_update' do
it 'logs previous state to gitlab subscription history' do
subject.update max_seats_used: 42, seats: 13
subject.update max_seats_used: 32
expect(GitlabSubscriptionHistory.count).to eq(2)
expected_attrs = {
'gitlab_subscription_id' => subject.id,
'change_type' => 'gitlab_subscription_updated',
'max_seats_used' => 42,
'seats' => 13
}
expect(GitlabSubscriptionHistory.last.attributes).to include(expected_attrs)
end
end
context 'after_destroy_commit' do
it 'logs previous state to gitlab subscription history' do
group = create(:group)
plan = create(:bronze_plan)
subject.update max_seats_used: 37, seats: 11, namespace: group, hosted_plan: plan
db_created_at = described_class.last.created_at
subject.destroy
expect(GitlabSubscriptionHistory.count).to eq(2)
expected_attrs = {
'gitlab_subscription_id' => subject.id,
'change_type' => 'gitlab_subscription_destroyed',
'max_seats_used' => 37,
'seats' => 11,
'namespace_id' => group.id,
'hosted_plan_id' => plan.id,
'gitlab_subscription_created_at' => db_created_at
}
expect(GitlabSubscriptionHistory.last.attributes).to include(expected_attrs)
end
end
end
end
......@@ -43,6 +43,7 @@ describe 'Database schema' do
geo_nodes: %w[oauth_application_id],
geo_repository_deleted_events: %w[project_id],
geo_upload_deleted_events: %w[upload_id model_id],
gitlab_subscription_histories: %w[gitlab_subscription_id hosted_plan_id namespace_id],
import_failures: %w[project_id],
identities: %w[user_id],
issues: %w[last_edited_by_id state_id],
......
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