From 93374f4327c5bad15179de8841c0bf427c302a2d Mon Sep 17 00:00:00 2001 From: Vinay Keerthi <11478411+stonecharioteer@users.noreply.github.com> Date: Mon, 17 Nov 2025 16:09:36 +0530 Subject: [PATCH] fix: Change contact_inboxes.source_id to text column (#12882) ## Description Fixes CW-5961 where IMAP email processing failed with `ActiveRecord::RecordInvalid: Validation failed: Source is too long (maximum is 255 characters)` error. This changes the `contact_inboxes.source_id` column from `string` (255 character limit) to `text` (unlimited) to accommodate long email message IDs that were causing validation failures. Fixes CW-5961 ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? - Added spec test validating `source_id` values longer than 255 characters (300 chars) - All existing `contact_inbox_spec.rb` tests pass (7 examples, 0 failures) - Migration applied successfully with reversible up/down methods - Verified `source_id` column type changed to `text` with `null: false` constraint preserved ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes --- app/models/contact_inbox.rb | 2 +- app/models/conversation.rb | 1 + .../20251114173609_change_source_id_to_text.rb | 9 +++++++++ db/schema.rb | 6 +++--- spec/models/contact_inbox_spec.rb | 12 ++++++++++++ 5 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 db/migrate/20251114173609_change_source_id_to_text.rb diff --git a/app/models/contact_inbox.rb b/app/models/contact_inbox.rb index 6d034880e..893ab87f3 100644 --- a/app/models/contact_inbox.rb +++ b/app/models/contact_inbox.rb @@ -9,7 +9,7 @@ # updated_at :datetime not null # contact_id :bigint # inbox_id :bigint -# source_id :string not null +# source_id :text not null # # Indexes # diff --git a/app/models/conversation.rb b/app/models/conversation.rb index eb97a22e8..ca8a3258e 100644 --- a/app/models/conversation.rb +++ b/app/models/conversation.rb @@ -40,6 +40,7 @@ # index_conversations_on_contact_inbox_id (contact_inbox_id) # index_conversations_on_first_reply_created_at (first_reply_created_at) # index_conversations_on_id_and_account_id (account_id,id) +# index_conversations_on_identifier_and_account_id (identifier,account_id) # index_conversations_on_inbox_id (inbox_id) # index_conversations_on_priority (priority) # index_conversations_on_status_and_account_id (status,account_id) diff --git a/db/migrate/20251114173609_change_source_id_to_text.rb b/db/migrate/20251114173609_change_source_id_to_text.rb new file mode 100644 index 000000000..c6a41131f --- /dev/null +++ b/db/migrate/20251114173609_change_source_id_to_text.rb @@ -0,0 +1,9 @@ +class ChangeSourceIdToText < ActiveRecord::Migration[7.1] + def up + change_column :contact_inboxes, :source_id, :text, null: false + end + + def down + change_column :contact_inboxes, :source_id, :string, null: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 0aeea5cc9..7b893ecd2 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.1].define(version: 2025_10_22_152158) do +ActiveRecord::Schema[7.1].define(version: 2025_11_14_173609) do # These extensions should be enabled to support this database enable_extension "pg_stat_statements" enable_extension "pg_trgm" @@ -585,7 +585,7 @@ ActiveRecord::Schema[7.1].define(version: 2025_10_22_152158) do create_table "contact_inboxes", force: :cascade do |t| t.bigint "contact_id" t.bigint "inbox_id" - t.string "source_id", null: false + t.text "source_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false t.boolean "hmac_verified", default: false @@ -676,7 +676,7 @@ ActiveRecord::Schema[7.1].define(version: 2025_10_22_152158) do 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 ["identifier", "account_id"], name: "index_conversations_on_identifier_and_account_id" + t.index ["identifier", "account_id"], name: "index_conversations_on_identifier_and_account_id" t.index ["inbox_id"], name: "index_conversations_on_inbox_id" t.index ["priority"], name: "index_conversations_on_priority" t.index ["status", "account_id"], name: "index_conversations_on_status_and_account_id" diff --git a/spec/models/contact_inbox_spec.rb b/spec/models/contact_inbox_spec.rb index 23d4b7bc7..c0a2faf9e 100644 --- a/spec/models/contact_inbox_spec.rb +++ b/spec/models/contact_inbox_spec.rb @@ -40,6 +40,18 @@ RSpec.describe ContactInbox do describe 'validations' do context 'when source_id' do + it 'allows source_id longer than 255 characters for channels without format restrictions' do + long_source_id = 'a' * 300 + email_inbox = create(:inbox, channel: create(:channel_email)) + contact = create(:contact, account: email_inbox.account) + contact_inbox = build(:contact_inbox, contact: contact, inbox: email_inbox, source_id: long_source_id) + + expect(contact_inbox.valid?).to be(true) + expect { contact_inbox.save! }.not_to raise_error + expect(contact_inbox.reload.source_id).to eq(long_source_id) + expect(contact_inbox.source_id.length).to eq(300) + end + it 'validates whatsapp channel source_id' do whatsapp_inbox = create(:channel_whatsapp, sync_templates: false, validate_provider_config: false).inbox contact = create(:contact)