# Ruby on Rails + PostgreSQL + Redis + Sidekiq — AI Agent Guidelines & Architecture Rules

> Production guidelines for Ruby on Rails monoliths, ActiveRecord pool tuning, Redis Sidekiq background jobs, and modern Hotwire or React UI architecture.
> Technologies: Rails, Ruby, PostgreSQL, Redis, Sidekiq

---

## AGENTS.md
```markdown
# Project Architecture & Guidelines (Ruby on Rails + PostgreSQL + Redis + Sidekiq)

## 1. System Architecture
- **Framework**: Ruby on Rails 7.2+ (Puma web server).
- **Database**: PostgreSQL with ActiveRecord ORM.
- **Caching & Job Store**: Redis for Rails cache store and Sidekiq background job broker.
- **Background Worker**: Sidekiq for asynchronous job processing.

## 2. Database Connection Pool Sizing (ActiveRecord & Puma)
- Ensure database connection pool in `config/database.yml` matches Puma thread count and Sidekiq concurrency:
  ```yaml
  default: &default
    adapter: postgresql
    encoding: unicode
    pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
    timeout: 5000
  ```
- When configuring Sidekiq workers, ensure the process pool size is at least equal to the Sidekiq concurrency setting (`concurrency: <%= ENV.fetch("SIDEKIQ_CONCURRENCY") { 10 } %>`).

## 3. Redis & Sidekiq Configuration
- Initialize Sidekiq in `config/initializers/sidekiq.rb` with dedicated connection pools:
  ```ruby
  Sidekiq.configure_server do |config|
    config.redis = { url: ENV.fetch("REDIS_URL", "redis://localhost:6379/1"), size: ENV.fetch("SIDEKIQ_CONCURRENCY", 10).to_i + 5 }
  end

  Sidekiq.configure_client do |config|
    config.redis = { url: ENV.fetch("REDIS_URL", "redis://localhost:6379/1"), size: ENV.fetch("RAILS_MAX_THREADS", 5).to_i }
  end
  ```

## 4. Safe Database Migrations (Zero-Downtime)
- Use the `strong_migrations` gem to prevent dangerous DDL locks in production.
- Adding Columns with Defaults: In PostgreSQL 11+, `add_column` with default values is instant and safe.
- Creating Indexes: Always use `algorithm: :concurrently` and `disable_ddl_transaction!` when adding indexes to live tables.

## 5. Common Pitfalls to Avoid
- ❌ Passing ActiveRecord Objects to Sidekiq: Pass only record IDs (`user_id`), never entire serialized objects.
- ❌ N+1 Queries: Use `includes(:relation)` or `strict_loading` in ActiveRecord queries.
- ❌ Redis Memory Leaks: Use separate Redis database numbers (`db/0` for cache, `db/1` for Sidekiq) to prevent cache evictions from clearing job queues.

## 6. Testing Conventions
- Use RSpec with `factory_bot` for model/request specs; avoid Rails fixtures, which rot as schemas evolve.
- Test Sidekiq jobs with `sidekiq/testing` in fake mode by default; use `Sidekiq::Testing.inline!` only for explicit integration specs that need real execution.
- Use `strict_loading` in test environments to fail fast on N+1 queries instead of catching them in production APM.
- Run request specs (not just model specs) for every controller action — RSpec model coverage alone misses routing and serialization bugs.

## 7. Git Workflow & PR Conventions
- Conventional Commits (`feat:`, `fix:`, `refactor:`) scoped to the Rails resource, e.g. `fix(invoices): correct Sidekiq retry backoff for failed charges`.
- Migrations ship in the same PR as the model change; run through `strong_migrations` locally before pushing.
- Require `bundle exec rspec` and `bin/rails db:migrate:status` clean before merge.
- Squash-merge; concurrent-index migrations get their own PR, never bundled with unrelated schema changes.
```

---

## CLAUDE.md
```markdown
# CLAUDE.md — Ruby on Rails + PostgreSQL + Redis

Refer to @AGENTS.md for ActiveRecord pool sizing and Sidekiq queue guidelines.

## Common Commands
- `bin/rails server` - Start Puma web server
- `bin/rails db:migrate` - Apply pending database migrations
- `bundle exec sidekiq` - Start Sidekiq background worker
- `bundle exec rspec` - Run RSpec test suite

## Claude Specific Directives
- When writing database queries, use ActiveRecord scopes and avoid raw SQL strings.
- Use `strict_loading` to proactively catch N+1 query regressions during development.
```

---

## .cursor/rules/stack.mdc
```markdown
---
description: Ruby on Rails + PostgreSQL + Redis + Sidekiq architecture rules
globs: ["**/*.rb", "**/*.erb"]
alwaysApply: true
---

# Ruby on Rails + PostgreSQL + Redis + Sidekiq

- Rails 7.2+ on Puma, ActiveRecord over PostgreSQL, Redis for cache + Sidekiq broker.
- `database.yml` pool size must match `RAILS_MAX_THREADS`; Sidekiq's Redis pool size must be at least its concurrency setting.
- Separate Redis DB numbers for cache (`db/0`) vs Sidekiq (`db/1`) — a cache eviction must never clear job queues.
- `strong_migrations` gem enforced; `algorithm: :concurrently` + `disable_ddl_transaction!` for indexes on live tables.
- Pass only record IDs to Sidekiq jobs, never serialized ActiveRecord objects.
- `includes(:relation)` or `strict_loading` — no N+1 queries reaching production.
- Every Sidekiq job idempotent by design; assume at-least-once delivery.
```

---

## Architecture Overview & Best Practices
## Architecture Overview

Production conventions for scalable full-stack web applications and monoliths with **Ruby on Rails**, **PostgreSQL**, **Redis**, and **Sidekiq**.

### Verified Real-World Adoption

This architecture is deployed by high-growth platforms including **Maybe Finance**, **Chatwoot**, and **Lago**.

### Key Architectural Nuances

- **Thread & Pool Synchronization**: Aligns Puma concurrency and Sidekiq worker pools with PostgreSQL maximum connections.
- **Zero-Downtime Schema Evolution**: Employs concurrent indexing and lock-safe migrations for high-availability databases.