diff --git a/.opencode/agents/rails-code-auditor.md b/.opencode/agents/rails-code-auditor.md new file mode 100644 index 00000000..6f871835 --- /dev/null +++ b/.opencode/agents/rails-code-auditor.md @@ -0,0 +1,59 @@ +--- +description: Review code for quality and Rails conventions (report + suggest on request) +mode: subagent +permission: + skill: + "rails-code-quality": "allow" + "rails-controllers": "allow" + "rails-models": "allow" + "rails-migrations": "allow" + "service-objects": "allow" + "viewcomponent": "allow" + "rspec-testing": "allow" + "*": "deny" +tools: + bash: true + read: true +--- + +You are a Rails code auditor focused on reviewing code quality and ensuring adherence to Rails conventions. + +## Your Responsibilities + +### Code Quality Checks +- Run code quality tools: `bin/rubocop` +- Run security scans: `bin/brakeman` +- Review for code smells and anti-patterns +- Check against Rails best practices + +### Convention Reviews +- Verify controller patterns (thin controllers, service delegation) +- Check model patterns (validations, scopes, associations) +- Review migration patterns (reversible, proper indexes) +- Ensure service objects follow Result pattern +- Verify ViewComponent structure +- Check test coverage and patterns + +### Security Reviews +- Identify input validation vulnerabilities +- Check authentication and authorization +- Review data exposure risks +- Check dependency vulnerabilities +- Verify configuration security + +## Guidelines + +- Load relevant skills based on what you're reviewing +- Report issues clearly with detailed explanations +- Ask: "Would you like me to suggest fixes?" before providing solutions +- Provide code suggestions only when explicitly requested +- Be constructive and educational +- Reference specific patterns from skills + +## Important Notes + +- Do NOT modify code without explicit permission +- Focus on identifying issues first, then suggest on request +- Use project's existing code as reference for conventions +- Prioritize security and critical issues + diff --git a/.opencode/agents/rails-migration-manager.md b/.opencode/agents/rails-migration-manager.md new file mode 100644 index 00000000..b28fdeeb --- /dev/null +++ b/.opencode/agents/rails-migration-manager.md @@ -0,0 +1,55 @@ +--- +description: Manage Rails migrations - create, run, rollback, and troubleshoot +mode: subagent +permission: + skill: + "rails-migrations": "allow" + "*": "deny" +tools: + bash: true + write: true + edit: true + read: true +--- + +You are a Rails migration manager specializing in all aspects of database migrations. + +## Your Responsibilities + +### Creating Migrations +- Generate migrations following reversible patterns +- Use `change` method for reversible operations +- Use `up`/`down` methods for irreversible operations +- Add indexes for foreign keys and frequently queried columns +- Include proper database constraints + +### Managing Migrations +- Run migrations: `rails db:migrate` +- Rollback migrations: `rails db:rollback [STEP=n]` +- View migration status: `rails db:migrate:status` +- Redo migrations: `rails db:redo` +- Reset database: `rails db:reset` +- Seed database: `rails db:seed` + +### Troubleshooting +- Identify and fix migration failures +- Resolve conflicting migrations +- Handle schema changes safely +- Provide rollback options + +## Guidelines + +- Load `rails-migrations` skill for patterns and conventions +- Always provide rollback information +- Check migration status before running +- Warn about data loss operations +- Follow reversible migration patterns when possible +- Use proper naming conventions for migration files + +## Important Notes + +- Migration files go in `db/migrate/` +- Always test migrations in development first +- Use transactions when possible +- Provide clear descriptions of what each migration does + diff --git a/.opencode/agents/rails-refactor.md b/.opencode/agents/rails-refactor.md new file mode 100644 index 00000000..1f2a8bea --- /dev/null +++ b/.opencode/agents/rails-refactor.md @@ -0,0 +1,62 @@ +--- +description: Refactor code following Rails and project conventions +mode: subagent +permission: + skill: + "rails-code-quality": "allow" + "rails-controllers": "allow" + "rails-models": "allow" + "rails-migrations": "allow" + "service-objects": "allow" + "viewcomponent": "allow" + "rspec-testing": "allow" + "*": "deny" +tools: + write: true + edit: true + bash: true + read: true +--- + +You are a Rails refactoring specialist focused on improving code quality while maintaining functionality. + +## Your Responsibilities + +### Code Refactoring +- Extract business logic to service objects +- Refactor controllers to use service delegation +- Apply Rails conventions and patterns +- Remove code smells and anti-patterns +- Improve code organization and structure + +### Performance Optimizations +- Optimize database queries (N+1 problems, eager loading) +- Improve caching strategies +- Reduce memory usage +- Optimize algorithmic complexity + +### Test Improvements +- Improve test coverage +- Refactor flaky tests +- Apply testing patterns from skills +- Ensure tests are fast and maintainable + +## Guidelines + +- Load relevant skills based on what's being refactored +- Always run tests after refactoring: `bin/rspec` +- Ensure all tests pass before considering refactoring complete +- Run code quality checks: `bin/rubocop` +- Make small, incremental changes +- Explain why each refactoring is necessary +- Follow existing codebase patterns + +## Important Notes + +- Always verify tests pass after refactoring +- Run `bin/rspec` before and after changes +- Use `bin/rubocop -a` to fix style issues +- Maintain backward compatibility when possible +- Focus on meaningful improvements, not changes for change's sake +- Ask for clarification if refactoring scope is unclear + diff --git a/.opencode/agents/rails-resource-builder.md b/.opencode/agents/rails-resource-builder.md new file mode 100644 index 00000000..a7928ece --- /dev/null +++ b/.opencode/agents/rails-resource-builder.md @@ -0,0 +1,57 @@ +--- +description: Generate complete Rails resources (models, controllers, routes, tests) +mode: subagent +permission: + skill: + "rails-models": "allow" + "rails-controllers": "allow" + "rspec-testing": "allow" + "*": "deny" +tools: + write: true + edit: true + bash: true + read: true +--- + +You are a Rails resource builder specializing in generating complete RESTful resources following Rails 8.0.3 conventions. + +## Your Responsibilities + +Generate complete Rails resources that include: + +1. **Models** with: + - Proper validations + - Associations (belongs_to, has_many, etc.) + - Scopes + - Class methods + +2. **Controllers** with: + - Thin controller pattern + - Service delegation + - Before action filters + - Strong parameters + - Appropriate HTTP status codes + +3. **Specs** for both models and controllers: + - FactoryBot factories + - RSpec patterns + - Test coverage following project conventions + +## Guidelines + +- Load `rails-models` skill for model patterns +- Load `rails-controllers` skill for controller patterns +- Load `rspec-testing` skill for test structure +- Follow service delegation pattern in controllers +- Generate proper factory traits +- Ensure all generated code passes RuboCop checks +- Use project's existing patterns as reference + +## Important Notes + +- Always ask for clarification on requirements before generating +- Follow the existing codebase conventions +- Ensure generated specs follow the `*_spec.rb` naming pattern +- Place files in appropriate directories (app/models/, app/controllers/, spec/) + diff --git a/.opencode/agents/rails-test-runner.md b/.opencode/agents/rails-test-runner.md new file mode 100644 index 00000000..55d34f8a --- /dev/null +++ b/.opencode/agents/rails-test-runner.md @@ -0,0 +1,46 @@ +--- +description: Execute tests and report results only +mode: subagent +permission: + skill: + "rspec-testing": "allow" + "*": "deny" +tools: + bash: true + read: true +--- + +You are a Rails test runner focused solely on executing tests and reporting results. + +## Your Responsibilities + +### Running Tests +- Execute tests using `bin/rspec` +- Run all tests: `bin/rspec` +- Run specific test file: `bin/rspec spec/models/facility_spec.rb` +- Run test by line: `bin/rspec spec/models/facility_spec.rb:42` +- Run tests by description: `bin/rspec -e "validates name presence"` +- Run directory of tests: `bin/rspec spec/models/` + +### Reporting Results +- Report test results clearly +- Show failures with detailed output +- Provide summary statistics (passed, failed, pending) +- Identify flaky or slow tests + +## Guidelines + +- Load `rspec-testing` skill for test commands and patterns +- Do NOT write or edit any code +- Do NOT modify test files +- Only execute tests and report results +- Provide actionable error messages +- Suggest how to fix failing tests based on RSpec output + +## Important Notes + +- Test files use `*_spec.rb` suffix +- Test directory mirrors app structure +- Focus on execution and reporting, not fixing +- Use FactoryBot patterns from the skill + diff --git a/.opencode/skills/rails-code-quality/SKILL.md b/.opencode/skills/rails-code-quality/SKILL.md new file mode 100644 index 00000000..956c356d --- /dev/null +++ b/.opencode/skills/rails-code-quality/SKILL.md @@ -0,0 +1,136 @@ +--- +name: rails-code-quality +description: RuboCop metrics, Brakeman security, code style conventions, and quality checks for this Rails codebase +--- + +## Code Quality Commands + +```bash +bin/rubocop # Lint Ruby code +bin/rubocop -a # Auto-fix issues +bin/brakeman # Security scan +``` + +## Ruby Code Style + +### Basic Style +- **ALWAYS** start with `# frozen_string_literal: true` +- Use double quotes for strings +- Use new hash syntax: `{ a: 1 }` not `{ :a => 1 }` +- Two spaces for indentation, no tabs +- No trailing whitespace +- Use `&&/||` instead of `and/or` +- Method definitions with parentheses: `def my_method(arg)` not `def my_method arg` + +### Constants & Magic Numbers +- Define constants at class level using SCREAMING_SNAKE_CASE +- Avoid magic numbers, use named constants +- Freeze constants to prevent mutation: + ```ruby + MAX_ATTEMPTS = 5.freeze + STATUS_CLASSES = { + active: "success", + pending: "warning" + }.freeze + ``` + +## RuboCop Metrics (Enforced) + +These metrics are enforced by RuboCop in this codebase: + +- **Method length**: max 50 lines +- **Class length**: max 300 lines +- **Cyclomatic complexity**: max 15 +- **Perceived complexity**: max 12 +- **AbcSize**: max 41 (excludes migrations) +- **Block length**: max 75 (excluded in specs) + +## Running Quality Checks + +```bash +# Check all code +bin/rubocop + +# Check specific file +bin/rubocop app/models/facility.rb + +# Auto-fix issues +bin/rubocop -a + +# Auto-fix with safety level +bin/rubocop -a --safe + +# Security scan +bin/brakeman + +# Check for warnings only +bin/brakeman --no-pager --no-highlight --skip-warning-list +``` + +## Fixing RuboCop Issues + +1. Run `bin/rubocop` to see issues +2. Run `bin/rubocop -a` to auto-fix +3. Manually fix remaining issues +4. Run `bin/rubocop` again to verify + +## Security Best Practices (Brakeman) + +- Never expose secrets or API keys +- Use strong parameters to prevent mass assignment +- Sanitize user input +- Use HTTPS in production +- Keep dependencies updated +- Run `bin/brakeman` regularly + +## Code Organization + +- Keep methods under 50 lines +- Keep classes under 300 lines +- Reduce complexity by extracting methods +- Use services for complex business logic +- Follow SOLID principles + +## Naming Conventions + +### Ruby/Rails +- Models: Singular PascalCase (e.g., `Facility`) +- Controllers: Plural PascalCase (e.g., `FacilitiesController`) +- Components: Namespace::Name (e.g., `Facilities::CardComponent`) +- Services: Action + Service (e.g., `FacilitySerializer`) +- Factories: `factory :name` (e.g., `factory :facility`) +- Tests: *_spec.rb suffix (e.g., `facility_spec.rb`) +- Constants: SCREAMING_SNAKE_CASE (e.g., `STATUS_CLASSES`) + +## Error Handling + +- Use `raise` for programmer errors +- Use `Result.new(errors: [...])` for service object validation failures +- Handle exceptions with `begin/rescue` blocks when necessary +- Log errors appropriately before re-raising if needed + +## Pre-Commit Workflow + +Always run before committing: + +```bash +# Run tests +bin/rspec + +# Run linter +bin/rubocop + +# Run security scan +bin/brakeman + +# Fix auto-fixable issues +bin/rubocop -a +``` + +## Important Notes + +- Always run tests and linting before committing +- Follow Ruby style guide conventions +- Keep complexity low by extracting methods +- Use RuboCop metrics as guidelines +- Security scan with Brakeman regularly diff --git a/.opencode/skills/rails-controllers/SKILL.md b/.opencode/skills/rails-controllers/SKILL.md new file mode 100644 index 00000000..fa17a23e --- /dev/null +++ b/.opencode/skills/rails-controllers/SKILL.md @@ -0,0 +1,137 @@ +--- +name: rails-controllers +description: Controller patterns, service delegation, strong parameters, and HTTP conventions for this Rails codebase +--- + +## Controller Naming + +- Controllers use Plural PascalCase (e.g., `FacilitiesController`) +- File names match class names: `facilities_controller.rb` +- Located in `app/controllers/` directory + +## Thin Controller Pattern + +- Keep controllers thin, delegate logic to services +- Controllers should handle: + - Request/response cycle + - Parameter handling + - Response formatting + - Redirect/flow control + +## Service Delegation + +```ruby +def create + result = FacilityCreateService.call(facility_params) + + if result.errors.any? + render json: { errors: result.errors }, status: :unprocessable_entity + else + render json: result.data, status: :created + end +end +``` + +## Before Actions + +- Use `before_action` for shared logic: + ```ruby + before_action :authenticate_user! + before_action :set_facility, only: [:show, :update, :destroy] + ``` + +## Strong Parameters + +```ruby +def facility_params + params.require(:facility).permit(:name, :address, :status) +end + +def nested_params + params.require(:facility).permit(:name, bookings_attributes: [:id, :date, :_destroy]) +end +``` + +## HTTP Status Codes + +- Return appropriate HTTP status codes: + - `200 OK` - Successful GET/PUT/PATCH + - `201 Created` - Successful POST + - `204 No Content` - Successful DELETE + - `400 Bad Request` - Invalid request + - `401 Unauthorized` - Not authenticated + - `403 Forbidden` - Not authorized + - `404 Not Found` - Resource not found + - `422 Unprocessable Entity` - Validation errors + - `500 Internal Server Error` - Server error + +## Response Formats + +```ruby +# JSON response +render json: @facility + +# JSON with status +render json: @facility, status: :ok + +# JSON with errors +render json: { errors: ["Validation failed"] }, status: :unprocessable_entity + +# Redirect +redirect_to @facility, notice: "Success" + +# Render template +render :new +``` + +## Testing Controllers + +- Test files located in `spec/controllers/` +- Use `*_controller_spec.rb` suffix +- Test actions, status codes, and responses +- Use RSpec request specs for API endpoints + +## Example Controller + +```ruby +class FacilitiesController < ApplicationController + before_action :authenticate_user! + before_action :set_facility, only: [:show, :update, :destroy] + + def index + @facilities = Facility.all + render json: @facilities + end + + def show + render json: @facility + end + + def create + result = FacilityCreateService.call(facility_params) + + if result.errors.any? + render json: { errors: result.errors }, status: :unprocessable_entity + else + render json: result.data, status: :created + end + end + + private + + def set_facility + @facility = Facility.find(params[:id]) + end + + def facility_params + params.require(:facility).permit(:name, :address, :status) + end +end +``` + +## Important Notes + +- Always use strong parameters +- Delegate business logic to services +- Return appropriate HTTP status codes +- Keep actions focused on request/response diff --git a/.opencode/skills/rails-migrations/SKILL.md b/.opencode/skills/rails-migrations/SKILL.md new file mode 100644 index 00000000..85a2e70c --- /dev/null +++ b/.opencode/skills/rails-migrations/SKILL.md @@ -0,0 +1,152 @@ +--- +name: rails-migrations +description: Database migration patterns, reversible migrations, indexes, and conventions for this Rails codebase +--- + +## Migration Commands + +```bash +rails db:create db:migrate db:seed db:reset rails console +rails db:migrate:status # Check migration status +rails db:rollback # Rollback last migration +rails db:migrate:redo # Rollback and re-run +``` + +## Migration Structure + +- Migrations located in `db/migrate/` directory +- Use timestamp prefix: `YYYYMMDDHHMMSS_migration_name.rb` +- Name migrations descriptively: `add_email_to_users.rb` + +## Reversible Migrations + +- Use `change` method instead of `up/down` when possible: + ```ruby + class AddEmailToUsers < ActiveRecord::Migration[8.0] + def change + add_column :users, :email, :string + end + end + ``` + +## Creating Migrations + +```bash +rails generate migration AddFieldToTable field:type +rails generate migration RemoveFieldFromTable field:type +rails generate migration CreateTableName field1:type field2:type +``` + +## Common Migration Patterns + +### Add Column +```ruby +def change + add_column :users, :email, :string, null: false +end +``` + +### Remove Column +```ruby +def change + remove_column :users, :email, :string +end +``` + +### Add Index +```ruby +def change + add_index :users, :email, unique: true +end +``` + +### Add Reference +```ruby +def change + add_reference :bookings, :facility, foreign_key: true +end +``` + +### Add Foreign Key Constraint +```ruby +def change + add_foreign_key :bookings, :facilities +end +``` + +### Create Table +```ruby +def change + create_table :facilities do |t| + t.string :name, null: false + t.text :address + t.timestamps + end +end +``` + +## Best Practices + +- Keep migrations reversible +- Use `change` method instead of `up/down` +- Add indexes for foreign keys and frequently queried columns +- Use `null: false` and foreign key constraints +- Use appropriate data types +- Include defaults when appropriate + +## Adding Indexes + +```ruby +# Single column index +add_index :users, :email + +# Composite index +add_index :bookings, [:user_id, :facility_id] + +# Unique index +add_index :users, :email, unique: true + +# Index with name +add_index :users, :email, name: 'index_users_on_email_lower' +``` + +## Foreign Keys + +```ruby +# Add reference with foreign key +add_reference :bookings, :facility, foreign_key: true + +# Add foreign key constraint +add_foreign_key :bookings, :facilities + +# Add foreign key with options +add_foreign_key :bookings, :facilities, on_delete: :cascade +``` + +## When to Use Up/Down + +Use `up/down` when `change` doesn't support the operation: + +```ruby +class ChangeUserEmailFormat < ActiveRecord::Migration[8.0] + def up + execute <<-SQL + UPDATE users SET email = LOWER(email) + SQL + end + + def down + # Cannot automatically rollback + raise ActiveRecord::IrreversibleMigration + end +end +``` + +## Important Notes + +- Always test migrations in development +- Keep migrations small and focused +- Use `rails db:migrate:status` to check status +- Never modify existing migrations after deployment +- Use `null: false` for required fields +- Add indexes for performance diff --git a/.opencode/skills/rails-models/SKILL.md b/.opencode/skills/rails-models/SKILL.md new file mode 100644 index 00000000..c7adc076 --- /dev/null +++ b/.opencode/skills/rails-models/SKILL.md @@ -0,0 +1,85 @@ +--- +name: rails-models +description: ActiveRecord model patterns, validations, scopes, and conventions for this Rails codebase +--- + +## Model Naming + +- Models use Singular PascalCase (e.g., `Facility`) +- File names match class names: `facility.rb` +- Located in `app/models/` directory + +## Validations + +- Use ActiveRecord validations for model-level validation: + ```ruby + validates :name, presence: true + validates :email, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP } + ``` + +## Scopes + +- Use scopes for complex queries: + ```ruby + scope :active, -> { where(active: true) } + scope :recent, -> { order(created_at: :desc) } + ``` + +## Enums + +- Use enum for fixed state fields: + ```ruby + enum status: { pending: 0, active: 1, archived: 2 } + ``` + +## Callbacks + +- Use callbacks sparingly +- Prefer explicit methods over callbacks +- Keep callback logic simple and focused + +## Associations + +- Define standard ActiveRecord associations +- Use proper foreign key conventions +- Consider inverse_of for better performance + +## Model Methods + +- Define business logic as instance methods +- Use class methods for collection operations +- Keep methods small and focused + +## Testing Models + +- Test files located in `spec/models/` +- Use `*_spec.rb` suffix (e.g., `facility_spec.rb`) +- Test validations, scopes, and custom methods +- Use factories for test data + +## Example Model + +```ruby +class Facility < ApplicationRecord + has_many :bookings + + validates :name, presence: true + validates :status, presence: true + + scope :active, -> { where(active: true) } + scope :recent, -> { order(created_at: :desc) } + + enum status: { pending: 0, active: 1, archived: 2 } + + def active? + status == 'active' + end +end +``` + +## Important Notes + +- Keep database logic in models +- Avoid complex business logic in models (use services) +- Use factories for test fixtures +- Always run model tests after changes diff --git a/.opencode/skills/rspec-testing/SKILL.md b/.opencode/skills/rspec-testing/SKILL.md new file mode 100644 index 00000000..cc9af8e6 --- /dev/null +++ b/.opencode/skills/rspec-testing/SKILL.md @@ -0,0 +1,59 @@ +--- +name: rspec-testing +description: RSpec testing patterns, conventions, and test commands for this Rails codebase +--- + +## Testing Commands + +```bash +bin/rspec # Run all tests +bin/rspec spec/models/facility_spec.rb # Run single test file +bin/rspec spec/models/facility_spec.rb:42 # Run specific test by line +bin/rspec spec/models/facility_spec.rb -e "validates name presence" # Run by description +bin/rspec spec/models/ # All model specs +bin/rspec spec/services/facility_serializer_spec.rb # Specific service spec +``` + +## Testing Patterns + +- Use RSpec's `describe` for context and `it` for examples +- Prefer `expect(x).to eq(y)` over `expect(x) == y` +- Use `let` for lazy evaluation, `let!` for immediate +- Use `subject` for the main object being tested +- Use shared contexts with `it_behaves_like` for repeated patterns + +## Testing Structure + +- Test files use `*_spec.rb` suffix (e.g., `facility_spec.rb`) +- Test directory mirrors app structure: + - `spec/models/` - Model tests + - `spec/services/` - Service tests + - `spec/controllers/` - Controller tests +- ViewComponent tests use `type: :component` +- System specs use Capybara and Puma + +## Example Test Pattern + +```ruby +RSpec.describe Facility do + subject(:facility) { create(:facility, :with_verified) } + + describe "#managed_by?" do + it "returns true for admin users" do + expect(facility.managed_by?(admin_user)).to be true + end + end +end +``` + +## Factory Usage + +- Use FactoryBot for test data +- Define factories with `factory :name` (e.g., `factory :facility`) +- Use traits with `:trait_name` syntax (e.g., `:with_verified`) + +## Important Notes + +- Always run tests before committing: `bin/rspec` +- Use factory-bot gem for test fixtures +- Test coverage should mirror application structure diff --git a/.opencode/skills/service-objects/SKILL.md b/.opencode/skills/service-objects/SKILL.md new file mode 100644 index 00000000..4c0a25fa --- /dev/null +++ b/.opencode/skills/service-objects/SKILL.md @@ -0,0 +1,83 @@ +--- +name: service-objects +description: Service object patterns, Result objects, and validation conventions for this Rails codebase +--- + +## Service Object Pattern + +All services inherit from `ApplicationService` and follow this structure: + +```ruby +class MyService < ApplicationService + def initialize(arg1, arg2) + super() + @arg1 = arg1 + @arg2 = arg2 + end + + def call + return Result.new(errors: ["validation error"]) unless valid? + Result.new(data: result_data) + end + + private + + def validate + add_error("Invalid input") if invalid_condition? + end +end +``` + +## Usage Pattern + +```ruby +# Call service directly +result = MyService.call(arg1, arg2) + +# Check for errors +if result.errors.any? + # Handle errors +else + # Use result.data +end +``` + +## Naming Convention + +- Services use "Action + Service" pattern (e.g., `FacilitySerializer`) +- File names match class names: `facility_serializer.rb` +- Located in `app/services/` directory + +## Result Pattern + +- Services return `Result` objects +- `Result.new(errors: [...])` for validation failures +- `Result.new(data: ...)` for successful operations +- Check `result.errors.any?` to determine success/failure + +## Validation in Services + +- Use private `validate` methods for validation logic +- Use `add_error(message)` to collect validation errors +- Return early with error Result if validation fails +- Keep validation logic separate from business logic + +## Error Handling + +- Use `raise` for programmer errors +- Use `Result.new(errors: [...])` for service object validation failures +- Handle exceptions with `begin/rescue` blocks when necessary +- Log errors appropriately before re-raising if needed + +## Testing Services + +- Test files located in `spec/services/` +- Use `*_service_spec.rb` suffix (e.g., `facility_serializer_spec.rb`) +- Test both success and error paths +- Verify Result objects structure + +## Important Notes + +- Keep services focused on single responsibilities +- Avoid complex nested logic in services +- Use services to keep controllers thin diff --git a/.opencode/skills/viewcomponent/SKILL.md b/.opencode/skills/viewcomponent/SKILL.md new file mode 100644 index 00000000..61246522 --- /dev/null +++ b/.opencode/skills/viewcomponent/SKILL.md @@ -0,0 +1,82 @@ +--- +name: viewcomponent +description: ViewComponent patterns, naming conventions, and structure for this Rails codebase +--- + +## ViewComponent Pattern + +All components inherit from `ViewComponent::Base`: + +```ruby +class Features::CardComponent < ViewComponent::Base + def initialize(feature:) + super() + @feature = feature + end + + def private_method + # Helper methods + end +end +``` + +## Naming Convention + +- Components use `Namespace::Name` pattern (e.g., `Facilities::CardComponent`) +- File names match class names: `features/card_component.rb` +- Located in `app/components/` directory (namespaced) + +## Component Structure + +- Always call `super()` in `initialize` +- Use keyword arguments in `initialize` (e.g., `feature:`) +- Store arguments in instance variables with `@` prefix +- Define helper methods for complex logic in templates + +## Directory Structure + +``` +app/components/ +├── facilities/ +│ └── card_component.rb +└── features/ + └── card_component.rb +``` + +## Testing Components + +- Test files located in `spec/components/` +- Use `type: :component` in RSpec specs +- Test rendering output and state +- Test helper methods individually + +## Usage in Views + +```ruby +# Render component with arguments +<%= render Features::CardComponent.new(feature: @feature) %> + +# Or with shorthand +<%= render Features::CardComponent.new(@feature) %> +``` + +## Best Practices + +- Keep components small and focused +- Use helper methods for complex logic in views +- Avoid embedding business logic in components +- Components should receive data, not fetch it +- Use components to reduce partial duplication + +## Component Patterns + +- Card components for displaying items +- List components for collections +- Form components for reusable form fields +- Button components for UI actions + +## Important Notes + +- ViewComponent is used for UI components in this codebase +- Components are namespaced by domain (e.g., `Features::`, `Facilities::`) +- Test components using `type: :component` in RSpec diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..a45b2f3f --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,100 @@ +# AGENTS.md - Linkvan API Development Guide + +This file provides essential information for agentic coding assistants working on the Linkvan API codebase. + +## Essential Commands + +### Testing +```bash +bin/rspec # Run all tests +bin/rspec spec/models/facility_spec.rb # Run single test file +bin/rspec spec/models/facility_spec.rb:42 # Run specific test by line +``` + +### Code Quality +```bash +bin/rubocop # Lint Ruby code +bin/rubocop -a # Auto-fix issues +bin/brakeman # Security scan +``` + +### Database +```bash +rails db:create db:migrate db:seed db:reset +rails console +``` + +## Project Structure + +- `app/models/` - ActiveRecord models +- `app/controllers/` - Request handlers +- `app/services/` - Business logic services +- `app/components/` - ViewComponents (namespaced) +- `spec/` - RSpec tests (mirrors app structure) +- `db/migrate/` - Database migrations +- `config/` - Application configuration + +## Available Skills + +This codebase includes specialized skills for detailed development guidance. Load them using the `skill` tool when needed: + +- **rspec-testing** - RSpec patterns, test commands, and testing conventions +- **service-objects** - Service class structure, Result pattern, and validation +- **viewcomponent** - Component structure, naming conventions, and patterns +- **rails-models** - ActiveRecord patterns, validations, scopes, and enums +- **rails-controllers** - Controller patterns, service delegation, and HTTP conventions +- **rails-migrations** - Reversible migrations, indexes, and database constraints +- **rails-code-quality** - RuboCop metrics, Brakeman security, and code style + +## Available Agents + +This codebase includes specialized agents for Rails development workflows. Invoke them using the `@` mention or `Task` tool: + +- **@rails-resource-builder** - Generate complete Rails resources (models, controllers, routes, tests) + - Generates RESTful resources with proper validations, associations, and specs + - Follows service delegation pattern in controllers + - Creates FactoryBot factories and RSpec tests + - Skills: rails-models, rails-controllers, rspec-testing + +- **@rails-migration-manager** - Manage Rails migrations (create, run, rollback, troubleshoot) + - Creates reversible migrations with indexes and constraints + - Runs, rolls back, and monitors migrations + - Handles schema changes and resolves conflicts + - Skills: rails-migrations + +- **@rails-test-runner** - Execute tests and report results + - Runs all tests or specific tests by file/line/description + - Reports test failures with detailed output + - Does NOT modify code or fix tests + - Skills: rspec-testing + +- **@rails-code-auditor** - Review code for quality and Rails conventions + - Runs RuboCop and Brakeman for quality/security + - Reviews adherence to Rails patterns and conventions + - Reports issues, suggests fixes only when requested + - Skills: All pattern skills (context-dependent) + +- **@rails-refactor** - Refactor code following Rails conventions + - Extracts logic to service objects + - Applies Rails conventions and removes code smells + - Optimizes queries and improves performance + - Ensures tests pass after refactoring + - Skills: All pattern skills (context-dependent) + +## Tech Stack + +- Ruby 3.4.5, Rails 8.0.3 with PostgreSQL +- RSpec, FactoryBot, Shoulda Matchers (testing) +- RuboCop, Brakeman (quality/security) +- ViewComponent (UI components) +- Hotwire/Turbo (frontend) +- Devise (authentication), Pagy (pagination) + +## Important Notes + +- Active development on `develop` branch +- Admin interface at `/admin/dashboard` +- Always run tests and linting before committing +- ViewComponent tests use `type: :component` +- System specs use Capybara and Puma +