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.
This commit is contained in:
Shivam Mishra
2025-01-21 14:49:44 +05:30
parent 64596722c0
commit 9c0e7b1897
3 changed files with 26 additions and 21 deletions
+12 -10
View File
@@ -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?
+8 -8
View File
@@ -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
@@ -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',