This document outlines the backend development guidelines specific to Chatwoot. All contributors are expected to follow these guidelines to ensure consistency, readability, and maintainability of the codebase.
Note: We follow the general Ruby on Rails development guidelines as mentioned in the official guide: Ruby on Rails Contributing Guide.
Project Structure
- 
Follow Rails' default conventions and directory structure.
 - 
Organize code using service objects, concerns, and modules to keep controllers and models lean.
 
Design Principles
1. Single Responsibility Principle (SRP)
Each class or module should focus on a single responsibility.
✅ Good:
class AccountBuilder
  def initialize(user); @user = user; end
  def perform
    create_account
    setup_inbox
  end
  private
  def create_account
    # account creation logic
  end
  def setup_inbox
    # inbox setup logic
  end
end
❌ Bad:
class SetupEverything
  def execute
    create_account
    setup_inbox
    create_contact
    seed_conversations
  end
end
2. Minimal Namespace Pollution
Group helper classes and utilities under a shared namespace to avoid cluttering top-level modules.
✅ Good:
module TestData
  class AccountCreator
    def self.create; end
  end
end
❌ Bad:
class AccountCreator
  def self.create; end
end
3. Extract Long Methods
Split large methods into smaller private methods to improve readability and testability.
✅ Good:
def process_account_data
  validate_data
  transform_data
  persist_data
end
❌ Bad:
def process_account_data
  # 100+ lines of logic in one place
end
4. Avoid Side Effects in lib/tasks
Rake tasks should only serve as an orchestrator. Move core logic to services or jobs.
✅ Good:
# lib/tasks/seed.rake
namespace :db do
  task seed: :environment do
    Seed::AccountSeeder.new.run
  end
end
❌ Bad:
# lib/tasks/seed.rake
namespace :db do
  task seed: :environment do
    Account.create!(...) # all logic directly in rake task
  end
end
5. Clear Naming
Name variables and methods in a way that clearly communicates their purpose.
✅ Good:
def generate_contact_for_account(account_id); end
❌ Bad:
def gen_contact(id); end
Code Style
- 
Use 2 spaces for indentation.
 - 
Use snake_case for methods and variables.
 - 
Use CamelCase for class and module names.
 - 
Avoid trailing whitespace.
 - 
Run
rubocopbefore committing changes. 
Pull Request Guidelines
Refer to our Pull Request Guidelines for best practices on how to structure, describe, and submit your changes.
API Design
- 
Follow RESTful conventions.
 - 
Use JSON:API specification for consistency.
 - 
Version APIs (e.g.,
/api/v1/...). - 
Use proper status codes and include error messages in a standard format.
 - 
Document all new endpoints by following the Swagger Documentation Guide.
 
Background Jobs
- 
Use Sidekiq for background processing.
 - 
Name jobs with the
Jobsuffix (e.g.,ContactMergeJob). - 
Keep jobs idempotent and retry-safe.
 
Database
- 
Use migrations for schema changes.
 - 
Avoid writing raw SQL unless necessary.
 - 
Use PostgreSQL features (e.g., JSONB, GIN indexes) when beneficial.
 - 
Index foreign keys and columns used in queries.
 
Testing
- 
Use RSpec for all tests.
 - 
Write unit, request, and system tests.
 - 
Aim for high test coverage, especially on critical paths.
 - 
Use FactoryBot for setting up test data.
 
Security
- 
Never trust user input; sanitize and validate.
 - 
Use
strong_parametersin controllers. - 
Avoid dynamic
eval,send, or string interpolation in SQL. 
Performance
- 
Profile slow endpoints using tools like rack-mini-profiler or Skylight.
 - 
Use N+1 detection tools (e.g., Bullet) during development.
 - 
Cache where appropriate, but invalidate caches correctly.
 
Documentation
- 
Document all new endpoints in the API reference.
 - 
Add inline comments for complex logic.
 - 
Update the handbook or README if behavior changes.
 
By adhering to these practices, we ensure that Chatwoot remains a scalable, maintainable, and developer-friendly codebase.