6.2 KiB
6.2 KiB
| description | applyTo |
|---|---|
| L4D Tools - Rails 8.1 application with Solid Queue, Hotwire stack | **/*.rb |
L4D Tools - AI Coding Guide
Project Overview
l4d_tools is a Rails 8.1 application using modern Rails conventions. Key architectural decisions:
- Database: SQLite (development), supports production deployment via Kamal/Docker
- Job Processing: Solid Queue (replaces Sidekiq) - background jobs embedded with app via
:solid_queueplugin in Puma - Frontend Stack: Hotwire (Turbo + Stimulus) with importmap-rails and Propshaft
- Testing: Minitest with Capybara for system tests (parallelized workers)
- Deployment: Kamal-based Docker containerization with private registry support
- Security Scanning: Brakeman (security), Rubocop-rails-omakase (style), Bundler-audit (gems)
Critical Developer Workflows
Initial Setup
bin/setup # Installs gems, prepares DB, starts server
bin/setup --reset # Full reset including DB wipe
bin/setup --skip-server # Setup without starting server
Development Commands
bin/dev # Start Rails server (port 3000)
bin/rails console # REPL with app context
bin/rails test # Full test suite (parallel workers)
bin/rails test test/path # Specific test file/directory
bundle exec brakeman # Security vulnerability scan
bundle exec rubocop -a # Auto-fix style violations
Database Management
bin/rails db:prepare # Create/migrate DB
bin/rails db:reset # Wipe and re-seed
bin/rails db:migrate # Apply pending migrations
bin/rails db:rollback # Revert last migration
Deployment (Kamal/Docker)
- Config:
config/deploy.yml- registry, servers, environment variables - Secrets:
.kamal/secretsfile (contains RAILS_MASTER_KEY) - Registry: Private registry at localhost:5555 for deployment target
- Job Processing:
SOLID_QUEUE_IN_PUMA=trueruns supervisor in web process (single-server only) - Build:
docker build -t l4d_tools .builds production image
Architecture & Key Components
Job Processing (Solid Queue)
- Location:
app/jobs/ - Pattern: Inherit from
ApplicationJob < ActiveJob::Base - Configuration:
config/queue.ymldefines adapters and queues - Execution: Jobs run synchronously in test mode; async in development/production
- Puma Integration:
plugin :solid_queue if ENV["SOLID_QUEUE_IN_PUMA"]inconfig/puma.rb - Usage:
MyJob.perform_later(args)for async;MyJob.perform_now(args)for testing
Frontend (Hotwire)
- Turbo: Rapid page transitions via AJAX without full reloads
- Stimulus: Minimal DOM binding framework; controllers in
app/javascript/controllers/ - Asset Pipeline: Propshaft + importmap-rails; no build step needed
- Entry Point:
app/javascript/application.jsloads all controllers - Naming:
data-controller="hello"maps toHelloControllerinapp/javascript/controllers/hello_controller.js
Database & Models
- Schema:
db/schema.rbauto-generated from migrations (commit to VCS) - Migrations: Generate via
bin/rails generate migration CreateTableName - Patterns: Use model scopes for complex queries; keep migrations simple and reversible
- Fixtures: YAML files in
test/fixtures/*.ymlauto-loaded by Minitest
Testing Structure
- Unit Tests:
test/models/,test/helpers/,test/controllers/ - Integration Tests:
test/integration/ - System Tests: Full browser tests via Capybara/Selenium
- Parallelization: Enabled by default; workers scale to CPU count
- Fixtures: Auto-loaded and available as lowercase underscore-separated variables (e.g.,
posts(:one))
Project-Specific Guidelines
- Follow RuboCop-rails-omakase style guide strictly; run
rubocop -ato auto-fix - Use snake_case for variables/methods, CamelCase for classes
- Extract reusable business logic into
app/services/to keep models lean - Use Solid Queue
perform_laterfor background work; never block HTTP requests - Prefer Turbo Frames for dynamic UI updates over full page reloads
- Write tests using fixtures; auto-loaded into test instance variables
- Use
bin/rails testto run full suite with parallel workers - Keep
config/routes.rbsimple; add routes only when adding controller actions - Store secrets in
Rails.application.credentials(encrypted viamaster.key) - Debug with
byebugor Rails logger; avoidputsfor production debugging
Common Patterns
Job Enqueue (Solid Queue)
# app/jobs/my_job.rb
class MyJob < ApplicationJob
queue_as :default
def perform(arg1, arg2)
# async work here
end
end
# Trigger: MyJob.perform_later(arg1, arg2)
# Test: MyJob.perform_now(arg1, arg2)
Model Scopes & Queries
# app/models/post.rb
class Post < ApplicationRecord
scope :published, -> { where(published: true) }
scope :recent, -> { order(created_at: :desc) }
def self.active; where(active: true); end
end
# Usage: Post.published.recent
Stimulus Controller
// app/javascript/controllers/search_controller.js
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["input"]
search() {
console.log(this.inputTarget.value)
}
}
<!-- View: -->
<div data-controller="search">
<input type="text" data-search-target="input" data-action="input->search#search">
</div>
Test Pattern (Minitest)
# test/models/post_test.rb
class PostTest < ActiveSupport::TestCase
fixtures :posts # Auto-loads test/fixtures/posts.yml
test "post is valid" do
assert posts(:one).valid?
end
end
Security & Production Readiness
- Brakeman scans detect security issues; fix all warnings before merge
- Bundler-audit tracks vulnerable gems; update versions regularly
- Strong parameters required for all user input in controllers
- RAILS_MASTER_KEY (from
config/master.key) must be set in Docker via secrets - SQLite adequate for single-server; use PostgreSQL for multi-server scaling
- Content Security Policy configured in
config/initializers/content_security_policy.rb - Never commit
master.keyor.kamal/secrets; set RAILS_MASTER_KEY via environment