From 9c0e7b1897aa0bad6c0b539f352f62a745d129f2 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Tue, 21 Jan 2025 14:49:44 +0530 Subject: [PATCH] feat: swap limits and custom attributes We will store the usage in custom attributes and the max allowed in limits, this is much more aligned semantically in comparison to the previous implementation. --- enterprise/app/models/enterprise/account.rb | 22 ++++++++++--------- spec/enterprise/models/account_spec.rb | 16 +++++++------- .../handle_stripe_event_service_spec.rb | 9 +++++--- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/enterprise/app/models/enterprise/account.rb b/enterprise/app/models/enterprise/account.rb index 869843e3b..61ca742ed 100644 --- a/enterprise/app/models/enterprise/account.rb +++ b/enterprise/app/models/enterprise/account.rb @@ -1,6 +1,8 @@ module Enterprise::Account CAPTAIN_RESPONSES = 'captain_responses'.freeze CAPTAIN_DOCUMENTS = 'captain_documents'.freeze + CAPTAIN_RESPONSES_USAGE = 'captain_responses_usage'.freeze + CAPTAIN_DOCUMENTS_USAGE = 'captain_documents_usage'.freeze def usage_limits { @@ -14,19 +16,19 @@ module Enterprise::Account end def increment_response_usage - current_usage = self[:limits][CAPTAIN_RESPONSES].to_i || 0 - self[:limits][CAPTAIN_RESPONSES] = current_usage + 1 + current_usage = custom_attributes[CAPTAIN_RESPONSES_USAGE].to_i || 0 + custom_attributes[CAPTAIN_RESPONSES_USAGE] = current_usage + 1 save end def reset_response_usage - self[:limits][CAPTAIN_RESPONSES] = 0 + custom_attributes[CAPTAIN_RESPONSES_USAGE] = 0 save end def update_document_usage # this will ensure that the document count is always accurate - self[:limits][CAPTAIN_DOCUMENTS] = captain_documents.count + custom_attributes[CAPTAIN_DOCUMENTS_USAGE] = captain_documents.count save end @@ -38,11 +40,11 @@ module Enterprise::Account end def captain_monthly_limit - default_limits = default_captain_limit + default_limits = default_captain_limits { - documents: custom_attributes['captain_document_limit'] || default_limits['documents'], - responses: custom_attributes['captain_response_limit'] || default_limits['responses'] + documents: self[:limits][CAPTAIN_DOCUMENTS] || default_limits['documents'], + responses: self[:limits][CAPTAIN_RESPONSES] || default_limits['responses'] }.with_indifferent_access end @@ -52,9 +54,9 @@ module Enterprise::Account total_count = captain_monthly_limit[type.to_s].to_i consumed = if type == :documents - self[:limits][CAPTAIN_DOCUMENTS].to_i || 0 + custom_attributes[CAPTAIN_DOCUMENTS_USAGE].to_i || 0 else - self[:limits][CAPTAIN_RESPONSES].to_i || 0 + custom_attributes[CAPTAIN_RESPONSES_USAGE].to_i || 0 end consumed = 0 if consumed.negative? @@ -66,7 +68,7 @@ module Enterprise::Account } end - def default_captain_limit + def default_captain_limits default_value = { documents: ChatwootApp.max_limit, responses: ChatwootApp.max_limit }.with_indifferent_access return default_value if plan_name.blank? diff --git a/spec/enterprise/models/account_spec.rb b/spec/enterprise/models/account_spec.rb index 894fabca6..ed72409cd 100644 --- a/spec/enterprise/models/account_spec.rb +++ b/spec/enterprise/models/account_spec.rb @@ -51,13 +51,13 @@ RSpec.describe Account, type: :model do ## Document it 'updates document count accurately' do account.update_document_usage - expect(account.limits['captain_documents']).to eq(3) + expect(account.custom_attributes['captain_documents_usage']).to eq(3) end it 'handles zero documents' do account.captain_documents.destroy_all account.update_document_usage - expect(account.limits['captain_documents']).to eq(0) + expect(account.custom_attributes['captain_documents_usage']).to eq(0) end it 'reflects document limits' do @@ -73,13 +73,13 @@ RSpec.describe Account, type: :model do responses_limits = account.usage_limits[:captain][:responses] - expect(account.limits['captain_responses']).to eq 1 + expect(account.custom_attributes['captain_responses_usage']).to eq 1 expect(responses_limits[:consumed]).to eq 1 expect(responses_limits[:current_available]).to eq captain_limits[:startups][:responses] - 1 end it 'reseting responses limits updates usage_limits' do - account.limits['captain_responses'] = 30 + account.custom_attributes['captain_responses_usage'] = 30 account.save! responses_limits = account.usage_limits[:captain][:responses] @@ -90,7 +90,7 @@ RSpec.describe Account, type: :model do account.reset_response_usage responses_limits = account.usage_limits[:captain][:responses] - expect(account.limits['captain_responses']).to eq 0 + expect(account.custom_attributes['captain_responses_usage']).to eq 0 expect(responses_limits[:consumed]).to eq 0 expect(responses_limits[:current_available]).to eq captain_limits[:startups][:responses] end @@ -104,14 +104,14 @@ RSpec.describe Account, type: :model do end it 'current_available is never out of bounds' do - account.limits['captain_responses'] = 3000 + account.custom_attributes['captain_responses_usage'] = 3000 account.save! responses_limits = account.usage_limits[:captain][:responses] expect(responses_limits[:consumed]).to eq 3000 expect(responses_limits[:current_available]).to eq 0 - account.limits['captain_responses'] = -100 + account.custom_attributes['captain_responses_usage'] = -100 account.save! responses_limits = account.usage_limits[:captain][:responses] @@ -132,7 +132,7 @@ RSpec.describe Account, type: :model do describe 'when limits are configured for an account' do before do create(:installation_config, name: 'CAPTAIN_CLOUD_PLAN_LIMITS', value: captain_limits.to_json) - account.update(custom_attributes: { captain_document_limit: 5555, captain_response_limit: 9999 }) + account.update(limits: { captain_documents: 5555, captain_responses: 9999 }) end it 'returns limits based on custom attributes' do diff --git a/spec/enterprise/services/enterprise/billing/handle_stripe_event_service_spec.rb b/spec/enterprise/services/enterprise/billing/handle_stripe_event_service_spec.rb index 2e2ce7d09..d6d2e187e 100644 --- a/spec/enterprise/services/enterprise/billing/handle_stripe_event_service_spec.rb +++ b/spec/enterprise/services/enterprise/billing/handle_stripe_event_service_spec.rb @@ -44,6 +44,7 @@ describe Enterprise::Billing::HandleStripeEventService do stripe_event_service.new.perform(event: event) expect(account.reload.custom_attributes).to eq({ + 'captain_responses_usage' => 0, 'stripe_customer_id' => 'cus_123', 'stripe_price_id' => 'test', 'stripe_product_id' => 'plan_id', @@ -55,14 +56,14 @@ describe Enterprise::Billing::HandleStripeEventService do end it 'resets captain usage' do - account.increment_response_usage - expect(account.limits['captain_responses']).to eq(1) + 5.times { account.increment_response_usage } + expect(account.custom_attributes['captain_responses_usage']).to eq(5) allow(event).to receive(:type).and_return('customer.subscription.updated') allow(subscription).to receive(:customer).and_return('cus_123') stripe_event_service.new.perform(event: event) - expect(account.reload.limits['captain_responses']).to eq(0) + expect(account.reload.custom_attributes['captain_responses_usage']).to eq(0) end end @@ -71,6 +72,7 @@ describe Enterprise::Billing::HandleStripeEventService do allow(subscription).to receive(:customer).and_return('cus_123') stripe_event_service.new.perform(event: event) expect(account.reload.custom_attributes).to eq({ + 'captain_responses_usage' => 0, 'stripe_customer_id' => 'cus_123', 'stripe_price_id' => 'test', 'stripe_product_id' => 'plan_id', @@ -110,6 +112,7 @@ describe Enterprise::Billing::HandleStripeEventService do allow(subscription).to receive(:customer).and_return('cus_123') stripe_event_service.new.perform(event: event) expect(account.reload.custom_attributes).to eq({ + 'captain_responses_usage' => 0, 'stripe_customer_id' => 'cus_123', 'stripe_price_id' => 'test', 'stripe_product_id' => 'plan_id_2',