Upgrade rails to 7.2.2 so that we can proceed with the rails 8 upgrade afterwards # Changelog - `.circleci/config.yml` — align CI DB setup with GitHub Actions (`db:create` + `db:schema:load`) to avoid trigger-dependent prep steps. - `.rubocop.yml` — add `rubocop-rspec_rails` and disable new cops that don't match existing spec style. - `AGENTS.md` — document that specs should run without `.env` (rename temporarily when present). - `Gemfile` — upgrade to Rails 7.2, switch Azure storage gem, pin `commonmarker`, bump `sidekiq-cron`, add `rubocop-rspec_rails`, and relax some gem pins. - `Gemfile.lock` — dependency lockfile updates from the Rails 7.2 and gem changes. - `app/controllers/api/v1/accounts/integrations/linear_controller.rb` — stringify params before passing to the Linear service to keep key types stable. - `app/controllers/super_admin/instance_statuses_controller.rb` — use `MigrationContext` API for migration status in Rails 7.2. - `app/models/installation_config.rb` — add commentary on YAML serialization and future JSONB migration (no behavior change). - `app/models/integrations/hook.rb` — ensure hook type is set on create only and guard against missing app. - `app/models/user.rb` — update enum syntax for Rails 7.2 deprecation, serialize OTP backup codes with JSON, and use Ruby `alias`. - `app/services/crm/leadsquared/setup_service.rb` — stringify hook settings keys before merge to keep JSON shape consistent. - `app/services/macros/execution_service.rb` — remove macro-specific assignee activity workaround; rely on standard assignment handlers. - `config/application.rb` — load Rails 7.2 defaults. - `config/storage.yml` — update Azure Active Storage service name to `AzureBlob`. - `db/migrate/20230515051424_update_article_image_keys.rb` — use credentials `secret_key_base` with fallback to legacy secrets. - `docker/Dockerfile` — add `yaml-dev` and `pkgconf` packages for native extensions (Ruby 3.4 / psych). - `lib/seeders/reports/message_creator.rb` — add parentheses for clarity in range calculation. - `package.json` — pin Vite version and bump `vite-plugin-ruby`. - `pnpm-lock.yaml` — lockfile changes from JS dependency updates. - `spec/builders/v2/report_builder_spec.rb` — disable transactional fixtures; truncate tables per example via Rails `truncate_tables` so after_commit callbacks run with clean isolation; keep builder spec metadata minimal. - `spec/builders/v2/reports/label_summary_builder_spec.rb` — disable transactional fixtures + truncate tables via Rails `truncate_tables`; revert to real `resolved!`/`open!`/`resolved!` flow for multiple resolution events; align date range to `Time.zone` to avoid offset gaps; keep builder spec metadata minimal. - `spec/controllers/api/v1/accounts/macros_controller_spec.rb` — assert `assignee_id` instead of activity message to avoid transaction-timing flakes. - `spec/services/telegram/incoming_message_service_spec.rb` — reference the contact tied to the created conversation instead of `Contact.all.first` to avoid order-dependent failures when other specs leave data behind. - `spec/mailers/administrator_notifications/shared/smtp_config_shared.rb` — use `with_modified_env` instead of stubbing mailer internals. - `spec/services/account/sign_up_email_validation_service_spec.rb` — compare error `class.name` for parallel/reload-safe assertions.
90 lines
4.7 KiB
Markdown
90 lines
4.7 KiB
Markdown
# Chatwoot Development Guidelines
|
||
|
||
## Build / Test / Lint
|
||
|
||
- **Setup**: `bundle install && pnpm install`
|
||
- **Run Dev**: `pnpm dev` or `overmind start -f ./Procfile.dev`
|
||
- **Lint JS/Vue**: `pnpm eslint` / `pnpm eslint:fix`
|
||
- **Lint Ruby**: `bundle exec rubocop -a`
|
||
- **Test JS**: `pnpm test` or `pnpm test:watch`
|
||
- **Test Ruby**: `bundle exec rspec spec/path/to/file_spec.rb`
|
||
- **Single Test**: `bundle exec rspec spec/path/to/file_spec.rb:LINE_NUMBER`
|
||
- **Run Project**: `overmind start -f Procfile.dev`
|
||
- **Ruby Version**: Manage Ruby via `rbenv` and install the version listed in `.ruby-version` (e.g., `rbenv install $(cat .ruby-version)`)
|
||
- **rbenv setup**: Before running any `bundle` or `rspec` commands, init rbenv in your shell (`eval "$(rbenv init -)"`) so the correct Ruby/Bundler versions are used
|
||
- Always prefer `bundle exec` for Ruby CLI tasks (rspec, rake, rubocop, etc.)
|
||
- **Test env**: Specs should run without `.env`. If present, temporarily rename it (e.g., `.env` -> `.env.bak`) while running specs and restore afterward.
|
||
|
||
## Code Style
|
||
|
||
- **Ruby**: Follow RuboCop rules (150 character max line length)
|
||
- **Vue/JS**: Use ESLint (Airbnb base + Vue 3 recommended)
|
||
- **Vue Components**: Use PascalCase
|
||
- **Events**: Use camelCase
|
||
- **I18n**: No bare strings in templates; use i18n
|
||
- **Error Handling**: Use custom exceptions (`lib/custom_exceptions/`)
|
||
- **Models**: Validate presence/uniqueness, add proper indexes
|
||
- **Type Safety**: Use PropTypes in Vue, strong params in Rails
|
||
- **Naming**: Use clear, descriptive names with consistent casing
|
||
- **Vue API**: Always use Composition API with `<script setup>` at the top
|
||
|
||
## Styling
|
||
|
||
- **Tailwind Only**:
|
||
- Do not write custom CSS
|
||
- Do not use scoped CSS
|
||
- Do not use inline styles
|
||
- Always use Tailwind utility classes
|
||
- **Colors**: Refer to `tailwind.config.js` for color definitions
|
||
|
||
## General Guidelines
|
||
|
||
- MVP focus: Least code change, happy-path only
|
||
- No unnecessary defensive programming
|
||
- Ship the happy path first: limit guards/fallbacks to what production has proven necessary, then iterate
|
||
- Prefer minimal, readable code over elaborate abstractions; clarity beats cleverness
|
||
- Break down complex tasks into small, testable units
|
||
- Iterate after confirmation
|
||
- Avoid writing specs unless explicitly asked
|
||
- Remove dead/unreachable/unused code
|
||
- Don’t write multiple versions or backups for the same logic — pick the best approach and implement it
|
||
- Prefer `with_modified_env` (from spec helpers) over stubbing `ENV` directly in specs
|
||
- Specs in parallel/reloading environments: prefer comparing `error.class.name` over constant class equality when asserting raised errors
|
||
|
||
## Commit Messages
|
||
|
||
- Prefer Conventional Commits: `type(scope): subject` (scope optional)
|
||
- Example: `feat(auth): add user authentication`
|
||
- Don't reference Claude in commit messages
|
||
|
||
## Project-Specific
|
||
|
||
- **Translations**:
|
||
- Only update `en.yml` and `en.json`
|
||
- Other languages are handled by the community
|
||
- Backend i18n → `en.yml`, Frontend i18n → `en.json`
|
||
- **Frontend**:
|
||
- Use `components-next/` for message bubbles (the rest is being deprecated)
|
||
|
||
## Ruby Best Practices
|
||
|
||
- Use compact `module/class` definitions; avoid nested styles
|
||
|
||
## Enterprise Edition Notes
|
||
|
||
- Chatwoot has an Enterprise overlay under `enterprise/` that extends/overrides OSS code.
|
||
- When you add or modify core functionality, always check for corresponding files in `enterprise/` and keep behavior compatible.
|
||
- Follow the Enterprise development practices documented here:
|
||
- https://chatwoot.help/hc/handbook/articles/developing-enterprise-edition-features-38
|
||
|
||
Practical checklist for any change impacting core logic or public APIs
|
||
- Search for related files in both trees before editing (e.g., `rg -n "FooService|ControllerName|ModelName" app enterprise`).
|
||
- If adding new endpoints, services, or models, consider whether Enterprise needs:
|
||
- An override (e.g., `enterprise/app/...`), or
|
||
- An extension point (e.g., `prepend_mod_with`, hooks, configuration) to avoid hard forks.
|
||
- Avoid hardcoding instance- or plan-specific behavior in OSS; prefer configuration, feature flags, or extension points consumed by Enterprise.
|
||
- Keep request/response contracts stable across OSS and Enterprise; update both sets of routes/controllers when introducing new APIs.
|
||
- When renaming/moving shared code, mirror the change in `enterprise/` to prevent drift.
|
||
- Tests: Add Enterprise-specific specs under `spec/enterprise`, mirroring OSS spec layout where applicable.
|
||
- When modifying existing OSS features for Enterprise-only behavior, add an Enterprise module (via `prepend_mod_with`/`include_mod_with`) instead of editing OSS files directly—especially for policies, controllers, and services. For Enterprise-exclusive features, place code directly under `enterprise/`.
|