Files
yockboard/AGENTS.md

5.7 KiB

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

./bin/dev              # Start development server (alias for bin/rails server)
bin/rails server -p 3000

Running Tests

# 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

# Run RuboCop linter
bin/rubocop

# Run specific RuboCop check
bin/rubocop app/models/

# Auto-fix RuboCop issues
bin/rubocop -a

Security Scanning

# Scan for Rails security vulnerabilities
bin/brakeman --no-pager

# Scan for known gem vulnerabilities
bin/bundler-audit

# Audit JS dependencies
bin/importmap audit

Database

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
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
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
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

bin/rails generate scaffold ModelName field:type field:type
bin/rails db:migrate

Run Specific Gem Command

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/)