9b3f0029a4db72a6edf94dea7e7edb3b1dc0c846
5 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
059506b1db |
feat: Add automatic favicon fetching for companies (#13013)
## Summary This Enterprise-only feature automatically fetches a favicon for companies created with a domain, and adds a batch task to backfill missing avatars for existing companies. The flow only targets companies that do not already have an attached avatar, so existing avatars are left untouched. ## Demo https://github.com/user-attachments/assets/d050334e-769f-4e46-b6e7-f7423727a192 ## What changed - Added `Avatar::AvatarFromFaviconJob` to build a Google favicon URL from the company domain and fetch it through `Avatar::AvatarFromUrlJob` - Triggered favicon fetching from `Company` with `after_create_commit` - Added `Companies::FetchAvatarsJob` to batch existing companies that are missing avatars - Added `companies:fetch_missing_avatars` under `enterprise/lib/tasks` - Kept the company-specific implementation inside the Enterprise boundary - Stubbed the new favicon request in unrelated specs that now hit this callback indirectly - Updated a couple of CI-sensitive specs that were failing due to callback side effects / reload-safe exception assertions ## How to verify 1. Create a company in Enterprise with a valid domain and no avatar. 2. Confirm that a favicon-based avatar gets attached shortly after creation. 3. Create another company with a domain and an avatar already attached. 4. Confirm that the existing avatar is not replaced. 5. Run `companies:fetch_missing_avatars`. 6. Confirm that existing companies without avatars get one, while companies that already have avatars remain unchanged. ## Notes - This change does not refresh or overwrite existing company avatars - Favicon fetching only runs for companies with a present domain - The branch includes the latest `develop` --------- Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com> Co-authored-by: Sojan Jose <sojan@pepalo.com> |
||
|
|
005a22fd69 |
feat: Add sorting by contacts count to companies list (#13012)
## Description Adds the ability to sort companies by the number of contacts they have (contacts_count) in ascending or descending order. This is part of the Chatwoot 5.0 release requirements for the companies feature. The implementation uses a scope-based approach consistent with other sorting implementations in the codebase (e.g., contacts sorting by last_activity_at). ## Type of change - [x] New feature (non-breaking change which adds functionality) ## Available Sorting Options After this change, the Companies API supports the following sorting options: | Sort Field | Type | Ascending | Descending | |------------|------|-----------|------------| | `name` | string | `?sort=name` | `?sort=-name` | | `domain` | string | `?sort=domain` | `?sort=-domain` | | `created_at` | datetime | `?sort=created_at` | `?sort=-created_at` | | `contacts_count` | integer (scope) | `?sort=contacts_count` | `?sort=-contacts_count` | **Note:** Prefix with `-` for descending order. Companies with NULL contacts_count will appear last (NULLS LAST). ## CURL Examples **Sort by contacts count (ascending):** ```bash curl -X GET 'https://app.chatwoot.com/api/v1/accounts/{account_id}/companies?sort=contacts_count' \ -H 'api_access_token: YOUR_API_TOKEN' ``` **Sort by contacts count (descending):** ```bash curl -X GET 'https://app.chatwoot.com/api/v1/accounts/{account_id}/companies?sort=-contacts_count' \ -H 'api_access_token: YOUR_API_TOKEN' ``` **Sort by name (ascending):** ```bash curl -X GET 'https://app.chatwoot.com/api/v1/accounts/{account_id}/companies?sort=name' \ -H 'api_access_token: YOUR_API_TOKEN' ``` **Sort by created_at (descending):** ```bash curl -X GET 'https://app.chatwoot.com/api/v1/accounts/{account_id}/companies?sort=-created_at' \ -H 'api_access_token: YOUR_API_TOKEN' ``` **With pagination:** ```bash curl -X GET 'https://app.chatwoot.com/api/v1/accounts/{account_id}/companies?sort=-contacts_count&page=2' \ -H 'api_access_token: YOUR_API_TOKEN' ``` ## How Has This Been Tested? - Added RSpec tests for both ascending and descending sort - All 24 existing specs pass - Manually tested the sorting functionality with test data **Test configuration:** - Ruby 3.4.4 - Rails 7.1.5.2 - PostgreSQL (test database) **To reproduce:** 1. Run `bundle exec rspec spec/enterprise/controllers/api/v1/accounts/companies_controller_spec.rb` 2. All tests should pass (24 examples, 0 failures) ## 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 ## Technical Details **Backend changes:** - Controller: Added `sort_on :contacts_count` with scope-based sorting - Model: Added `order_on_contacts_count` scope using `Arel::Nodes::SqlLiteral` and `sanitize_sql_for_order` with `NULLS LAST` for consistent NULL handling - Specs: Added 2 new tests for ascending/descending sort validation **Files changed:** - `enterprise/app/controllers/api/v1/accounts/companies_controller.rb` - `enterprise/app/models/company.rb` - `spec/enterprise/controllers/api/v1/accounts/companies_controller_spec.rb` **Note:** This PR only includes the backend implementation. Frontend changes (sort menu UI + i18n) will follow in a separate commit. --------- Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com> Co-authored-by: iamsivin <iamsivin@gmail.com> Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com> Co-authored-by: Pranav <pranav@chatwoot.com> |
||
|
|
58ca82c720 |
feat: Backend - Companies API endpoint with pagination and search (#12840)
## Description Adds API endpoint to list companies with pagination, search, and sorting. Fixes https://linear.app/chatwoot/issue/CW-5930/add-backend-routes-to-get-companies-result Parent issue: https://linear.app/chatwoot/issue/CW-5928/add-companies-tab-to-dashboard ## Type of change - [x] New feature (non-breaking change which adds functionality) ## How Has This Been Tested? Added comprehensive specs to `spec/enterprise/controllers/api/v1/accounts/companies_controller_spec.rb`: - Pagination (25 per page, multiple pages) - Search by name and domain (case-insensitive) - Counter cache for contacts_count - Account scoping - Authorization To reproduce: ```bash bundle exec rspec spec/enterprise/controllers/api/v1/accounts/companies_controller_spec.rb bundle exec rubocop enterprise/app/controllers/api/v1/accounts/companies_controller.rb ``` ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [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 - [ ] Any dependent changes have been merged and published in downstream modules --------- Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com> Co-authored-by: iamsivin <iamsivin@gmail.com> Co-authored-by: Shivam Mishra <scm.mymail@gmail.com> Co-authored-by: Sojan Jose <sojan@pepalo.com> |
||
|
|
ef54f07d5b |
feat: Add company backfill migration for existing contacts (Part 1) (#12657)
## Description Implements company backfill migration infrastructure for existing contacts. This is **Part 1 of 2** for the company model production rollout as described in [CW-5726](https://linear.app/chatwoot/issue/CW-5726/company-model-setting-it-up-on-production). Creates jobs and services to associate existing contacts with companies based on their email domains, filtering out free email providers (gmail, yahoo, etc.) and disposable addresses. **What's included:** - Business email detector service with ValidEmail2 (uses `disposable_domain?` to avoid DNS lookups) - Per-account batch job to process contacts for one account - Orchestrator job to iterate all accounts - Rake task: `bundle exec rake companies:backfill` ~~*NOTE*: I'm using a hard-coded approach to determine if something is a "business" email by filtering out emails that are usually personal. I've also added domains that are common to some of our customers' regions. This should be simpler. I looked into `Valid_Email2` and I couldn't find anything to dictate whether an email is a personal email or a business one. I don't think the approach used in the frontend is valid here.~~ UPDATE: Using `email_provider_info` gem instead. **Pending - Part 2 (separate PR):** Real-time company creation for new contacts ## Type of change - [x] New feature (non-breaking change which adds functionality) ## How Has This Been Tested? ```bash # Run all new tests bundle exec rspec spec/enterprise/services/companies/business_email_detector_service_spec.rb \\ spec/enterprise/jobs/migration/company_account_batch_job_spec.rb \\ spec/enterprise/jobs/migration/company_backfill_job_spec.rb # Run RuboCop bundle exec rubocop enterprise/app/services/companies/business_email_detector_service.rb \\ enterprise/app/jobs/migration/company_account_batch_job.rb \\ enterprise/app/jobs/migration/company_backfill_job.rb \\ lib/tasks/companies.rake ``` **Performance optimization:** - Uses `disposable_domain?` instead of `disposable?` to avoid DNS MX lookups (discovered via tcpdump analysis - `disposable?` was making network calls for every email, causing 100x slowdown) ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [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 - [ ] Any dependent changes have been merged and published in downstream modules --------- Co-authored-by: Sojan Jose <sojan@pepalo.com> |
||
|
|
170ea7691f |
feat: Add company model and API with tests (#12548)
# Pull Request Template ## Description * add Company model with validations for name, domain, description and avatar * Add database migration fo * Implement endpoints for company CRUD operations * Add optional company relationship for contacts * Add test for models, controllers, factories and policies * Add authorization policies restricting delete to admins * support JSON API responses Please include a summary of the change and issue(s) fixed. Also, mention relevant motivation, context, and any dependencies that this change requires. Fixes #(cw-5650) ## Type of change Please delete options that are not relevant. - [x] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality not to work as expected) - [ ] This change requires a documentation update ## How Has This Been Tested? Tests are implemented using `RSpec` ``` $ bundle exec rails db:migrate $ bundle exec rspec spec/models/company_spec.rb spec/controllers/api/v1/accounts/companies_controller_spec.rb ``` ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules |