229 lines
5.7 KiB
Markdown
229 lines
5.7 KiB
Markdown
# AGENTS.md - Yockboard Development Guide
|
|
|
|
This document provides guidelines for agentic coding agents working on the Yockboard Rails application.
|
|
|
|
## Project Overview
|
|
|
|
- **Framework**: Ruby on Rails 8.1.2
|
|
- **Ruby Version**: 3.4.7
|
|
- **Database**: PostgreSQL
|
|
- **Testing**: Minitest (Rails default)
|
|
- **JavaScript**: Turbo + Stimulus with Importmap
|
|
|
|
## Build / Lint / Test Commands
|
|
|
|
### Development Server
|
|
```bash
|
|
./bin/dev # Start development server (alias for bin/rails server)
|
|
bin/rails server -p 3000
|
|
```
|
|
|
|
### Running Tests
|
|
```bash
|
|
# Run all tests
|
|
bin/rails test
|
|
|
|
# Run a single test file
|
|
bin/rails test test/models/user_test.rb
|
|
|
|
# Run a single test by name
|
|
bin/rails test test/models/user_test.rb -n test_user_validity
|
|
|
|
# Run system tests (browser-based)
|
|
bin/rails test:system
|
|
|
|
# Run tests in specific directory
|
|
bin/rails test test/controllers/
|
|
```
|
|
|
|
### Linting & Code Style
|
|
```bash
|
|
# Run RuboCop linter
|
|
bin/rubocop
|
|
|
|
# Run specific RuboCop check
|
|
bin/rubocop app/models/
|
|
|
|
# Auto-fix RuboCop issues
|
|
bin/rubocop -a
|
|
```
|
|
|
|
### Security Scanning
|
|
```bash
|
|
# Scan for Rails security vulnerabilities
|
|
bin/brakeman --no-pager
|
|
|
|
# Scan for known gem vulnerabilities
|
|
bin/bundler-audit
|
|
|
|
# Audit JS dependencies
|
|
bin/importmap audit
|
|
```
|
|
|
|
### Database
|
|
```bash
|
|
bin/rails db:create db:migrate # Setup database
|
|
bin/rails db:test:prepare # Prepare test database
|
|
bin/rails db:reset # Reset database
|
|
```
|
|
|
|
### CI Pipeline (in .github/workflows/ci.yml)
|
|
- `scan_ruby`: Brakeman + bundler-audit
|
|
- `scan_js`: Importmap audit
|
|
- `lint`: RuboCop
|
|
- `test`: Full test suite with PostgreSQL
|
|
- `system-test`: System/integration tests
|
|
|
|
## Code Style Guidelines
|
|
|
|
### General Philosophy
|
|
Follow the **Rails Omakase** style (via `rubocop-rails-omakase`). This is the default Rails team style.
|
|
|
|
### File Organization
|
|
- Models: `app/models/`
|
|
- Controllers: `app/controllers/`
|
|
- Views: `app/views/controller_name/`
|
|
- Helpers: `app/helpers/`
|
|
- Jobs: `app/jobs/`
|
|
- Mailers: `app/mailers/`
|
|
|
|
### Naming Conventions
|
|
- **Classes/Modules**: `PascalCase` (e.g., `UserAccount`, `OrderProcessor`)
|
|
- **Database tables**: `snake_case_plurals` (e.g., `user_accounts`, `orders`)
|
|
- **Files**: `snake_case.rb` (e.g., `user_account.rb`, `order_processor.rb`)
|
|
- **Methods/variables**: `snake_case` (e.g., `user_accounts`, `process_order`)
|
|
- **Boolean methods**: End with `?` (e.g., `valid?`, `confirmed?`)
|
|
- **Bang methods**: End with `!` for mutating variants (e.g., `save!`, `update!`)
|
|
- **Query methods**: End with `?` or use plural names (e.g., `admin?`, `users`)
|
|
|
|
### Routing
|
|
- Use RESTful routes with `resources` when applicable
|
|
- Use namespace for admin/API routes
|
|
- Prefer shallow nesting: `resources :posts, shallow: true do resources :comments end`
|
|
|
|
### Models
|
|
- Inherit from `ApplicationRecord`
|
|
- Use concerns for shared behavior in `app/models/concerns/`
|
|
- Define associations explicitly
|
|
- Use scopes for common queries
|
|
|
|
```ruby
|
|
class User < ApplicationRecord
|
|
has_many :posts, dependent: :destroy
|
|
|
|
scope :active, -> { where(active: true) }
|
|
|
|
def full_name
|
|
"#{first_name} #{last_name}".strip
|
|
end
|
|
end
|
|
```
|
|
|
|
### Controllers
|
|
- Inherit from `ApplicationController`
|
|
- Use strong parameters for mass assignment
|
|
- Follow RESTful actions pattern
|
|
- Keep controllers thin; push logic to models/services
|
|
|
|
```ruby
|
|
class UsersController < ApplicationController
|
|
def index
|
|
@users = User.active.order(:created_at)
|
|
end
|
|
|
|
def create
|
|
@user = User.new(user_params)
|
|
if @user.save
|
|
redirect_to @user, notice: "User created"
|
|
else
|
|
render :new, status: :unprocessable_entity
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def user_params
|
|
params.require(:user).permit(:first_name, :last_name, :email)
|
|
end
|
|
end
|
|
```
|
|
|
|
### Views
|
|
- Use ERB with HTML
|
|
- Use Turbo Frames/Streams for SPA-like behavior
|
|
- Prefer Stimulus controllers over vanilla JS
|
|
- Use partials for reusable components
|
|
|
|
### Testing (Minitest)
|
|
- Test files go in `test/` mirroring `app/` structure
|
|
- Use `test/test_helper.rb` for shared setup
|
|
- Use fixtures in `test/fixtures/` for test data
|
|
|
|
```ruby
|
|
require "test_helper"
|
|
|
|
class UserTest < ActiveSupport::TestCase
|
|
test "valid user" do
|
|
user = User.new(email: "test@example.com", name: "Test")
|
|
assert user.valid?
|
|
end
|
|
|
|
test "invalid without email" do
|
|
user = User.new(name: "Test")
|
|
assert_not user.valid?
|
|
assert_includes user.errors[:email], "must be present"
|
|
end
|
|
end
|
|
```
|
|
|
|
### Error Handling
|
|
- Use ` rescue` blocks for expected errors
|
|
- Use `fail` or `raise` for unexpected states
|
|
- Flash messages for user feedback
|
|
- Render appropriate HTTP status codes
|
|
|
|
### Database
|
|
- Use migrations for schema changes: `bin/rails generate migration AddFieldToTable`
|
|
- Use `change` method for reversible migrations
|
|
- Add indexes for foreign keys and frequently queried columns
|
|
|
|
### Dependencies
|
|
- Add gems to appropriate groups in `Gemfile`
|
|
- Run `bundle install` after adding gems
|
|
- Use `Gemfile.lock` for reproducible builds
|
|
|
|
### Git Conventions
|
|
- Write clear, concise commit messages
|
|
- Create feature branches for new work
|
|
- Run linter and tests before committing
|
|
|
|
## Important File Locations
|
|
|
|
- Routes: `config/routes.rb`
|
|
- Application config: `config/application.rb`
|
|
- Environment configs: `config/environments/`
|
|
- Database config: `config/database.yml`
|
|
- Test config: `test/test_helper.rb`
|
|
|
|
## Common Tasks
|
|
|
|
### Generate New Resource
|
|
```bash
|
|
bin/rails generate scaffold ModelName field:type field:type
|
|
bin/rails db:migrate
|
|
```
|
|
|
|
### Run Specific Gem Command
|
|
```bash
|
|
bundle exec brakeman --no-pager
|
|
bundle exec rubocop
|
|
bundle exec rails test
|
|
```
|
|
|
|
## Notes
|
|
|
|
- This project uses **Solid** gems for cache/queue/cable (SolidCache, SolidQueue, SolidCable)
|
|
- Asset pipeline: Propshaft (Rails 8 default)
|
|
- JS: Importmap with Turbo and Stimulus
|
|
- Deployment: Kamal (see `.kamal/`)
|