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.