@@ -44,7 +53,7 @@
<% if ChatwootHub.pricing_plan != 'community' && User.count > ChatwootHub.pricing_plan_quantity %>
-
You have <%= User.count %> agents. Please add more licenses.
+
You have <%= User.count %> agents. Please add more licenses to add more users.
<% end %>
diff --git a/config/features.yml b/config/features.yml
index 1bb355fc8..529ad37d9 100644
--- a/config/features.yml
+++ b/config/features.yml
@@ -11,6 +11,7 @@
enabled: false
- name: disable_branding
enabled: false
+ premium: true
- name: email_continuity_on_api_channel
enabled: false
- name: help_center
@@ -55,9 +56,13 @@
enabled: false
- name: audit_logs
enabled: false
+ premium: true
- name: response_bot
enabled: false
+ premium: true
- name: message_reply_to
enabled: false
- name: insert_article_in_reply
enabled: false
+- name: inbox_view
+ enabled: false
diff --git a/config/initializers/rack_attack.rb b/config/initializers/rack_attack.rb
index 3c6b7611f..99974f4f7 100644
--- a/config/initializers/rack_attack.rb
+++ b/config/initializers/rack_attack.rb
@@ -94,6 +94,11 @@ class Rack::Attack
end
end
+ ## Resend confirmation throttling
+ throttle('resend_confirmation/ip', limit: 5, period: 30.minutes) do |req|
+ req.ip if req.path_without_extentions == '/api/v1/profile/resend_confirmation' && req.post?
+ end
+
## Prevent Brute-Force Signup Attacks ###
throttle('accounts/ip', limit: 5, period: 30.minutes) do |req|
req.ip if req.path_without_extentions == '/api/v1/accounts' && req.post?
diff --git a/config/installation_config.yml b/config/installation_config.yml
index 0778ab922..2643461e2 100644
--- a/config/installation_config.yml
+++ b/config/installation_config.yml
@@ -1,5 +1,20 @@
-# if you don't specify locked attribute, the default value will be true
-# which means the particular config will be locked
+# This file contains all the installation wide configuration which controls various settings in Chatwoot
+# This is internal config and should not be modified by the user directly in database
+# Chatwoot might override and modify these values during the upgrade process
+# Configs which can be modified by the user are available in the dashboard under appropriate UI
+#
+# name: the name of the config referenced in the code
+# value: the value of the config
+# display_title: the title of the config displayed in the dashboard UI
+# description: the description of the config displayed in the dashboard UI
+# locked: if you don't specify locked attribute in yaml, the default value will be true,
+# which means the particular config will be locked and won't be available in `super_admin/installation_configs`
+# premium: These values get overwritten unless the user is on a premium plan
+# type: The type of the config. Default is text, boolean is also supported
+
+
+
+# ------- Branding Related Config ------- #
- name: INSTALLATION_NAME
value: 'Chatwoot'
display_title: 'Installation Name'
@@ -41,32 +56,20 @@
display_title: 'Chatwoot Metadata'
description: 'Display default Chatwoot metadata like favicons and upgrade warnings'
type: boolean
-- name: MAILER_INBOUND_EMAIL_DOMAIN
- value:
- locked: false
-- name: MAILER_SUPPORT_EMAIL
- value:
+# ------- End of Branding Related Config ------- #
+
+
+
+# ------- Signup & Account Related Config ------- #
+- name: ENABLE_ACCOUNT_SIGNUP
+ display_title: 'Enable Account Signup'
+ value: false
+ description: 'Allow users to signup for new accounts'
locked: false
+ type: boolean
- name: CREATE_NEW_ACCOUNT_FROM_DASHBOARD
value: false
- locked: false
-- name: INSTALLATION_EVENTS_WEBHOOK_URL
- value:
- locked: false
-- name: CHATWOOT_INBOX_TOKEN
- value:
- locked: false
-- name: CHATWOOT_INBOX_HMAC_KEY
- value:
- locked: false
-- name: API_CHANNEL_NAME
- value:
-- name: API_CHANNEL_THUMBNAIL
- value:
-- name: ANALYTICS_TOKEN
- value:
-- name: DIRECT_UPLOADS_ENABLED
- value: false
+ description: 'Allow users to create new accounts from the dashboard'
locked: false
- name: HCAPTCHA_SITE_KEY
value:
@@ -74,34 +77,107 @@
- name: HCAPTCHA_SERVER_KEY
value:
locked: false
-- name: LOGOUT_REDIRECT_LINK
- value: /app/login
+- name: INSTALLATION_EVENTS_WEBHOOK_URL
+ value:
+ display_title: 'System events Webhook URL'
+ description: 'The URL to which the system events like new accounts created will be sent'
locked: false
-- name: DISABLE_USER_PROFILE_UPDATE
+- name: DIRECT_UPLOADS_ENABLED
+ type: boolean
value: false
+ description: 'Enable direct uploads to cloud storage'
+ locked: false
+# ------- End of Account Related Config ------- #
+
+
+
+# ------- Email Related Config ------- #
+- name: MAILER_INBOUND_EMAIL_DOMAIN
+ value:
+ description: 'The domain name to be used for generating conversation continuity emails (reply+id@domain.com)'
+ locked: false
+- name: MAILER_SUPPORT_EMAIL
+ value:
+ locked: false
+# ------- End of Email Related Config ------- #
+
+
+# ------- Facebook Channel Related Config ------- #
+- name: FB_APP_ID
+ display_title: 'Facebook App ID'
+ locked: false
+- name: FB_VERIFY_TOKEN
+ display_title: 'Facebook Verify Token'
+ description: 'The verify token used for Facebook Messenger Webhook'
+ locked: false
+- name: FB_APP_SECRET
+ display_title: 'Facebook App Secret'
+ locked: false
+- name: IG_VERIFY_TOKEN
+ display_title: 'Instagram Verify Token'
+ description: 'The verify token used for Instagram Webhook'
locked: false
- name: ENABLE_MESSENGER_CHANNEL_HUMAN_AGENT
+ display_title: 'Enable human agent'
value: false
locked: false
-- name: CSML_BOT_HOST
+ description: 'Enable human agent for messenger channel for longer message back period. Needs additional app approval: https://developers.facebook.com/docs/features-reference/human-agent/'
+ type: boolean
+# ------- End of Facebook Channel Related Config ------- #
+
+# ------- Chatwoot Internal Config for Cloud ----#
+- name: CHATWOOT_INBOX_TOKEN
value:
+ description: 'The Chatwoot Inbox Token for Contact Support in Cloud'
locked: false
-- name: CSML_BOT_API_KEY
+- name: CHATWOOT_INBOX_HMAC_KEY
value:
+ description: 'The Chatwoot Inbox HMAC Key for Contact Support in Cloud'
locked: false
- name: CHATWOOT_CLOUD_PLANS
value:
+ description: 'Config to store stripe plans for cloud'
- name: DEPLOYMENT_ENV
value: self-hosted
-- name: CSML_EDITOR_HOST
+ description: 'The deployment environment of the installation, to differentiate between Chatwoot cloud and self-hosted'
+- name: ANALYTICS_TOKEN
value:
+ description: 'The June.so analytics token for Chatwoot cloud'
+# ------- End of Chatwoot Internal Config for Cloud ----#
+
+
+# ------- Chatwoot Internal Config for Self Hosted ----#
- name: INSTALLATION_PRICING_PLAN
value: 'community'
+ description: 'The pricing plan for the installation, retrieved from the billing API'
- name: INSTALLATION_PRICING_PLAN_QUANTITY
value: 0
+ description: 'The number of licenses purchased for the installation, retrieved from the billing API'
- name: CHATWOOT_SUPPORT_WEBSITE_TOKEN
value:
+ description: 'The Chatwoot website token, used to identify the Chatwoot inbox and display the "Contact Support" option on the billing page'
- name: CHATWOOT_SUPPORT_SCRIPT_URL
value:
+ description: 'The Chatwoot script base URL, to display the "Contact Support" option on the billing page'
- name: CHATWOOT_SUPPORT_IDENTIFIER_HASH
value:
+ description: 'The Chatwoot identifier hash, to validate the contact in the live chat window.'
+# ------- End of Chatwoot Internal Config for Self Hosted ----#
+
+## ------ Configs added for enterprise clients ------ ##
+- name: API_CHANNEL_NAME
+ value:
+ description: 'Custom name for the API channel'
+- name: API_CHANNEL_THUMBNAIL
+ value:
+ description: 'Custom thumbnail for the API channel'
+- name: LOGOUT_REDIRECT_LINK
+ value: /app/login
+ locked: false
+ description: 'Redirect to a different link after logout'
+- name: DISABLE_USER_PROFILE_UPDATE
+ value: false
+ locked: false
+ description: 'Disable rendering profile update page for users'
+
+## ------ End of Configs added for enterprise clients ------ ##
\ No newline at end of file
diff --git a/config/locales/en.yml b/config/locales/en.yml
index e6629ae8d..da4f35032 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -45,6 +45,7 @@ en:
disposable_email: We do not allow disposable emails
invalid_email: You have entered an invalid email
email_already_exists: "You have already signed up for an account with %{email}"
+ invalid_params: 'Invalid, please check the signup paramters and try again'
failed: Signup failed
data_import:
data_type:
diff --git a/config/routes.rb b/config/routes.rb
index ec838c107..210d5bc0e 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -44,7 +44,9 @@ Rails.application.routes.draw do
resource :contact_merge, only: [:create]
end
resource :bulk_actions, only: [:create]
- resources :agents, only: [:index, :create, :update, :destroy]
+ resources :agents, only: [:index, :create, :update, :destroy] do
+ post :bulk_create, on: :collection
+ end
resources :agent_bots, only: [:index, :create, :show, :update, :destroy] do
delete :avatar, on: :member
end
@@ -173,9 +175,11 @@ Rails.application.routes.draw do
collection do
post :read_all
get :unread_count
+ post :destroy_all
end
member do
post :snooze
+ post :unread
end
end
resource :notification_settings, only: [:show, :update]
@@ -247,6 +251,7 @@ Rails.application.routes.draw do
post :availability
post :auto_offline
put :set_active_account
+ post :resend_confirmation
end
end
@@ -287,16 +292,18 @@ Rails.application.routes.draw do
end
namespace :v2 do
- resources :accounts, only: [], module: :accounts do
- resources :reports, only: [:index] do
- collection do
- get :summary
- get :agents
- get :inboxes
- get :labels
- get :teams
- get :conversations
- get :conversation_traffic
+ resources :accounts, only: [:create] do
+ scope module: :accounts do
+ resources :reports, only: [:index] do
+ collection do
+ get :summary
+ get :agents
+ get :inboxes
+ get :labels
+ get :teams
+ get :conversations
+ get :conversation_traffic
+ end
end
end
end
diff --git a/db/migrate/20200225162150_init_schema.rb b/db/migrate/20200225162150_init_schema.rb
deleted file mode 100644
index 9b6bd39c3..000000000
--- a/db/migrate/20200225162150_init_schema.rb
+++ /dev/null
@@ -1,280 +0,0 @@
-class InitSchema < ActiveRecord::Migration[6.0]
- def up
- # These are extensions that must be enabled in order to support this database
- enable_extension 'plpgsql'
- create_table 'account_users' do |t|
- t.bigint 'account_id'
- t.bigint 'user_id'
- t.integer 'role', default: 0
- t.bigint 'inviter_id'
- t.datetime 'created_at', precision: 6, null: false
- t.datetime 'updated_at', precision: 6, null: false
- t.index %w[account_id user_id], name: 'uniq_user_id_per_account_id', unique: true
- t.index ['account_id'], name: 'index_account_users_on_account_id'
- t.index ['user_id'], name: 'index_account_users_on_user_id'
- end
- create_table 'accounts', id: :serial do |t|
- t.string 'name', null: false
- t.datetime 'created_at', null: false
- t.datetime 'updated_at', null: false
- end
- create_table 'active_storage_attachments' do |t|
- t.string 'name', null: false
- t.string 'record_type', null: false
- t.bigint 'record_id', null: false
- t.bigint 'blob_id', null: false
- t.datetime 'created_at', null: false
- t.index ['blob_id'], name: 'index_active_storage_attachments_on_blob_id'
- t.index %w[record_type record_id name blob_id], name: 'index_active_storage_attachments_uniqueness', unique: true
- end
- create_table 'active_storage_blobs' do |t|
- t.string 'key', null: false
- t.string 'filename', null: false
- t.string 'content_type'
- t.text 'metadata'
- t.bigint 'byte_size', null: false
- t.string 'checksum', null: false
- t.datetime 'created_at', null: false
- t.index ['key'], name: 'index_active_storage_blobs_on_key', unique: true
- end
- create_table 'agent_bot_inboxes' do |t|
- t.integer 'inbox_id'
- t.integer 'agent_bot_id'
- t.integer 'status', default: 0
- t.datetime 'created_at', precision: 6, null: false
- t.datetime 'updated_at', precision: 6, null: false
- end
- create_table 'agent_bots' do |t|
- t.string 'name'
- t.string 'description'
- t.string 'outgoing_url'
- t.string 'auth_token'
- t.datetime 'created_at', precision: 6, null: false
- t.datetime 'updated_at', precision: 6, null: false
- end
- create_table 'attachments', id: :serial do |t|
- t.integer 'file_type', default: 0
- t.string 'external_url'
- t.float 'coordinates_lat', default: 0.0
- t.float 'coordinates_long', default: 0.0
- t.integer 'message_id', null: false
- t.integer 'account_id', null: false
- t.datetime 'created_at', null: false
- t.datetime 'updated_at', null: false
- t.string 'fallback_title'
- t.string 'extension'
- end
- create_table 'canned_responses', id: :serial do |t|
- t.integer 'account_id', null: false
- t.string 'short_code'
- t.text 'content'
- t.datetime 'created_at', null: false
- t.datetime 'updated_at', null: false
- end
- create_table 'channel_facebook_pages', id: :serial do |t|
- t.string 'name', null: false
- t.string 'page_id', null: false
- t.string 'user_access_token', null: false
- t.string 'page_access_token', null: false
- t.integer 'account_id', null: false
- t.datetime 'created_at', null: false
- t.datetime 'updated_at', null: false
- t.index %w[page_id account_id], name: 'index_channel_facebook_pages_on_page_id_and_account_id', unique: true
- t.index ['page_id'], name: 'index_channel_facebook_pages_on_page_id'
- end
- create_table 'channel_twitter_profiles' do |t|
- t.string 'name'
- t.string 'profile_id', null: false
- t.string 'twitter_access_token', null: false
- t.string 'twitter_access_token_secret', null: false
- t.integer 'account_id', null: false
- t.datetime 'created_at', precision: 6, null: false
- t.datetime 'updated_at', precision: 6, null: false
- end
- create_table 'channel_web_widgets', id: :serial do |t|
- t.string 'website_name'
- t.string 'website_url'
- t.integer 'account_id'
- t.datetime 'created_at', null: false
- t.datetime 'updated_at', null: false
- t.string 'website_token'
- t.string 'widget_color', default: '#1f93ff'
- t.index ['website_token'], name: 'index_channel_web_widgets_on_website_token', unique: true
- end
- create_table 'contact_inboxes' do |t|
- t.bigint 'contact_id'
- t.bigint 'inbox_id'
- t.string 'source_id', null: false
- t.datetime 'created_at', precision: 6, null: false
- t.datetime 'updated_at', precision: 6, null: false
- t.index ['contact_id'], name: 'index_contact_inboxes_on_contact_id'
- t.index %w[inbox_id source_id], name: 'index_contact_inboxes_on_inbox_id_and_source_id', unique: true
- t.index ['inbox_id'], name: 'index_contact_inboxes_on_inbox_id'
- t.index ['source_id'], name: 'index_contact_inboxes_on_source_id'
- end
- create_table 'contacts', id: :serial do |t|
- t.string 'name'
- t.string 'email'
- t.string 'phone_number'
- t.integer 'account_id', null: false
- t.datetime 'created_at', null: false
- t.datetime 'updated_at', null: false
- t.string 'pubsub_token'
- t.jsonb 'additional_attributes'
- t.index ['account_id'], name: 'index_contacts_on_account_id'
- t.index ['pubsub_token'], name: 'index_contacts_on_pubsub_token', unique: true
- end
- create_table 'conversations', id: :serial do |t|
- t.integer 'account_id', null: false
- t.integer 'inbox_id', null: false
- t.integer 'status', default: 0, null: false
- t.integer 'assignee_id'
- t.datetime 'created_at', null: false
- t.datetime 'updated_at', null: false
- t.bigint 'contact_id'
- t.integer 'display_id', null: false
- t.datetime 'user_last_seen_at'
- t.datetime 'agent_last_seen_at'
- t.boolean 'locked', default: false
- t.jsonb 'additional_attributes'
- t.bigint 'contact_inbox_id'
- t.index %w[account_id display_id], name: 'index_conversations_on_account_id_and_display_id', unique: true
- t.index ['account_id'], name: 'index_conversations_on_account_id'
- t.index ['contact_inbox_id'], name: 'index_conversations_on_contact_inbox_id'
- end
- create_table 'inbox_members', id: :serial do |t|
- t.integer 'user_id', null: false
- t.integer 'inbox_id', null: false
- t.datetime 'created_at', null: false
- t.datetime 'updated_at', null: false
- t.index ['inbox_id'], name: 'index_inbox_members_on_inbox_id'
- end
- create_table 'inboxes', id: :serial do |t|
- t.integer 'channel_id', null: false
- t.integer 'account_id', null: false
- t.string 'name', null: false
- t.datetime 'created_at', null: false
- t.datetime 'updated_at', null: false
- t.string 'channel_type'
- t.boolean 'enable_auto_assignment', default: true
- t.index ['account_id'], name: 'index_inboxes_on_account_id'
- end
- create_table 'messages', id: :serial do |t|
- t.text 'content'
- t.integer 'account_id', null: false
- t.integer 'inbox_id', null: false
- t.integer 'conversation_id', null: false
- t.integer 'message_type', null: false
- t.datetime 'created_at', null: false
- t.datetime 'updated_at', null: false
- t.boolean 'private', default: false
- t.integer 'user_id'
- t.integer 'status', default: 0
- t.string 'source_id'
- t.integer 'content_type', default: 0
- t.json 'content_attributes', default: {}
- t.bigint 'contact_id'
- t.index ['contact_id'], name: 'index_messages_on_contact_id'
- t.index ['conversation_id'], name: 'index_messages_on_conversation_id'
- t.index ['source_id'], name: 'index_messages_on_source_id'
- end
- create_table 'notification_settings' do |t|
- t.integer 'account_id'
- t.integer 'user_id'
- t.integer 'email_flags', default: 0, null: false
- t.datetime 'created_at', precision: 6, null: false
- t.datetime 'updated_at', precision: 6, null: false
- t.index %w[account_id user_id], name: 'by_account_user', unique: true
- end
- create_table 'subscriptions', id: :serial do |t|
- t.string 'pricing_version'
- t.integer 'account_id'
- t.datetime 'expiry'
- t.string 'billing_plan', default: 'trial'
- t.string 'stripe_customer_id'
- t.datetime 'created_at', null: false
- t.datetime 'updated_at', null: false
- t.integer 'state', default: 0
- t.boolean 'payment_source_added', default: false
- end
- create_table 'taggings', id: :serial do |t|
- t.integer 'tag_id'
- t.string 'taggable_type'
- t.integer 'taggable_id'
- t.string 'tagger_type'
- t.integer 'tagger_id'
- t.string 'context', limit: 128
- t.datetime 'created_at'
- t.index ['context'], name: 'index_taggings_on_context'
- t.index %w[tag_id taggable_id taggable_type context tagger_id tagger_type], name: 'taggings_idx', unique: true
- t.index ['tag_id'], name: 'index_taggings_on_tag_id'
- t.index %w[taggable_id taggable_type context], name: 'index_taggings_on_taggable_id_and_taggable_type_and_context'
- t.index %w[taggable_id taggable_type tagger_id context], name: 'taggings_idy'
- t.index ['taggable_id'], name: 'index_taggings_on_taggable_id'
- t.index %w[taggable_type taggable_id], name: 'index_taggings_on_taggable_type_and_taggable_id'
- t.index ['taggable_type'], name: 'index_taggings_on_taggable_type'
- t.index %w[tagger_id tagger_type], name: 'index_taggings_on_tagger_id_and_tagger_type'
- t.index ['tagger_id'], name: 'index_taggings_on_tagger_id'
- t.index %w[tagger_type tagger_id], name: 'index_taggings_on_tagger_type_and_tagger_id'
- end
- create_table 'tags', id: :serial do |t|
- t.string 'name'
- t.integer 'taggings_count', default: 0
- t.index ['name'], name: 'index_tags_on_name', unique: true
- end
- create_table 'telegram_bots', id: :serial do |t|
- t.string 'name'
- t.string 'auth_key'
- t.integer 'account_id'
- t.datetime 'created_at', null: false
- t.datetime 'updated_at', null: false
- end
- create_table 'users', id: :serial do |t|
- t.string 'provider', default: 'email', null: false
- t.string 'uid', default: '', null: false
- t.string 'encrypted_password', default: '', null: false
- t.string 'reset_password_token'
- t.datetime 'reset_password_sent_at'
- t.datetime 'remember_created_at'
- t.integer 'sign_in_count', default: 0, null: false
- t.datetime 'current_sign_in_at'
- t.datetime 'last_sign_in_at'
- t.string 'current_sign_in_ip'
- t.string 'last_sign_in_ip'
- t.string 'confirmation_token'
- t.datetime 'confirmed_at'
- t.datetime 'confirmation_sent_at'
- t.string 'unconfirmed_email'
- t.string 'name', null: false
- t.string 'nickname'
- t.string 'email'
- t.json 'tokens'
- t.datetime 'created_at', null: false
- t.datetime 'updated_at', null: false
- t.string 'pubsub_token'
- t.index ['email'], name: 'index_users_on_email'
- t.index ['pubsub_token'], name: 'index_users_on_pubsub_token', unique: true
- t.index ['reset_password_token'], name: 'index_users_on_reset_password_token', unique: true
- t.index %w[uid provider], name: 'index_users_on_uid_and_provider', unique: true
- end
- create_table 'webhooks' do |t|
- t.integer 'account_id'
- t.integer 'inbox_id'
- t.string 'url'
- t.datetime 'created_at', precision: 6, null: false
- t.datetime 'updated_at', precision: 6, null: false
- t.integer 'webhook_type', default: 0
- end
- add_foreign_key 'account_users', 'accounts'
- add_foreign_key 'account_users', 'users'
- add_foreign_key 'active_storage_attachments', 'active_storage_blobs', column: 'blob_id'
- add_foreign_key 'contact_inboxes', 'contacts'
- add_foreign_key 'contact_inboxes', 'inboxes'
- add_foreign_key 'conversations', 'contact_inboxes'
- add_foreign_key 'messages', 'contacts'
- end
-
- def down
- raise ActiveRecord::IrreversibleMigration, 'The initial migration is not revertable'
- end
-end
diff --git a/db/migrate/20200309170810_create_access_tokens.rb b/db/migrate/20200309170810_create_access_tokens.rb
deleted file mode 100644
index fa6cf8058..000000000
--- a/db/migrate/20200309170810_create_access_tokens.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-class CreateAccessTokens < ActiveRecord::Migration[6.0]
- def change
- create_table :access_tokens do |t|
- t.references :owner, polymorphic: true, index: true
- t.string :token, index: { unique: true }
- t.timestamps
- end
-
- remove_column :agent_bots, :auth_token, :string
-
- [::User, ::AgentBot].each do |access_tokenable|
- generate_access_tokens(access_tokenable)
- end
- end
-
- def generate_access_tokens(access_tokenable)
- access_tokenable.find_in_batches do |record_batch|
- record_batch.each do |record|
- record.create_access_token if record.access_token.blank?
- end
- end
- end
-end
diff --git a/db/migrate/20200309213132_add_account_id_to_agent_bot_inboxes.rb b/db/migrate/20200309213132_add_account_id_to_agent_bot_inboxes.rb
deleted file mode 100644
index be77b9dbc..000000000
--- a/db/migrate/20200309213132_add_account_id_to_agent_bot_inboxes.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-class AddAccountIdToAgentBotInboxes < ActiveRecord::Migration[6.0]
- def change
- add_column :agent_bot_inboxes, :account_id, :integer, index: true
-
- AgentBotInbox.all.each do |agent_bot_inbox|
- agent_bot_inbox.account_id = agent_bot_inbox.inbox.account_id
- agent_bot_inbox.save!
- end
- end
-end
diff --git a/db/migrate/20200310062527_create_events.rb b/db/migrate/20200310062527_create_events.rb
deleted file mode 100644
index ee5492a0f..000000000
--- a/db/migrate/20200310062527_create_events.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-class CreateEvents < ActiveRecord::Migration[6.0]
- def change
- create_table :events do |t|
- t.string :name
- t.float :value
- t.integer :account_id
- t.integer :inbox_id
- t.integer :user_id
- t.integer :conversation_id
-
- t.timestamps
- end
- end
-end
diff --git a/db/migrate/20200310070540_add_index_to_event.rb b/db/migrate/20200310070540_add_index_to_event.rb
deleted file mode 100644
index 45eadea6f..000000000
--- a/db/migrate/20200310070540_add_index_to_event.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class AddIndexToEvent < ActiveRecord::Migration[6.0]
- def change
- add_index :events, :name
- add_index :events, :created_at
- add_index :events, :account_id
- add_index :events, :inbox_id
- add_index :events, :user_id
- end
-end
diff --git a/db/migrate/20200311083854_add_index_to_message.rb b/db/migrate/20200311083854_add_index_to_message.rb
deleted file mode 100644
index 7ad85e78f..000000000
--- a/db/migrate/20200311083854_add_index_to_message.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class AddIndexToMessage < ActiveRecord::Migration[6.0]
- def change
- add_index :messages, :account_id
- add_index :messages, :inbox_id
- add_index :messages, :user_id
- end
-end
diff --git a/db/migrate/20200325210612_add_locale_to_account.rb b/db/migrate/20200325210612_add_locale_to_account.rb
deleted file mode 100644
index 08ecff067..000000000
--- a/db/migrate/20200325210612_add_locale_to_account.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddLocaleToAccount < ActiveRecord::Migration[6.0]
- def change
- add_column :accounts, :locale, :integer, default: 0
- end
-end
diff --git a/db/migrate/20200330071706_create_channel_twilio_sms.rb b/db/migrate/20200330071706_create_channel_twilio_sms.rb
deleted file mode 100644
index 545c845e6..000000000
--- a/db/migrate/20200330071706_create_channel_twilio_sms.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class CreateChannelTwilioSms < ActiveRecord::Migration[6.0]
- def change
- create_table :channel_twilio_sms do |t|
- t.string :phone_number, null: false
- t.string :auth_token, null: false
- t.string :account_sid, null: false
- t.integer :account_id, null: false
- t.timestamps
- end
- end
-end
diff --git a/db/migrate/20200330115622_create_action_mailbox_tables.action_mailbox.rb b/db/migrate/20200330115622_create_action_mailbox_tables.action_mailbox.rb
deleted file mode 100644
index a5dd66e02..000000000
--- a/db/migrate/20200330115622_create_action_mailbox_tables.action_mailbox.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# This migration comes from action_mailbox (originally 20180917164000)
-class CreateActionMailboxTables < ActiveRecord::Migration[6.0]
- def change
- create_table :action_mailbox_inbound_emails do |t|
- t.integer :status, default: 0, null: false
- t.string :message_id, null: false
- t.string :message_checksum, null: false
-
- t.timestamps
-
- t.index [:message_id, :message_checksum], name: 'index_action_mailbox_inbound_emails_uniqueness', unique: true
- end
- end
-end
diff --git a/db/migrate/20200331095710_add_identifier_to_contact.rb b/db/migrate/20200331095710_add_identifier_to_contact.rb
deleted file mode 100644
index f34557c57..000000000
--- a/db/migrate/20200331095710_add_identifier_to_contact.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class AddIdentifierToContact < ActiveRecord::Migration[6.0]
- def change
- add_column :contacts, :identifier, :string, index: true, default: nil
- add_index :contacts, ['identifier', :account_id], unique: true, name: 'uniq_identifier_per_account_contact'
- add_index :contacts, ['email', :account_id], unique: true, name: 'uniq_email_per_account_contact'
- end
-end
diff --git a/db/migrate/20200404092329_add_conversation_uuid.rb b/db/migrate/20200404092329_add_conversation_uuid.rb
deleted file mode 100644
index 19de9110c..000000000
--- a/db/migrate/20200404092329_add_conversation_uuid.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-class AddConversationUuid < ActiveRecord::Migration[6.0]
- def change
- enable_extension 'pgcrypto'
- add_column :conversations, :uuid, :uuid, default: 'gen_random_uuid()', null: false
- end
-end
diff --git a/db/migrate/20200404135009_add_unique_validation_index.rb b/db/migrate/20200404135009_add_unique_validation_index.rb
deleted file mode 100644
index 7dcab8c46..000000000
--- a/db/migrate/20200404135009_add_unique_validation_index.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class AddUniqueValidationIndex < ActiveRecord::Migration[6.0]
- def change
- add_index :channel_twitter_profiles, [:account_id, :profile_id], unique: true
- add_index :channel_twilio_sms, [:account_id, :phone_number], unique: true
- add_index :webhooks, [:account_id, :url], unique: true
- end
-end
diff --git a/db/migrate/20200410145519_devise_create_super_admins.rb b/db/migrate/20200410145519_devise_create_super_admins.rb
deleted file mode 100644
index 4a74847dc..000000000
--- a/db/migrate/20200410145519_devise_create_super_admins.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-# frozen_string_literal: true
-
-class DeviseCreateSuperAdmins < ActiveRecord::Migration[6.0]
- def change
- return if ActiveRecord::Base.connection.table_exists? 'super_admins'
-
- create_table :super_admins do |t|
- ## Database authenticatable
- t.string :email, null: false, default: ''
- t.string :encrypted_password, null: false, default: ''
-
- ## Recoverable
- # t.string :reset_password_token
- # t.datetime :reset_password_sent_at
-
- ## Rememberable
- t.datetime :remember_created_at
-
- ## Trackable
- t.integer :sign_in_count, default: 0, null: false
- t.datetime :current_sign_in_at
- t.datetime :last_sign_in_at
- t.inet :current_sign_in_ip
- t.inet :last_sign_in_ip
-
- ## Confirmable
- # t.string :confirmation_token
- # t.datetime :confirmed_at
- # t.datetime :confirmation_sent_at
- # t.string :unconfirmed_email # Only if using reconfirmable
-
- ## Lockable
- # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
- # t.string :unlock_token # Only if unlock strategy is :email or :both
- # t.datetime :locked_at
-
- t.timestamps null: false
- end
-
- add_index :super_admins, :email, unique: true
- # add_index :super_admins, :reset_password_token, unique: true
- # add_index :super_admins, :confirmation_token, unique: true
- # add_index :super_admins, :unlock_token, unique: true
- end
-end
diff --git a/db/migrate/20200411125638_add_domain_to_accounts.rb b/db/migrate/20200411125638_add_domain_to_accounts.rb
deleted file mode 100644
index fdb5ea8f9..000000000
--- a/db/migrate/20200411125638_add_domain_to_accounts.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class AddDomainToAccounts < ActiveRecord::Migration[6.0]
- def change
- change_table :accounts, bulk: true do |t|
- t.string :domain, limit: 100
- t.string :support_email, limit: 100
- t.integer :settings_flags, default: 0, null: false
- end
- end
-end
diff --git a/db/migrate/20200417093432_remove_name_from_channels.rb b/db/migrate/20200417093432_remove_name_from_channels.rb
deleted file mode 100644
index 1b246801d..000000000
--- a/db/migrate/20200417093432_remove_name_from_channels.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-class RemoveNameFromChannels < ActiveRecord::Migration[6.0]
- def change
- remove_column :channel_facebook_pages, :name, :string
- remove_column :channel_twitter_profiles, :name, :string
- migrate_web_widget_name_to_inbox
- remove_column :channel_web_widgets, :website_name, :string
-
- add_column :channel_web_widgets, :welcome_title, :string
- add_column :channel_web_widgets, :welcome_tagline, :string
- add_column :channel_web_widgets, :agent_away_message, :string
- purge_orphan_facebook_pages
- remove_avatars_from_channel_to_inbox
- end
-
- def purge_orphan_facebook_pages
- Channel::FacebookPage.all.each do |facebook_page|
- facebook_page.destroy! if facebook_page.inbox.nil?
- end
- end
-
- def migrate_web_widget_name_to_inbox
- Channel::WebWidget.all.each do |widget|
- widget.inbox.name = widget.website_name
- widget.save!
- end
- end
-
- def remove_avatars_from_channel_to_inbox
- Channel::FacebookPage.all.each do |facebook_page|
- next unless facebook_page.avatar
-
- facebook_page.avatar.purge
- end
- end
-end
diff --git a/db/migrate/20200418124534_add_sender_to_messages.rb b/db/migrate/20200418124534_add_sender_to_messages.rb
deleted file mode 100644
index 79a1a2a03..000000000
--- a/db/migrate/20200418124534_add_sender_to_messages.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-class AddSenderToMessages < ActiveRecord::Migration[6.0]
- def change
- add_reference :messages, :sender, polymorphic: true, index: true
- add_sender_from_message
- remove_index :messages, name: 'index_messages_on_contact_id', column: 'contact_id'
- remove_index :messages, name: 'index_messages_on_user_id', column: 'user_id'
- remove_column :messages, :user_id, :integer
- remove_column :messages, :contact_id, :integer
- end
-
- def add_sender_from_message
- ::Message.find_in_batches do |messages_batch|
- Rails.logger.info "migrated till #{messages_batch.first.id}\n"
- messages_batch.each do |message|
- # rubocop:disable Rails/SkipsModelValidations
- message.update_columns(sender_id: message.user.id, sender_type: 'User') if message.user.present?
- message.update_columns(sender_id: message.contact.id, sender_type: 'Contact') if message.contact.present?
- message.update_columns(sender_id: message.conversation.contact.id, sender_type: 'Contact') if message.sender.nil? && message.incoming?
- # rubocop:enable Rails/SkipsModelValidations
- end
- end
- end
-end
diff --git a/db/migrate/20200422130153_create_notifications.rb b/db/migrate/20200422130153_create_notifications.rb
deleted file mode 100644
index cace1f981..000000000
--- a/db/migrate/20200422130153_create_notifications.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-class CreateNotifications < ActiveRecord::Migration[6.0]
- def change
- create_table :notifications do |t|
- t.references :account, index: true, null: false
- t.references :user, index: true, null: false
- t.integer :notification_type, null: false
- t.references :primary_actor, polymorphic: true, null: false, index: { name: 'uniq_primary_actor_per_account_notifications' }
- t.references :secondary_actor, polymorphic: true, index: { name: 'uniq_secondary_actor_per_account_notifications' }
- t.timestamp :read_at, default: nil
-
- t.timestamps
- end
-
- create_table :notification_subscriptions do |t|
- t.references :user, index: true, null: false
- t.integer :subscription_type, null: false
- t.jsonb :subscription_attributes, null: false, default: '{}'
- t.timestamps
- end
-
- add_column :notification_settings, :push_flags, :integer, default: 0, null: false
- add_push_settings_to_users
- end
-
- def add_push_settings_to_users
- ::User.find_in_batches do |users_batch|
- users_batch.each do |user|
- user_notification_setting = user.notification_settings.first
- user_notification_setting.push_conversation_assignment = true
- user_notification_setting.save!
- end
- end
- end
-end
diff --git a/db/migrate/20200429082655_add_medium_to_twilio_sms.rb b/db/migrate/20200429082655_add_medium_to_twilio_sms.rb
deleted file mode 100644
index d54429104..000000000
--- a/db/migrate/20200429082655_add_medium_to_twilio_sms.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddMediumToTwilioSms < ActiveRecord::Migration[6.0]
- def change
- add_column :channel_twilio_sms, :medium, :integer, index: true, default: 0
- end
-end
diff --git a/db/migrate/20200430163438_create_integrations_hooks.rb b/db/migrate/20200430163438_create_integrations_hooks.rb
deleted file mode 100644
index 487297bf6..000000000
--- a/db/migrate/20200430163438_create_integrations_hooks.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class CreateIntegrationsHooks < ActiveRecord::Migration[6.0]
- def change
- create_table :integrations_hooks do |t|
- t.integer :status, default: 0
- t.integer :inbox_id
- t.integer :account_id
- t.string :app_id
- t.text :settings
- t.integer :hook_type, default: 0
- t.string :reference_id
- t.string :access_token
- t.timestamps
- end
- end
-end
diff --git a/db/migrate/20200503151130_add_account_feature_flag.rb b/db/migrate/20200503151130_add_account_feature_flag.rb
deleted file mode 100644
index 9b0628867..000000000
--- a/db/migrate/20200503151130_add_account_feature_flag.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddAccountFeatureFlag < ActiveRecord::Migration[6.0]
- def change
- add_column :accounts, :feature_flags, :integer, index: true, default: 0, null: false
- end
-end
diff --git a/db/migrate/20200504144712_add_index_on_notification_subscriptions.rb b/db/migrate/20200504144712_add_index_on_notification_subscriptions.rb
deleted file mode 100644
index e07285e4a..000000000
--- a/db/migrate/20200504144712_add_index_on_notification_subscriptions.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-class AddIndexOnNotificationSubscriptions < ActiveRecord::Migration[6.0]
- def change
- add_column :notification_subscriptions, :identifier, :string
- add_index :notification_subscriptions, :identifier, unique: true
- end
-end
diff --git a/db/migrate/20200509044639_add_hide_input_flag_to_bot_config.rb b/db/migrate/20200509044639_add_hide_input_flag_to_bot_config.rb
deleted file mode 100644
index 41b9cda56..000000000
--- a/db/migrate/20200509044639_add_hide_input_flag_to_bot_config.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddHideInputFlagToBotConfig < ActiveRecord::Migration[6.0]
- def change
- add_column :agent_bots, :hide_input_for_bot_conversations, :boolean, default: false
- end
-end
diff --git a/db/migrate/20200510112339_create_installation_config.rb b/db/migrate/20200510112339_create_installation_config.rb
deleted file mode 100644
index 7397bb7bf..000000000
--- a/db/migrate/20200510112339_create_installation_config.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-class CreateInstallationConfig < ActiveRecord::Migration[6.0]
- def change
- create_table :installation_configs do |t|
- t.string :name, null: false
- t.jsonb :serialized_value, null: false, default: '{}'
- t.timestamps
- end
-
- add_index :installation_configs, [:name, :created_at], unique: true
-
- ConfigLoader.new.process
- end
-end
diff --git a/db/migrate/20200510154151_add_reference_id_to_conversation.rb b/db/migrate/20200510154151_add_reference_id_to_conversation.rb
deleted file mode 100644
index 5bc0af68a..000000000
--- a/db/migrate/20200510154151_add_reference_id_to_conversation.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddReferenceIdToConversation < ActiveRecord::Migration[6.0]
- def change
- add_column :conversations, :reference_id, :string
- end
-end
diff --git a/db/migrate/20200520125815_add_active_at_to_account_users.rb b/db/migrate/20200520125815_add_active_at_to_account_users.rb
deleted file mode 100644
index b46557f53..000000000
--- a/db/migrate/20200520125815_add_active_at_to_account_users.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddActiveAtToAccountUsers < ActiveRecord::Migration[6.0]
- def change
- add_column :account_users, :active_at, :datetime, default: nil
- end
-end
diff --git a/db/migrate/20200522115645_reload_config.rb b/db/migrate/20200522115645_reload_config.rb
deleted file mode 100644
index 530ec9218..000000000
--- a/db/migrate/20200522115645_reload_config.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class ReloadConfig < ActiveRecord::Migration[6.0]
- def change
- ConfigLoader.new.process
- end
-end
diff --git a/db/migrate/20200605130625_agent_away_message_to_auto_reply.rb b/db/migrate/20200605130625_agent_away_message_to_auto_reply.rb
deleted file mode 100644
index 0cb7fa4a8..000000000
--- a/db/migrate/20200605130625_agent_away_message_to_auto_reply.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-class AgentAwayMessageToAutoReply < ActiveRecord::Migration[6.0]
- def change
- add_column :inboxes, :greeting_enabled, :boolean, default: false
- add_column :inboxes, :greeting_message, :string
-
- migrate_agent_away_to_greeting
-
- remove_column :channel_web_widgets, :agent_away_message, :string
- end
-
- def migrate_agent_away_to_greeting
- ::Channel::WebWidget.find_in_batches do |widget_batch|
- widget_batch.each do |widget|
- inbox = widget.inbox
- inbox.greeting_enabled = true
- inbox.greeting_message = widget.agent_away_message
- widget.save!
- end
- end
- end
-end
diff --git a/db/migrate/20200606132552_create_labels.rb b/db/migrate/20200606132552_create_labels.rb
deleted file mode 100644
index 81ac698e9..000000000
--- a/db/migrate/20200606132552_create_labels.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-class CreateLabels < ActiveRecord::Migration[6.0]
- def change
- create_table :labels do |t|
- t.string :title
- t.text :description
- t.string :color
- t.boolean :show_on_sidebar
- t.references :account, index: true
-
- t.timestamps
- end
- end
-end
diff --git a/db/migrate/20200607140737_remove_subscriptions.rb b/db/migrate/20200607140737_remove_subscriptions.rb
deleted file mode 100644
index 33f756083..000000000
--- a/db/migrate/20200607140737_remove_subscriptions.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class RemoveSubscriptions < ActiveRecord::Migration[6.0]
- def change
- drop_table :subscriptions do |t|
- t.string 'pricing_version'
- t.integer 'account_id'
- t.datetime 'expiry'
- t.string 'billing_plan', default: 'trial'
- t.string 'stripe_customer_id'
- t.datetime 'created_at', null: false
- t.datetime 'updated_at', null: false
- t.integer 'state', default: 0
- t.boolean 'payment_source_added', default: false
- end
- end
-end
diff --git a/db/migrate/20200610143132_rename_reference_id.rb b/db/migrate/20200610143132_rename_reference_id.rb
deleted file mode 100644
index e15e642a2..000000000
--- a/db/migrate/20200610143132_rename_reference_id.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class RenameReferenceId < ActiveRecord::Migration[6.0]
- def change
- rename_column :conversations, :reference_id, :identifier
- end
-end
diff --git a/db/migrate/20200625124400_migrate_and_add_unique_index_to_labels.rb b/db/migrate/20200625124400_migrate_and_add_unique_index_to_labels.rb
deleted file mode 100644
index 02e9fcd49..000000000
--- a/db/migrate/20200625124400_migrate_and_add_unique_index_to_labels.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-class MigrateAndAddUniqueIndexToLabels < ActiveRecord::Migration[6.0]
- def change
- add_index :labels, [:title, :account_id], unique: true
- migrate_existing_tags
- end
-
- private
-
- def migrate_existing_tags
- ::ActsAsTaggableOn::Tag.all.each do |tag|
- tag.taggings.each do |tagging|
- ensure_label_for_account(tag.name, tagging.taggable.account)
- end
- end
- end
-
- def ensure_label_for_account(name, account)
- account.labels.where(title: name.downcase).first_or_create
- end
-end
diff --git a/db/migrate/20200625154254_add_default_value_to_color.rb b/db/migrate/20200625154254_add_default_value_to_color.rb
deleted file mode 100644
index 9257cc3ae..000000000
--- a/db/migrate/20200625154254_add_default_value_to_color.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class AddDefaultValueToColor < ActiveRecord::Migration[6.0]
- def up
- Label.where(color: nil).find_each { |u| u.update(color: '#1f93ff') }
-
- change_column :labels, :color, :string, default: '#1f93ff', null: false
- end
-
- def down
- change_column :labels, :color, :string, default: nil, null: true
- end
-end
diff --git a/db/migrate/20200627115105_create_api_channel.rb b/db/migrate/20200627115105_create_api_channel.rb
deleted file mode 100644
index 3c9e92553..000000000
--- a/db/migrate/20200627115105_create_api_channel.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class CreateApiChannel < ActiveRecord::Migration[6.0]
- def change
- create_table :channel_api do |t|
- t.integer :account_id, null: false
- t.string :webhook_url, null: false
- t.timestamps
- end
- end
-end
diff --git a/db/migrate/20200629122646_add_availability_to_user.rb b/db/migrate/20200629122646_add_availability_to_user.rb
deleted file mode 100644
index dd062af15..000000000
--- a/db/migrate/20200629122646_add_availability_to_user.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddAvailabilityToUser < ActiveRecord::Migration[6.0]
- def change
- add_column :users, :availability, :integer, default: 0
- end
-end
diff --git a/db/migrate/20200704135408_create_kbase_portals.rb b/db/migrate/20200704135408_create_kbase_portals.rb
deleted file mode 100644
index 3d460456e..000000000
--- a/db/migrate/20200704135408_create_kbase_portals.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-class CreateKbasePortals < ActiveRecord::Migration[6.0]
- def change
- create_table :kbase_portals do |t|
- t.integer :account_id, null: false
- t.string :name, null: false
- t.string :slug, null: false
- t.string :custom_domain
- t.string :color
- t.string :homepage_link
- t.string :page_title
- t.text :header_text
-
- t.index :slug, unique: true
- t.timestamps
- end
- end
-end
diff --git a/db/migrate/20200704135810_create_kbase_categories.rb b/db/migrate/20200704135810_create_kbase_categories.rb
deleted file mode 100644
index 22f33bc21..000000000
--- a/db/migrate/20200704135810_create_kbase_categories.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-class CreateKbaseCategories < ActiveRecord::Migration[6.0]
- def change
- create_table :kbase_categories do |t|
- t.integer :account_id, null: false
- t.integer :portal_id, null: false
- t.string :name
- t.text :description
- t.integer :position
-
- t.timestamps
- end
- end
-end
diff --git a/db/migrate/20200704140029_create_kbase_folders.rb b/db/migrate/20200704140029_create_kbase_folders.rb
deleted file mode 100644
index d2f9f5e02..000000000
--- a/db/migrate/20200704140029_create_kbase_folders.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class CreateKbaseFolders < ActiveRecord::Migration[6.0]
- def change
- create_table :kbase_folders do |t|
- t.integer :account_id, null: false
- t.integer :category_id, null: false
- t.string :name
-
- t.timestamps
- end
- end
-end
diff --git a/db/migrate/20200704140509_create_kbase_articles.rb b/db/migrate/20200704140509_create_kbase_articles.rb
deleted file mode 100644
index 2d2e12a1f..000000000
--- a/db/migrate/20200704140509_create_kbase_articles.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-class CreateKbaseArticles < ActiveRecord::Migration[6.0]
- def change
- create_table :kbase_articles do |t|
- t.integer :account_id, null: false
- t.integer :portal_id, null: false
- t.integer :category_id
- t.integer :folder_id
- t.integer :author_id
- t.string :title
- t.text :description
- t.text :content
- t.integer :status
- t.integer :views
-
- t.timestamps
- end
- end
-end
diff --git a/db/migrate/20200704173104_add_twitter_feature_flag.rb b/db/migrate/20200704173104_add_twitter_feature_flag.rb
deleted file mode 100644
index 047313d70..000000000
--- a/db/migrate/20200704173104_add_twitter_feature_flag.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddTwitterFeatureFlag < ActiveRecord::Migration[6.0]
- def change
- ConfigLoader.new.process
- end
-end
diff --git a/db/migrate/20200709145000_remove_multiple_feature_flags.rb b/db/migrate/20200709145000_remove_multiple_feature_flags.rb
deleted file mode 100644
index a7384a529..000000000
--- a/db/migrate/20200709145000_remove_multiple_feature_flags.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-class RemoveMultipleFeatureFlags < ActiveRecord::Migration[6.0]
- def change
- current_config = InstallationConfig.where(name: 'ACCOUNT_LEVEL_FEATURE_DEFAULTS').last
- InstallationConfig.where(name: 'ACCOUNT_LEVEL_FEATURE_DEFAULTS').where.not(id: current_config.id).destroy_all
- ConfigLoader.new.process
- update_existing_accounts
- end
-
- def update_existing_accounts
- feature_config = InstallationConfig.find_by(name: 'ACCOUNT_LEVEL_FEATURE_DEFAULTS')
- facebook_config = feature_config.value.find { |value| value['name'] == 'channel_facebook' }
- twitter_config = feature_config.value.find { |value| value['name'] == 'channel_twitter' }
- Account.find_in_batches do |account_batch|
- account_batch.each do |account|
- account.enable_features('channel_facebook') if facebook_config['enabled']
- account.enable_features('channel_twitter') if twitter_config['enabled']
- account.save!
- end
- end
- end
-end
diff --git a/db/migrate/20200715124113_create_email_channel.rb b/db/migrate/20200715124113_create_email_channel.rb
deleted file mode 100644
index ca066aacb..000000000
--- a/db/migrate/20200715124113_create_email_channel.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-class CreateEmailChannel < ActiveRecord::Migration[6.0]
- def change
- create_table :channel_email do |t|
- t.integer :account_id, null: false
- t.string :email, null: false, index: { unique: true }
- t.string :forward_to_address, null: false, index: { unique: true }
- t.timestamps
- end
- end
-end
diff --git a/db/migrate/20200719171437_rename_nick_name_to_display_name.rb b/db/migrate/20200719171437_rename_nick_name_to_display_name.rb
deleted file mode 100644
index 35a53a3c1..000000000
--- a/db/migrate/20200719171437_rename_nick_name_to_display_name.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class RenameNickNameToDisplayName < ActiveRecord::Migration[6.0]
- def change
- rename_column :users, :nickname, :display_name
- end
-end
diff --git a/db/migrate/20200725131651_create_email_templates.rb b/db/migrate/20200725131651_create_email_templates.rb
deleted file mode 100644
index 00cef28eb..000000000
--- a/db/migrate/20200725131651_create_email_templates.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-class CreateEmailTemplates < ActiveRecord::Migration[6.0]
- def change
- create_table :email_templates do |t|
- t.string :name, null: false
- t.text :body, null: false
- t.integer :account_id, null: true
- t.integer :template_type, default: 1
- t.integer :locale, default: 0, null: false
- t.timestamps
- end
- add_index :email_templates, [:name, :account_id], unique: true
- end
-end
diff --git a/db/migrate/20200730080242_add_feature_setting_to_website_inbox.rb b/db/migrate/20200730080242_add_feature_setting_to_website_inbox.rb
deleted file mode 100644
index 7ffbe401f..000000000
--- a/db/migrate/20200730080242_add_feature_setting_to_website_inbox.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddFeatureSettingToWebsiteInbox < ActiveRecord::Migration[6.0]
- def change
- add_column :channel_web_widgets, :feature_flags, :integer, default: 3, null: false
- end
-end
diff --git a/db/migrate/20200802170002_reset_agent_last_seen_at.rb b/db/migrate/20200802170002_reset_agent_last_seen_at.rb
deleted file mode 100644
index b6d4198a7..000000000
--- a/db/migrate/20200802170002_reset_agent_last_seen_at.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class ResetAgentLastSeenAt < ActiveRecord::Migration[6.0]
- def change
- # rubocop:disable Rails/SkipsModelValidations
- ::Conversation.where('agent_last_seen_at > ?', DateTime.now.utc).update_all(agent_last_seen_at: DateTime.now.utc)
- # rubocop:enable Rails/SkipsModelValidations
- end
-end
diff --git a/db/migrate/20200819190629_add_custom_attributes_to_contacts.rb b/db/migrate/20200819190629_add_custom_attributes_to_contacts.rb
deleted file mode 100644
index 9fb865885..000000000
--- a/db/migrate/20200819190629_add_custom_attributes_to_contacts.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddCustomAttributesToContacts < ActiveRecord::Migration[6.0]
- def change
- add_column :contacts, :custom_attributes, :jsonb, default: {}
- end
-end
diff --git a/db/migrate/20200828175931_add_external_source_ids_to_messages.rb b/db/migrate/20200828175931_add_external_source_ids_to_messages.rb
deleted file mode 100644
index 772a18364..000000000
--- a/db/migrate/20200828175931_add_external_source_ids_to_messages.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-class AddExternalSourceIdsToMessages < ActiveRecord::Migration[6.0]
- def change
- add_column :messages, :external_source_ids, :jsonb, default: {}
- migrate_slack_external_source_ids
- end
-
- def migrate_slack_external_source_ids
- Message.where('source_id LIKE ?', 'slack_%').find_in_batches do |message_batch|
- message_batch.each do |message|
- message.external_source_id_slack = message.source_id.split('slack_')[1]
- message.source_id = nil
- message.save!
- end
- end
- end
-end
diff --git a/db/migrate/20200907094912_rename_user_last_seen.rb b/db/migrate/20200907094912_rename_user_last_seen.rb
deleted file mode 100644
index 66740c509..000000000
--- a/db/migrate/20200907094912_rename_user_last_seen.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class RenameUserLastSeen < ActiveRecord::Migration[6.0]
- def change
- rename_column :conversations, :user_last_seen_at, :contact_last_seen_at
- end
-end
diff --git a/db/migrate/20200907171106_add_reply_time_to_web_widget.rb b/db/migrate/20200907171106_add_reply_time_to_web_widget.rb
deleted file mode 100644
index 900a1bf0c..000000000
--- a/db/migrate/20200907171106_add_reply_time_to_web_widget.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddReplyTimeToWebWidget < ActiveRecord::Migration[6.0]
- def change
- add_column :channel_web_widgets, :reply_time, :integer, default: 0
- end
-end
diff --git a/db/migrate/20200927135222_add_last_activity_at_to_conversation.rb b/db/migrate/20200927135222_add_last_activity_at_to_conversation.rb
deleted file mode 100644
index 353c414cd..000000000
--- a/db/migrate/20200927135222_add_last_activity_at_to_conversation.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-class AddLastActivityAtToConversation < ActiveRecord::Migration[6.0]
- def up
- add_column :conversations,
- :last_activity_at,
- :datetime,
- default: -> { 'CURRENT_TIMESTAMP' },
- index: true
-
- add_last_activity_at_to_conversations
-
- change_column_null(:conversations, :last_activity_at, false)
- end
-
- def down
- remove_column(:conversations, :last_activity_at)
- end
-
- private
-
- def add_last_activity_at_to_conversations
- ::Conversation.find_in_batches do |conversation_batch|
- Rails.logger.info "Migrated till #{conversation_batch.first.id}\n"
- conversation_batch.each do |conversation|
- # rubocop:disable Rails/SkipsModelValidations
- last_activity_at = if conversation.messages.last
- conversation.messages.last.created_at
- else
- conversation.created_at
- end
- conversation.update_columns(last_activity_at: last_activity_at)
- # rubocop:enable Rails/SkipsModelValidations
- end
- end
- end
-end
diff --git a/db/migrate/20201003105618_add_auto_resolve_duration_to_account.rb b/db/migrate/20201003105618_add_auto_resolve_duration_to_account.rb
deleted file mode 100644
index 03dfb3362..000000000
--- a/db/migrate/20201003105618_add_auto_resolve_duration_to_account.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddAutoResolveDurationToAccount < ActiveRecord::Migration[6.0]
- def change
- add_column :accounts, :auto_resolve_duration, :integer
- end
-end
diff --git a/db/migrate/20201011152227_add_email_address_to_inbox.rb b/db/migrate/20201011152227_add_email_address_to_inbox.rb
deleted file mode 100644
index 2691c563d..000000000
--- a/db/migrate/20201011152227_add_email_address_to_inbox.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class AddEmailAddressToInbox < ActiveRecord::Migration[6.0]
- def up
- add_column :inboxes, :email_address, :string
- end
-
- def down
- remove_column(:inboxes, :email_address)
- end
-end
diff --git a/db/migrate/20201019173944_add_default_value_to_jsonb_colums.rb b/db/migrate/20201019173944_add_default_value_to_jsonb_colums.rb
deleted file mode 100644
index 1b6394af9..000000000
--- a/db/migrate/20201019173944_add_default_value_to_jsonb_colums.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-class AddDefaultValueToJsonbColums < ActiveRecord::Migration[6.0]
- def change
- change_column_default :contacts, :additional_attributes, from: nil, to: {}
- change_column_default :conversations, :additional_attributes, from: nil, to: {}
- change_column_default :installation_configs, :serialized_value, from: '{}', to: {}
- change_column_default :notification_subscriptions, :subscription_attributes, from: '{}', to: {}
- end
-end
diff --git a/db/migrate/20201027135006_create_working_hours.rb b/db/migrate/20201027135006_create_working_hours.rb
deleted file mode 100644
index 6d06e385f..000000000
--- a/db/migrate/20201027135006_create_working_hours.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-class CreateWorkingHours < ActiveRecord::Migration[6.0]
- def change
- create_table :working_hours do |t|
- t.belongs_to :inbox
- t.belongs_to :account
-
- t.integer :day_of_week, null: false
- t.boolean :closed_all_day, default: false
- t.integer :open_hour
- t.integer :open_minutes
- t.integer :close_hour
- t.integer :close_minutes
-
- t.timestamps
- end
-
- add_column :accounts, :timezone, :string, default: 'UTC'
-
- change_table :inboxes, bulk: true do |t|
- t.boolean :working_hours_enabled, default: false
- t.string :out_of_office_message
- end
-
- Inbox.where.not(id: WorkingHour.select(:inbox_id)).each do |inbox|
- create_working_hours_for_inbox(inbox)
- end
- end
-
- private
-
- def create_working_hours_for_inbox(inbox)
- inbox.working_hours.create!(day_of_week: 1, open_hour: 9, open_minutes: 0, close_hour: 17, close_minutes: 0)
- inbox.working_hours.create!(day_of_week: 2, open_hour: 9, open_minutes: 0, close_hour: 17, close_minutes: 0)
- inbox.working_hours.create!(day_of_week: 3, open_hour: 9, open_minutes: 0, close_hour: 17, close_minutes: 0)
- inbox.working_hours.create!(day_of_week: 4, open_hour: 9, open_minutes: 0, close_hour: 17, close_minutes: 0)
- inbox.working_hours.create!(day_of_week: 5, open_hour: 9, open_minutes: 0, close_hour: 17, close_minutes: 0)
- inbox.working_hours.create!(day_of_week: 6, closed_all_day: true)
- inbox.working_hours.create!(day_of_week: 7, closed_all_day: true)
- end
-end
diff --git a/db/migrate/20201123195011_create_platform_apps.rb b/db/migrate/20201123195011_create_platform_apps.rb
deleted file mode 100644
index bfa36fc89..000000000
--- a/db/migrate/20201123195011_create_platform_apps.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-class CreatePlatformApps < ActiveRecord::Migration[6.0]
- def change
- create_table :platform_apps do |t|
- t.string :name, null: false
- t.timestamps
- end
- end
-end
diff --git a/db/migrate/20201124101124_create_platform_app_permissibles.rb b/db/migrate/20201124101124_create_platform_app_permissibles.rb
deleted file mode 100644
index 309d4f36a..000000000
--- a/db/migrate/20201124101124_create_platform_app_permissibles.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class CreatePlatformAppPermissibles < ActiveRecord::Migration[6.0]
- def change
- create_table :platform_app_permissibles do |t|
- t.references :platform_app, index: true, null: false
- t.references :permissible, null: false, polymorphic: true, index: { name: :index_platform_app_permissibles_on_permissibles }
- t.timestamps
- end
-
- add_index :platform_app_permissibles, [:platform_app_id, :permissible_id, :permissible_type], unique: true, name: 'unique_permissibles_index'
- end
-end
diff --git a/db/migrate/20201125121240_create_triggers_accounts_insert_or_conversations_insert.rb b/db/migrate/20201125121240_create_triggers_accounts_insert_or_conversations_insert.rb
deleted file mode 100644
index 5ea5d38a5..000000000
--- a/db/migrate/20201125121240_create_triggers_accounts_insert_or_conversations_insert.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-# This migration was auto-generated via `rake db:generate_trigger_migration'.
-# While you can edit this file, any changes you make to the definitions here
-# will be undone by the next auto-generated trigger migration.
-
-class CreateTriggersAccountsInsertOrConversationsInsert < ActiveRecord::Migration[6.0]
- def up
- create_trigger('accounts_after_insert_row_tr', generated: true, compatibility: 1)
- .on('accounts')
- .after(:insert)
- .for_each(:row) do
- "execute format('create sequence IF NOT EXISTS conv_dpid_seq_%s', NEW.id);"
- end
-
- create_trigger('conversations_before_insert_row_tr', generated: true, compatibility: 1)
- .on('conversations')
- .before(:insert)
- .for_each(:row) do
- "NEW.display_id := nextval('conv_dpid_seq_' || NEW.account_id);"
- end
- end
-
- def down
- drop_trigger('accounts_after_insert_row_tr', 'accounts', generated: true)
-
- drop_trigger('conversations_before_insert_row_tr', 'conversations', generated: true)
- end
-end
diff --git a/db/migrate/20201125123131_conv_dpid_seq_for_existing_accnts.rb b/db/migrate/20201125123131_conv_dpid_seq_for_existing_accnts.rb
deleted file mode 100644
index 73acb8ae8..000000000
--- a/db/migrate/20201125123131_conv_dpid_seq_for_existing_accnts.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-class ConvDpidSeqForExistingAccnts < ActiveRecord::Migration[6.0]
- def up
- ::Account.find_in_batches do |accounts_batch|
- Rails.logger.info "migrated till #{accounts_batch.first.id}\n"
- accounts_batch.each do |account|
- display_id = Conversation.where(account_id: account.id).maximum('display_id')
- display_id ||= 0 # for accounts with out conversations
- ActiveRecord::Base.connection.exec_query("create sequence IF NOT EXISTS conv_dpid_seq_#{account.id} START #{display_id + 1}")
- end
- end
- end
-
- def down
- ::Account.find_in_batches do |accounts_batch|
- Rails.logger.info "migrated till #{accounts_batch.first.id}\n"
- accounts_batch.each do |account|
- ActiveRecord::Base.connection.exec_query("drop sequence IF EXISTS conv_dpid_seq_#{account.id}")
- end
- end
- end
-end
diff --git a/db/migrate/20210105185632_enable_pg_stats_extention.rb b/db/migrate/20210105185632_enable_pg_stats_extention.rb
deleted file mode 100644
index f03b0dc20..000000000
--- a/db/migrate/20210105185632_enable_pg_stats_extention.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class EnablePgStatsExtention < ActiveRecord::Migration[6.0]
- def change
- enable_extension 'pg_stat_statements'
- end
-end
diff --git a/db/migrate/20210109211805_add_ui_settings_to_users.rb b/db/migrate/20210109211805_add_ui_settings_to_users.rb
deleted file mode 100644
index f8b18a971..000000000
--- a/db/migrate/20210109211805_add_ui_settings_to_users.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class AddUiSettingsToUsers < ActiveRecord::Migration[6.0]
- def up
- add_column :users, :ui_settings, :jsonb, default: {}
- end
-
- def down
- remove_column :users, :ui_settings, :jsonb
- end
-end
diff --git a/db/migrate/20210112174124_add_hmac_token_to_inbox.rb b/db/migrate/20210112174124_add_hmac_token_to_inbox.rb
deleted file mode 100644
index cd614cd16..000000000
--- a/db/migrate/20210112174124_add_hmac_token_to_inbox.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class AddHmacTokenToInbox < ActiveRecord::Migration[6.0]
- def change
- add_column :channel_web_widgets, :hmac_token, :string
- add_index :channel_web_widgets, :hmac_token, unique: true
- set_up_existing_webwidgets
- add_column :contact_inboxes, :hmac_verified, :boolean, default: false
- end
-
- def set_up_existing_webwidgets
- ::Channel::WebWidget.find_in_batches do |webwidgets_batch|
- Rails.logger.info "migrated till #{webwidgets_batch.first.id}\n"
- webwidgets_batch.map(&:regenerate_hmac_token)
- end
- end
-end
diff --git a/db/migrate/20210113045116_add_locked_attribute_to_installation_config.rb b/db/migrate/20210113045116_add_locked_attribute_to_installation_config.rb
deleted file mode 100644
index c3715d244..000000000
--- a/db/migrate/20210113045116_add_locked_attribute_to_installation_config.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-class AddLockedAttributeToInstallationConfig < ActiveRecord::Migration[6.0]
- def up
- add_column :installation_configs, :locked, :boolean, default: true, null: false
- purge_duplicates
- add_index :installation_configs, :name, unique: true
- end
-
- def down
- remove_column :installation_configs, :locked
- remove_index :installation_configs, :name
- end
-
- def purge_duplicates
- config_names = InstallationConfig.all.map(&:name).uniq
-
- config_names.each do |name|
- ids = InstallationConfig.where(name: name).pluck(&:id)
- next if ids.size <= 1
-
- # preserve the last config and destroy rest
- ids.sort!
- ids.pop
- InstallationConfig.where(id: ids).destroy_all
- end
- end
-end
diff --git a/db/migrate/20210114202310_create_teams.rb b/db/migrate/20210114202310_create_teams.rb
deleted file mode 100644
index cccc891c2..000000000
--- a/db/migrate/20210114202310_create_teams.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-class CreateTeams < ActiveRecord::Migration[6.0]
- def change
- create_table :teams do |t|
- t.string :name, null: false
- t.text :description
- t.boolean :allow_auto_assign, default: true
- t.references :account, null: false, foreign_key: true
-
- t.timestamps
- end
-
- create_table :team_members do |t|
- t.references :team, null: false, foreign_key: true
- t.references :user, null: false, foreign_key: true
- t.timestamps
- end
-
- add_reference :conversations, :team, foreign_key: true
- end
-end
diff --git a/db/migrate/20210126121313_addunique_index_to_team_members.rb b/db/migrate/20210126121313_addunique_index_to_team_members.rb
deleted file mode 100644
index 1a1db98eb..000000000
--- a/db/migrate/20210126121313_addunique_index_to_team_members.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-class AdduniqueIndexToTeamMembers < ActiveRecord::Migration[6.0]
- def change
- add_index :teams, [:name, :account_id], unique: true
- add_index :team_members, [:team_id, :user_id], unique: true
- end
-end
diff --git a/db/migrate/20210201150037_create_data_imports.rb b/db/migrate/20210201150037_create_data_imports.rb
deleted file mode 100644
index 349453a8d..000000000
--- a/db/migrate/20210201150037_create_data_imports.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-class CreateDataImports < ActiveRecord::Migration[6.0]
- def change
- create_table :data_imports do |t|
- t.references :account, null: false, foreign_key: true
- t.string :data_type, null: false
- t.integer :status, null: false, default: 0
- t.text :processing_errors
- t.integer :total_records
- t.integer :processed_records
-
- t.timestamps
- end
- end
-end
diff --git a/db/migrate/20210212154240_add_request_for_email_on_channel_web_widget.rb b/db/migrate/20210212154240_add_request_for_email_on_channel_web_widget.rb
deleted file mode 100644
index 646dd2139..000000000
--- a/db/migrate/20210212154240_add_request_for_email_on_channel_web_widget.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class AddRequestForEmailOnChannelWebWidget < ActiveRecord::Migration[6.0]
- def up
- change_table :channel_web_widgets, bulk: true do |t|
- t.column :pre_chat_form_enabled, :boolean, default: false
- t.column :pre_chat_form_options, :jsonb, default: {}
- end
- end
-
- def down
- change_table :channel_web_widgets, bulk: true do |t|
- t.remove :pre_chat_form_enabled
- t.remove :pre_chat_form_options
- end
- end
-end
diff --git a/db/migrate/20210217154129_remove_orphan_inbox_members_from_inboxes.rb b/db/migrate/20210217154129_remove_orphan_inbox_members_from_inboxes.rb
deleted file mode 100644
index 6dbd89ce8..000000000
--- a/db/migrate/20210217154129_remove_orphan_inbox_members_from_inboxes.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-class RemoveOrphanInboxMembersFromInboxes < ActiveRecord::Migration[6.0]
- def change
- Account.all.map do |account|
- user_ids = account.users.all.map(&:id)
- inboxes = account.inboxes
- inboxes.each do |inbox|
- inbox.inbox_members.each do |inbox_member|
- inbox_member.destroy! unless user_ids.include?(inbox_member.user_id)
- end
- end
- end
- end
-end
diff --git a/db/migrate/20210219085719_remove_old_notifications.rb b/db/migrate/20210219085719_remove_old_notifications.rb
deleted file mode 100644
index 06021a341..000000000
--- a/db/migrate/20210219085719_remove_old_notifications.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class RemoveOldNotifications < ActiveRecord::Migration[6.0]
- def change
- Notification.where(notification_type: 'assigned_conversation_new_message').destroy_all
- end
-end
diff --git a/db/migrate/20210222131048_change_working_hours_to_zero.rb b/db/migrate/20210222131048_change_working_hours_to_zero.rb
deleted file mode 100644
index 7d163e55e..000000000
--- a/db/migrate/20210222131048_change_working_hours_to_zero.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class ChangeWorkingHoursToZero < ActiveRecord::Migration[6.0]
- # rubocop:disable Rails/SkipsModelValidations
- def up
- WorkingHour.where(day_of_week: 7).update_all(day_of_week: 0)
- end
-
- def down
- WorkingHour.where(day_of_week: 0).update_all(day_of_week: 7)
- end
- # rubocop:enable Rails/SkipsModelValidations
-end
diff --git a/db/migrate/20210222131155_switch_time_zone_from_account_to_inbox.rb b/db/migrate/20210222131155_switch_time_zone_from_account_to_inbox.rb
deleted file mode 100644
index b30d3dffc..000000000
--- a/db/migrate/20210222131155_switch_time_zone_from_account_to_inbox.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-class SwitchTimeZoneFromAccountToInbox < ActiveRecord::Migration[6.0]
- def change
- remove_column :accounts, :timezone, :string, default: 'UTC'
- add_column :inboxes, :timezone, :string, default: 'UTC'
- end
-end
diff --git a/db/migrate/20210303192243_rename_channel_email_forward_address.rb b/db/migrate/20210303192243_rename_channel_email_forward_address.rb
deleted file mode 100644
index 1ccec24f5..000000000
--- a/db/migrate/20210303192243_rename_channel_email_forward_address.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class RenameChannelEmailForwardAddress < ActiveRecord::Migration[6.0]
- def change
- rename_column :channel_email, :forward_to_address, :forward_to_email
- end
-end
diff --git a/db/migrate/20210306170117_add_last_activity_at_to_contacts.rb b/db/migrate/20210306170117_add_last_activity_at_to_contacts.rb
deleted file mode 100644
index b35c064fc..000000000
--- a/db/migrate/20210306170117_add_last_activity_at_to_contacts.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-class AddLastActivityAtToContacts < ActiveRecord::Migration[6.0]
- def up
- # rubocop:disable Rails/SkipsModelValidations
- add_column :contacts, :last_activity_at, :datetime, index: true, default: nil
- Conversation.find_in_batches do |conversation_batch|
- conversation_batch.each do |conversation|
- contact = conversation.contact
- if contact.last_activity_at.nil? || conversation.updated_at > contact.last_activity_at
- contact.update_columns(last_activity_at: conversation.updated_at)
- end
- end
- end
-
- Contact.where(additional_attributes: nil).update_all(additional_attributes: {})
- Contact.where(phone_number: '').update_all(phone_number: nil)
- # rubocop:enable Rails/SkipsModelValidations
- end
-
- def down
- remove_column :contacts, :last_activity_at, :datetime, index: true, default: nil
- end
-end
diff --git a/db/migrate/20210315101919_enable_email_channel.rb b/db/migrate/20210315101919_enable_email_channel.rb
deleted file mode 100644
index 194a4c5a3..000000000
--- a/db/migrate/20210315101919_enable_email_channel.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-class EnableEmailChannel < ActiveRecord::Migration[6.0]
- def change
- current_config = InstallationConfig.where(name: 'ACCOUNT_LEVEL_FEATURE_DEFAULTS').last
- current_config.value.each { |v| v['enabled'] = true if %w[inbound_emails channel_email].include?(v['name']) }
- current_config.save!
-
- ConfigLoader.new.process
-
- Account.find_in_batches do |account_batch|
- account_batch.each do |account|
- account.enable_features('inbound_emails')
- account.enable_features('channel_email')
- account.save!
- end
- end
- end
-end
diff --git a/db/migrate/20210425093724_convert_integration_hook_settings_field.rb b/db/migrate/20210425093724_convert_integration_hook_settings_field.rb
deleted file mode 100644
index 3ba021291..000000000
--- a/db/migrate/20210425093724_convert_integration_hook_settings_field.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-class ConvertIntegrationHookSettingsField < ActiveRecord::Migration[6.0]
- def change
- remove_column :integrations_hooks, :settings, :text
- add_column :integrations_hooks, :settings, :jsonb, default: {}
- end
-end
diff --git a/db/migrate/20210426191914_migration_remove_locked_from_conversation.rb b/db/migrate/20210426191914_migration_remove_locked_from_conversation.rb
deleted file mode 100644
index 402935f28..000000000
--- a/db/migrate/20210426191914_migration_remove_locked_from_conversation.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class MigrationRemoveLockedFromConversation < ActiveRecord::Migration[6.0]
- def change
- remove_column :conversations, :locked, :boolean
- end
-end
diff --git a/db/migrate/20210428135041_add_campaigns.rb b/db/migrate/20210428135041_add_campaigns.rb
deleted file mode 100644
index 7df93a347..000000000
--- a/db/migrate/20210428135041_add_campaigns.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-class AddCampaigns < ActiveRecord::Migration[6.0]
- def change
- create_table :campaigns do |t|
- t.integer :display_id, null: false
- t.string :title, null: false
- t.text :description
- t.text :content, null: false
- t.integer :sender_id
- t.boolean :enabled, default: true
- t.references :account, null: false, foreign_key: true
- t.references :inbox, null: false, foreign_key: true
- t.column :trigger_rules, :jsonb, default: {}
- t.timestamps
- end
-
- add_reference :conversations, :campaign, foreign_key: true
- end
-end
diff --git a/db/migrate/20210428151147_create_triggers_accounts_insert_or_campaigns_insert.rb b/db/migrate/20210428151147_create_triggers_accounts_insert_or_campaigns_insert.rb
deleted file mode 100644
index 3fdc4f18e..000000000
--- a/db/migrate/20210428151147_create_triggers_accounts_insert_or_campaigns_insert.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# This migration was auto-generated via `rake db:generate_trigger_migration'.
-# While you can edit this file, any changes you make to the definitions here
-# will be undone by the next auto-generated trigger migration.
-
-class CreateTriggersAccountsInsertOrCampaignsInsert < ActiveRecord::Migration[6.0]
- def up
- create_trigger('camp_dpid_before_insert', generated: true, compatibility: 1)
- .on('accounts')
- .name('camp_dpid_before_insert')
- .after(:insert)
- .for_each(:row) do
- "execute format('create sequence IF NOT EXISTS camp_dpid_seq_%s', NEW.id);"
- end
-
- create_trigger('campaigns_before_insert_row_tr', generated: true, compatibility: 1)
- .on('campaigns')
- .before(:insert)
- .for_each(:row) do
- "NEW.display_id := nextval('camp_dpid_seq_' || NEW.account_id);"
- end
- end
-
- def down
- drop_trigger('camp_dpid_before_insert', 'accounts', generated: true)
-
- drop_trigger('campaigns_before_insert_row_tr', 'campaigns', generated: true)
- end
-end
diff --git a/db/migrate/20210430095748_add_camp_dp_id_seq_for_existing_accounts.rb b/db/migrate/20210430095748_add_camp_dp_id_seq_for_existing_accounts.rb
deleted file mode 100644
index 1b37e8345..000000000
--- a/db/migrate/20210430095748_add_camp_dp_id_seq_for_existing_accounts.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-class AddCampDpIdSeqForExistingAccounts < ActiveRecord::Migration[6.0]
- def up
- ::Account.find_in_batches do |accounts_batch|
- Rails.logger.info "migrated till #{accounts_batch.first.id}\n"
- accounts_batch.each do |account|
- display_id = account.campaigns.count
- ActiveRecord::Base.connection.exec_query("create sequence IF NOT EXISTS camp_dpid_seq_#{account.id} START #{display_id + 1}")
- end
- end
- end
-
- def down
- ::Account.find_in_batches do |accounts_batch|
- Rails.logger.info "migrated till #{accounts_batch.first.id}\n"
- accounts_batch.each do |account|
- ActiveRecord::Base.connection.exec_query("drop sequence IF EXISTS camp_dpid_seq_#{account.id}")
- end
- end
- end
-end
diff --git a/db/migrate/20210430100138_rename_campaign_content_to_message.rb b/db/migrate/20210430100138_rename_campaign_content_to_message.rb
deleted file mode 100644
index 161ef299e..000000000
--- a/db/migrate/20210430100138_rename_campaign_content_to_message.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class RenameCampaignContentToMessage < ActiveRecord::Migration[6.0]
- def change
- rename_column :campaigns, :content, :message
- end
-end
diff --git a/db/migrate/20210513083044_remove_not_null_from_webhook_url_channel_api.rb b/db/migrate/20210513083044_remove_not_null_from_webhook_url_channel_api.rb
deleted file mode 100644
index 790c52ec5..000000000
--- a/db/migrate/20210513083044_remove_not_null_from_webhook_url_channel_api.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class RemoveNotNullFromWebhookUrlChannelApi < ActiveRecord::Migration[6.0]
- def change
- change_column :channel_api, :webhook_url, :string, null: true
- end
-end
diff --git a/db/migrate/20210513143021_rename_events_to_report_events.rb b/db/migrate/20210513143021_rename_events_to_report_events.rb
deleted file mode 100644
index 9241ff7b2..000000000
--- a/db/migrate/20210513143021_rename_events_to_report_events.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class RenameEventsToReportEvents < ActiveRecord::Migration[6.0]
- def change
- rename_table :events, :reporting_events
- end
-end
diff --git a/db/migrate/20210520200729_add_account_id_to_agent_bots.rb b/db/migrate/20210520200729_add_account_id_to_agent_bots.rb
deleted file mode 100644
index cd4a26073..000000000
--- a/db/migrate/20210520200729_add_account_id_to_agent_bots.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-class AddAccountIdToAgentBots < ActiveRecord::Migration[6.0]
- def change
- remove_column :agent_bots, :hide_input_for_bot_conversations, :boolean
- add_reference :agent_bots, :account, foreign_key: true
- end
-end
diff --git a/db/migrate/20210527173755_remove_super_admin_access_tokes.rb b/db/migrate/20210527173755_remove_super_admin_access_tokes.rb
deleted file mode 100644
index 18ad7d4f8..000000000
--- a/db/migrate/20210527173755_remove_super_admin_access_tokes.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class RemoveSuperAdminAccessTokes < ActiveRecord::Migration[6.0]
- def change
- AccessToken.where(owner_type: 'SuperAdmin').destroy_all
- end
-end
diff --git a/db/migrate/20210602182058_add_hmac_to_api_channel.rb b/db/migrate/20210602182058_add_hmac_to_api_channel.rb
deleted file mode 100644
index f441c2829..000000000
--- a/db/migrate/20210602182058_add_hmac_to_api_channel.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-class AddHmacToApiChannel < ActiveRecord::Migration[6.0]
- def change
- add_column :channel_api, :identifier, :string
- add_index :channel_api, :identifier, unique: true
- add_column :channel_api, :hmac_token, :string
- add_index :channel_api, :hmac_token, unique: true
- add_column :channel_api, :hmac_mandatory, :boolean, default: false
- add_column :channel_web_widgets, :hmac_mandatory, :boolean, default: false
- set_up_existing_api_channels
- end
-
- def set_up_existing_api_channels
- ::Channel::Api.find_in_batches do |api_channels_batch|
- Rails.logger.info "migrated till #{api_channels_batch.first.id}\n"
- api_channels_batch.map(&:regenerate_hmac_token)
- api_channels_batch.map(&:regenerate_identifier)
- end
- end
-end
diff --git a/db/migrate/20210609133433_add_email_collect_to_inboxes.rb b/db/migrate/20210609133433_add_email_collect_to_inboxes.rb
deleted file mode 100644
index f4da1f73e..000000000
--- a/db/migrate/20210609133433_add_email_collect_to_inboxes.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddEmailCollectToInboxes < ActiveRecord::Migration[6.0]
- def change
- add_column :inboxes, :enable_email_collect, :boolean, default: true
- end
-end
diff --git a/db/migrate/20210611180221_add_service_name_to_active_storage_blobs.active_storage.rb b/db/migrate/20210611180221_add_service_name_to_active_storage_blobs.active_storage.rb
deleted file mode 100644
index 9967a1323..000000000
--- a/db/migrate/20210611180221_add_service_name_to_active_storage_blobs.active_storage.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# This migration comes from active_storage (originally 20190112182829)
-class AddServiceNameToActiveStorageBlobs < ActiveRecord::Migration[6.0]
- def up
- unless column_exists?(:active_storage_blobs, :service_name)
- add_column :active_storage_blobs, :service_name, :string
-
- if configured_service = ActiveStorage::Blob.service.name
- ActiveStorage::Blob.unscoped.update_all(service_name: configured_service)
- end
-
- change_column :active_storage_blobs, :service_name, :string, null: false
- end
- end
-
- def down
- remove_column :active_storage_blobs, :service_name
- end
-end
diff --git a/db/migrate/20210611180222_create_active_storage_variant_records.active_storage.rb b/db/migrate/20210611180222_create_active_storage_variant_records.active_storage.rb
deleted file mode 100644
index 71b27d1c1..000000000
--- a/db/migrate/20210611180222_create_active_storage_variant_records.active_storage.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# This migration comes from active_storage (originally 20191206030411)
-class CreateActiveStorageVariantRecords < ActiveRecord::Migration[6.0]
- def change
- create_table :active_storage_variant_records do |t|
- t.belongs_to :blob, null: false, index: false
- t.string :variation_digest, null: false
-
- t.index %i[blob_id variation_digest], name: 'index_active_storage_variant_records_uniqueness', unique: true
- t.foreign_key :active_storage_blobs, column: :blob_id
- end
- end
-end
diff --git a/db/migrate/20210618073042_create_notes.rb b/db/migrate/20210618073042_create_notes.rb
deleted file mode 100644
index 1e7b091a7..000000000
--- a/db/migrate/20210618073042_create_notes.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class CreateNotes < ActiveRecord::Migration[6.0]
- def change
- create_table :notes do |t|
- t.text :content, null: false
- t.references :account, foreign_key: true, null: false
- t.references :contact, foreign_key: true, null: false
- t.references :user, foreign_key: true
- t.timestamps
- end
- end
-end
diff --git a/db/migrate/20210618095823_add_csat_toggle_for_inbox.rb b/db/migrate/20210618095823_add_csat_toggle_for_inbox.rb
deleted file mode 100644
index bcdfd839c..000000000
--- a/db/migrate/20210618095823_add_csat_toggle_for_inbox.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddCsatToggleForInbox < ActiveRecord::Migration[6.0]
- def change
- add_column :inboxes, :csat_survey_enabled, :boolean, default: false
- end
-end
diff --git a/db/migrate/20210623150613_create_custom_filters.rb b/db/migrate/20210623150613_create_custom_filters.rb
deleted file mode 100644
index fe9d920ce..000000000
--- a/db/migrate/20210623150613_create_custom_filters.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-class CreateCustomFilters < ActiveRecord::Migration[6.0]
- def change
- create_table :custom_filters do |t|
- t.string :name, null: false
- t.integer :filter_type, null: false, default: 0
- t.jsonb :query, null: false, default: '{}'
- t.references :account, index: true, null: false
- t.references :user, index: true, null: false
- t.timestamps
- end
- end
-end
diff --git a/db/migrate/20210623155413_create_csat_survey_responses.rb b/db/migrate/20210623155413_create_csat_survey_responses.rb
deleted file mode 100644
index 02c232b24..000000000
--- a/db/migrate/20210623155413_create_csat_survey_responses.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class CreateCsatSurveyResponses < ActiveRecord::Migration[6.0]
- def change
- create_table :csat_survey_responses do |t|
- t.references :account, null: false, foreign_key: true
- t.references :conversation, null: false, foreign_key: true
- t.references :message, null: false, foreign_key: true, index: { unique: true }
- t.integer :rating, null: false
- t.text :feedback_message
- t.references :contact, null: false, foreign_key: true
- t.references :assigned_agent, foreign_key: { to_table: :users }
-
- t.timestamps
- end
- end
-end
diff --git a/db/migrate/20210707142801_add_campaign_type_to_campaigns.rb b/db/migrate/20210707142801_add_campaign_type_to_campaigns.rb
deleted file mode 100644
index c89cecea5..000000000
--- a/db/migrate/20210707142801_add_campaign_type_to_campaigns.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-class AddCampaignTypeToCampaigns < ActiveRecord::Migration[6.0]
- def change
- change_table :campaigns, bulk: true do |t|
- t.integer :campaign_type, default: 0, null: false, index: true
- t.integer :campaign_status, default: 0, null: false, index: true
- t.jsonb :audience, default: []
- t.datetime :scheduled_at, index: true
- end
- end
-end
diff --git a/db/migrate/20210708140842_remove_notifications_without_primary_actor.rb b/db/migrate/20210708140842_remove_notifications_without_primary_actor.rb
deleted file mode 100644
index 1c365bd69..000000000
--- a/db/migrate/20210708140842_remove_notifications_without_primary_actor.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class RemoveNotificationsWithoutPrimaryActor < ActiveRecord::Migration[6.0]
- def change
- deleted_ids = []
- Notification.where(primary_actor_type: 'Conversation').pluck(:primary_actor_id).uniq.each_slice(1000) do |id_list|
- deleted_ids << (id_list - Conversation.where(id: id_list).pluck(:id))
- end
- Notification.where(primary_actor_type: 'Conversation', primary_actor_id: deleted_ids).destroy_all
- end
-end
diff --git a/db/migrate/20210714110714_remove_duplicate_access_tokens_for_existing_users.rb b/db/migrate/20210714110714_remove_duplicate_access_tokens_for_existing_users.rb
deleted file mode 100644
index 23cacbf8a..000000000
--- a/db/migrate/20210714110714_remove_duplicate_access_tokens_for_existing_users.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-class RemoveDuplicateAccessTokensForExistingUsers < ActiveRecord::Migration[6.0]
- def up
- # find all models and group them on owner
- grouped_tokens = AccessToken.all.group_by(&:owner)
- grouped_tokens.each_value do |duplicates|
- # we want to keep the latest token as it is being used in all requests
- duplicates.pop
- # Remaining ones are duplicates, delete them all
- duplicates.each { |duplicate| AccessToken.find_by(id: duplicate).destroy }
- end
- end
-end
diff --git a/db/migrate/20210721182458_add_snoozed_until_to_conversations.rb b/db/migrate/20210721182458_add_snoozed_until_to_conversations.rb
deleted file mode 100644
index 9e4fbca41..000000000
--- a/db/migrate/20210721182458_add_snoozed_until_to_conversations.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddSnoozedUntilToConversations < ActiveRecord::Migration[6.0]
- def change
- add_column :conversations, :snoozed_until, :datetime
- end
-end
diff --git a/db/migrate/20210722095814_add_custom_attribute_definition.rb b/db/migrate/20210722095814_add_custom_attribute_definition.rb
deleted file mode 100644
index 3aae0b2f7..000000000
--- a/db/migrate/20210722095814_add_custom_attribute_definition.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-class AddCustomAttributeDefinition < ActiveRecord::Migration[6.0]
- def change
- create_table :custom_attribute_definitions do |t|
- t.string :attribute_display_name
- t.string :attribute_key
- t.integer :attribute_display_type, default: 0
- t.integer :default_value
- t.integer :attribute_model, default: 0
- t.references :account, index: true
-
- t.timestamps
- end
-
- add_index :custom_attribute_definitions, [:attribute_key, :attribute_model], unique: true, name: 'attribute_key_model_index'
- end
-end
diff --git a/db/migrate/20210723094412_add_index_to_conversations.rb b/db/migrate/20210723094412_add_index_to_conversations.rb
deleted file mode 100644
index ad31696d1..000000000
--- a/db/migrate/20210723094412_add_index_to_conversations.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-class AddIndexToConversations < ActiveRecord::Migration[6.0]
- def change
- add_index :conversations, [:status, :account_id]
- add_index :conversations, [:assignee_id, :account_id]
- end
-end
diff --git a/db/migrate/20210723095657_add_index_to_contacts.rb b/db/migrate/20210723095657_add_index_to_contacts.rb
deleted file mode 100644
index aeccfa1de..000000000
--- a/db/migrate/20210723095657_add_index_to_contacts.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddIndexToContacts < ActiveRecord::Migration[6.0]
- def change
- add_index :contacts, [:phone_number, :account_id]
- end
-end
diff --git a/db/migrate/20210824152852_add_description_to_custom_attribute_definition.rb b/db/migrate/20210824152852_add_description_to_custom_attribute_definition.rb
deleted file mode 100644
index 45ca3ba9f..000000000
--- a/db/migrate/20210824152852_add_description_to_custom_attribute_definition.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddDescriptionToCustomAttributeDefinition < ActiveRecord::Migration[6.1]
- def change
- add_column :custom_attribute_definitions, :attribute_description, :text
- end
-end
diff --git a/db/migrate/20210827120929_add_custom_attributes_to_user.rb b/db/migrate/20210827120929_add_custom_attributes_to_user.rb
deleted file mode 100644
index 4eb709284..000000000
--- a/db/migrate/20210827120929_add_custom_attributes_to_user.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddCustomAttributesToUser < ActiveRecord::Migration[6.1]
- def change
- add_column :users, :custom_attributes, :jsonb, default: {}
- end
-end
diff --git a/db/migrate/20210828124043_add_telegram_channel.rb b/db/migrate/20210828124043_add_telegram_channel.rb
deleted file mode 100644
index 58466550c..000000000
--- a/db/migrate/20210828124043_add_telegram_channel.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-class AddTelegramChannel < ActiveRecord::Migration[6.1]
- def change
- create_table :channel_telegram do |t|
- t.string :bot_name
- t.integer :account_id, null: false
- t.string :bot_token, null: false, index: { unique: true }
- t.timestamps
- end
- end
-end
diff --git a/db/migrate/20210829124254_add_line_channel.rb b/db/migrate/20210829124254_add_line_channel.rb
deleted file mode 100644
index 54995b5b7..000000000
--- a/db/migrate/20210829124254_add_line_channel.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class AddLineChannel < ActiveRecord::Migration[6.1]
- def change
- create_table :channel_line do |t|
- t.integer :account_id, null: false
- t.string :line_channel_id, null: false, index: { unique: true }
- t.string :line_channel_secret, null: false
- t.string :line_channel_token, null: false
- t.timestamps
- end
- end
-end
diff --git a/db/migrate/20210902181438_add_instagram_id_to_facebook_page.rb b/db/migrate/20210902181438_add_instagram_id_to_facebook_page.rb
deleted file mode 100644
index 391fac835..000000000
--- a/db/migrate/20210902181438_add_instagram_id_to_facebook_page.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class AddInstagramIdToFacebookPage < ActiveRecord::Migration[6.1]
- def up
- add_column :channel_facebook_pages, :instagram_id, :string
- end
-
- def down
- remove_column :channel_facebook_pages, :instagram_id, :string
- end
-end
diff --git a/db/migrate/20210916060144_add_custom_attributes_to_conversations.rb b/db/migrate/20210916060144_add_custom_attributes_to_conversations.rb
deleted file mode 100644
index ef5f8cac1..000000000
--- a/db/migrate/20210916060144_add_custom_attributes_to_conversations.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddCustomAttributesToConversations < ActiveRecord::Migration[6.1]
- def change
- add_column :conversations, :custom_attributes, :jsonb, default: {}
- end
-end
diff --git a/db/migrate/20210916112533_add_whatsapp_channel.rb b/db/migrate/20210916112533_add_whatsapp_channel.rb
deleted file mode 100644
index 7e1f35951..000000000
--- a/db/migrate/20210916112533_add_whatsapp_channel.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class AddWhatsappChannel < ActiveRecord::Migration[6.1]
- def change
- create_table :channel_whatsapp do |t|
- t.integer :account_id, null: false
- t.string :phone_number, null: false, index: { unique: true }
- t.string :provider, default: 'default'
- t.jsonb :provider_config, default: {}
- t.timestamps
- end
- end
-end
diff --git a/db/migrate/20210922082754_add_assignee_last_seen.rb b/db/migrate/20210922082754_add_assignee_last_seen.rb
deleted file mode 100644
index 41ff17818..000000000
--- a/db/migrate/20210922082754_add_assignee_last_seen.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddAssigneeLastSeen < ActiveRecord::Migration[6.1]
- def change
- add_column :conversations, :assignee_last_seen_at, :datetime
- end
-end
diff --git a/db/migrate/20210923132659_set_content_type_text_for_the_old_messages.rb b/db/migrate/20210923132659_set_content_type_text_for_the_old_messages.rb
deleted file mode 100644
index d9af6f19b..000000000
--- a/db/migrate/20210923132659_set_content_type_text_for_the_old_messages.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class SetContentTypeTextForTheOldMessages < ActiveRecord::Migration[6.1]
- def change
- change_column_null(:messages, :content_type, false, 0)
- end
-end
diff --git a/db/migrate/20210923190418_add_online_status_to_account_users.rb b/db/migrate/20210923190418_add_online_status_to_account_users.rb
deleted file mode 100644
index 00b2d4999..000000000
--- a/db/migrate/20210923190418_add_online_status_to_account_users.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-class AddOnlineStatusToAccountUsers < ActiveRecord::Migration[6.1]
- def change
- change_table :account_users, bulk: true do |t|
- t.integer :availability, default: 0, null: false
- t.boolean :auto_offline, default: true, null: false
- end
- end
-
- # run as a seperate data migration if you want to migrate the user statuses
- def update_existing_user_availability
- User.find_in_batches do |user_batch|
- user_batch.each do |user|
- availability = user.availability
- user.account_users.update(availability: availability)
- end
- end
- end
-end
diff --git a/db/migrate/20210927062350_add_trigger_only_during_business_hours_collect_to_campaigns.rb b/db/migrate/20210927062350_add_trigger_only_during_business_hours_collect_to_campaigns.rb
deleted file mode 100644
index 480f17d66..000000000
--- a/db/migrate/20210927062350_add_trigger_only_during_business_hours_collect_to_campaigns.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddTriggerOnlyDuringBusinessHoursCollectToCampaigns < ActiveRecord::Migration[6.1]
- def change
- add_column :campaigns, :trigger_only_during_business_hours, :boolean, default: false
- end
-end
diff --git a/db/migrate/20211012135050_add_limits_to_accounts.rb b/db/migrate/20211012135050_add_limits_to_accounts.rb
deleted file mode 100644
index 8f5b28c25..000000000
--- a/db/migrate/20211012135050_add_limits_to_accounts.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddLimitsToAccounts < ActiveRecord::Migration[6.1]
- def change
- add_column :accounts, :limits, :jsonb, default: {}
- end
-end
diff --git a/db/migrate/20211027073553_add_imap_smtp_config_to_channel_email.rb b/db/migrate/20211027073553_add_imap_smtp_config_to_channel_email.rb
deleted file mode 100644
index 7bd7aca50..000000000
--- a/db/migrate/20211027073553_add_imap_smtp_config_to_channel_email.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-class AddImapSmtpConfigToChannelEmail < ActiveRecord::Migration[6.1]
- def change
- change_table :channel_email, bulk: true do |t|
- # IMAP
- t.boolean :imap_enabled, default: false
- t.string :imap_address, default: ''
- t.integer :imap_port, default: 0
- t.string :imap_email, default: ''
- t.string :imap_password, default: ''
- t.boolean :imap_enable_ssl, default: true
- t.datetime :imap_inbox_synced_at
-
- # SMTP
- t.boolean :smtp_enabled, default: false
- t.string :smtp_address, default: ''
- t.integer :smtp_port, default: 0
- t.string :smtp_email, default: ''
- t.string :smtp_password, default: ''
- t.string :smtp_domain, default: ''
- t.boolean :smtp_enable_starttls_auto, default: true
- t.string :smtp_authentication, default: 'login'
- end
- end
-end
diff --git a/db/migrate/20211109143122_add_tweet_enabled_flag_to_twitter_channel.rb b/db/migrate/20211109143122_add_tweet_enabled_flag_to_twitter_channel.rb
deleted file mode 100644
index 02846a2c9..000000000
--- a/db/migrate/20211109143122_add_tweet_enabled_flag_to_twitter_channel.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddTweetEnabledFlagToTwitterChannel < ActiveRecord::Migration[6.1]
- def change
- add_column :channel_twitter_profiles, :tweets_enabled, :boolean, default: true
- end
-end
diff --git a/db/migrate/20211110101046_create_automation_rules.rb b/db/migrate/20211110101046_create_automation_rules.rb
deleted file mode 100644
index ee7349413..000000000
--- a/db/migrate/20211110101046_create_automation_rules.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-class CreateAutomationRules < ActiveRecord::Migration[6.1]
- def change
- create_table :automation_rules do |t|
- t.bigint :account_id, null: false
- t.string :name, null: false
- t.text :description
- t.string :event_name, null: false
- t.jsonb :conditions, null: false, default: '{}'
- t.jsonb :actions, null: false, default: '{}'
- t.timestamps
- t.index :account_id, name: 'index_automation_rules_on_account_id'
- end
- end
-end
diff --git a/db/migrate/20211116131740_add_values_to_custom_attribute_definitions.rb b/db/migrate/20211116131740_add_values_to_custom_attribute_definitions.rb
deleted file mode 100644
index 2625fe30c..000000000
--- a/db/migrate/20211116131740_add_values_to_custom_attribute_definitions.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddValuesToCustomAttributeDefinitions < ActiveRecord::Migration[6.1]
- def change
- add_column :custom_attribute_definitions, :values, :jsonb, default: []
- end
-end
diff --git a/db/migrate/20211118100301_change_values_to_attribute_values_in_custom_attribute_definitions.rb b/db/migrate/20211118100301_change_values_to_attribute_values_in_custom_attribute_definitions.rb
deleted file mode 100644
index fdf8fd661..000000000
--- a/db/migrate/20211118100301_change_values_to_attribute_values_in_custom_attribute_definitions.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class ChangeValuesToAttributeValuesInCustomAttributeDefinitions < ActiveRecord::Migration[6.1]
- def change
- rename_column :custom_attribute_definitions, :values, :attribute_values
- end
-end
diff --git a/db/migrate/20211122061012_add_pub_sub_token_to_contact_inbox.rb b/db/migrate/20211122061012_add_pub_sub_token_to_contact_inbox.rb
deleted file mode 100644
index 7ba816efc..000000000
--- a/db/migrate/20211122061012_add_pub_sub_token_to_contact_inbox.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-class AddPubSubTokenToContactInbox < ActiveRecord::Migration[6.1]
- def change
- add_column :contact_inboxes, :pubsub_token, :string
- add_index :contact_inboxes, :pubsub_token, unique: true
- end
-end
diff --git a/db/migrate/20211122112607_remove_invalid_migration.rb b/db/migrate/20211122112607_remove_invalid_migration.rb
deleted file mode 100644
index 51a9701c8..000000000
--- a/db/migrate/20211122112607_remove_invalid_migration.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-class RemoveInvalidMigration < ActiveRecord::Migration[6.1]
- def change
- return unless ActiveRecord::Base.connection.table_exists? 'actions'
-
- drop_table :actions do |t|
- t.string :name
- t.jsonb :execution_list
- t.datetime :created_at
- t.datetime :updated_at
- t.index ['name'], name: 'index_actions_on_name'
- end
- end
-end
diff --git a/db/migrate/20211129120040_add_templates_to_whatsapp_channel.rb b/db/migrate/20211129120040_add_templates_to_whatsapp_channel.rb
deleted file mode 100644
index 247fd9095..000000000
--- a/db/migrate/20211129120040_add_templates_to_whatsapp_channel.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class AddTemplatesToWhatsappChannel < ActiveRecord::Migration[6.1]
- def up
- change_table :channel_whatsapp, bulk: true do |t|
- t.column :message_templates, :jsonb, default: {}
- t.column :message_templates_last_updated, :datetime
- end
- end
-
- def down
- change_table :channel_whatsapp, bulk: true do |t|
- t.remove :message_templates
- t.remove :message_templates_last_updated
- end
- end
-end
diff --git a/db/migrate/20211201224513_create_mentions.rb b/db/migrate/20211201224513_create_mentions.rb
deleted file mode 100644
index 736be1ccf..000000000
--- a/db/migrate/20211201224513_create_mentions.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-class CreateMentions < ActiveRecord::Migration[6.1]
- def change
- create_table :mentions do |t|
- t.references :user, null: false, foreign_key: true
- t.references :conversation, null: false, foreign_key: true
- t.references :account, index: true, null: false
- t.datetime :mentioned_at, null: false
- t.timestamps
- end
-
- add_index :mentions, [:user_id, :conversation_id], unique: true
- end
-end
diff --git a/db/migrate/20211207113102_remove_attribute_key_index_on_custom_attribute_definition.rb b/db/migrate/20211207113102_remove_attribute_key_index_on_custom_attribute_definition.rb
deleted file mode 100644
index 9beed0de6..000000000
--- a/db/migrate/20211207113102_remove_attribute_key_index_on_custom_attribute_definition.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class RemoveAttributeKeyIndexOnCustomAttributeDefinition < ActiveRecord::Migration[6.1]
- def change
- remove_index :custom_attribute_definitions, [:attribute_key, :account_id], name: 'attribute_key_model_index',
- if_exists: true
- add_index :custom_attribute_definitions, [:attribute_key, :account_id], unique: true, name: 'attribute_key_index', if_not_exists: true
- end
-end
diff --git a/db/migrate/20211208081344_add_attribute_model_index_on_custom_attribute_definition.rb b/db/migrate/20211208081344_add_attribute_model_index_on_custom_attribute_definition.rb
deleted file mode 100644
index a79826668..000000000
--- a/db/migrate/20211208081344_add_attribute_model_index_on_custom_attribute_definition.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-class AddAttributeModelIndexOnCustomAttributeDefinition < ActiveRecord::Migration[6.1]
- def change
- remove_index :custom_attribute_definitions, [:attribute_key, :account_id], name: 'attribute_key_index',
- if_exists: true
- add_index :custom_attribute_definitions, [:attribute_key, :attribute_model, :account_id], unique: true, name: 'attribute_key_model_index',
- if_not_exists: true
- end
-end
diff --git a/db/migrate/20211208085931_update_contact_inbox_foreign_key.rb b/db/migrate/20211208085931_update_contact_inbox_foreign_key.rb
deleted file mode 100644
index 100d410d6..000000000
--- a/db/migrate/20211208085931_update_contact_inbox_foreign_key.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-class UpdateContactInboxForeignKey < ActiveRecord::Migration[6.1]
- def change
- remove_foreign_key :contact_inboxes, :contacts
- add_foreign_key :contact_inboxes, :contacts, on_delete: :cascade
-
- remove_foreign_key :contact_inboxes, :inboxes
- add_foreign_key :contact_inboxes, :inboxes, on_delete: :cascade
-
- remove_foreign_key :conversations, :contact_inboxes
- add_foreign_key :conversations, :contact_inboxes, on_delete: :cascade
- end
-end
diff --git a/db/migrate/20211216110209_add_allow_messages_after_resolved_to_inbox.rb b/db/migrate/20211216110209_add_allow_messages_after_resolved_to_inbox.rb
deleted file mode 100644
index 4c44ac2bb..000000000
--- a/db/migrate/20211216110209_add_allow_messages_after_resolved_to_inbox.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-class AddAllowMessagesAfterResolvedToInbox < ActiveRecord::Migration[6.1]
- def change
- add_column :inboxes, :allow_messages_after_resolved, :boolean, default: true
-
- update_csat_enabled_inboxes
- end
-
- def update_csat_enabled_inboxes
- ::Inbox.where(channel_type: 'Channel::WebWidget', csat_survey_enabled: true).find_in_batches do |inboxes_batch|
- inboxes_batch.each do |inbox|
- inbox.allow_messages_after_resolved = false
- inbox.save!
- end
- end
- end
-end
diff --git a/db/migrate/20211219031453_update_foreign_keys_on_delete.rb b/db/migrate/20211219031453_update_foreign_keys_on_delete.rb
deleted file mode 100644
index 61e71cc52..000000000
--- a/db/migrate/20211219031453_update_foreign_keys_on_delete.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-class UpdateForeignKeysOnDelete < ActiveRecord::Migration[6.1]
- def change
- remove_foreign_key 'account_users', 'accounts'
- add_foreign_key 'account_users', 'accounts', on_delete: :cascade
-
- remove_foreign_key 'account_users', 'users'
- add_foreign_key 'account_users', 'users', on_delete: :cascade
-
- remove_foreign_key 'agent_bots', 'accounts'
- add_foreign_key 'agent_bots', 'accounts', on_delete: :cascade
-
- remove_foreign_key 'campaigns', 'accounts'
- add_foreign_key 'campaigns', 'accounts', on_delete: :cascade
-
- remove_foreign_key 'campaigns', 'inboxes'
- add_foreign_key 'campaigns', 'inboxes', on_delete: :cascade
-
- remove_foreign_key 'conversations', 'campaigns'
- add_foreign_key 'conversations', 'campaigns', on_delete: :cascade
-
- remove_foreign_key 'conversations', 'teams'
- add_foreign_key 'conversations', 'teams', on_delete: :cascade
-
- remove_foreign_key 'csat_survey_responses', 'accounts'
- add_foreign_key 'csat_survey_responses', 'accounts', on_delete: :cascade
-
- remove_foreign_key 'csat_survey_responses', 'contacts'
- add_foreign_key 'csat_survey_responses', 'contacts', on_delete: :cascade
-
- remove_foreign_key 'csat_survey_responses', 'conversations'
- add_foreign_key 'csat_survey_responses', 'conversations', on_delete: :cascade
-
- remove_foreign_key 'csat_survey_responses', 'messages'
- add_foreign_key 'csat_survey_responses', 'messages', on_delete: :cascade
-
- remove_foreign_key 'csat_survey_responses', 'users', column: 'assigned_agent_id'
- add_foreign_key 'csat_survey_responses', 'users', column: 'assigned_agent_id', on_delete: :cascade
-
- remove_foreign_key 'data_imports', 'accounts'
- add_foreign_key 'data_imports', 'accounts', on_delete: :cascade
-
- remove_foreign_key 'mentions', 'conversations'
- add_foreign_key 'mentions', 'conversations', on_delete: :cascade
-
- remove_foreign_key 'mentions', 'users'
- add_foreign_key 'mentions', 'users', on_delete: :cascade
-
- remove_foreign_key 'notes', 'accounts'
- add_foreign_key 'notes', 'accounts', on_delete: :cascade
-
- remove_foreign_key 'notes', 'contacts'
- add_foreign_key 'notes', 'contacts', on_delete: :cascade
-
- remove_foreign_key 'notes', 'users'
- add_foreign_key 'notes', 'users', on_delete: :cascade
-
- remove_foreign_key 'team_members', 'teams'
- add_foreign_key 'team_members', 'teams', on_delete: :cascade
-
- remove_foreign_key 'team_members', 'users'
- add_foreign_key 'team_members', 'users', on_delete: :cascade
-
- remove_foreign_key 'teams', 'accounts'
- add_foreign_key 'teams', 'accounts', on_delete: :cascade
- end
-end
diff --git a/db/migrate/20211221125545_add_unique_index_on_inbox_members.rb b/db/migrate/20211221125545_add_unique_index_on_inbox_members.rb
deleted file mode 100644
index 0af4219e7..000000000
--- a/db/migrate/20211221125545_add_unique_index_on_inbox_members.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# ref: https://dev.to/nodefiend/rails-migration-adding-a-unique-index-and-deleting-duplicates-5cde
-
-class AddUniqueIndexOnInboxMembers < ActiveRecord::Migration[6.1]
- def up
- # partioning the duplicate records and then removing where more than one row is found
- ActiveRecord::Base.connection.execute('
- DELETE FROM inbox_members WHERE id IN (SELECT id from (
- SELECT id, user_id, inbox_id, ROW_NUMBER() OVER w AS rnum FROM inbox_members WINDOW w AS (
- PARTITION BY inbox_id, user_id ORDER BY id
- )
- ) t WHERE t.rnum > 1)
- ')
- add_index :inbox_members, [:inbox_id, :user_id], unique: true
- end
-
- def down
- remove_index :inbox_members, [:inbox_id, :user_id]
- end
-end
diff --git a/db/migrate/20220110090126_add_active_flag_to_automation_rule.rb b/db/migrate/20220110090126_add_active_flag_to_automation_rule.rb
deleted file mode 100644
index cd1d73270..000000000
--- a/db/migrate/20220110090126_add_active_flag_to_automation_rule.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddActiveFlagToAutomationRule < ActiveRecord::Migration[6.1]
- def change
- add_column :automation_rules, :active, :boolean, default: true, null: false
- end
-end
diff --git a/db/migrate/20220111200105_update_nil_contact_attributes_to_empty_hash.rb b/db/migrate/20220111200105_update_nil_contact_attributes_to_empty_hash.rb
deleted file mode 100644
index 31881fe1d..000000000
--- a/db/migrate/20220111200105_update_nil_contact_attributes_to_empty_hash.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-class UpdateNilContactAttributesToEmptyHash < ActiveRecord::Migration[6.1]
- def change
- # rubocop:disable Rails/SkipsModelValidations
- Contact.where(custom_attributes: nil).update_all(custom_attributes: {})
- Contact.where(additional_attributes: nil).update_all(additional_attributes: {})
- # rubocop:enable Rails/SkipsModelValidations
- end
-end
diff --git a/db/migrate/20220111223630_remove_platform_app_permissible_access_tokens.rb b/db/migrate/20220111223630_remove_platform_app_permissible_access_tokens.rb
deleted file mode 100644
index 2afbde57e..000000000
--- a/db/migrate/20220111223630_remove_platform_app_permissible_access_tokens.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class RemovePlatformAppPermissibleAccessTokens < ActiveRecord::Migration[6.1]
- def change
- AccessToken.where(owner_type: 'PlatformAppPermissible').destroy_all
- end
-end
diff --git a/db/migrate/20220116103902_add_open_ssl_verify_mode_to_channel_email.rb b/db/migrate/20220116103902_add_open_ssl_verify_mode_to_channel_email.rb
deleted file mode 100644
index 77cddc7c5..000000000
--- a/db/migrate/20220116103902_add_open_ssl_verify_mode_to_channel_email.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-class AddOpenSslVerifyModeToChannelEmail < ActiveRecord::Migration[6.1]
- def change
- change_table :channel_email, bulk: true do |t|
- t.string :smtp_openssl_verify_mode, default: 'none'
- t.boolean :smtp_enable_ssl_tls, default: false
- end
- end
-end
diff --git a/db/migrate/20220119051739_enable_conversation_continuity.rb b/db/migrate/20220119051739_enable_conversation_continuity.rb
deleted file mode 100644
index 0deb5f0d6..000000000
--- a/db/migrate/20220119051739_enable_conversation_continuity.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class EnableConversationContinuity < ActiveRecord::Migration[6.1]
- def change
- add_column :channel_web_widgets, :continuity_via_email, :boolean, null: false, default: true
- end
-end
diff --git a/db/migrate/20220121055444_add_type_to_users.rb b/db/migrate/20220121055444_add_type_to_users.rb
deleted file mode 100644
index b4e0687b5..000000000
--- a/db/migrate/20220121055444_add_type_to_users.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-class AddTypeToUsers < ActiveRecord::Migration[6.1]
- def change
- add_column :users, :type, :string
- migrate_existing_super_admins
-
- drop_table :super_admins do |t|
- t.string :email, null: false, default: ''
- t.string :encrypted_password, null: false, default: ''
- t.datetime :remember_created_at
- t.integer :sign_in_count, default: 0, null: false
- t.datetime :current_sign_in_at
- t.datetime :last_sign_in_at
- t.inet :current_sign_in_ip
- t.inet :last_sign_in_ip
- t.timestamps null: false
- end
- end
-
- private
-
- def old_super_admins
- ActiveRecord::Base.connection.execute('SELECT * from super_admins').to_a
- end
-
- def create_user_account_for_super_admin(super_admin)
- u = User.new(email: super_admin['email'], name: "SuperUser #{super_admin['id']}", encrypted_password: super_admin['encrypted_password'],
- confirmed_at: DateTime.now, type: 'SuperAdmin')
- u.save(validate: false)
- end
-
- def migrate_existing_super_admins
- old_super_admins.each do |super_admin|
- user = User.find_by(email: super_admin['email'])
- if user.present?
- user.update(type: 'SuperAdmin')
- else
- Rails.logger.debug { "User with email #{super_admin['email']} not found" }
- create_user_account_for_super_admin(super_admin)
- end
- end
- end
-end
diff --git a/db/migrate/20220129024443_add_sms_channel.rb b/db/migrate/20220129024443_add_sms_channel.rb
deleted file mode 100644
index c65019f7e..000000000
--- a/db/migrate/20220129024443_add_sms_channel.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class AddSmsChannel < ActiveRecord::Migration[6.1]
- def change
- create_table :channel_sms do |t|
- t.integer :account_id, null: false
- t.string :phone_number, null: false, index: { unique: true }
- t.string :provider, default: 'default'
- t.jsonb :provider_config, default: {}
- t.timestamps
- end
- end
-end
diff --git a/db/migrate/20220131081750_add_email_signature_to_user.rb b/db/migrate/20220131081750_add_email_signature_to_user.rb
deleted file mode 100644
index 54edc049e..000000000
--- a/db/migrate/20220131081750_add_email_signature_to_user.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-class AddEmailSignatureToUser < ActiveRecord::Migration[6.1]
- def change
- change_table :users, bulk: true do |t|
- t.boolean :message_signature_enabled, null: false, default: false
- t.text :message_signature, null: true
- end
- end
-end
diff --git a/db/migrate/20220207124741_add_direct_uploads_to_installation_config.rb b/db/migrate/20220207124741_add_direct_uploads_to_installation_config.rb
deleted file mode 100644
index 1261eae64..000000000
--- a/db/migrate/20220207124741_add_direct_uploads_to_installation_config.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddDirectUploadsToInstallationConfig < ActiveRecord::Migration[6.1]
- def change
- ConfigLoader.new.process
- end
-end
diff --git a/db/migrate/20220215060751_remove_message_signature_enabled.rb b/db/migrate/20220215060751_remove_message_signature_enabled.rb
deleted file mode 100644
index e627ba34f..000000000
--- a/db/migrate/20220215060751_remove_message_signature_enabled.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class RemoveMessageSignatureEnabled < ActiveRecord::Migration[6.1]
- def change
- remove_column :users, :message_signature_enabled, :boolean
- end
-end
diff --git a/db/migrate/20220216151613_add_open_all_day_to_working_hour.rb b/db/migrate/20220216151613_add_open_all_day_to_working_hour.rb
deleted file mode 100644
index 138f6edb6..000000000
--- a/db/migrate/20220216151613_add_open_all_day_to_working_hour.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddOpenAllDayToWorkingHour < ActiveRecord::Migration[6.1]
- def change
- add_column :working_hours, :open_all_day, :boolean, default: false
- end
-end
diff --git a/db/migrate/20220218120357_add_h_captcha_key.rb b/db/migrate/20220218120357_add_h_captcha_key.rb
deleted file mode 100644
index 02b06e5d3..000000000
--- a/db/migrate/20220218120357_add_h_captcha_key.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddHCaptchaKey < ActiveRecord::Migration[6.1]
- def change
- ConfigLoader.new.process
- end
-end
diff --git a/db/migrate/20220315204137_add_account_sid_unique_index_to_channel_twilio_sms.rb b/db/migrate/20220315204137_add_account_sid_unique_index_to_channel_twilio_sms.rb
deleted file mode 100644
index e9bb5e189..000000000
--- a/db/migrate/20220315204137_add_account_sid_unique_index_to_channel_twilio_sms.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-class AddAccountSidUniqueIndexToChannelTwilioSms < ActiveRecord::Migration[6.1]
- def change
- clear_possible_duplicates
-
- has_duplicates = Channel::TwilioSms.select(:phone_number).group(:phone_number).having('count(*) > 1').exists?
-
- if has_duplicates
- raise <<~ERR.squish
- ERROR: You have duplicate values for phone_number in "channel_twilio_sms".
- This causes Twilio account lookup to behave unpredictably. Please eliminate the duplicates
- and then re-run this migration.
- ERR
- end
-
- remove_index :channel_twilio_sms, [:account_id, :phone_number], unique: true
- add_index :channel_twilio_sms, :phone_number, unique: true
- # since look ups are done via account_sid + phone_number, we need to add a unique index
- add_index :channel_twilio_sms, [:account_sid, :phone_number], unique: true
- end
-
- def clear_possible_duplicates
- # based on the look up in saas it seems like only the first inbox is used in case of duplicates,
- # so lets try to clear our inboxes with out conversations
- duplicate_phone_numbers = Channel::TwilioSms.select(:phone_number).group(:phone_number).having('count(*) > 1').collect(&:phone_number)
- duplicate_phone_numbers.each do |phone_number|
- # we are skipping the first inbox that was created
- Channel::TwilioSms.where(phone_number: phone_number).drop(1).each do |channel|
- inbox = channel.inbox
- # skip inboxes with conversations
- next if inbox.conversations.count.positive?
-
- inbox.destroy
- end
- end
-
- # clear the accounts created with twilio sandbox whatsapp number
- # Channel::TwilioSms.where(phone_number: 'whatsapp:+14155238886').each { |channel| channel.inbox.destroy }
- end
-end
diff --git a/db/migrate/20220316054933_add_custom_fields_to_pre_chat_form.rb b/db/migrate/20220316054933_add_custom_fields_to_pre_chat_form.rb
deleted file mode 100644
index a2fe3d9a7..000000000
--- a/db/migrate/20220316054933_add_custom_fields_to_pre_chat_form.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-class AddCustomFieldsToPreChatForm < ActiveRecord::Migration[6.1]
- def change
- Channel::WebWidget.find_in_batches do |channels_batch|
- channels_batch.each do |channel|
- pre_chat_message = channel[:pre_chat_form_options]['pre_chat_message'] || 'Share your queries or comments here.'
- pre_chat_fields = pre_chat_fields?(channel)
- channel[:pre_chat_form_options] = {
- 'pre_chat_message': pre_chat_message,
- 'pre_chat_fields': pre_chat_fields
- }
- channel.save!
- end
- end
- end
-
- def pre_chat_fields?(channel)
- email_enabled = channel[:pre_chat_form_options]['require_email'] || false
- [
- {
- 'field_type': 'standard', 'label': 'Email Id', 'name': 'emailAddress', 'type': 'email', 'required': true, 'enabled': email_enabled
- },
- {
- 'field_type': 'standard', 'label': 'Full name', 'name': 'fullName', 'type': 'text', 'required': false, 'enabled': false
- }, {
- 'field_type': 'standard', 'label': 'Phone number', 'name': 'phoneNumber', 'type': 'text', 'required': false, 'enabled': false
- }
- ]
- end
-end
diff --git a/db/migrate/20220317171031_add_messaging_service_sid_to_channel_twilio_sms.rb b/db/migrate/20220317171031_add_messaging_service_sid_to_channel_twilio_sms.rb
deleted file mode 100644
index 2c8e18ec1..000000000
--- a/db/migrate/20220317171031_add_messaging_service_sid_to_channel_twilio_sms.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class AddMessagingServiceSidToChannelTwilioSms < ActiveRecord::Migration[6.1]
- def change
- change_column_null :channel_twilio_sms, :phone_number, true
- add_column :channel_twilio_sms, :messaging_service_sid, :string
- add_index :channel_twilio_sms, [:messaging_service_sid], unique: true
- end
-end
diff --git a/db/migrate/20220329131401_add_value_in_business_hours_to_reporting_event.rb b/db/migrate/20220329131401_add_value_in_business_hours_to_reporting_event.rb
deleted file mode 100644
index 4b8138eb7..000000000
--- a/db/migrate/20220329131401_add_value_in_business_hours_to_reporting_event.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class AddValueInBusinessHoursToReportingEvent < ActiveRecord::Migration[6.1]
- def change
- change_table :reporting_events, bulk: true do |t|
- t.float :value_in_business_hours, default: nil
- t.datetime :event_start_time, default: nil
- t.datetime :event_end_time, default: nil
- end
- end
-end
diff --git a/db/migrate/20220405092033_update_web_widget_feature_flags.rb b/db/migrate/20220405092033_update_web_widget_feature_flags.rb
deleted file mode 100644
index 5b534aa15..000000000
--- a/db/migrate/20220405092033_update_web_widget_feature_flags.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-class UpdateWebWidgetFeatureFlags < ActiveRecord::Migration[6.1]
- def change
- change_column_default(:channel_web_widgets, :feature_flags, from: 3, to: 7)
-
- set_end_conversation_to_default
- end
-
- def set_end_conversation_to_default
- ::Channel::WebWidget.find_in_batches do |widget_batch|
- widget_batch.each do |widget|
- widget.end_conversation = true
- widget.save!
- end
- end
- end
-end
diff --git a/db/migrate/20220409044943_rename_imap_email_and_smtp_email_columns.rb b/db/migrate/20220409044943_rename_imap_email_and_smtp_email_columns.rb
deleted file mode 100644
index 4518647b4..000000000
--- a/db/migrate/20220409044943_rename_imap_email_and_smtp_email_columns.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-class RenameImapEmailAndSmtpEmailColumns < ActiveRecord::Migration[6.1]
- def change
- rename_column :channel_email, :imap_email, :imap_login
- rename_column :channel_email, :smtp_email, :smtp_login
- end
-end
diff --git a/db/migrate/20220416203340_add_config_to_portal.rb b/db/migrate/20220416203340_add_config_to_portal.rb
deleted file mode 100644
index 27cd53773..000000000
--- a/db/migrate/20220416203340_add_config_to_portal.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddConfigToPortal < ActiveRecord::Migration[6.1]
- def change
- add_column :kbase_portals, :config, :jsonb, default: { allowed_locales: ['en'] }
- end
-end
diff --git a/db/migrate/20220416205519_add_locale_to_kbase_category.rb b/db/migrate/20220416205519_add_locale_to_kbase_category.rb
deleted file mode 100644
index 04cdc4bf3..000000000
--- a/db/migrate/20220416205519_add_locale_to_kbase_category.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class AddLocaleToKbaseCategory < ActiveRecord::Migration[6.1]
- def change
- add_column :kbase_categories, :locale, :string, default: 'en'
- add_index :kbase_categories, :locale
- add_index :kbase_categories, [:locale, :account_id]
- end
-end
diff --git a/db/migrate/20220418094715_remove_contact_pubsub_token.rb b/db/migrate/20220418094715_remove_contact_pubsub_token.rb
deleted file mode 100644
index e625b9046..000000000
--- a/db/migrate/20220418094715_remove_contact_pubsub_token.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class RemoveContactPubsubToken < ActiveRecord::Migration[6.1]
- def change
- remove_column :contacts, :pubsub_token, :string
- end
-end
diff --git a/db/migrate/20220424081117_add_subscriptions_to_webhooks.rb b/db/migrate/20220424081117_add_subscriptions_to_webhooks.rb
deleted file mode 100644
index b4e8d4dfc..000000000
--- a/db/migrate/20220424081117_add_subscriptions_to_webhooks.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-class AddSubscriptionsToWebhooks < ActiveRecord::Migration[6.1]
- def change
- add_column :webhooks, :subscriptions, :jsonb, default: %w[
- conversation_status_changed
- conversation_updated
- conversation_created
- message_created
- message_updated
- webwidget_triggered
- ]
- end
-end
diff --git a/db/migrate/20220428101325_add_index_to_conversation_and_reporting_event.rb b/db/migrate/20220428101325_add_index_to_conversation_and_reporting_event.rb
deleted file mode 100644
index f1b982a8b..000000000
--- a/db/migrate/20220428101325_add_index_to_conversation_and_reporting_event.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-class AddIndexToConversationAndReportingEvent < ActiveRecord::Migration[6.1]
- def change
- add_index :conversations, :last_activity_at
- add_index :reporting_events, :conversation_id
- end
-end
diff --git a/db/migrate/20220506061540_change_kbase_portals_to_portals.rb b/db/migrate/20220506061540_change_kbase_portals_to_portals.rb
deleted file mode 100644
index c9765abbb..000000000
--- a/db/migrate/20220506061540_change_kbase_portals_to_portals.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class ChangeKbasePortalsToPortals < ActiveRecord::Migration[6.1]
- def change
- rename_table :kbase_portals, :portals
- end
-end
diff --git a/db/migrate/20220506064938_create_portals_members_join_table.rb b/db/migrate/20220506064938_create_portals_members_join_table.rb
deleted file mode 100644
index a24bb7356..000000000
--- a/db/migrate/20220506064938_create_portals_members_join_table.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class CreatePortalsMembersJoinTable < ActiveRecord::Migration[6.1]
- def change
- create_join_table :portals, :users, table_name: :portals_members do |t|
- t.index :portal_id
- t.index :user_id
- t.index [:portal_id, :user_id], unique: true
- end
- end
-end
diff --git a/db/migrate/20220506072007_change_kbase_categories_to_categories.rb b/db/migrate/20220506072007_change_kbase_categories_to_categories.rb
deleted file mode 100644
index b527e3e80..000000000
--- a/db/migrate/20220506072007_change_kbase_categories_to_categories.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class ChangeKbaseCategoriesToCategories < ActiveRecord::Migration[6.1]
- def change
- rename_table :kbase_categories, :categories
- end
-end
diff --git a/db/migrate/20220506080338_change_kbase_folders_to_folders.rb b/db/migrate/20220506080338_change_kbase_folders_to_folders.rb
deleted file mode 100644
index 8e0ba6642..000000000
--- a/db/migrate/20220506080338_change_kbase_folders_to_folders.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class ChangeKbaseFoldersToFolders < ActiveRecord::Migration[6.1]
- def change
- rename_table :kbase_folders, :folders
- end
-end
diff --git a/db/migrate/20220506080429_change_kbase_articles_to_articles.rb b/db/migrate/20220506080429_change_kbase_articles_to_articles.rb
deleted file mode 100644
index ba041ca84..000000000
--- a/db/migrate/20220506080429_change_kbase_articles_to_articles.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class ChangeKbaseArticlesToArticles < ActiveRecord::Migration[6.1]
- def change
- rename_table :kbase_articles, :articles
- end
-end
diff --git a/db/migrate/20220506163839_add_additional_attributes_to_message.rb b/db/migrate/20220506163839_add_additional_attributes_to_message.rb
deleted file mode 100644
index 713584c41..000000000
--- a/db/migrate/20220506163839_add_additional_attributes_to_message.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-class AddAdditionalAttributesToMessage < ActiveRecord::Migration[6.1]
- disable_ddl_transaction!
-
- def up
- add_column :messages, :additional_attributes, :jsonb, default: {}
- add_index :messages, "((additional_attributes->'campaign_id'))", name: 'index_messages_on_additional_attributes_campaign_id', using: 'gin',
- algorithm: :concurrently
- end
-
- def down
- remove_index :messages, name: 'index_messages_on_additional_attributes_campaign_id'
- remove_column :messages, :additional_attributes
- end
-end
diff --git a/db/migrate/20220511072655_add_archive_column_to_portal.rb b/db/migrate/20220511072655_add_archive_column_to_portal.rb
deleted file mode 100644
index b3a504e97..000000000
--- a/db/migrate/20220511072655_add_archive_column_to_portal.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddArchiveColumnToPortal < ActiveRecord::Migration[6.1]
- def change
- add_column :portals, :archived, :boolean, default: false
- end
-end
diff --git a/db/migrate/20220513145010_add_first_reply_activity_at_to_conversation.rb b/db/migrate/20220513145010_add_first_reply_activity_at_to_conversation.rb
deleted file mode 100644
index 9afb58feb..000000000
--- a/db/migrate/20220513145010_add_first_reply_activity_at_to_conversation.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-class AddFirstReplyActivityAtToConversation < ActiveRecord::Migration[6.1]
- def change
- add_column :conversations, :first_reply_created_at, :datetime
- add_index :conversations, :first_reply_created_at
-
- # rubocop:disable Rails/SkipsModelValidations
- ::Conversation.update_all(first_reply_created_at: Time.now.utc)
- # rubocop:enable Rails/SkipsModelValidations
-
- backfill_first_reply_activity_at_to_conversations
- end
-
- private
-
- def backfill_first_reply_activity_at_to_conversations
- ::Account.find_in_batches do |account_batch|
- Rails.logger.info "Migrated till #{account_batch.first.id}\n"
- account_batch.each do |account|
- Migration::ConversationsFirstReplySchedulerJob.perform_later(account)
- end
- end
- end
-end
diff --git a/db/migrate/20220525141844_create_dashboard_apps.rb b/db/migrate/20220525141844_create_dashboard_apps.rb
deleted file mode 100644
index 0e4fee9e2..000000000
--- a/db/migrate/20220525141844_create_dashboard_apps.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class CreateDashboardApps < ActiveRecord::Migration[6.1]
- def change
- create_table :dashboard_apps do |t|
- t.string :title, null: false
- t.jsonb :content, default: []
- t.references :account, null: false, foreign_key: true
- t.references :user, foreign_key: true
- t.timestamps
- end
- end
-end
diff --git a/db/migrate/20220527040433_add_auto_assignment_configuration_to_inboxes.rb b/db/migrate/20220527040433_add_auto_assignment_configuration_to_inboxes.rb
deleted file mode 100644
index 31e324ce9..000000000
--- a/db/migrate/20220527040433_add_auto_assignment_configuration_to_inboxes.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddAutoAssignmentConfigurationToInboxes < ActiveRecord::Migration[6.1]
- def change
- add_column :inboxes, :auto_assignment_config, :jsonb, default: {}
- end
-end
diff --git a/db/migrate/20220527080906_add_reference_for_author_id.rb b/db/migrate/20220527080906_add_reference_for_author_id.rb
deleted file mode 100644
index cf7fd22fc..000000000
--- a/db/migrate/20220527080906_add_reference_for_author_id.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-class AddReferenceForAuthorId < ActiveRecord::Migration[6.1]
- def change
- remove_column :articles, :author_id, :integer
- add_reference :articles, :author, foreign_key: { to_table: :users }
- end
-end
diff --git a/db/migrate/20220527120826_add_index_on_category_slug_and_locale.rb b/db/migrate/20220527120826_add_index_on_category_slug_and_locale.rb
deleted file mode 100644
index be17caac7..000000000
--- a/db/migrate/20220527120826_add_index_on_category_slug_and_locale.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class AddIndexOnCategorySlugAndLocale < ActiveRecord::Migration[6.1]
- def change
- add_column :categories, :slug, :string, null: false, default: ''
- add_index :categories, [:slug, :locale, :portal_id], unique: true
- change_column_default :categories, :slug, from: '', to: nil
- end
-end
diff --git a/db/migrate/20220608084622_add_associated_article_id.rb b/db/migrate/20220608084622_add_associated_article_id.rb
deleted file mode 100644
index f6cefb74c..000000000
--- a/db/migrate/20220608084622_add_associated_article_id.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddAssociatedArticleId < ActiveRecord::Migration[6.1]
- def change
- add_reference :articles, :associated_article, foreign_key: { to_table: :articles }
- end
-end
diff --git a/db/migrate/20220610091206_add_additional_attributes_to_api_channel.rb b/db/migrate/20220610091206_add_additional_attributes_to_api_channel.rb
deleted file mode 100644
index ca5580883..000000000
--- a/db/migrate/20220610091206_add_additional_attributes_to_api_channel.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddAdditionalAttributesToApiChannel < ActiveRecord::Migration[6.1]
- def change
- add_column :channel_api, :additional_attributes, :jsonb, default: {}
- end
-end
diff --git a/db/migrate/20220616154502_remove_special_characters_from_inbox_name.rb b/db/migrate/20220616154502_remove_special_characters_from_inbox_name.rb
deleted file mode 100644
index d108bb415..000000000
--- a/db/migrate/20220616154502_remove_special_characters_from_inbox_name.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-class RemoveSpecialCharactersFromInboxName < ActiveRecord::Migration[6.1]
- # This PR tried to remove special characters from the inbox name
- # It broke in the Chatwoot Cloud as there were inboxes with valid special characters
- # We had to push a temporary fix to continue the deployment by removing the logic
- # from this migration. Keeping this migration here to remove inconsistency.
-
- def change; end
-end
diff --git a/db/migrate/20220622090344_add_type_to_agent_bots.rb b/db/migrate/20220622090344_add_type_to_agent_bots.rb
deleted file mode 100644
index b247d3cfa..000000000
--- a/db/migrate/20220622090344_add_type_to_agent_bots.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class AddTypeToAgentBots < ActiveRecord::Migration[6.1]
- def up
- change_table :agent_bots, bulk: true do |t|
- t.column :bot_type, :integer, default: 0
- t.column :bot_config, :jsonb, default: {}
- end
- end
-
- def down
- change_table :agent_bots, bulk: true do |t|
- t.remove :bot_type
- t.remove :bot_config
- end
- end
-end
diff --git a/db/migrate/20220623113405_add_parent_id_to_category.rb b/db/migrate/20220623113405_add_parent_id_to_category.rb
deleted file mode 100644
index 57a694bac..000000000
--- a/db/migrate/20220623113405_add_parent_id_to_category.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddParentIdToCategory < ActiveRecord::Migration[6.1]
- def change
- add_reference :categories, :parent_category, foreign_key: { to_table: :categories }
- end
-end
diff --git a/db/migrate/20220623113604_create_related_categories.rb b/db/migrate/20220623113604_create_related_categories.rb
deleted file mode 100644
index c9633c61e..000000000
--- a/db/migrate/20220623113604_create_related_categories.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-class CreateRelatedCategories < ActiveRecord::Migration[6.1]
- def change
- create_table :related_categories do |t|
- t.bigint :category_id
- t.bigint :related_category_id
- t.timestamps
- end
-
- add_index :related_categories, [:category_id, :related_category_id], unique: true
- add_index :related_categories, [:related_category_id, :category_id], unique: true
- end
-end
diff --git a/db/migrate/20220627135753_add_linked_category_id_to_categories.rb b/db/migrate/20220627135753_add_linked_category_id_to_categories.rb
deleted file mode 100644
index 662a55879..000000000
--- a/db/migrate/20220627135753_add_linked_category_id_to_categories.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddLinkedCategoryIdToCategories < ActiveRecord::Migration[6.1]
- def change
- add_reference :categories, :linked_category, foreign_key: { to_table: :categories }
- end
-end
diff --git a/db/migrate/20220628124837_create_portal_members.rb b/db/migrate/20220628124837_create_portal_members.rb
deleted file mode 100644
index 2bf062b4b..000000000
--- a/db/migrate/20220628124837_create_portal_members.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-class CreatePortalMembers < ActiveRecord::Migration[6.1]
- def change
- create_table :portal_members do |t|
- t.bigint :portal_id
- t.bigint :user_id
- t.timestamps
- end
-
- add_index :portal_members, [:portal_id, :user_id], unique: true
- add_index :portal_members, [:user_id, :portal_id], unique: true
- end
-end
diff --git a/db/migrate/20220706085458_rename_linked_category_column_name.rb b/db/migrate/20220706085458_rename_linked_category_column_name.rb
deleted file mode 100644
index 295b70c31..000000000
--- a/db/migrate/20220706085458_rename_linked_category_column_name.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class RenameLinkedCategoryColumnName < ActiveRecord::Migration[6.1]
- def change
- rename_column :categories, :linked_category_id, :associated_category_id
- end
-end
diff --git a/db/migrate/20220711090528_create_macros.rb b/db/migrate/20220711090528_create_macros.rb
deleted file mode 100644
index 35c0825a7..000000000
--- a/db/migrate/20220711090528_create_macros.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-class CreateMacros < ActiveRecord::Migration[6.1]
- def change
- create_table :macros do |t|
- t.bigint :account_id, null: false
- t.string :name, null: false
- t.integer :visibility, default: 0
- t.references :created_by, null: false, index: true, foreign_key: { to_table: :users }
- t.references :updated_by, null: false, index: true, foreign_key: { to_table: :users }
- t.jsonb :actions, null: false, default: {}
- t.timestamps
- t.index :account_id, name: 'index_macros_on_account_id'
- end
- end
-end
diff --git a/db/migrate/20220712145440_sync_gravatar_for_existing_avatarables.rb b/db/migrate/20220712145440_sync_gravatar_for_existing_avatarables.rb
deleted file mode 100644
index 41405fcaa..000000000
--- a/db/migrate/20220712145440_sync_gravatar_for_existing_avatarables.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-class SyncGravatarForExistingAvatarables < ActiveRecord::Migration[6.1]
- def change
- return if GlobalConfigService.load('DISABLE_GRAVATAR', '').present?
-
- sync_user_avatars
- sync_contact_avatars
- end
-
- private
-
- def sync_user_avatars
- ::User.find_in_batches do |users_batch|
- users_batch.each do |user|
- Avatar::AvatarFromGravatarJob.perform_later(user, user.email)
- end
- end
- end
-
- def sync_contact_avatars
- ::Contact.where.not(email: nil).find_in_batches do |contacts_batch|
- contacts_batch.each do |contact|
- Avatar::AvatarFromGravatarJob.perform_later(contact, contact.email)
- end
- end
- end
-end
diff --git a/db/migrate/20220718123938_add_custom_attributes_to_account.rb b/db/migrate/20220718123938_add_custom_attributes_to_account.rb
deleted file mode 100644
index 39e9abcea..000000000
--- a/db/migrate/20220718123938_add_custom_attributes_to_account.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddCustomAttributesToAccount < ActiveRecord::Migration[6.1]
- def change
- add_column :accounts, :custom_attributes, :jsonb, default: {}
- end
-end
diff --git a/db/migrate/20220720080126_add_meta_column_to_article.rb b/db/migrate/20220720080126_add_meta_column_to_article.rb
deleted file mode 100644
index 6cb7ca23c..000000000
--- a/db/migrate/20220720080126_add_meta_column_to_article.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddMetaColumnToArticle < ActiveRecord::Migration[6.1]
- def change
- add_column :articles, :meta, :jsonb, default: {}
- end
-end
diff --git a/db/migrate/20220720123615_set_default_locale_at_accounts.rb b/db/migrate/20220720123615_set_default_locale_at_accounts.rb
deleted file mode 100644
index d17837fb9..000000000
--- a/db/migrate/20220720123615_set_default_locale_at_accounts.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class SetDefaultLocaleAtAccounts < ActiveRecord::Migration[6.1]
- def change
- change_column_default :accounts, :locale, from: nil, to: 0
- end
-end
diff --git a/db/migrate/20220802133722_add_status_to_accounts.rb b/db/migrate/20220802133722_add_status_to_accounts.rb
deleted file mode 100644
index b94e8ee74..000000000
--- a/db/migrate/20220802133722_add_status_to_accounts.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-class AddStatusToAccounts < ActiveRecord::Migration[6.1]
- def change
- add_column :accounts, :status, :integer, default: 0
- add_index :accounts, :status
- end
-end
diff --git a/db/migrate/20220802193353_add_conversation_uuid_unique_index.rb b/db/migrate/20220802193353_add_conversation_uuid_unique_index.rb
deleted file mode 100644
index 79ca8e626..000000000
--- a/db/migrate/20220802193353_add_conversation_uuid_unique_index.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddConversationUuidUniqueIndex < ActiveRecord::Migration[6.1]
- def change
- add_index :conversations, :uuid, unique: true
- end
-end
diff --git a/db/migrate/20220808193420_add_conversation_participants.rb b/db/migrate/20220808193420_add_conversation_participants.rb
deleted file mode 100644
index a130a5e01..000000000
--- a/db/migrate/20220808193420_add_conversation_participants.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class AddConversationParticipants < ActiveRecord::Migration[6.1]
- def change
- create_table 'conversation_participants', force: :cascade do |t|
- t.references :account, null: false
- t.references :user, null: false
- t.references :conversation, null: false
- t.datetime 'created_at', precision: 6, null: false
- t.datetime 'updated_at', precision: 6, null: false
- end
- end
-end
diff --git a/db/migrate/20220809104508_revert_cascading_indexes.rb b/db/migrate/20220809104508_revert_cascading_indexes.rb
deleted file mode 100644
index 96d3309d0..000000000
--- a/db/migrate/20220809104508_revert_cascading_indexes.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-class RevertCascadingIndexes < ActiveRecord::Migration[6.1]
- def change
- remove_foreign_key 'account_users', 'accounts' if foreign_key_exists? 'account_users', 'accounts'
- remove_foreign_key 'account_users', 'users' if foreign_key_exists? 'account_users', 'users'
- remove_foreign_key 'agent_bots', 'accounts' if foreign_key_exists? 'agent_bots', 'accounts'
- remove_foreign_key 'campaigns', 'accounts' if foreign_key_exists? 'campaigns', 'accounts'
- remove_foreign_key 'campaigns', 'inboxes' if foreign_key_exists? 'campaigns', 'inboxes'
- remove_foreign_key 'conversations', 'campaigns' if foreign_key_exists? 'conversations', 'campaigns'
- remove_foreign_key 'conversations', 'contact_inboxes' if foreign_key_exists? 'conversations', 'contact_inboxes'
- remove_foreign_key 'conversations', 'teams' if foreign_key_exists? 'conversations', 'teams'
- remove_foreign_key 'csat_survey_responses', 'accounts' if foreign_key_exists? 'csat_survey_responses', 'accounts'
- remove_foreign_key 'csat_survey_responses', 'contacts' if foreign_key_exists? 'csat_survey_responses', 'contacts'
- remove_foreign_key 'csat_survey_responses', 'conversations' if foreign_key_exists? 'csat_survey_responses', 'conversations'
- remove_foreign_key 'csat_survey_responses', 'messages' if foreign_key_exists? 'csat_survey_responses', 'messages'
- remove_foreign_key 'csat_survey_responses', 'users', column: 'assigned_agent_id' if foreign_key_exists? 'csat_survey_responses', 'users',
- column: 'assigned_agent_id'
- remove_foreign_key 'data_imports', 'accounts' if foreign_key_exists? 'data_imports', 'accounts'
- remove_foreign_key 'mentions', 'conversations' if foreign_key_exists? 'mentions', 'conversations'
- remove_foreign_key 'mentions', 'users' if foreign_key_exists? 'mentions', 'users'
- remove_foreign_key 'notes', 'accounts' if foreign_key_exists? 'notes', 'accounts'
- remove_foreign_key 'notes', 'contacts' if foreign_key_exists? 'notes', 'contacts'
- remove_foreign_key 'notes', 'users' if foreign_key_exists? 'notes', 'users'
- remove_foreign_key 'team_members', 'teams' if foreign_key_exists? 'team_members', 'teams'
- remove_foreign_key 'team_members', 'users' if foreign_key_exists? 'team_members', 'users'
- remove_foreign_key 'teams', 'accounts' if foreign_key_exists? 'teams', 'accounts'
- remove_foreign_key 'contact_inboxes', 'contacts' if foreign_key_exists? 'contact_inboxes', 'contacts'
- remove_foreign_key 'contact_inboxes', 'inboxes' if foreign_key_exists? 'contact_inboxes', 'inboxes'
-
- remove_foreign_key 'articles', 'articles', column: 'associated_article_id' if foreign_key_exists? 'articles', 'articles',
- column: 'associated_article_id'
- remove_foreign_key 'articles', 'users', column: 'author_id' if foreign_key_exists? 'articles', 'users', column: 'author_id'
-
- remove_foreign_key 'categories', 'categories', column: 'parent_category_id' if foreign_key_exists? 'categories', 'categories',
- column: 'parent_category_id'
- remove_foreign_key 'categories', 'categories', column: 'associated_category_id' if foreign_key_exists? 'categories', 'categories',
- column: 'associated_category_id'
-
- remove_foreign_key 'dashboard_apps', 'accounts' if foreign_key_exists? 'dashboard_apps', 'accounts'
- remove_foreign_key 'dashboard_apps', 'users' if foreign_key_exists? 'dashboard_apps', 'users'
-
- remove_foreign_key 'macros', 'users', column: 'created_by_id' if foreign_key_exists? 'macros', 'users', column: 'created_by_id'
- remove_foreign_key 'macros', 'users', column: 'updated_by_id' if foreign_key_exists? 'macros', 'users', column: 'updated_by_id'
-
- Migration::RemoveStaleNotificationsJob.perform_later
- end
-end
diff --git a/db/migrate/20220919225556_make_help_center_custom_domain_unique.rb b/db/migrate/20220919225556_make_help_center_custom_domain_unique.rb
deleted file mode 100644
index 89267855c..000000000
--- a/db/migrate/20220919225556_make_help_center_custom_domain_unique.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class MakeHelpCenterCustomDomainUnique < ActiveRecord::Migration[6.1]
- def change
- add_index :portals, :custom_domain, unique: true
- end
-end
diff --git a/db/migrate/20220920014549_enable_help_center.rb b/db/migrate/20220920014549_enable_help_center.rb
deleted file mode 100644
index 8b9f72388..000000000
--- a/db/migrate/20220920014549_enable_help_center.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-class EnableHelpCenter < ActiveRecord::Migration[6.1]
- def change
- return if ENV['DEPLOYMENT_ENV'] == 'cloud'
-
- Account.find_in_batches do |account_batch|
- account_batch.each do |account|
- account.enable_features('help_center')
- account.save!
- end
- end
- end
-end
diff --git a/db/migrate/20220926164441_add_slug_to_article.rb b/db/migrate/20220926164441_add_slug_to_article.rb
deleted file mode 100644
index 4eac09b86..000000000
--- a/db/migrate/20220926164441_add_slug_to_article.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-class AddSlugToArticle < ActiveRecord::Migration[6.1]
- def up
- add_column :articles, :slug, :string
-
- update_past_articles_with_slug
-
- add_index :articles, :slug
- change_column_null(:articles, :slug, false)
- end
-
- def down
- remove_column(:articles, :slug)
- end
-
- def update_past_articles_with_slug
- Article.all.each_with_index do |article, index|
- slug = article.title.underscore.parameterize(separator: '-')
- article.update!(slug: "#{slug}-#{index}")
- end
- end
-end
diff --git a/db/migrate/20220930025317_add_unique_index_to_slug.rb b/db/migrate/20220930025317_add_unique_index_to_slug.rb
deleted file mode 100644
index e35f6289c..000000000
--- a/db/migrate/20220930025317_add_unique_index_to_slug.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-class AddUniqueIndexToSlug < ActiveRecord::Migration[6.1]
- def change
- remove_index :articles, :slug
- add_index :articles, :slug, unique: true
- end
-end
diff --git a/db/migrate/20221010212946_add_index_to_message_attachments.rb b/db/migrate/20221010212946_add_index_to_message_attachments.rb
deleted file mode 100644
index 1ba2be299..000000000
--- a/db/migrate/20221010212946_add_index_to_message_attachments.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-class AddIndexToMessageAttachments < ActiveRecord::Migration[6.1]
- def change
- add_index :attachments, :account_id
- add_index :attachments, :message_id
- add_index :conversations, :contact_id
- add_index :conversations, :inbox_id
- end
-end
diff --git a/db/migrate/20221017201914_add_features_to_accounts.rb b/db/migrate/20221017201914_add_features_to_accounts.rb
deleted file mode 100644
index 60f47f7d3..000000000
--- a/db/migrate/20221017201914_add_features_to_accounts.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-class AddFeaturesToAccounts < ActiveRecord::Migration[6.1]
- def change
- Account.find_in_batches do |account_batch|
- account_batch.each do |account|
- account.enable_features(
- 'agent_management',
- 'automations',
- 'canned_responses',
- 'custom_attributes',
- 'inbox_management',
- 'integrations',
- 'labels',
- 'team_management',
- 'voice_recorder'
- )
- account.save!
- end
- end
- end
-end
diff --git a/db/migrate/20221029202300_add_two_features_to_accounts.rb b/db/migrate/20221029202300_add_two_features_to_accounts.rb
deleted file mode 100644
index bda92e159..000000000
--- a/db/migrate/20221029202300_add_two_features_to_accounts.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-class AddTwoFeaturesToAccounts < ActiveRecord::Migration[6.1]
- def change
- Account.find_in_batches do |account_batch|
- account_batch.each do |account|
- account.enable_features(
- 'campaigns',
- 'channel_website'
- )
- account.save!
- end
- end
- end
-end
diff --git a/db/migrate/20221102082737_change_macros_created_by_to_null.rb b/db/migrate/20221102082737_change_macros_created_by_to_null.rb
deleted file mode 100644
index f3f318028..000000000
--- a/db/migrate/20221102082737_change_macros_created_by_to_null.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class ChangeMacrosCreatedByToNull < ActiveRecord::Migration[6.1]
- def change
- change_column_null :macros, :created_by_id, true
- change_column_null :macros, :updated_by_id, true
-
- remove_index :macros, :created_by_id, if_exists: true
- remove_index :macros, :updated_by_id, if_exists: true
- end
-end
diff --git a/db/migrate/20221109065043_add_lock_conversation_to_single_thread.rb b/db/migrate/20221109065043_add_lock_conversation_to_single_thread.rb
deleted file mode 100644
index 9a0dbd450..000000000
--- a/db/migrate/20221109065043_add_lock_conversation_to_single_thread.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddLockConversationToSingleThread < ActiveRecord::Migration[6.1]
- def change
- add_column :inboxes, :lock_to_single_conversation, :boolean, null: false, default: false
- end
-end
diff --git a/db/migrate/20221116000514_enable_macros_for_all_accounts.rb b/db/migrate/20221116000514_enable_macros_for_all_accounts.rb
deleted file mode 100644
index 76bc1a8b7..000000000
--- a/db/migrate/20221116000514_enable_macros_for_all_accounts.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-class EnableMacrosForAllAccounts < ActiveRecord::Migration[6.1]
- def change
- current_config = InstallationConfig.where(name: 'ACCOUNT_LEVEL_FEATURE_DEFAULTS').last
- current_config.value.each { |v| v['enabled'] = true if v['name'] == 'macros' }
- current_config.save!
-
- ConfigLoader.new.process
-
- Account.find_in_batches do |account_batch|
- account_batch.each do |account|
- account.enable_features('macros')
- account.enable_features('channel_email')
- account.save!
- end
- end
- end
-end
diff --git a/db/migrate/20221219162759_enabled_new_features.rb b/db/migrate/20221219162759_enabled_new_features.rb
deleted file mode 100644
index 6340ad668..000000000
--- a/db/migrate/20221219162759_enabled_new_features.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-class EnabledNewFeatures < ActiveRecord::Migration[6.1]
- def change
- Account.find_in_batches do |account_batch|
- account_batch.each do |account|
- account.enable_features(
- 'channel_website',
- 'campaigns',
- 'reports',
- 'crm',
- 'auto_resolve_conversations'
- )
- account.save!
- end
- end
- end
-end
diff --git a/db/migrate/20221230113108_add_ms_oauth_token_to_channel.rb b/db/migrate/20221230113108_add_ms_oauth_token_to_channel.rb
deleted file mode 100644
index d1a375599..000000000
--- a/db/migrate/20221230113108_add_ms_oauth_token_to_channel.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-class AddMsOauthTokenToChannel < ActiveRecord::Migration[6.1]
- def change
- change_table :channel_email, bulk: true do |t|
- t.jsonb :provider_config, default: {}
- t.string :provider
- end
- end
-end
diff --git a/db/migrate/20230118155353_add_unique_index_to_conversation_participants.rb b/db/migrate/20230118155353_add_unique_index_to_conversation_participants.rb
deleted file mode 100644
index cf47c6ea8..000000000
--- a/db/migrate/20230118155353_add_unique_index_to_conversation_participants.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddUniqueIndexToConversationParticipants < ActiveRecord::Migration[6.1]
- def change
- add_index :conversation_participants, [:user_id, :conversation_id], unique: true
- end
-end
diff --git a/db/migrate/20230202132107_install_audited.rb b/db/migrate/20230202132107_install_audited.rb
deleted file mode 100644
index a59afc0b9..000000000
--- a/db/migrate/20230202132107_install_audited.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-# frozen_string_literal: true
-
-class InstallAudited < ActiveRecord::Migration[6.1]
- # rubocop:disable Metrics/MethodLength
- def self.up
- create_table :audits, :force => true do |t|
- t.bigint :auditable_id
- t.string :auditable_type
- t.bigint :associated_id
- t.string :associated_type
- t.bigint :user_id
- t.string :user_type
- t.string :username
- t.string :action
- t.jsonb :audited_changes
- t.integer :version, :default => 0
- t.string :comment
- t.string :remote_address
- t.string :request_uuid
- t.datetime :created_at
- end
- # rubocop:enable Metrics/MethodLength
-
- add_index :audits, [:auditable_type, :auditable_id, :version], :name => 'auditable_index'
- add_index :audits, [:associated_type, :associated_id], :name => 'associated_index'
- add_index :audits, [:user_id, :user_type], :name => 'user_index'
- add_index :audits, :request_uuid
- add_index :audits, :created_at
- end
-
- def self.down
- drop_table :audits
- end
-end
diff --git a/db/migrate/20230209033203_update_default_on_subscriptions_webhooks.rb b/db/migrate/20230209033203_update_default_on_subscriptions_webhooks.rb
deleted file mode 100644
index 18be46ebe..000000000
--- a/db/migrate/20230209033203_update_default_on_subscriptions_webhooks.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class UpdateDefaultOnSubscriptionsWebhooks < ActiveRecord::Migration[6.1]
- def change
- change_column_default :webhooks, :subscriptions,
- from: %w[conversation_status_changed conversation_updated conversation_created
- message_created message_updated webwidget_triggered],
- to: %w[conversation_status_changed conversation_updated conversation_created
- contact_created contact_updated message_created message_updated webwidget_triggered]
- end
-end
diff --git a/db/migrate/20230214025901_update_reporting_events_with_incorrect_first_responses.rb b/db/migrate/20230214025901_update_reporting_events_with_incorrect_first_responses.rb
deleted file mode 100644
index 35dfed168..000000000
--- a/db/migrate/20230214025901_update_reporting_events_with_incorrect_first_responses.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class UpdateReportingEventsWithIncorrectFirstResponses < ActiveRecord::Migration[6.1]
- def change
- Rails.logger.info "Skipping this migration, it's replaced by a new one"
- end
-end
diff --git a/db/migrate/20230224124632_add_index_for_search_operations.rb b/db/migrate/20230224124632_add_index_for_search_operations.rb
deleted file mode 100644
index 77386a50c..000000000
--- a/db/migrate/20230224124632_add_index_for_search_operations.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-class AddIndexForSearchOperations < ActiveRecord::Migration[6.1]
- def change
- enable_extension('pg_trgm')
- Migration::AddSearchIndexesJob.perform_later
- end
-end
diff --git a/db/migrate/20230302054408_update_reporting_events_first_response_time.rb b/db/migrate/20230302054408_update_reporting_events_first_response_time.rb
deleted file mode 100644
index 99b9fbc16..000000000
--- a/db/migrate/20230302054408_update_reporting_events_first_response_time.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-class UpdateReportingEventsFirstResponseTime < ActiveRecord::Migration[6.1]
- def change
- ::Account.find_in_batches do |account_batch|
- Rails.logger.info "Updated reporting events till #{account_batch.first.id}\n"
- account_batch.each do |account|
- Migration::UpdateFirstResponseTimeInReportingEventsJob.perform_later(account)
- end
- end
- end
-end
diff --git a/db/migrate/20230306100327_add_trgm_index_to_tag_name.rb b/db/migrate/20230306100327_add_trgm_index_to_tag_name.rb
deleted file mode 100644
index d5ba0c8e1..000000000
--- a/db/migrate/20230306100327_add_trgm_index_to_tag_name.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# This migration adds a trigram index to the tags table on the name column.
-# This is used to speed up the search for tags by name, this is a heavy
-# sub query when genereating reports where labels are involved.
-#
-# Trigram indexes are used to speed up LIKE queries, they are not used for
-# equality queries. This is because the index is not a btree index, it is a
-# GIN index. This means that the index is not ordered, and so cannot be used
-# for equality queries.
-#
-# Read more: https://www.postgresql.org/docs/current/pgtrgm.html
-
-class AddTrgmIndexToTagName < ActiveRecord::Migration[6.1]
- # disabling ddl transaction is required for concurrent index creation
- # https://thoughtbot.com/blog/how-to-create-postgres-indexes-concurrently-in
- disable_ddl_transaction!
-
- def change
- add_index :tags, 'LOWER(name) gin_trgm_ops', using: :gin, name: 'tags_name_trgm_idx', algorithm: :concurrently
- # resolves to CREATE INDEX tags_name_trgm_idx ON public.tags USING gin (lower((name)::text) gin_trgm_ops);
- end
-end
diff --git a/db/migrate/20230313113920_add_position_to_articles.rb b/db/migrate/20230313113920_add_position_to_articles.rb
deleted file mode 100644
index d7e195923..000000000
--- a/db/migrate/20230313113920_add_position_to_articles.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddPositionToArticles < ActiveRecord::Migration[6.1]
- def change
- add_column :articles, :position, :integer
- end
-end
diff --git a/db/migrate/20230315105847_add_indexes_for_common_queries.rb b/db/migrate/20230315105847_add_indexes_for_common_queries.rb
deleted file mode 100644
index b16adb71f..000000000
--- a/db/migrate/20230315105847_add_indexes_for_common_queries.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class AddIndexesForCommonQueries < ActiveRecord::Migration[6.1]
- # disabling ddl transaction is required for concurrent index creation
- # https://thoughtbot.com/blog/how-to-create-postgres-indexes-concurrently-in
- disable_ddl_transaction!
-
- def change
- ActiveRecord::Migration[6.1].add_index(:inboxes, [:channel_id, :channel_type], algorithm: :concurrently)
- ActiveRecord::Migration[6.1].add_index(:conversations, [:account_id, :inbox_id, :status, :assignee_id], name: 'conv_acid_inbid_stat_asgnid_idx',
- algorithm: :concurrently)
- end
-end
diff --git a/db/migrate/20230321073727_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb b/db/migrate/20230321073727_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb
deleted file mode 100644
index 93c8b85ad..000000000
--- a/db/migrate/20230321073727_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-# This migration comes from active_storage (originally 20211119233751)
-class RemoveNotNullOnActiveStorageBlobsChecksum < ActiveRecord::Migration[6.0]
- def change
- return unless table_exists?(:active_storage_blobs)
-
- change_column_null(:active_storage_blobs, :checksum, true)
- end
-end
diff --git a/db/migrate/20230327081350_add_index_to_conversations_account_id_and_id.rb b/db/migrate/20230327081350_add_index_to_conversations_account_id_and_id.rb
deleted file mode 100644
index 70fe99b81..000000000
--- a/db/migrate/20230327081350_add_index_to_conversations_account_id_and_id.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class AddIndexToConversationsAccountIdAndId < ActiveRecord::Migration[6.1]
- disable_ddl_transaction!
-
- def change
- add_index :conversations, [:account_id, :id], name: 'index_conversations_on_id_and_account_id', algorithm: :concurrently
- end
-end
diff --git a/db/migrate/20230328131926_drop_extra_audit_integer_column.rb b/db/migrate/20230328131926_drop_extra_audit_integer_column.rb
deleted file mode 100644
index 58a7d91c4..000000000
--- a/db/migrate/20230328131926_drop_extra_audit_integer_column.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class DropExtraAuditIntegerColumn < ActiveRecord::Migration[6.1]
- def change
- # this column was added unintentionally for a time in a migration but not in schema.rb, so some
- # installations will have it and some won't.
- remove_column :audits, :integer, :integer, default: 0, if_exists: true
- end
-end
diff --git a/db/migrate/20230404030719_remove_settings_flags_from_account.rb b/db/migrate/20230404030719_remove_settings_flags_from_account.rb
deleted file mode 100644
index fda575506..000000000
--- a/db/migrate/20230404030719_remove_settings_flags_from_account.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-class RemoveSettingsFlagsFromAccount < ActiveRecord::Migration[6.1]
- def up
- change_table :accounts do |t|
- t.remove :settings_flags
- end
- end
-
- def down
- change_table :accounts do |t|
- t.integer :settings_flags, default: 0, null: false
- end
- end
-end
diff --git a/db/migrate/20230405104405_update_position_for_articles.rb b/db/migrate/20230405104405_update_position_for_articles.rb
deleted file mode 100644
index b10513933..000000000
--- a/db/migrate/20230405104405_update_position_for_articles.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-class UpdatePositionForArticles < ActiveRecord::Migration[6.1]
- def change
- # Get the unique combinations of account_id and category_id
- groups = Article.select(:account_id, :category_id).distinct
-
- # Iterate through the groups
- groups.each do |group|
- # Get articles belonging to the current group
- articles = Article.where(account_id: group.account_id, category_id: group.category_id)
-
- # Separate articles with a position set and those without
- articles_with_position = articles.where.not(position: nil).order(:position, :updated_at)
- articles_without_position = articles.where(position: nil).order(:updated_at)
-
- # Set the position for articles with a position set, in multiples of 10
- # why multiples of 10? because we want to leave room for articles which can be added in between in case we are editing the order from the DB
- position_counter = 0
- articles_with_position.each do |article|
- position_counter += 10
- article.update(position: position_counter)
- end
-
- # Set the position for articles without a position, starting from where the last position ended
- articles_without_position.each do |article|
- position_counter += 10
- article.update(position: position_counter)
- end
- end
- end
-end
diff --git a/db/migrate/20230407191457_migrate_env_var_to_channel_feature.rb b/db/migrate/20230407191457_migrate_env_var_to_channel_feature.rb
deleted file mode 100644
index 3bb9800a3..000000000
--- a/db/migrate/20230407191457_migrate_env_var_to_channel_feature.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-class MigrateEnvVarToChannelFeature < ActiveRecord::Migration[6.1]
- def change
- return unless ActiveModel::Type::Boolean.new.cast(ENV.fetch('USE_INBOX_AVATAR_FOR_BOT', false))
-
- Channel::WebWidget.find_in_batches do |widget_batch|
- widget_batch.each do |widget|
- widget.use_inbox_avatar_for_bot = true
- widget.save!
- end
- end
- end
-end
diff --git a/db/migrate/20230413085302_add_portal_id_to_inbox.rb b/db/migrate/20230413085302_add_portal_id_to_inbox.rb
deleted file mode 100644
index 05f71078e..000000000
--- a/db/migrate/20230413085302_add_portal_id_to_inbox.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class AddPortalIdToInbox < ActiveRecord::Migration[6.1]
- def change
- add_reference :inboxes, :portal, foreign_key: true
- end
-end
diff --git a/db/migrate/20230418100944_add_priority_to_conversation.rb b/db/migrate/20230418100944_add_priority_to_conversation.rb
deleted file mode 100644
index 5f1ec286c..000000000
--- a/db/migrate/20230418100944_add_priority_to_conversation.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class AddPriorityToConversation < ActiveRecord::Migration[6.1]
- def change
- add_column :conversations, :priority, :integer
- add_index :conversations, :priority
- add_index :conversations, [:status, :priority]
- end
-end
diff --git a/db/migrate/20230426130150_add_index_for_widget_contact_look_up.rb b/db/migrate/20230426130150_add_index_for_widget_contact_look_up.rb
deleted file mode 100644
index f8f2b9f36..000000000
--- a/db/migrate/20230426130150_add_index_for_widget_contact_look_up.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class AddIndexForWidgetContactLookUp < ActiveRecord::Migration[6.1]
- disable_ddl_transaction!
-
- def change
- add_index :contacts, 'LOWER(email), account_id', name: 'index_contacts_on_lower_email_account_id', algorithm: :concurrently
- end
-end
diff --git a/db/migrate/20230426130150_init_schema.rb b/db/migrate/20230426130150_init_schema.rb
new file mode 100644
index 000000000..369d7dea3
--- /dev/null
+++ b/db/migrate/20230426130150_init_schema.rb
@@ -0,0 +1,878 @@
+class InitSchema < ActiveRecord::Migration[6.1]
+ def up
+ # These are extensions that must be enabled in order to support this database
+ enable_extension "pg_stat_statements"
+ enable_extension "pg_trgm"
+ enable_extension "pgcrypto"
+ enable_extension "plpgsql"
+ create_table "access_tokens" do |t|
+ t.string "owner_type"
+ t.bigint "owner_id"
+ t.string "token"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["owner_type", "owner_id"], name: "index_access_tokens_on_owner_type_and_owner_id"
+ t.index ["token"], name: "index_access_tokens_on_token", unique: true
+ end
+ create_table "account_users" do |t|
+ t.bigint "account_id"
+ t.bigint "user_id"
+ t.integer "role", default: 0
+ t.bigint "inviter_id"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.datetime "active_at", precision: nil
+ t.integer "availability", default: 0, null: false
+ t.boolean "auto_offline", default: true, null: false
+ t.index ["account_id", "user_id"], name: "uniq_user_id_per_account_id", unique: true
+ t.index ["account_id"], name: "index_account_users_on_account_id"
+ t.index ["user_id"], name: "index_account_users_on_user_id"
+ end
+ create_table "accounts", id: :serial do |t|
+ t.string "name", null: false
+ t.datetime "created_at", precision: nil, null: false
+ t.datetime "updated_at", precision: nil, null: false
+ t.integer "locale", default: 0
+ t.string "domain", limit: 100
+ t.string "support_email", limit: 100
+ t.integer "feature_flags", default: 0, null: false
+ t.integer "auto_resolve_duration"
+ t.jsonb "limits", default: {}
+ t.jsonb "custom_attributes", default: {}
+ t.integer "status", default: 0
+ t.index ["status"], name: "index_accounts_on_status"
+ end
+ create_table "action_mailbox_inbound_emails" do |t|
+ t.integer "status", default: 0, null: false
+ t.string "message_id", null: false
+ t.string "message_checksum", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["message_id", "message_checksum"], name: "index_action_mailbox_inbound_emails_uniqueness", unique: true
+ end
+ create_table "active_storage_attachments" do |t|
+ t.string "name", null: false
+ t.string "record_type", null: false
+ t.bigint "record_id", null: false
+ t.bigint "blob_id", null: false
+ t.datetime "created_at", precision: nil, null: false
+ t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id"
+ t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true
+ end
+ create_table "active_storage_blobs" do |t|
+ t.string "key", null: false
+ t.string "filename", null: false
+ t.string "content_type"
+ t.text "metadata"
+ t.bigint "byte_size", null: false
+ t.string "checksum"
+ t.datetime "created_at", precision: nil, null: false
+ t.string "service_name", null: false
+ t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true
+ end
+ create_table "active_storage_variant_records" do |t|
+ t.bigint "blob_id", null: false
+ t.string "variation_digest", null: false
+ t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true
+ end
+ create_table "agent_bot_inboxes" do |t|
+ t.integer "inbox_id"
+ t.integer "agent_bot_id"
+ t.integer "status", default: 0
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.integer "account_id"
+ end
+ create_table "agent_bots" do |t|
+ t.string "name"
+ t.string "description"
+ t.string "outgoing_url"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.bigint "account_id"
+ t.integer "bot_type", default: 0
+ t.jsonb "bot_config", default: {}
+ t.index ["account_id"], name: "index_agent_bots_on_account_id"
+ end
+ create_table "articles" do |t|
+ t.integer "account_id", null: false
+ t.integer "portal_id", null: false
+ t.integer "category_id"
+ t.integer "folder_id"
+ t.string "title"
+ t.text "description"
+ t.text "content"
+ t.integer "status"
+ t.integer "views"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.bigint "author_id"
+ t.bigint "associated_article_id"
+ t.jsonb "meta", default: {}
+ t.string "slug", null: false
+ t.integer "position"
+ t.index ["associated_article_id"], name: "index_articles_on_associated_article_id"
+ t.index ["author_id"], name: "index_articles_on_author_id"
+ t.index ["slug"], name: "index_articles_on_slug", unique: true
+ end
+ create_table "attachments", id: :serial do |t|
+ t.integer "file_type", default: 0
+ t.string "external_url"
+ t.float "coordinates_lat", default: 0.0
+ t.float "coordinates_long", default: 0.0
+ t.integer "message_id", null: false
+ t.integer "account_id", null: false
+ t.datetime "created_at", precision: nil, null: false
+ t.datetime "updated_at", precision: nil, null: false
+ t.string "fallback_title"
+ t.string "extension"
+ t.index ["account_id"], name: "index_attachments_on_account_id"
+ t.index ["message_id"], name: "index_attachments_on_message_id"
+ end
+ create_table "audits" do |t|
+ t.bigint "auditable_id"
+ t.string "auditable_type"
+ t.bigint "associated_id"
+ t.string "associated_type"
+ t.bigint "user_id"
+ t.string "user_type"
+ t.string "username"
+ t.string "action"
+ t.jsonb "audited_changes"
+ t.integer "version", default: 0
+ t.string "comment"
+ t.string "remote_address"
+ t.string "request_uuid"
+ t.datetime "created_at", precision: nil
+ t.index ["associated_type", "associated_id"], name: "associated_index"
+ t.index ["auditable_type", "auditable_id", "version"], name: "auditable_index"
+ t.index ["created_at"], name: "index_audits_on_created_at"
+ t.index ["request_uuid"], name: "index_audits_on_request_uuid"
+ t.index ["user_id", "user_type"], name: "user_index"
+ end
+ create_table "automation_rules" do |t|
+ t.bigint "account_id", null: false
+ t.string "name", null: false
+ t.text "description"
+ t.string "event_name", null: false
+ t.jsonb "conditions", default: "{}", null: false
+ t.jsonb "actions", default: "{}", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.boolean "active", default: true, null: false
+ t.index ["account_id"], name: "index_automation_rules_on_account_id"
+ end
+ create_table "campaigns" do |t|
+ t.integer "display_id", null: false
+ t.string "title", null: false
+ t.text "description"
+ t.text "message", null: false
+ t.integer "sender_id"
+ t.boolean "enabled", default: true
+ t.bigint "account_id", null: false
+ t.bigint "inbox_id", null: false
+ t.jsonb "trigger_rules", default: {}
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.integer "campaign_type", default: 0, null: false
+ t.integer "campaign_status", default: 0, null: false
+ t.jsonb "audience", default: []
+ t.datetime "scheduled_at", precision: nil
+ t.boolean "trigger_only_during_business_hours", default: false
+ t.index ["account_id"], name: "index_campaigns_on_account_id"
+ t.index ["campaign_status"], name: "index_campaigns_on_campaign_status"
+ t.index ["campaign_type"], name: "index_campaigns_on_campaign_type"
+ t.index ["inbox_id"], name: "index_campaigns_on_inbox_id"
+ t.index ["scheduled_at"], name: "index_campaigns_on_scheduled_at"
+ end
+ create_table "canned_responses", id: :serial do |t|
+ t.integer "account_id", null: false
+ t.string "short_code"
+ t.text "content"
+ t.datetime "created_at", precision: nil, null: false
+ t.datetime "updated_at", precision: nil, null: false
+ end
+ create_table "categories" do |t|
+ t.integer "account_id", null: false
+ t.integer "portal_id", null: false
+ t.string "name"
+ t.text "description"
+ t.integer "position"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.string "locale", default: "en"
+ t.string "slug", null: false
+ t.bigint "parent_category_id"
+ t.bigint "associated_category_id"
+ t.index ["associated_category_id"], name: "index_categories_on_associated_category_id"
+ t.index ["locale", "account_id"], name: "index_categories_on_locale_and_account_id"
+ t.index ["locale"], name: "index_categories_on_locale"
+ t.index ["parent_category_id"], name: "index_categories_on_parent_category_id"
+ t.index ["slug", "locale", "portal_id"], name: "index_categories_on_slug_and_locale_and_portal_id", unique: true
+ end
+ create_table "channel_api" do |t|
+ t.integer "account_id", null: false
+ t.string "webhook_url"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.string "identifier"
+ t.string "hmac_token"
+ t.boolean "hmac_mandatory", default: false
+ t.jsonb "additional_attributes", default: {}
+ t.index ["hmac_token"], name: "index_channel_api_on_hmac_token", unique: true
+ t.index ["identifier"], name: "index_channel_api_on_identifier", unique: true
+ end
+ create_table "channel_email" do |t|
+ t.integer "account_id", null: false
+ t.string "email", null: false
+ t.string "forward_to_email", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.boolean "imap_enabled", default: false
+ t.string "imap_address", default: ""
+ t.integer "imap_port", default: 0
+ t.string "imap_login", default: ""
+ t.string "imap_password", default: ""
+ t.boolean "imap_enable_ssl", default: true
+ t.datetime "imap_inbox_synced_at", precision: nil
+ t.boolean "smtp_enabled", default: false
+ t.string "smtp_address", default: ""
+ t.integer "smtp_port", default: 0
+ t.string "smtp_login", default: ""
+ t.string "smtp_password", default: ""
+ t.string "smtp_domain", default: ""
+ t.boolean "smtp_enable_starttls_auto", default: true
+ t.string "smtp_authentication", default: "login"
+ t.string "smtp_openssl_verify_mode", default: "none"
+ t.boolean "smtp_enable_ssl_tls", default: false
+ t.jsonb "provider_config", default: {}
+ t.string "provider"
+ t.index ["email"], name: "index_channel_email_on_email", unique: true
+ t.index ["forward_to_email"], name: "index_channel_email_on_forward_to_email", unique: true
+ end
+ create_table "channel_facebook_pages", id: :serial do |t|
+ t.string "page_id", null: false
+ t.string "user_access_token", null: false
+ t.string "page_access_token", null: false
+ t.integer "account_id", null: false
+ t.datetime "created_at", precision: nil, null: false
+ t.datetime "updated_at", precision: nil, null: false
+ t.string "instagram_id"
+ t.index ["page_id", "account_id"], name: "index_channel_facebook_pages_on_page_id_and_account_id", unique: true
+ t.index ["page_id"], name: "index_channel_facebook_pages_on_page_id"
+ end
+ create_table "channel_line" do |t|
+ t.integer "account_id", null: false
+ t.string "line_channel_id", null: false
+ t.string "line_channel_secret", null: false
+ t.string "line_channel_token", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["line_channel_id"], name: "index_channel_line_on_line_channel_id", unique: true
+ end
+ create_table "channel_sms" do |t|
+ t.integer "account_id", null: false
+ t.string "phone_number", null: false
+ t.string "provider", default: "default"
+ t.jsonb "provider_config", default: {}
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["phone_number"], name: "index_channel_sms_on_phone_number", unique: true
+ end
+ create_table "channel_telegram" do |t|
+ t.string "bot_name"
+ t.integer "account_id", null: false
+ t.string "bot_token", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["bot_token"], name: "index_channel_telegram_on_bot_token", unique: true
+ end
+ create_table "channel_twilio_sms" do |t|
+ t.string "phone_number"
+ t.string "auth_token", null: false
+ t.string "account_sid", null: false
+ t.integer "account_id", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.integer "medium", default: 0
+ t.string "messaging_service_sid"
+ t.index ["account_sid", "phone_number"], name: "index_channel_twilio_sms_on_account_sid_and_phone_number", unique: true
+ t.index ["messaging_service_sid"], name: "index_channel_twilio_sms_on_messaging_service_sid", unique: true
+ t.index ["phone_number"], name: "index_channel_twilio_sms_on_phone_number", unique: true
+ end
+ create_table "channel_twitter_profiles" do |t|
+ t.string "profile_id", null: false
+ t.string "twitter_access_token", null: false
+ t.string "twitter_access_token_secret", null: false
+ t.integer "account_id", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.boolean "tweets_enabled", default: true
+ t.index ["account_id", "profile_id"], name: "index_channel_twitter_profiles_on_account_id_and_profile_id", unique: true
+ end
+ create_table "channel_web_widgets", id: :serial do |t|
+ t.string "website_url"
+ t.integer "account_id"
+ t.datetime "created_at", precision: nil, null: false
+ t.datetime "updated_at", precision: nil, null: false
+ t.string "website_token"
+ t.string "widget_color", default: "#1f93ff"
+ t.string "welcome_title"
+ t.string "welcome_tagline"
+ t.integer "feature_flags", default: 7, null: false
+ t.integer "reply_time", default: 0
+ t.string "hmac_token"
+ t.boolean "pre_chat_form_enabled", default: false
+ t.jsonb "pre_chat_form_options", default: {}
+ t.boolean "hmac_mandatory", default: false
+ t.boolean "continuity_via_email", default: true, null: false
+ t.index ["hmac_token"], name: "index_channel_web_widgets_on_hmac_token", unique: true
+ t.index ["website_token"], name: "index_channel_web_widgets_on_website_token", unique: true
+ end
+ create_table "channel_whatsapp" do |t|
+ t.integer "account_id", null: false
+ t.string "phone_number", null: false
+ t.string "provider", default: "default"
+ t.jsonb "provider_config", default: {}
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.jsonb "message_templates", default: {}
+ t.datetime "message_templates_last_updated", precision: nil
+ t.index ["phone_number"], name: "index_channel_whatsapp_on_phone_number", unique: true
+ end
+ create_table "contact_inboxes" do |t|
+ t.bigint "contact_id"
+ t.bigint "inbox_id"
+ t.string "source_id", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.boolean "hmac_verified", default: false
+ t.string "pubsub_token"
+ t.index ["contact_id"], name: "index_contact_inboxes_on_contact_id"
+ t.index ["inbox_id", "source_id"], name: "index_contact_inboxes_on_inbox_id_and_source_id", unique: true
+ t.index ["inbox_id"], name: "index_contact_inboxes_on_inbox_id"
+ t.index ["pubsub_token"], name: "index_contact_inboxes_on_pubsub_token", unique: true
+ t.index ["source_id"], name: "index_contact_inboxes_on_source_id"
+ end
+ create_table "contacts", id: :serial do |t|
+ t.string "name"
+ t.string "email"
+ t.string "phone_number"
+ t.integer "account_id", null: false
+ t.datetime "created_at", precision: nil, null: false
+ t.datetime "updated_at", precision: nil, null: false
+ t.jsonb "additional_attributes", default: {}
+ t.string "identifier"
+ t.jsonb "custom_attributes", default: {}
+ t.datetime "last_activity_at", precision: nil
+ t.index "lower((email)::text), account_id", name: "index_contacts_on_lower_email_account_id"
+ t.index ["account_id"], name: "index_contacts_on_account_id"
+ t.index ["name", "email", "phone_number", "identifier"], using: 'gin', opclass: "gin_trgm_ops", name: "index_contacts_on_name_email_phone_number_identifier"
+ t.index ["email", "account_id"], name: "uniq_email_per_account_contact", unique: true
+ t.index ["identifier", "account_id"], name: "uniq_identifier_per_account_contact", unique: true
+ t.index ["phone_number", "account_id"], name: "index_contacts_on_phone_number_and_account_id"
+ end
+ create_table "conversation_participants" do |t|
+ t.bigint "account_id", null: false
+ t.bigint "user_id", null: false
+ t.bigint "conversation_id", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["account_id"], name: "index_conversation_participants_on_account_id"
+ t.index ["conversation_id"], name: "index_conversation_participants_on_conversation_id"
+ t.index ["user_id", "conversation_id"], name: "index_conversation_participants_on_user_id_and_conversation_id", unique: true
+ t.index ["user_id"], name: "index_conversation_participants_on_user_id"
+ end
+ create_table "conversations", id: :serial do |t|
+ t.integer "account_id", null: false
+ t.integer "inbox_id", null: false
+ t.integer "status", default: 0, null: false
+ t.integer "assignee_id"
+ t.datetime "created_at", precision: nil, null: false
+ t.datetime "updated_at", precision: nil, null: false
+ t.bigint "contact_id"
+ t.integer "display_id", null: false
+ t.datetime "contact_last_seen_at", precision: nil
+ t.datetime "agent_last_seen_at", precision: nil
+ t.jsonb "additional_attributes", default: {}
+ t.bigint "contact_inbox_id"
+ t.uuid "uuid", default: -> { "gen_random_uuid()" }, null: false
+ t.string "identifier"
+ t.datetime "last_activity_at", precision: nil, default: -> { "CURRENT_TIMESTAMP" }, null: false
+ t.bigint "team_id"
+ t.bigint "campaign_id"
+ t.datetime "snoozed_until", precision: nil
+ t.jsonb "custom_attributes", default: {}
+ t.datetime "assignee_last_seen_at", precision: nil
+ t.datetime "first_reply_created_at", precision: nil
+ t.integer "priority"
+ t.index ["account_id", "display_id"], name: "index_conversations_on_account_id_and_display_id", unique: true
+ t.index ["account_id", "id"], name: "index_conversations_on_id_and_account_id"
+ t.index ["account_id", "inbox_id", "status", "assignee_id"], name: "conv_acid_inbid_stat_asgnid_idx"
+ t.index ["account_id"], name: "index_conversations_on_account_id"
+ t.index ["assignee_id", "account_id"], name: "index_conversations_on_assignee_id_and_account_id"
+ t.index ["campaign_id"], name: "index_conversations_on_campaign_id"
+ t.index ["contact_id"], name: "index_conversations_on_contact_id"
+ t.index ["contact_inbox_id"], name: "index_conversations_on_contact_inbox_id"
+ t.index ["first_reply_created_at"], name: "index_conversations_on_first_reply_created_at"
+ t.index ["inbox_id"], name: "index_conversations_on_inbox_id"
+ t.index ["last_activity_at"], name: "index_conversations_on_last_activity_at"
+ t.index ["priority"], name: "index_conversations_on_priority"
+ t.index ["status", "account_id"], name: "index_conversations_on_status_and_account_id"
+ t.index ["status", "priority"], name: "index_conversations_on_status_and_priority"
+ t.index ["team_id"], name: "index_conversations_on_team_id"
+ t.index ["uuid"], name: "index_conversations_on_uuid", unique: true
+ end
+ create_table "csat_survey_responses" do |t|
+ t.bigint "account_id", null: false
+ t.bigint "conversation_id", null: false
+ t.bigint "message_id", null: false
+ t.integer "rating", null: false
+ t.text "feedback_message"
+ t.bigint "contact_id", null: false
+ t.bigint "assigned_agent_id"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["account_id"], name: "index_csat_survey_responses_on_account_id"
+ t.index ["assigned_agent_id"], name: "index_csat_survey_responses_on_assigned_agent_id"
+ t.index ["contact_id"], name: "index_csat_survey_responses_on_contact_id"
+ t.index ["conversation_id"], name: "index_csat_survey_responses_on_conversation_id"
+ t.index ["message_id"], name: "index_csat_survey_responses_on_message_id", unique: true
+ end
+ create_table "custom_attribute_definitions" do |t|
+ t.string "attribute_display_name"
+ t.string "attribute_key"
+ t.integer "attribute_display_type", default: 0
+ t.integer "default_value"
+ t.integer "attribute_model", default: 0
+ t.bigint "account_id"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.text "attribute_description"
+ t.jsonb "attribute_values", default: []
+ t.index ["account_id"], name: "index_custom_attribute_definitions_on_account_id"
+ t.index ["attribute_key", "attribute_model", "account_id"], unique: true, name: 'attribute_key_model_index'
+ end
+ create_table "custom_filters" do |t|
+ t.string "name", null: false
+ t.integer "filter_type", default: 0, null: false
+ t.jsonb "query", default: "{}", null: false
+ t.bigint "account_id", null: false
+ t.bigint "user_id", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["account_id"], name: "index_custom_filters_on_account_id"
+ t.index ["user_id"], name: "index_custom_filters_on_user_id"
+ end
+ create_table "dashboard_apps" do |t|
+ t.string "title", null: false
+ t.jsonb "content", default: []
+ t.bigint "account_id", null: false
+ t.bigint "user_id"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["account_id"], name: "index_dashboard_apps_on_account_id"
+ t.index ["user_id"], name: "index_dashboard_apps_on_user_id"
+ end
+ create_table "data_imports" do |t|
+ t.bigint "account_id", null: false
+ t.string "data_type", null: false
+ t.integer "status", default: 0, null: false
+ t.text "processing_errors"
+ t.integer "total_records"
+ t.integer "processed_records"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["account_id"], name: "index_data_imports_on_account_id"
+ end
+ create_table "email_templates" do |t|
+ t.string "name", null: false
+ t.text "body", null: false
+ t.integer "account_id"
+ t.integer "template_type", default: 1
+ t.integer "locale", default: 0, null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["name", "account_id"], name: "index_email_templates_on_name_and_account_id", unique: true
+ end
+ create_table "folders" do |t|
+ t.integer "account_id", null: false
+ t.integer "category_id", null: false
+ t.string "name"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ end
+ create_table "inbox_members", id: :serial do |t|
+ t.integer "user_id", null: false
+ t.integer "inbox_id", null: false
+ t.datetime "created_at", precision: nil, null: false
+ t.datetime "updated_at", precision: nil, null: false
+ t.index ["inbox_id", "user_id"], name: "index_inbox_members_on_inbox_id_and_user_id", unique: true
+ t.index ["inbox_id"], name: "index_inbox_members_on_inbox_id"
+ end
+ create_table "inboxes", id: :serial do |t|
+ t.integer "channel_id", null: false
+ t.integer "account_id", null: false
+ t.string "name", null: false
+ t.datetime "created_at", precision: nil, null: false
+ t.datetime "updated_at", precision: nil, null: false
+ t.string "channel_type"
+ t.boolean "enable_auto_assignment", default: true
+ t.boolean "greeting_enabled", default: false
+ t.string "greeting_message"
+ t.string "email_address"
+ t.boolean "working_hours_enabled", default: false
+ t.string "out_of_office_message"
+ t.string "timezone", default: "UTC"
+ t.boolean "enable_email_collect", default: true
+ t.boolean "csat_survey_enabled", default: false
+ t.boolean "allow_messages_after_resolved", default: true
+ t.jsonb "auto_assignment_config", default: {}
+ t.boolean "lock_to_single_conversation", default: false, null: false
+ t.bigint "portal_id"
+ t.index ["account_id"], name: "index_inboxes_on_account_id"
+ t.index ["channel_id", "channel_type"], name: "index_inboxes_on_channel_id_and_channel_type"
+ t.index ["portal_id"], name: "index_inboxes_on_portal_id"
+ end
+ create_table "installation_configs" do |t|
+ t.string "name", null: false
+ t.jsonb "serialized_value", default: {}, null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.boolean "locked", default: true, null: false
+ t.index ["name", "created_at"], name: "index_installation_configs_on_name_and_created_at", unique: true
+ t.index ["name"], name: "index_installation_configs_on_name", unique: true
+ end
+ create_table "integrations_hooks" do |t|
+ t.integer "status", default: 0
+ t.integer "inbox_id"
+ t.integer "account_id"
+ t.string "app_id"
+ t.integer "hook_type", default: 0
+ t.string "reference_id"
+ t.string "access_token"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.jsonb "settings", default: {}
+ end
+ create_table "labels" do |t|
+ t.string "title"
+ t.text "description"
+ t.string "color", default: "#1f93ff", null: false
+ t.boolean "show_on_sidebar"
+ t.bigint "account_id"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["account_id"], name: "index_labels_on_account_id"
+ t.index ["title", "account_id"], name: "index_labels_on_title_and_account_id", unique: true
+ end
+ create_table "macros" do |t|
+ t.bigint "account_id", null: false
+ t.string "name", null: false
+ t.integer "visibility", default: 0
+ t.bigint "created_by_id"
+ t.bigint "updated_by_id"
+ t.jsonb "actions", default: {}, null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["account_id"], name: "index_macros_on_account_id"
+ end
+ create_table "mentions" do |t|
+ t.bigint "user_id", null: false
+ t.bigint "conversation_id", null: false
+ t.bigint "account_id", null: false
+ t.datetime "mentioned_at", precision: nil, null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["account_id"], name: "index_mentions_on_account_id"
+ t.index ["conversation_id"], name: "index_mentions_on_conversation_id"
+ t.index ["user_id", "conversation_id"], name: "index_mentions_on_user_id_and_conversation_id", unique: true
+ t.index ["user_id"], name: "index_mentions_on_user_id"
+ end
+ create_table "messages", id: :serial do |t|
+ t.text "content"
+ t.integer "account_id", null: false
+ t.integer "inbox_id", null: false
+ t.integer "conversation_id", null: false
+ t.integer "message_type", null: false
+ t.datetime "created_at", precision: nil, null: false
+ t.datetime "updated_at", precision: nil, null: false
+ t.boolean "private", default: false
+ t.integer "status", default: 0
+ t.string "source_id"
+ t.integer "content_type", default: 0, null: false
+ t.json "content_attributes", default: {}
+ t.string "sender_type"
+ t.bigint "sender_id"
+ t.jsonb "external_source_ids", default: {}
+ t.jsonb "additional_attributes", default: {}
+ t.index "((additional_attributes -> 'campaign_id'::text))", name: "index_messages_on_additional_attributes_campaign_id", using: :gin
+ t.index ["account_id"], name: "index_messages_on_account_id"
+ t.index ["account_id", "inbox_id"]
+ t.index ["conversation_id"], name: "index_messages_on_conversation_id"
+ t.index "content", using: 'gin', opclass: "gin_trgm_ops"
+ t.index ["inbox_id"], name: "index_messages_on_inbox_id"
+ t.index ["sender_type", "sender_id"], name: "index_messages_on_sender_type_and_sender_id"
+ t.index ["source_id"], name: "index_messages_on_source_id"
+ end
+ create_table "notes" do |t|
+ t.text "content", null: false
+ t.bigint "account_id", null: false
+ t.bigint "contact_id", null: false
+ t.bigint "user_id"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["account_id"], name: "index_notes_on_account_id"
+ t.index ["contact_id"], name: "index_notes_on_contact_id"
+ t.index ["user_id"], name: "index_notes_on_user_id"
+ end
+ create_table "notification_settings" do |t|
+ t.integer "account_id"
+ t.integer "user_id"
+ t.integer "email_flags", default: 0, null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.integer "push_flags", default: 0, null: false
+ t.index ["account_id", "user_id"], name: "by_account_user", unique: true
+ end
+ create_table "notification_subscriptions" do |t|
+ t.bigint "user_id", null: false
+ t.integer "subscription_type", null: false
+ t.jsonb "subscription_attributes", default: {}, null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.string "identifier"
+ t.index ["identifier"], name: "index_notification_subscriptions_on_identifier", unique: true
+ t.index ["user_id"], name: "index_notification_subscriptions_on_user_id"
+ end
+ create_table "notifications" do |t|
+ t.bigint "account_id", null: false
+ t.bigint "user_id", null: false
+ t.integer "notification_type", null: false
+ t.string "primary_actor_type", null: false
+ t.bigint "primary_actor_id", null: false
+ t.string "secondary_actor_type"
+ t.bigint "secondary_actor_id"
+ t.datetime "read_at", precision: nil
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["account_id"], name: "index_notifications_on_account_id"
+ t.index ["primary_actor_type", "primary_actor_id"], name: "uniq_primary_actor_per_account_notifications"
+ t.index ["secondary_actor_type", "secondary_actor_id"], name: "uniq_secondary_actor_per_account_notifications"
+ t.index ["user_id"], name: "index_notifications_on_user_id"
+ end
+ create_table "platform_app_permissibles" do |t|
+ t.bigint "platform_app_id", null: false
+ t.string "permissible_type", null: false
+ t.bigint "permissible_id", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["permissible_type", "permissible_id"], name: "index_platform_app_permissibles_on_permissibles"
+ t.index ["platform_app_id", "permissible_id", "permissible_type"], name: "unique_permissibles_index", unique: true
+ t.index ["platform_app_id"], name: "index_platform_app_permissibles_on_platform_app_id"
+ end
+ create_table "platform_apps" do |t|
+ t.string "name", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ end
+ create_table "portal_members" do |t|
+ t.bigint "portal_id"
+ t.bigint "user_id"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["portal_id", "user_id"], name: "index_portal_members_on_portal_id_and_user_id", unique: true
+ t.index ["user_id", "portal_id"], name: "index_portal_members_on_user_id_and_portal_id", unique: true
+ end
+ create_table "portals" do |t|
+ t.integer "account_id", null: false
+ t.string "name", null: false
+ t.string "slug", null: false
+ t.string "custom_domain"
+ t.string "color"
+ t.string "homepage_link"
+ t.string "page_title"
+ t.text "header_text"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.jsonb "config", default: {"allowed_locales"=>["en"]}
+ t.boolean "archived", default: false
+ t.index ["custom_domain"], name: "index_portals_on_custom_domain", unique: true
+ t.index ["slug"], name: "index_portals_on_slug", unique: true
+ end
+ create_table "portals_members", id: false do |t|
+ t.bigint "portal_id", null: false
+ t.bigint "user_id", null: false
+ t.index ["portal_id", "user_id"], name: "index_portals_members_on_portal_id_and_user_id", unique: true
+ t.index ["portal_id"], name: "index_portals_members_on_portal_id"
+ t.index ["user_id"], name: "index_portals_members_on_user_id"
+ end
+ create_table "related_categories" do |t|
+ t.bigint "category_id"
+ t.bigint "related_category_id"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["category_id", "related_category_id"], name: "index_related_categories_on_category_id_and_related_category_id", unique: true
+ t.index ["related_category_id", "category_id"], name: "index_related_categories_on_related_category_id_and_category_id", unique: true
+ end
+ create_table "reporting_events" do |t|
+ t.string "name"
+ t.float "value"
+ t.integer "account_id"
+ t.integer "inbox_id"
+ t.integer "user_id"
+ t.integer "conversation_id"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.float "value_in_business_hours"
+ t.datetime "event_start_time", precision: nil
+ t.datetime "event_end_time", precision: nil
+ t.index ["account_id"], name: "index_reporting_events_on_account_id"
+ t.index ["conversation_id"], name: "index_reporting_events_on_conversation_id"
+ t.index ["created_at"], name: "index_reporting_events_on_created_at"
+ t.index ["inbox_id"], name: "index_reporting_events_on_inbox_id"
+ t.index ["name"], name: "index_reporting_events_on_name"
+ t.index ["user_id"], name: "index_reporting_events_on_user_id"
+ end
+ create_table "taggings", id: :serial do |t|
+ t.integer "tag_id"
+ t.string "taggable_type"
+ t.integer "taggable_id"
+ t.string "tagger_type"
+ t.integer "tagger_id"
+ t.string "context", limit: 128
+ t.datetime "created_at", precision: nil
+ t.index ["context"], name: "index_taggings_on_context"
+ t.index ["tag_id", "taggable_id", "taggable_type", "context", "tagger_id", "tagger_type"], name: "taggings_idx", unique: true
+ t.index ["tag_id"], name: "index_taggings_on_tag_id"
+ t.index ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context"
+ t.index ["taggable_id", "taggable_type", "tagger_id", "context"], name: "taggings_idy"
+ t.index ["taggable_id"], name: "index_taggings_on_taggable_id"
+ t.index ["taggable_type"], name: "index_taggings_on_taggable_type"
+ t.index ["tagger_id", "tagger_type"], name: "index_taggings_on_tagger_id_and_tagger_type"
+ t.index ["tagger_id"], name: "index_taggings_on_tagger_id"
+ end
+ create_table "tags", id: :serial do |t|
+ t.string "name"
+ t.integer "taggings_count", default: 0
+ t.index "lower((name)::text) gin_trgm_ops", name: "tags_name_trgm_idx", using: :gin
+ t.index ["name"], name: "index_tags_on_name", unique: true
+ end
+ create_table "team_members" do |t|
+ t.bigint "team_id", null: false
+ t.bigint "user_id", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["team_id", "user_id"], name: "index_team_members_on_team_id_and_user_id", unique: true
+ t.index ["team_id"], name: "index_team_members_on_team_id"
+ t.index ["user_id"], name: "index_team_members_on_user_id"
+ end
+ create_table "teams" do |t|
+ t.string "name", null: false
+ t.text "description"
+ t.boolean "allow_auto_assign", default: true
+ t.bigint "account_id", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["account_id"], name: "index_teams_on_account_id"
+ t.index ["name", "account_id"], name: "index_teams_on_name_and_account_id", unique: true
+ end
+ create_table "telegram_bots", id: :serial do |t|
+ t.string "name"
+ t.string "auth_key"
+ t.integer "account_id"
+ t.datetime "created_at", precision: nil, null: false
+ t.datetime "updated_at", precision: nil, null: false
+ end
+ create_table "users", id: :serial do |t|
+ t.string "provider", default: "email", null: false
+ t.string "uid", default: "", null: false
+ t.string "encrypted_password", default: "", null: false
+ t.string "reset_password_token"
+ t.datetime "reset_password_sent_at", precision: nil
+ t.datetime "remember_created_at", precision: nil
+ t.integer "sign_in_count", default: 0, null: false
+ t.datetime "current_sign_in_at", precision: nil
+ t.datetime "last_sign_in_at", precision: nil
+ t.string "current_sign_in_ip"
+ t.string "last_sign_in_ip"
+ t.string "confirmation_token"
+ t.datetime "confirmed_at", precision: nil
+ t.datetime "confirmation_sent_at", precision: nil
+ t.string "unconfirmed_email"
+ t.string "name", null: false
+ t.string "display_name"
+ t.string "email"
+ t.json "tokens"
+ t.datetime "created_at", precision: nil, null: false
+ t.datetime "updated_at", precision: nil, null: false
+ t.string "pubsub_token"
+ t.integer "availability", default: 0
+ t.jsonb "ui_settings", default: {}
+ t.jsonb "custom_attributes", default: {}
+ t.string "type"
+ t.text "message_signature"
+ t.index ["email"], name: "index_users_on_email"
+ t.index ["pubsub_token"], name: "index_users_on_pubsub_token", unique: true
+ t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
+ t.index ["uid", "provider"], name: "index_users_on_uid_and_provider", unique: true
+ end
+ create_table "webhooks" do |t|
+ t.integer "account_id"
+ t.integer "inbox_id"
+ t.string "url"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.integer "webhook_type", default: 0
+ t.jsonb "subscriptions", default: ["conversation_status_changed", "conversation_updated", "conversation_created", "contact_created", "contact_updated", "message_created", "message_updated", "webwidget_triggered"]
+ t.index ["account_id", "url"], name: "index_webhooks_on_account_id_and_url", unique: true
+ end
+ create_table "working_hours" do |t|
+ t.bigint "inbox_id"
+ t.bigint "account_id"
+ t.integer "day_of_week", null: false
+ t.boolean "closed_all_day", default: false
+ t.integer "open_hour"
+ t.integer "open_minutes"
+ t.integer "close_hour"
+ t.integer "close_minutes"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.boolean "open_all_day", default: false
+ t.index ["account_id"], name: "index_working_hours_on_account_id"
+ t.index ["inbox_id"], name: "index_working_hours_on_inbox_id"
+ end
+ add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
+ add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
+ add_foreign_key "inboxes", "portals"
+ create_trigger("accounts_after_insert_row_tr", :generated => true, :compatibility => 1).
+ on("accounts").
+ after(:insert).
+ for_each(:row) do
+ "execute format('create sequence IF NOT EXISTS conv_dpid_seq_%s', NEW.id);"
+ end
+ create_trigger("conversations_before_insert_row_tr", :generated => true, :compatibility => 1).
+ on("conversations").
+ before(:insert).
+ for_each(:row) do
+ "NEW.display_id := nextval('conv_dpid_seq_' || NEW.account_id);"
+ end
+ create_trigger("camp_dpid_before_insert", :generated => true, :compatibility => 1).
+ on("accounts").
+ name("camp_dpid_before_insert").
+ after(:insert).
+ for_each(:row) do
+ "execute format('create sequence IF NOT EXISTS camp_dpid_seq_%s', NEW.id);"
+ end
+ create_trigger("campaigns_before_insert_row_tr", :generated => true, :compatibility => 1).
+ on("campaigns").
+ before(:insert).
+ for_each(:row) do
+ "NEW.display_id := nextval('camp_dpid_seq_' || NEW.account_id);"
+ end
+ end
+
+ def down
+ raise ActiveRecord::IrreversibleMigration, "The initial migration is not revertable"
+ end
+end
diff --git a/db/migrate/20240131040316_remove_imap_inbox_syned_at_from_channel_email.rb b/db/migrate/20240131040316_remove_imap_inbox_syned_at_from_channel_email.rb
new file mode 100644
index 000000000..20724f29c
--- /dev/null
+++ b/db/migrate/20240131040316_remove_imap_inbox_syned_at_from_channel_email.rb
@@ -0,0 +1,5 @@
+class RemoveImapInboxSynedAtFromChannelEmail < ActiveRecord::Migration[7.0]
+ def change
+ remove_column :channel_email, :imap_inbox_synced_at, :datetime
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index a5cff5fb3..3439a33da 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[7.0].define(version: 2024_01_29_080827) do
+ActiveRecord::Schema[7.0].define(version: 2024_01_31_040316) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_stat_statements"
enable_extension "pg_trgm"
@@ -276,7 +276,6 @@ ActiveRecord::Schema[7.0].define(version: 2024_01_29_080827) do
t.string "imap_login", default: ""
t.string "imap_password", default: ""
t.boolean "imap_enable_ssl", default: true
- t.datetime "imap_inbox_synced_at", precision: nil
t.boolean "smtp_enabled", default: false
t.string "smtp_address", default: ""
t.integer "smtp_port", default: 0
diff --git a/docker-compose.yaml b/docker-compose.yaml
index 1fbf28da9..37c21c069 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -78,6 +78,7 @@ services:
environment:
- WEBPACKER_DEV_SERVER_HOST=0.0.0.0
- NODE_ENV=development
+ - NODE_OPTIONS=--openssl-legacy-provider
- RAILS_ENV=development
entrypoint: docker/entrypoints/webpack.sh
command: bin/webpack-dev-server
diff --git a/enterprise/app/helpers/super_admin/features.yml b/enterprise/app/helpers/super_admin/features.yml
index 41e5af426..a3413a325 100644
--- a/enterprise/app/helpers/super_admin/features.yml
+++ b/enterprise/app/helpers/super_admin/features.yml
@@ -1,3 +1,5 @@
+# TODO: Move this values to features.yml itself
+# No need to replicate the same values in two places
custom_branding:
name: 'Custom Branding'
description: 'Apply your own branding to this installation.'
diff --git a/enterprise/app/jobs/enterprise/internal/check_new_versions_job.rb b/enterprise/app/jobs/enterprise/internal/check_new_versions_job.rb
new file mode 100644
index 000000000..b1f5d62ec
--- /dev/null
+++ b/enterprise/app/jobs/enterprise/internal/check_new_versions_job.rb
@@ -0,0 +1,30 @@
+module Enterprise::Internal::CheckNewVersionsJob
+ def perform
+ super
+ update_plan_info
+ reconcile_premium_config_and_features
+ end
+
+ private
+
+ def update_plan_info
+ return if @instance_info.blank?
+
+ update_installation_config(key: 'INSTALLATION_PRICING_PLAN', value: @instance_info['plan'])
+ update_installation_config(key: 'INSTALLATION_PRICING_PLAN_QUANTITY', value: @instance_info['plan_quantity'])
+ update_installation_config(key: 'CHATWOOT_SUPPORT_WEBSITE_TOKEN', value: @instance_info['chatwoot_support_website_token'])
+ update_installation_config(key: 'CHATWOOT_SUPPORT_IDENTIFIER_HASH', value: @instance_info['chatwoot_support_identifier_hash'])
+ update_installation_config(key: 'CHATWOOT_SUPPORT_SCRIPT_URL', value: @instance_info['chatwoot_support_script_url'])
+ end
+
+ def update_installation_config(key:, value:)
+ config = InstallationConfig.find_or_initialize_by(name: key)
+ config.value = value
+ config.locked = true
+ config.save!
+ end
+
+ def reconcile_premium_config_and_features
+ Internal::ReconcilePlanConfigService.new.perform
+ end
+end
diff --git a/enterprise/app/models/enterprise/automation_rule.rb b/enterprise/app/models/enterprise/automation_rule.rb
new file mode 100644
index 000000000..1e1e85a6d
--- /dev/null
+++ b/enterprise/app/models/enterprise/automation_rule.rb
@@ -0,0 +1,9 @@
+module Enterprise::AutomationRule
+ def conditions_attributes
+ super + %w[sla_policy_id]
+ end
+
+ def actions_attributes
+ super + %w[add_sla]
+ end
+end
diff --git a/enterprise/app/models/enterprise/concerns/user.rb b/enterprise/app/models/enterprise/concerns/user.rb
new file mode 100644
index 000000000..84eddc2ae
--- /dev/null
+++ b/enterprise/app/models/enterprise/concerns/user.rb
@@ -0,0 +1,13 @@
+module Enterprise::Concerns::User
+ extend ActiveSupport::Concern
+
+ included do
+ before_validation :ensure_installation_pricing_plan_quantity, on: :create
+ end
+
+ def ensure_installation_pricing_plan_quantity
+ return unless ChatwootHub.pricing_plan == 'premium'
+
+ errors.add(:base, 'User limit reached. Please purchase more licenses from super admin') if User.count >= ChatwootHub.pricing_plan_quantity
+ end
+end
diff --git a/enterprise/app/services/enterprise/action_service.rb b/enterprise/app/services/enterprise/action_service.rb
new file mode 100644
index 000000000..6e21031aa
--- /dev/null
+++ b/enterprise/app/services/enterprise/action_service.rb
@@ -0,0 +1,15 @@
+module Enterprise::ActionService
+ def add_sla(sla_policy)
+ @conversation.update!(sla_policy_id: sla_policy.id)
+ create_applied_sla(sla_policy)
+ end
+
+ def create_applied_sla(sla_policy)
+ AppliedSla.create!(
+ account_id: @conversation.account_id,
+ sla_policy_id: sla_policy.id,
+ conversation_id: @conversation.id,
+ sla_status: 'active'
+ )
+ end
+end
diff --git a/enterprise/app/services/internal/reconcile_plan_config_service.rb b/enterprise/app/services/internal/reconcile_plan_config_service.rb
new file mode 100644
index 000000000..04414ea68
--- /dev/null
+++ b/enterprise/app/services/internal/reconcile_plan_config_service.rb
@@ -0,0 +1,60 @@
+class Internal::ReconcilePlanConfigService
+ def perform
+ remove_premium_config_reset_warning
+ return if ChatwootHub.pricing_plan != 'community'
+
+ create_premium_config_reset_warning if premium_config_reset_required?
+
+ # We will have this enabled in the future
+ # reconcile_premium_config
+ reconcile_premium_features
+ end
+
+ private
+
+ def config_path
+ @config_path ||= Rails.root.join('enterprise/config')
+ end
+
+ def premium_config
+ @premium_config ||= YAML.safe_load(File.read("#{config_path}/premium_installation_config.yml")).freeze
+ end
+
+ def remove_premium_config_reset_warning
+ Redis::Alfred.delete(Redis::Alfred::CHATWOOT_INSTALLATION_CONFIG_RESET_WARNING)
+ end
+
+ def create_premium_config_reset_warning
+ Redis::Alfred.set(Redis::Alfred::CHATWOOT_INSTALLATION_CONFIG_RESET_WARNING, true)
+ end
+
+ def premium_config_reset_required?
+ premium_config.any? do |config|
+ config = config.with_indifferent_access
+ existing_config = InstallationConfig.find_by(name: config[:name])
+ existing_config&.value != config[:value] if existing_config.present?
+ end
+ end
+
+ def reconcile_premium_config
+ premium_config.each do |config|
+ new_config = config.with_indifferent_access
+ existing_config = InstallationConfig.find_by(name: new_config[:name])
+ next if existing_config&.value == new_config[:value]
+
+ existing_config&.update!(value: new_config[:value])
+ end
+ end
+
+ def premium_features
+ @premium_features ||= YAML.safe_load(File.read("#{config_path}/premium_features.yml")).freeze
+ end
+
+ def reconcile_premium_features
+ Account.find_in_batches do |accounts|
+ accounts.each do |account|
+ account.disable_features!(*premium_features)
+ end
+ end
+ end
+end
diff --git a/enterprise/config/premium_features.yml b/enterprise/config/premium_features.yml
new file mode 100644
index 000000000..9628e1da4
--- /dev/null
+++ b/enterprise/config/premium_features.yml
@@ -0,0 +1,4 @@
+# List of the premium features in EE edition
+- disable_branding
+- audit_logs
+- response_bot
diff --git a/enterprise/config/premium_installation_config.yml b/enterprise/config/premium_installation_config.yml
new file mode 100644
index 000000000..0f102b083
--- /dev/null
+++ b/enterprise/config/premium_installation_config.yml
@@ -0,0 +1,22 @@
+# ------- Branding Related Config ------- #
+- name: INSTALLATION_NAME
+ value: 'Chatwoot'
+- name: LOGO_THUMBNAIL
+ value: '/brand-assets/logo_thumbnail.svg'
+- name: LOGO
+ value: '/brand-assets/logo.svg'
+- name: LOGO_DARK
+ value: '/brand-assets/logo_dark.svg'
+- name: BRAND_URL
+ value: 'https://www.chatwoot.com'
+- name: WIDGET_BRAND_URL
+ value: 'https://www.chatwoot.com'
+- name: BRAND_NAME
+ value: 'Chatwoot'
+- name: TERMS_URL
+ value: 'https://www.chatwoot.com/terms-of-service'
+- name: PRIVACY_URL
+ value: 'https://www.chatwoot.com/privacy-policy'
+- name: DISPLAY_MANIFEST
+ value: true
+# ------- End of Branding Related Config ------- #
diff --git a/lib/custom_exceptions/account.rb b/lib/custom_exceptions/account.rb
index bd77c5a78..efacc9e6e 100644
--- a/lib/custom_exceptions/account.rb
+++ b/lib/custom_exceptions/account.rb
@@ -17,6 +17,12 @@ module CustomExceptions::Account
end
end
+ class InvalidParams < CustomExceptions::Base
+ def message
+ I18n.t 'errors.signup.invalid_params'
+ end
+ end
+
class UserErrors < CustomExceptions::Base
def message
@data[:errors].full_messages.join(',')
diff --git a/lib/redis/redis_keys.rb b/lib/redis/redis_keys.rb
index 535d3774d..f4a1520b1 100644
--- a/lib/redis/redis_keys.rb
+++ b/lib/redis/redis_keys.rb
@@ -28,6 +28,7 @@ module Redis::RedisKeys
## Internal Installation related keys
CHATWOOT_INSTALLATION_ONBOARDING = 'CHATWOOT_INSTALLATION_ONBOARDING'.freeze
+ CHATWOOT_INSTALLATION_CONFIG_RESET_WARNING = 'CHATWOOT_CONFIG_RESET_WARNING'.freeze
LATEST_CHATWOOT_VERSION = 'LATEST_CHATWOOT_VERSION'.freeze
# Check if a message create with same source-id is in progress?
MESSAGE_SOURCE_KEY = 'MESSAGE_SOURCE_KEY::%
s'.freeze
diff --git a/spec/builders/agent_builder_spec.rb b/spec/builders/agent_builder_spec.rb
new file mode 100644
index 000000000..9d7667306
--- /dev/null
+++ b/spec/builders/agent_builder_spec.rb
@@ -0,0 +1,87 @@
+require 'rails_helper'
+
+RSpec.describe AgentBuilder, type: :model do
+ subject(:agent_builder) { described_class.new(params) }
+
+ let(:account) { create(:account) }
+ let!(:current_user) { create(:user, account: account) }
+ let(:email) { 'test@example.com' }
+ let(:name) { 'Test User' }
+ let(:role) { 'agent' }
+ let(:availability) { 'offline' }
+ let(:auto_offline) { false }
+ let(:params) do
+ {
+ email: email,
+ name: name,
+ inviter: current_user,
+ account: account,
+ role: role,
+ availability: availability,
+ auto_offline: auto_offline
+ }
+ end
+
+ describe '#perform' do
+ context 'when user does not exist' do
+ it 'creates a new user' do
+ expect { agent_builder.perform }.to change(User, :count).by(1)
+ end
+
+ it 'creates a new account user' do
+ expect { agent_builder.perform }.to change(AccountUser, :count).by(1)
+ end
+
+ it 'returns a user' do
+ expect(agent_builder.perform).to be_a(User)
+ end
+ end
+
+ context 'when user exists' do
+ before do
+ create(:user, email: email)
+ end
+
+ it 'does not create a new user' do
+ expect { agent_builder.perform }.not_to change(User, :count)
+ end
+
+ it 'creates a new account user' do
+ expect { agent_builder.perform }.to change(AccountUser, :count).by(1)
+ end
+ end
+
+ context 'when only email is provided' do
+ let(:params) { { email: email, inviter: current_user, account: account } }
+
+ it 'creates a user with default values' do
+ user = agent_builder.perform
+ expect(user.name).to eq('')
+ expect(AccountUser.find_by(user: user).role).to eq('agent')
+ end
+ end
+
+ context 'when a temporary password is generated' do
+ it 'sets a temporary password for the user' do
+ user = agent_builder.perform
+ expect(user.encrypted_password).not_to be_empty
+ end
+ end
+
+ context 'with confirmation required' do
+ let(:unconfirmed_user) { create(:user, email: email) }
+
+ before do
+ unconfirmed_user.confirmed_at = nil
+ unconfirmed_user.save(validate: false)
+ allow(unconfirmed_user).to receive(:confirmed?).and_return(false)
+ end
+
+ it 'sends confirmation instructions' do
+ user = agent_builder.perform
+ expect(user).to receive(:send_confirmation_instructions)
+ agent_builder.send(:send_confirmation_if_required)
+ end
+ end
+ end
+end
diff --git a/spec/controllers/api/v1/accounts/agents_controller_spec.rb b/spec/controllers/api/v1/accounts/agents_controller_spec.rb
index 2b06301d6..10693443a 100644
--- a/spec/controllers/api/v1/accounts/agents_controller_spec.rb
+++ b/spec/controllers/api/v1/accounts/agents_controller_spec.rb
@@ -4,8 +4,8 @@ RSpec.describe 'Agents API', type: :request do
include ActiveJob::TestHelper
let(:account) { create(:account) }
- let(:admin) { create(:user, custom_attributes: { test: 'test' }, account: account, role: :administrator) }
- let(:agent) { create(:user, account: account, role: :agent) }
+ let!(:admin) { create(:user, custom_attributes: { test: 'test' }, account: account, role: :administrator) }
+ let!(:agent) { create(:user, account: account, role: :agent) }
describe 'GET /api/v1/accounts/{account.id}/agents' do
context 'when it is an unauthenticated user' do
@@ -63,6 +63,8 @@ RSpec.describe 'Agents API', type: :request do
end
it 'deletes the agent and user object if associated with only one account' do
+ expect(account.users).to include(other_agent)
+
perform_enqueued_jobs(only: DeleteObjectJob) do
delete "/api/v1/accounts/#{account.id}/agents/#{other_agent.id}",
headers: admin.create_new_auth_token,
@@ -70,8 +72,7 @@ RSpec.describe 'Agents API', type: :request do
end
expect(response).to have_http_status(:success)
- expect(account.reload.users.size).to eq(1)
- expect(User.count).to eq(account.reload.users.size)
+ expect(account.reload.users).not_to include(other_agent)
end
it 'deletes only the agent object when user is associated with multiple accounts' do
@@ -85,8 +86,8 @@ RSpec.describe 'Agents API', type: :request do
end
expect(response).to have_http_status(:success)
- expect(account.users.size).to eq(1)
- expect(User.count).to eq(account.reload.users.size + 1)
+ expect(account.reload.users).not_to include(other_agent)
+ expect(other_agent.account_users.count).to eq(1) # Should only be associated with other_account now
end
end
end
@@ -174,4 +175,27 @@ RSpec.describe 'Agents API', type: :request do
end
end
end
+
+ describe 'POST /api/v1/accounts/{account.id}/agents/bulk_create' do
+ let(:emails) { ['test1@example.com', 'test2@example.com', 'test3@example.com'] }
+ let(:bulk_create_params) { { emails: emails } }
+
+ context 'when it is an unauthenticated user' do
+ it 'returns unauthorized' do
+ post "/api/v1/accounts/#{account.id}/agents/bulk_create", params: bulk_create_params
+
+ expect(response).to have_http_status(:unauthorized)
+ end
+ end
+
+ context 'when authenticated as admin' do
+ it 'creates multiple agents successfully' do
+ expect do
+ post "/api/v1/accounts/#{account.id}/agents/bulk_create", params: bulk_create_params, headers: admin.create_new_auth_token
+ end.to change(User, :count).by(3)
+
+ expect(response).to have_http_status(:ok)
+ end
+ end
+ end
end
diff --git a/spec/controllers/api/v1/accounts/notifications_controller_spec.rb b/spec/controllers/api/v1/accounts/notifications_controller_spec.rb
index cadc212d4..3dcb47f71 100644
--- a/spec/controllers/api/v1/accounts/notifications_controller_spec.rb
+++ b/spec/controllers/api/v1/accounts/notifications_controller_spec.rb
@@ -154,7 +154,7 @@ RSpec.describe 'Notifications API', type: :request do
end
end
- describe 'PATCH /api/v1/accounts/{account.id}/notifications/:id/snooze' do
+ describe 'POST /api/v1/accounts/{account.id}/notifications/:id/snooze' do
let(:admin) { create(:user, account: account, role: :administrator) }
let!(:notification) { create(:notification, account: account, user: admin) }
@@ -181,4 +181,69 @@ RSpec.describe 'Notifications API', type: :request do
end
end
end
+
+ describe 'POST /api/v1/accounts/{account.id}/notifications/:id/unread' do
+ let(:admin) { create(:user, account: account, role: :administrator) }
+ let!(:notification) { create(:notification, account: account, user: admin) }
+
+ context 'when it is an unauthenticated user' do
+ it 'returns unauthorized' do
+ post "/api/v1/accounts/#{account.id}/notifications/#{notification.id}/unread"
+
+ expect(response).to have_http_status(:unauthorized)
+ end
+ end
+
+ context 'when it is an authenticated user' do
+ let(:admin) { create(:user, account: account, role: :administrator) }
+
+ it 'updates the notification read at' do
+ post "/api/v1/accounts/#{account.id}/notifications/#{notification.id}/unread",
+ headers: admin.create_new_auth_token,
+ as: :json
+
+ expect(response).to have_http_status(:success)
+ expect(notification.reload.read_at).to be_nil
+ end
+ end
+ end
+
+ describe 'POST /api/v1/accounts/{account.id}/notifications/destroy_all' do
+ let(:admin) { create(:user, account: account, role: :administrator) }
+ let(:notification1) { create(:notification, account: account, user: admin) }
+ let(:notification2) { create(:notification, account: account, user: admin) }
+
+ context 'when it is an unauthenticated user' do
+ it 'returns unauthorized' do
+ post "/api/v1/accounts/#{account.id}/notifications/destroy_all"
+
+ expect(response).to have_http_status(:unauthorized)
+ end
+ end
+
+ context 'when it is an authenticated user' do
+ let(:admin) { create(:user, account: account, role: :administrator) }
+
+ it 'deletes all the read notifications' do
+ expect(Notification::DeleteNotificationJob).to receive(:perform_later).with(admin, type: :read)
+
+ post "/api/v1/accounts/#{account.id}/notifications/destroy_all",
+ headers: admin.create_new_auth_token,
+ params: { type: 'read' },
+ as: :json
+
+ expect(response).to have_http_status(:success)
+ end
+
+ it 'deletes all the notifications' do
+ expect(Notification::DeleteNotificationJob).to receive(:perform_later).with(admin, type: :all)
+
+ post "/api/v1/accounts/#{account.id}/notifications/destroy_all",
+ headers: admin.create_new_auth_token,
+ as: :json
+
+ expect(response).to have_http_status(:success)
+ end
+ end
+ end
end
diff --git a/spec/controllers/api/v1/accounts_controller_spec.rb b/spec/controllers/api/v1/accounts_controller_spec.rb
index ce5f9623c..060e241a7 100644
--- a/spec/controllers/api/v1/accounts_controller_spec.rb
+++ b/spec/controllers/api/v1/accounts_controller_spec.rb
@@ -61,10 +61,9 @@ RSpec.describe 'Accounts API', type: :request do
params: params,
as: :json
- expect(AccountBuilder).to have_received(:new).with(params.merge(user_password: params[:password]))
- expect(account_builder).to have_received(:perform)
+ expect(AccountBuilder).not_to have_received(:new)
expect(response).to have_http_status(:forbidden)
- expect(response.body).to eq({ message: I18n.t('errors.signup.failed') }.to_json)
+ expect(response.body).to eq({ message: I18n.t('errors.signup.invalid_params') }.to_json)
end
end
end
diff --git a/spec/controllers/api/v1/profiles_controller_spec.rb b/spec/controllers/api/v1/profiles_controller_spec.rb
index 4feb359c6..80f6833f1 100644
--- a/spec/controllers/api/v1/profiles_controller_spec.rb
+++ b/spec/controllers/api/v1/profiles_controller_spec.rb
@@ -242,4 +242,44 @@ RSpec.describe 'Profile API', type: :request do
end
end
end
+
+ describe 'POST /api/v1/profile/resend_confirmation' do
+ context 'when it is an unauthenticated user' do
+ it 'returns unauthorized' do
+ post '/api/v1/profile/resend_confirmation'
+
+ expect(response).to have_http_status(:unauthorized)
+ end
+ end
+
+ context 'when it is an authenticated user' do
+ let(:agent) do
+ create(:user, password: 'Test123!', email: 'test-unconfirmed@email.com', account: account, role: :agent,
+ unconfirmed_email: 'test-unconfirmed@email.com')
+ end
+
+ it 'does not send the confirmation email if the user is already confirmed' do
+ expect do
+ post '/api/v1/profile/resend_confirmation',
+ headers: agent.create_new_auth_token,
+ as: :json
+ end.not_to have_enqueued_mail(Devise::Mailer, :confirmation_instructions)
+
+ expect(response).to have_http_status(:success)
+ end
+
+ it 'resends the confirmation email if the user is unconfirmed' do
+ agent.confirmed_at = nil
+ agent.save!
+
+ expect do
+ post '/api/v1/profile/resend_confirmation',
+ headers: agent.create_new_auth_token,
+ as: :json
+ end.to have_enqueued_mail(Devise::Mailer, :confirmation_instructions)
+
+ expect(response).to have_http_status(:success)
+ end
+ end
+ end
end
diff --git a/spec/controllers/api/v2/accounts_controller_spec.rb b/spec/controllers/api/v2/accounts_controller_spec.rb
new file mode 100644
index 000000000..e0181a282
--- /dev/null
+++ b/spec/controllers/api/v2/accounts_controller_spec.rb
@@ -0,0 +1,104 @@
+require 'rails_helper'
+
+RSpec.describe 'Accounts API', type: :request do
+ describe 'POST /api/v2/accounts' do
+ let(:email) { Faker::Internet.email }
+
+ context 'when posting to accounts with correct parameters' do
+ let(:account_builder) { double }
+ let(:account) { create(:account) }
+ let(:user) { create(:user, email: email, account: account) }
+
+ before do
+ allow(AccountBuilder).to receive(:new).and_return(account_builder)
+ end
+
+ it 'calls account builder' do
+ with_modified_env ENABLE_ACCOUNT_SIGNUP: 'true' do
+ allow(account_builder).to receive(:perform).and_return([user, account])
+
+ params = { email: email, user: nil, password: 'Password1!' }
+
+ post api_v2_accounts_url,
+ params: params,
+ as: :json
+
+ expect(AccountBuilder).to have_received(:new).with(params.except(:password).merge(user_password: params[:password]))
+ expect(account_builder).to have_received(:perform)
+ expect(response.headers.keys).to include('access-token', 'token-type', 'client', 'expiry', 'uid')
+ expect(response.body).to include('en')
+ end
+ end
+
+ it 'calls ChatwootCaptcha' do
+ with_modified_env ENABLE_ACCOUNT_SIGNUP: 'true' do
+ captcha = double
+ allow(account_builder).to receive(:perform).and_return([user, account])
+ allow(ChatwootCaptcha).to receive(:new).and_return(captcha)
+ allow(captcha).to receive(:valid?).and_return(true)
+
+ params = { email: email, user: nil, password: 'Password1!', h_captcha_client_response: '123' }
+
+ post api_v2_accounts_url,
+ params: params,
+ as: :json
+
+ expect(ChatwootCaptcha).to have_received(:new).with('123')
+ expect(response.headers.keys).to include('access-token', 'token-type', 'client', 'expiry', 'uid')
+ expect(response.body).to include('en')
+ end
+ end
+
+ it 'renders error response on invalid params' do
+ with_modified_env ENABLE_ACCOUNT_SIGNUP: 'true' do
+ allow(account_builder).to receive(:perform).and_return(nil)
+
+ params = { email: nil, user: nil }
+
+ post api_v2_accounts_url,
+ params: params,
+ as: :json
+
+ expect(AccountBuilder).to have_received(:new).with(params.merge(user_password: params[:password]))
+ expect(account_builder).to have_received(:perform)
+ expect(response).to have_http_status(:forbidden)
+ expect(response.body).to eq({ message: I18n.t('errors.signup.failed') }.to_json)
+ end
+ end
+ end
+
+ context 'when ENABLE_ACCOUNT_SIGNUP env variable is set to false' do
+ it 'responds 404 on requests' do
+ params = { email: email }
+ with_modified_env ENABLE_ACCOUNT_SIGNUP: 'false' do
+ post api_v2_accounts_url,
+ params: params,
+ as: :json
+
+ expect(response).to have_http_status(:not_found)
+ end
+ end
+ end
+
+ context 'when ENABLE_ACCOUNT_SIGNUP env variable is set to api_only' do
+ let(:account_builder) { double }
+ let(:account) { create(:account) }
+ let(:user) { create(:user, email: email, account: account) }
+
+ it 'does not respond 404 on requests' do
+ allow(AccountBuilder).to receive(:new).and_return(account_builder)
+ allow(account_builder).to receive(:perform).and_return([user, account])
+
+ params = { email: email, user: nil, password: 'Password1!' }
+ with_modified_env ENABLE_ACCOUNT_SIGNUP: 'api_only' do
+ post api_v2_accounts_url,
+ params: params,
+ as: :json
+
+ expect(AccountBuilder).to have_received(:new).with(params.except(:password).merge(user_password: params[:password]))
+ expect(response).to have_http_status(:success)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/controllers/super_admin/app_config_controller_spec.rb b/spec/controllers/super_admin/app_config_controller_spec.rb
index 338c3e611..f517009eb 100644
--- a/spec/controllers/super_admin/app_config_controller_spec.rb
+++ b/spec/controllers/super_admin/app_config_controller_spec.rb
@@ -16,9 +16,9 @@ RSpec.describe 'Super Admin Application Config API', type: :request do
it 'shows the app_config page' do
sign_in(super_admin, scope: :super_admin)
- get '/super_admin/app_config'
+ get '/super_admin/app_config?config=facebook'
expect(response).to have_http_status(:success)
- expect(response.body).to include(config.name)
+ expect(response.body).to include(config.value)
end
end
end
@@ -34,7 +34,7 @@ RSpec.describe 'Super Admin Application Config API', type: :request do
context 'when it is an aunthenticated super admin' do
it 'shows the app_config page' do
sign_in(super_admin, scope: :super_admin)
- post '/super_admin/app_config', params: { app_config: { FB_APP_ID: 'FB_APP_ID' } }
+ post '/super_admin/app_config?config=facebook', params: { app_config: { FB_APP_ID: 'FB_APP_ID' } }
expect(response).to have_http_status(:found)
expect(response).to redirect_to(super_admin_settings_path)
diff --git a/spec/enterprise/controllers/api/v1/accounts/agents_controller_spec.rb b/spec/enterprise/controllers/api/v1/accounts/agents_controller_spec.rb
new file mode 100644
index 000000000..97e76a6cd
--- /dev/null
+++ b/spec/enterprise/controllers/api/v1/accounts/agents_controller_spec.rb
@@ -0,0 +1,45 @@
+require 'rails_helper'
+
+RSpec.describe 'Agents API', type: :request do
+ include ActiveJob::TestHelper
+
+ let(:account) { create(:account) }
+ let!(:admin) { create(:user, custom_attributes: { test: 'test' }, account: account, role: :administrator) }
+
+ describe 'POST /api/v1/accounts/{account.id}/agents' do
+ context 'when the account has reached its agent limit' do
+ params = { name: 'NewUser', email: Faker::Internet.email, role: :agent }
+
+ before do
+ account.update(limits: { agents: 4 })
+ create_list(:user, 4, account: account, role: :agent)
+ end
+
+ it 'prevents adding a new agent and returns a payment required status' do
+ post "/api/v1/accounts/#{account.id}/agents", params: params, headers: admin.create_new_auth_token, as: :json
+
+ expect(response).to have_http_status(:payment_required)
+ expect(response.body).to include('Account limit exceeded. Please purchase more licenses')
+ end
+ end
+ end
+
+ describe 'POST /api/v1/accounts/{account.id}/agents/bulk_create' do
+ let(:emails) { ['test1@example.com', 'test2@example.com', 'test3@example.com'] }
+ let(:bulk_create_params) { { emails: emails } }
+
+ context 'when exceeding agent limit' do
+ it 'prevents creating agents and returns a payment required status' do
+ # Set the limit to be less than the number of emails
+ account.update(limits: { agents: 2 })
+
+ expect do
+ post "/api/v1/accounts/#{account.id}/agents/bulk_create", params: bulk_create_params, headers: admin.create_new_auth_token
+ end.not_to change(User, :count)
+
+ expect(response).to have_http_status(:payment_required)
+ expect(response.body).to include('Account limit exceeded. Please purchase more licenses')
+ end
+ end
+ end
+end
diff --git a/spec/enterprise/jobs/enterprise/internal/check_new_versions_job_spec.rb b/spec/enterprise/jobs/enterprise/internal/check_new_versions_job_spec.rb
new file mode 100644
index 000000000..48664c904
--- /dev/null
+++ b/spec/enterprise/jobs/enterprise/internal/check_new_versions_job_spec.rb
@@ -0,0 +1,32 @@
+require 'rails_helper'
+
+RSpec.describe Internal::CheckNewVersionsJob do
+ subject(:job) { described_class.perform_now }
+
+ let(:reconsile_premium_config_service) { instance_double(Internal::ReconcilePlanConfigService) }
+
+ before do
+ allow(Internal::ReconcilePlanConfigService).to receive(:new).and_return(reconsile_premium_config_service)
+ allow(reconsile_premium_config_service).to receive(:perform)
+ allow(Rails.env).to receive(:production?).and_return(true)
+ end
+
+ it 'updates the plan info' do
+ data = { 'version' => '1.2.3', 'plan' => 'enterprise', 'plan_quantity' => 1, 'chatwoot_support_website_token' => '123',
+ 'chatwoot_support_identifier_hash' => '123', 'chatwoot_support_script_url' => '123' }
+ allow(ChatwootHub).to receive(:sync_with_hub).and_return(data)
+ job
+ expect(InstallationConfig.find_by(name: 'INSTALLATION_PRICING_PLAN').value).to eq 'enterprise'
+ expect(InstallationConfig.find_by(name: 'INSTALLATION_PRICING_PLAN_QUANTITY').value).to eq 1
+ expect(InstallationConfig.find_by(name: 'CHATWOOT_SUPPORT_WEBSITE_TOKEN').value).to eq '123'
+ expect(InstallationConfig.find_by(name: 'CHATWOOT_SUPPORT_IDENTIFIER_HASH').value).to eq '123'
+ expect(InstallationConfig.find_by(name: 'CHATWOOT_SUPPORT_SCRIPT_URL').value).to eq '123'
+ end
+
+ it 'calls Internal::ReconcilePlanConfigService' do
+ data = { 'version' => '1.2.3' }
+ allow(ChatwootHub).to receive(:sync_with_hub).and_return(data)
+ job
+ expect(reconsile_premium_config_service).to have_received(:perform)
+ end
+end
diff --git a/enterprise/spec/integrations/openai/processor_service_spec.rb b/spec/enterprise/lib/integrations/openai/processor_service_spec.rb
similarity index 74%
rename from enterprise/spec/integrations/openai/processor_service_spec.rb
rename to spec/enterprise/lib/integrations/openai/processor_service_spec.rb
index 966062d37..2a98514cf 100644
--- a/enterprise/spec/integrations/openai/processor_service_spec.rb
+++ b/spec/enterprise/lib/integrations/openai/processor_service_spec.rb
@@ -44,6 +44,8 @@ RSpec.describe Integrations::Openai::ProcessorService do
create(:label, account: account)
create(:label, account: account)
+
+ hook.settings['label_suggestion'] = 'true'
end
it 'returns the label suggestions' do
@@ -81,5 +83,26 @@ RSpec.describe Integrations::Openai::ProcessorService do
expect(subject.perform).to be_nil
end
end
+
+ context 'when hook is not enabled' do
+ let(:event) { { 'name' => 'label_suggestion', 'data' => { 'conversation_display_id' => conversation.display_id } } }
+
+ before do
+ create(:message, account: account, conversation: conversation, message_type: :incoming, content: 'hello agent')
+ create(:message, account: account, conversation: conversation, message_type: :outgoing, content: 'hello customer')
+ create(:message, account: account, conversation: conversation, message_type: :incoming, content: 'hello agent 2')
+ create(:message, account: account, conversation: conversation, message_type: :incoming, content: 'hello agent 3')
+ create(:message, account: account, conversation: conversation, message_type: :incoming, content: 'hello agent 4')
+
+ create(:label, account: account)
+ create(:label, account: account)
+
+ hook.settings['label_suggestion'] = nil
+ end
+
+ it 'returns nil' do
+ expect(subject.perform).to be_nil
+ end
+ end
end
end
diff --git a/spec/enterprise/models/automation_rule_spec.rb b/spec/enterprise/models/automation_rule_spec.rb
index 69e7949b7..e2e929d2c 100644
--- a/spec/enterprise/models/automation_rule_spec.rb
+++ b/spec/enterprise/models/automation_rule_spec.rb
@@ -25,5 +25,12 @@ RSpec.describe AutomationRule do
expect(Audited::Audit.where(auditable_type: 'AutomationRule', action: 'destroy').count).to eq 1
end
end
+
+ context 'when automation rule is in enterprise namespace' do
+ it 'has associated sla methods available' do
+ expect(automation_rule.conditions_attributes).to include('sla_policy_id')
+ expect(automation_rule.actions_attributes).to include('add_sla')
+ end
+ end
end
end
diff --git a/spec/enterprise/models/user_spec.rb b/spec/enterprise/models/user_spec.rb
index ba1890a78..21e398709 100644
--- a/spec/enterprise/models/user_spec.rb
+++ b/spec/enterprise/models/user_spec.rb
@@ -3,9 +3,60 @@
require 'rails_helper'
RSpec.describe User do
- let(:user) { create(:user) }
+ let!(:user) { create(:user) }
+
+ describe 'before validation for pricing plans' do
+ let!(:existing_user) { create(:user) }
+ let(:new_user) { build(:user) }
+
+ context 'when pricing plan is not premium' do
+ before do
+ allow(ChatwootHub).to receive(:pricing_plan).and_return('community')
+ allow(ChatwootHub).to receive(:pricing_plan_quantity).and_return(0)
+ end
+
+ it 'does not add an error to the user' do
+ new_user.valid?
+ expect(new_user.errors[:base]).to be_empty
+ end
+ end
+
+ context 'when pricing plan is premium' do
+ before do
+ allow(ChatwootHub).to receive(:pricing_plan).and_return('premium')
+ end
+
+ context 'when the user limit is reached' do
+ it 'adds an error when trying to create a user' do
+ allow(ChatwootHub).to receive(:pricing_plan_quantity).and_return(1)
+ new_user.valid?
+ expect(new_user.errors[:base]).to include('User limit reached. Please purchase more licenses from super admin')
+ end
+
+ it 'will not add error when trying to update a existing user' do
+ allow(ChatwootHub).to receive(:pricing_plan_quantity).and_return(1)
+ existing_user.update(name: 'new name')
+ # since there is user and existing user, we are already over limits
+ existing_user.valid?
+ expect(existing_user.errors[:base]).to be_empty
+ end
+ end
+
+ context 'when the user limit is not reached' do
+ it 'does not add an error to the user' do
+ allow(ChatwootHub).to receive(:pricing_plan_quantity).and_return(3)
+ new_user.valid?
+ expect(user.errors[:base]).to be_empty
+ end
+ end
+ end
+ end
describe 'audit log' do
+ before do
+ create(:user)
+ end
+
context 'when user is created' do
it 'has no associated audit log created' do
expect(Audited::Audit.where(auditable_type: 'User', action: 'create').count).to eq 0
diff --git a/spec/enterprise/services/enterprise/action_service_spec.rb b/spec/enterprise/services/enterprise/action_service_spec.rb
new file mode 100644
index 000000000..6efffca6d
--- /dev/null
+++ b/spec/enterprise/services/enterprise/action_service_spec.rb
@@ -0,0 +1,23 @@
+require 'rails_helper'
+
+describe ActionService do
+ let(:account) { create(:account) }
+
+ describe '#add_sla' do
+ let(:sla_policy) { create(:sla_policy, account: account) }
+ let(:conversation) { create(:conversation, account: account) }
+ let(:action_service) { described_class.new(conversation) }
+
+ it 'adds the sla policy to the conversation and create applied_sla entry' do
+ action_service.add_sla(sla_policy)
+ expect(conversation.reload.sla_policy_id).to eq(sla_policy.id)
+
+ # check if appliedsla table entry is created with matching attributes
+ applied_sla = AppliedSla.last
+ expect(applied_sla.account_id).to eq(account.id)
+ expect(applied_sla.sla_policy_id).to eq(sla_policy.id)
+ expect(applied_sla.conversation_id).to eq(conversation.id)
+ expect(applied_sla.sla_status).to eq('active')
+ end
+ end
+end
diff --git a/spec/enterprise/services/internal/reconcile_plan_config_service_spec.rb b/spec/enterprise/services/internal/reconcile_plan_config_service_spec.rb
new file mode 100644
index 000000000..ee8b25557
--- /dev/null
+++ b/spec/enterprise/services/internal/reconcile_plan_config_service_spec.rb
@@ -0,0 +1,81 @@
+require 'rails_helper'
+
+RSpec.describe Internal::ReconcilePlanConfigService do
+ describe '#perform' do
+ let(:service) { described_class.new }
+
+ context 'when pricing plan is community' do
+ before do
+ allow(ChatwootHub).to receive(:pricing_plan).and_return('community')
+ end
+
+ it 'disables the premium features for accounts' do
+ account = create(:account)
+ account.enable_features!('disable_branding', 'audit_logs', 'response_bot')
+ response_bot_account = create(:account)
+ response_bot_account.enable_features!('response_bot')
+ disable_branding_account = create(:account)
+ disable_branding_account.enable_features!('disable_branding')
+ service.perform
+ expect(account.reload.enabled_features.keys).not_to include('response_bot', 'disable_branding', 'audit_logs')
+ expect(response_bot_account.reload.enabled_features.keys).not_to include('response_bot')
+ expect(disable_branding_account.reload.enabled_features.keys).not_to include('disable_branding')
+ end
+
+ it 'creates a premium config reset warning if config was modified' do
+ create(:installation_config, name: 'INSTALLATION_NAME', value: 'custom-name')
+ service.perform
+ expect(Redis::Alfred.get(Redis::Alfred::CHATWOOT_INSTALLATION_CONFIG_RESET_WARNING)).to eq('true')
+ end
+
+ it 'will not create a premium config reset warning if config is not modified' do
+ create(:installation_config, name: 'INSTALLATION_NAME', value: 'Chatwoot')
+ service.perform
+ expect(Redis::Alfred.get(Redis::Alfred::CHATWOOT_INSTALLATION_CONFIG_RESET_WARNING)).to be_nil
+ end
+
+ # To be enabled in the future when method is uncommented
+
+ # it 'updates the premium configs to default' do
+ # create(:installation_config, name: 'INSTALLATION_NAME', value: 'custom-name')
+ # create(:installation_config, name: 'LOGO', value: '/custom-path/logo.svg')
+ # service.perform
+ # expect(InstallationConfig.find_by(name: 'INSTALLATION_NAME').value).to eq('Chatwoot')
+ # expect(InstallationConfig.find_by(name: 'LOGO').value).to eq('/brand-assets/logo.svg')
+ # end
+ end
+
+ context 'when pricing plan is not community' do
+ before do
+ allow(ChatwootHub).to receive(:pricing_plan).and_return('enterprise')
+ end
+
+ it 'unset premium config warning on upgrade' do
+ Redis::Alfred.set(Redis::Alfred::CHATWOOT_INSTALLATION_CONFIG_RESET_WARNING, true)
+ service.perform
+ expect(Redis::Alfred.get(Redis::Alfred::CHATWOOT_INSTALLATION_CONFIG_RESET_WARNING)).to be_nil
+ end
+
+ it 'does not disable the premium features for accounts' do
+ account = create(:account)
+ account.enable_features!('disable_branding', 'audit_logs', 'response_bot')
+ response_bot_account = create(:account)
+ response_bot_account.enable_features!('response_bot')
+ disable_branding_account = create(:account)
+ disable_branding_account.enable_features!('disable_branding')
+ service.perform
+ expect(account.reload.enabled_features.keys).to include('response_bot', 'disable_branding', 'audit_logs')
+ expect(response_bot_account.reload.enabled_features.keys).to include('response_bot')
+ expect(disable_branding_account.reload.enabled_features.keys).to include('disable_branding')
+ end
+
+ it 'does not update the LOGO config' do
+ create(:installation_config, name: 'INSTALLATION_NAME', value: 'custom-name')
+ create(:installation_config, name: 'LOGO', value: '/custom-path/logo.svg')
+ service.perform
+ expect(InstallationConfig.find_by(name: 'INSTALLATION_NAME').value).to eq('custom-name')
+ expect(InstallationConfig.find_by(name: 'LOGO').value).to eq('/custom-path/logo.svg')
+ end
+ end
+ end
+end
diff --git a/spec/factories/channel/channel_email.rb b/spec/factories/channel/channel_email.rb
index 6e01dffdd..3ec96aaa4 100644
--- a/spec/factories/channel/channel_email.rb
+++ b/spec/factories/channel/channel_email.rb
@@ -8,5 +8,22 @@ FactoryBot.define do
after(:create) do |channel_email|
create(:inbox, channel: channel_email, account: channel_email.account)
end
+
+ trait :microsoft_email do
+ imap_enabled { true }
+ imap_address { 'outlook.office365.com' }
+ imap_port { 993 }
+ imap_login { 'email@example.com' }
+ imap_password { '' }
+ imap_enable_ssl { true }
+ provider_config do
+ {
+ expires_on: Time.zone.now + 3600,
+ access_token: SecureRandom.hex,
+ refresh_token: SecureRandom.hex
+ }
+ end
+ provider { 'microsoft' }
+ end
end
end
diff --git a/spec/finders/notification_finder_spec.rb b/spec/finders/notification_finder_spec.rb
index 294cef7ff..48a9f2785 100644
--- a/spec/finders/notification_finder_spec.rb
+++ b/spec/finders/notification_finder_spec.rb
@@ -63,5 +63,42 @@ describe NotificationFinder do
expect(result).to be 1
end
end
+
+ context 'when type read param is passed' do
+ let(:params) { { type: 'read' } }
+
+ it 'returns only read notifications' do
+ result = notification_finder.perform
+ expect(result.length).to be 2
+ end
+
+ it 'returns count' do
+ result = notification_finder.count
+ expect(result).to be 2
+ end
+ end
+
+ context 'when type read and snoozed param is passed' do
+ let(:params) { { type: 'read', status: 'snoozed' } }
+
+ it 'returns only read notifications' do
+ result = notification_finder.perform
+ expect(result.length).to be 0
+ end
+
+ it 'returns count' do
+ result = notification_finder.count
+ expect(result).to be 0
+ end
+ end
+
+ context 'when sort order is passed' do
+ let(:params) { { sort_order: :asc } }
+
+ it 'returns notifications in ascending order' do
+ result = notification_finder.perform
+ expect(result.first.last_activity_at).to be < result.last.last_activity_at
+ end
+ end
end
end
diff --git a/spec/fixtures/files/mail_with_no_date.eml b/spec/fixtures/files/mail_with_no_date.eml
index 745d5782d..f9f806d49 100644
--- a/spec/fixtures/files/mail_with_no_date.eml
+++ b/spec/fixtures/files/mail_with_no_date.eml
@@ -2,5 +2,6 @@ Date:
From: testemail@gmail.com
To: imap@outlook.com
Subject: test text only mail
+Message-Id: <0CB459E0-0336-41DA-BC88-E6E28C697DDB@chatwoot.com>
text only mail
diff --git a/spec/jobs/channels/whatsapp/templates_sync_scheduler_job_spec.rb b/spec/jobs/channels/whatsapp/templates_sync_scheduler_job_spec.rb
index e6545bfe3..cf0b30842 100644
--- a/spec/jobs/channels/whatsapp/templates_sync_scheduler_job_spec.rb
+++ b/spec/jobs/channels/whatsapp/templates_sync_scheduler_job_spec.rb
@@ -23,5 +23,23 @@ RSpec.describe Channels::Whatsapp::TemplatesSyncSchedulerJob do
have_been_enqueued.with(non_synced).on_queue('low')
)
end
+
+ it 'schedules templates_sync_job for oldest synced channels first' do
+ stub_const('Limits::BULK_EXTERNAL_HTTP_CALLS_LIMIT', 2)
+ stub_request(:post, 'https://waba.360dialog.io/v1/configs/webhook')
+ non_synced = create(:channel_whatsapp, sync_templates: false, message_templates_last_updated: nil)
+ synced_recently = create(:channel_whatsapp, sync_templates: false, message_templates_last_updated: 4.hours.ago)
+ synced_old = create(:channel_whatsapp, sync_templates: false, message_templates_last_updated: 6.hours.ago)
+ described_class.perform_now
+ expect(Channels::Whatsapp::TemplatesSyncJob).not_to(
+ have_been_enqueued.with(synced_recently).on_queue('low')
+ )
+ expect(Channels::Whatsapp::TemplatesSyncJob).to(
+ have_been_enqueued.with(synced_old).on_queue('low')
+ )
+ expect(Channels::Whatsapp::TemplatesSyncJob).to(
+ have_been_enqueued.with(non_synced).on_queue('low')
+ )
+ end
end
end
diff --git a/spec/jobs/inboxes/fetch_imap_emails_job_spec.rb b/spec/jobs/inboxes/fetch_imap_emails_job_spec.rb
index 30a77c5ec..12828bf68 100644
--- a/spec/jobs/inboxes/fetch_imap_emails_job_spec.rb
+++ b/spec/jobs/inboxes/fetch_imap_emails_job_spec.rb
@@ -6,17 +6,13 @@ RSpec.describe Inboxes::FetchImapEmailsJob do
let(:account) { create(:account) }
let(:imap_email_channel) do
create(:channel_email, imap_enabled: true, imap_address: 'imap.gmail.com', imap_port: 993, imap_login: 'imap@gmail.com',
- imap_password: 'password', imap_inbox_synced_at: Time.now.utc, account: account)
- end
- let(:microsoft_imap_email_channel) do
- create(:channel_email, provider: 'microsoft', imap_enabled: true, imap_address: 'outlook.office365.com',
- imap_port: 993, imap_login: 'imap@outlook.com', imap_password: 'password', account: account,
- provider_config: { access_token: 'access_token' })
+ imap_password: 'password', account: account)
end
+
+ let(:microsoft_imap_email_channel) { create(:channel_email, :microsoft_email) }
let(:ms_email_inbox) { create(:inbox, channel: microsoft_imap_email_channel, account: account) }
let!(:conversation) { create(:conversation, inbox: imap_email_channel.inbox, account: account) }
let(:inbound_mail) { create_inbound_email_from_mail(from: 'testemail@gmail.com', to: 'imap@outlook.com', subject: 'Hello!') }
- let(:inbound_mail_with_no_date) { create_inbound_email_from_fixture('mail_with_no_date.eml') }
let(:inbound_mail_with_attachments) { create_inbound_email_from_fixture('multiple_attachments.eml') }
it 'enqueues the job' do
@@ -56,25 +52,19 @@ RSpec.describe Inboxes::FetchImapEmailsJob do
end
it 'process the email with no date' do
- email = Mail.new do
- to 'test@outlook.com'
- from 'test@gmail.com'
- subject :test.to_s
- body 'hello'
- end
-
- imap_fetch_mail = Net::IMAP::FetchData.new
- imap_fetch_mail.attr = { seqno: 1, RFC822: email }.with_indifferent_access
+ fixture_path = Rails.root.join('spec/fixtures/files/mail_with_no_date.eml')
+ eml_content = File.read(fixture_path)
+ inbound_mail_with_no_date = create_inbound_email_from_fixture('mail_with_no_date.eml')
+ email_header = Net::IMAP::FetchData.new(1, 'BODY[HEADER]' => eml_content)
+ imap_fetch_mail = Net::IMAP::FetchData.new(1, 'RFC822' => eml_content)
imap = double
-
allow(Net::IMAP).to receive(:new).and_return(imap)
allow(imap).to receive(:authenticate)
allow(imap).to receive(:select)
allow(imap).to receive(:search).and_return([1])
- allow(imap).to receive(:fetch).and_return([imap_fetch_mail])
-
- allow(Mail).to receive(:read_from_string).and_return(inbound_mail_with_no_date.mail)
+ allow(imap).to receive(:fetch).with([1], 'BODY.PEEK[HEADER]').and_return([email_header])
+ allow(imap).to receive(:fetch).with(1, 'RFC822').and_return([imap_fetch_mail])
imap_mailbox = double
diff --git a/spec/jobs/internal/check_new_versions_job_spec.rb b/spec/jobs/internal/check_new_versions_job_spec.rb
index 3d36c4ba7..82424e202 100644
--- a/spec/jobs/internal/check_new_versions_job_spec.rb
+++ b/spec/jobs/internal/check_new_versions_job_spec.rb
@@ -4,7 +4,7 @@ RSpec.describe Internal::CheckNewVersionsJob do
subject(:job) { described_class.perform_now }
it 'updates the latest chatwoot version in redis' do
- data = { 'version' => '1.2.3' }.to_json
+ data = { 'version' => '1.2.3' }
allow(Rails.env).to receive(:production?).and_return(true)
allow(ChatwootHub).to receive(:sync_with_hub).and_return(data)
job
diff --git a/spec/jobs/notification/delete_notification_job_spec.rb b/spec/jobs/notification/delete_notification_job_spec.rb
new file mode 100644
index 000000000..194a24732
--- /dev/null
+++ b/spec/jobs/notification/delete_notification_job_spec.rb
@@ -0,0 +1,38 @@
+require 'rails_helper'
+
+RSpec.describe Notification::DeleteNotificationJob do
+ let(:user) { create(:user) }
+ let(:conversation) { create(:conversation) }
+
+ context 'when enqueuing the job' do
+ it 'enqueues the job to delete all notifications' do
+ expect do
+ described_class.perform_later(user.id, type: :all)
+ end.to have_enqueued_job(described_class).on_queue('low')
+ end
+
+ it 'enqueues the job to delete read notifications' do
+ expect do
+ described_class.perform_later(user.id, type: :read)
+ end.to have_enqueued_job(described_class).on_queue('low')
+ end
+ end
+
+ context 'when performing the job' do
+ before do
+ create(:notification, user: user, read_at: nil)
+ create(:notification, user: user, read_at: Time.current)
+ end
+
+ it 'deletes all notifications' do
+ described_class.perform_now(user, type: :all)
+ expect(user.notifications.count).to eq(0)
+ end
+
+ it 'deletes only read notifications' do
+ described_class.perform_now(user, type: :read)
+ expect(user.notifications.count).to eq(1)
+ expect(user.notifications.where(read_at: nil).count).to eq(1)
+ end
+ end
+end
diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb
index 86a7e6a5d..8f9ba7d2c 100644
--- a/spec/models/account_spec.rb
+++ b/spec/models/account_spec.rb
@@ -3,7 +3,6 @@
require 'rails_helper'
RSpec.describe Account do
- it { is_expected.to validate_presence_of(:name) }
it { is_expected.to validate_numericality_of(:auto_resolve_duration).is_greater_than_or_equal_to(1) }
it { is_expected.to validate_numericality_of(:auto_resolve_duration).is_less_than_or_equal_to(999) }
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index f38b3db0b..5dd3fc3c3 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -9,8 +9,6 @@ RSpec.describe User do
context 'validations' do
it { is_expected.to validate_presence_of(:email) }
- it { is_expected.to validate_presence_of(:name) }
- it { is_expected.to validate_length_of(:name).is_at_least(1) }
end
context 'associations' do
diff --git a/spec/services/microsoft/refresh_oauth_token_service_spec.rb b/spec/services/microsoft/refresh_oauth_token_service_spec.rb
index 5218d388b..346db70d8 100644
--- a/spec/services/microsoft/refresh_oauth_token_service_spec.rb
+++ b/spec/services/microsoft/refresh_oauth_token_service_spec.rb
@@ -1,51 +1,87 @@
require 'rails_helper'
RSpec.describe Microsoft::RefreshOauthTokenService do
- let(:access_token) { SecureRandom.hex }
- let(:refresh_token) { SecureRandom.hex }
- let(:expires_on) { Time.zone.now + 3600 }
-
- let!(:microsoft_email_channel) do
- create(:channel_email, provider_config: { access_token: access_token, refresh_token: refresh_token, expires_on: expires_on })
+ let!(:microsoft_channel) { create(:channel_email, :microsoft_email) }
+ let!(:microsoft_channel_with_expired_token) do
+ create(
+ :channel_email, :microsoft_email, provider_config: {
+ expires_on: Time.zone.now - 3600,
+ access_token: SecureRandom.hex,
+ refresh_token: SecureRandom.hex
+ }
+ )
end
- let(:new_tokens) { { access_token: access_token, refresh_token: refresh_token, expires_at: expires_on.to_i, token_type: 'bearer' } }
- describe '#access_token' do
- context 'when token is not expired' do
- it 'returns the existing access token' do
- expect(described_class.new(channel: microsoft_email_channel).access_token).to eq(access_token)
- expect(microsoft_email_channel.reload.provider_config['refresh_token']).to eq(refresh_token)
- end
+ let(:new_tokens) do
+ {
+ access_token: SecureRandom.hex,
+ refresh_token: SecureRandom.hex,
+ expires_at: (Time.zone.now + 3600).to_i,
+ token_type: 'bearer'
+ }
+ end
+
+ context 'when token is not expired' do
+ it 'returns the existing access token' do
+ service = described_class.new(channel: microsoft_channel)
+
+ expect(service.access_token).to eq(microsoft_channel.provider_config['access_token'])
+ expect(microsoft_channel.reload.provider_config['refresh_token']).to eq(microsoft_channel.provider_config['refresh_token'])
+ end
+ end
+
+ describe 'on expired token or invalid expiry' do
+ before do
+ stub_request(:post, 'https://login.microsoftonline.com/common/oauth2/v2.0/token').with(
+ body: { 'grant_type' => 'refresh_token', 'refresh_token' => microsoft_channel_with_expired_token.provider_config['refresh_token'] }
+ ).to_return(status: 200, body: new_tokens.to_json, headers: { 'Content-Type' => 'application/json' })
end
- context 'when token is expired' do
- let(:expires_on) { 1.minute.from_now }
-
- before do
- stub_request(:post, 'https://login.microsoftonline.com/common/oauth2/v2.0/token').with(
- body: { 'grant_type' => 'refresh_token', 'refresh_token' => refresh_token }
- ).to_return(status: 200, body: new_tokens.to_json, headers: { 'Content-Type' => 'application/json' })
- end
-
+ context 'when token is invalid' do
it 'fetches new access token and refresh tokens' do
- microsoft_email_channel.provider_config['expires_on'] = Time.zone.now - 3600
- microsoft_email_channel.save!
+ with_modified_env AZURE_APP_ID: SecureRandom.uuid, AZURE_APP_SECRET: SecureRandom.hex do
+ provider_config = microsoft_channel_with_expired_token.provider_config
+ service = described_class.new(channel: microsoft_channel_with_expired_token)
+ expect(service.access_token).not_to eq(provider_config['access_token'])
- expect(described_class.new(channel: microsoft_email_channel).access_token).not_to eq(access_token)
- expect(microsoft_email_channel.reload.provider_config['access_token']).to eq(new_tokens[:access_token])
- expect(microsoft_email_channel.reload.provider_config['refresh_token']).to eq(new_tokens[:refresh_token])
- expect(microsoft_email_channel.reload.provider_config['expires_on']).to eq(Time.at(new_tokens[:expires_at]).utc.to_s)
+ new_provider_config = microsoft_channel_with_expired_token.reload.provider_config
+ expect(new_provider_config['access_token']).to eq(new_tokens[:access_token])
+ expect(new_provider_config['refresh_token']).to eq(new_tokens[:refresh_token])
+ expect(new_provider_config['expires_on']).to eq(Time.at(new_tokens[:expires_at]).utc.to_s)
+ end
end
end
- context 'when refresh token is not present in provider config and access token is expired' do
- it 'throws an error' do
- microsoft_email_channel.update(provider_config: {
- access_token: access_token,
- expires_on: expires_on - 3600
- })
+ context 'when expiry time is missing' do
+ it 'fetches new access token and refresh tokens' do
+ with_modified_env AZURE_APP_ID: SecureRandom.uuid, AZURE_APP_SECRET: SecureRandom.hex do
+ microsoft_channel_with_expired_token.provider_config['expires_on'] = nil
+ microsoft_channel_with_expired_token.save!
+ provider_config = microsoft_channel_with_expired_token.provider_config
+ service = described_class.new(channel: microsoft_channel_with_expired_token)
+ expect(service.access_token).not_to eq(provider_config['access_token'])
+
+ new_provider_config = microsoft_channel_with_expired_token.reload.provider_config
+ expect(new_provider_config['access_token']).to eq(new_tokens[:access_token])
+ expect(new_provider_config['refresh_token']).to eq(new_tokens[:refresh_token])
+ expect(new_provider_config['expires_on']).to eq(Time.at(new_tokens[:expires_at]).utc.to_s)
+ end
+ end
+ end
+ end
+
+ context 'when refresh token is not present in provider config and access token is expired' do
+ it 'throws an error' do
+ with_modified_env AZURE_APP_ID: SecureRandom.uuid, AZURE_APP_SECRET: SecureRandom.hex do
+ microsoft_channel.update(
+ provider_config: {
+ access_token: SecureRandom.hex,
+ expires_on: Time.zone.now - 3600
+ }
+ )
+
expect do
- described_class.new(channel: microsoft_email_channel).access_token
+ described_class.new(channel: microsoft_channel).access_token
end.to raise_error(RuntimeError, 'A refresh_token is not available')
end
end
diff --git a/swagger/definitions/request/public/message/update_payload.yml b/swagger/definitions/request/public/message/update_payload.yml
index b581d7171..10926faa1 100644
--- a/swagger/definitions/request/public/message/update_payload.yml
+++ b/swagger/definitions/request/public/message/update_payload.yml
@@ -2,19 +2,5 @@
type: object
properties:
submitted_values:
- oneOf:
- - type: object
- description: Replies to the Bot Message Types
- properties:
- csat_survey_response:
- type: object
- description: CSAT Survey Response if original message is CSAT Survey
- properties:
- rating:
- type: integer
- description: CSAT Rating
- example: 5
- feedback_message:
- type: string
- description: CSAT Comment
- example: 'Great'
+ type: object
+ description: Replies to the Bot Message Types
\ No newline at end of file
diff --git a/swagger/parameters/index.yml b/swagger/parameters/index.yml
index 5dcc1f418..d9cb6872c 100644
--- a/swagger/parameters/index.yml
+++ b/swagger/parameters/index.yml
@@ -51,3 +51,6 @@ public_inbox_identifier:
public_contact_identifier:
$ref: ./public/contact_identifier.yml
+
+portal_id:
+ $ref: ./portal_id.yml
\ No newline at end of file
diff --git a/swagger/paths/application/contacts/filter.yml b/swagger/paths/application/contacts/filter.yml
index 639784ea5..2a1d53cf7 100644
--- a/swagger/paths/application/contacts/filter.yml
+++ b/swagger/paths/application/contacts/filter.yml
@@ -36,7 +36,7 @@ parameters:
query_operator:
type: string
description: query operator name
- enum: [ AND, OR ]
+ enum: [ AND, OR ]
example:
- attribute_key: 'name'
filter_operator: 'equal_to'
diff --git a/swagger/swagger.json b/swagger/swagger.json
index e42a43efe..9bee2c952 100644
--- a/swagger/swagger.json
+++ b/swagger/swagger.json
@@ -2154,12 +2154,12 @@
},
"query_operator": {
"type": "string",
- "description": "query operator name"
- },
- "enum": [
- "AND",
- "OR"
- ]
+ "description": "query operator name",
+ "enum": [
+ "AND",
+ "OR"
+ ]
+ }
}
},
"example": [
@@ -6746,30 +6746,8 @@
"type": "object",
"properties": {
"submitted_values": {
- "oneOf": [
- {
- "type": "object",
- "description": "Replies to the Bot Message Types",
- "properties": {
- "csat_survey_response": {
- "type": "object",
- "description": "CSAT Survey Response if original message is CSAT Survey",
- "properties": {
- "rating": {
- "type": "integer",
- "description": "CSAT Rating",
- "example": 5
- },
- "feedback_message": {
- "type": "string",
- "description": "CSAT Comment",
- "example": "Great"
- }
- }
- }
- }
- }
- ]
+ "type": "object",
+ "description": "Replies to the Bot Message Types"
}
}
},
@@ -7280,6 +7258,13 @@
"type": "string",
"required": true,
"description": "The source id of contact obtained on contact create"
+ },
+ "portal_id": {
+ "in": "path",
+ "name": "portal_id",
+ "type": "integer",
+ "required": true,
+ "description": "The numeric ID of the portal"
}
},
"x-tagGroups": [