CtrlK
BlogDocsLog inGet started
Tessl Logo

igmarin/rails-agent-skills

Curated library of 28 public AI agent skills for Ruby on Rails development. Organized by category: testing, code-quality, engines, infrastructure, api, and context. Covers code review, architecture, security, testing (RSpec), engines, Hotwire, and TDD automation. Shared Ruby skills (YARD docs, DDD, service objects) have moved to ruby-core-skills. Repository agents remain documented in GitHub but are intentionally excluded from the Tessl tile.

93

1.78x
Quality

95%

Does it follow best practices?

Impact

93%

1.78x

Average score across 28 eval scenarios

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

SKILL.mdskills/api/implement-graphql/

name:
implement-graphql
license:
MIT
description:
Use when building or reviewing GraphQL APIs in Rails with the graphql-ruby gem. Covers schema design, N+1 prevention with dataloaders, field-level auth, query limits, error handling, and testing resolvers/mutations with RSpec. Trigger words: graphql, graphql-ruby, resolver, mutation, dataloader, schema.
metadata:
{"version":"1.0.0","user-invocable":"true"}

Implement GraphQL

Use this skill when designing, implementing, or reviewing GraphQL APIs in a Rails application with the graphql-ruby gem.

Quick Reference

ConcernRequired choice
SpecsUse AppSchema.execute in spec/graphql/; do not dispatch HTTP controller specs
Resolver shapeDedicated resolver/mutation classes, not inline complex field blocks
AssociationsUse GraphQL dataloader sources, never direct object.association loads
Collection resolversReturn a scoped relation and prime dataloader records that exposed fields will load
CollectionsUse Types::*Type.connection_type for paginated collections
SecurityField-level authorization plus depth/complexity limits

HARD-GATE

Tests gate implementation — write specs before resolver code (see write-tests).
Before shipping a resolver/mutation slice, ALL of the following must be true:
- N+1 Prevention: use `dataloader.with(Source, Model).load(id)` — NEVER `object.association`
- Authorization: sensitive fields have field-level guards (not type-level alone).
- Type Conventions: paginated collections use Types::*Type.connection_type, not plain arrays.
- Schema safeguards: AppSchema disables introspection in production and sets max_depth / max_complexity.
- TESTING.md: specs in `spec/graphql/` use `AppSchema.execute`. Never use HTTP controller dispatch for GraphQL specs.
- Error Handling: mutations return `{ result, errors }` with rescue blocks — no unhandled exceptions.
- Documentation: `description:` on every field in every type.
- Resolver Structure: dedicated resolver classes, not inline field blocks.
- Dataloader Priming: collection resolvers prime records for association fields that will call dataloader.

Core Process

  1. SPEC: Write failing spec (happy path + auth + validation error case) — see TESTING.md.
  2. TYPE: Define arguments and return types. Use connection_type for pagination shapes. Do not leak internal model names.
  3. IMPLEMENT: Create resolver/mutation class delegating to a service object. Use dedicated classes instead of inline field blocks.
  4. N+1 CHECK: Ensure dataloader is used on every association load. For list resolvers, prime the dataloader with the records returned by the relation before fields resolve associated objects. Use bullet and db-query-matchers in specs.
    # ✅ batches loads across all records
    def buyer
      dataloader.with(Sources::RecordById, Buyer).load(object.buyer_id)
    end
  5. AUTH CHECK: Apply field-level guards where data is sensitive using Pundit or custom context guards.
    field :internal_notes, String, null: true do
      guard -> (_obj, _args, ctx) { ctx[:current_user]&.admin? }
    end
  6. FINAL CHECK: Verify every HARD-GATE item is met. Ensure your mutations return { result, errors } shapes on failure.
    rescue ActiveRecord::RecordInvalid => e
      { order: nil, errors: e.record.errors.full_messages }
  7. RUN: Ensure the full test suite is green before PR.

DO NOT proceed to step 3 before step 1 is written and failing.

Extended Resources (Progressive Disclosure)

Load these files only when their specific content is needed:

  • TESTING.md — For the spec template, paths, and checklist (happy path, unauthenticated, unauthorized, validation errors, N+1 counts, limits).
  • EXAMPLES.md — For detailed code examples of dataloaders, mutations, and types.

Output Style

When implementing GraphQL, your output MUST include:

  1. Schema contract — Types, fields, arguments, nullability, descriptions, and connection shape.
  2. Resolver/mutation structure — Dedicated class names and service-object delegation points.
  3. N+1 prevention — Dataloader source and every association load it protects.
  4. Authorization and limits — Field-level guards, Pundit checks, introspection/depth/complexity decisions.
  5. Error shape — Mutation { result, errors } or equivalent structured failure behavior.
  6. Verificationspec/graphql/ commands covering happy path, auth, validation errors, N+1 counts, and schema limits.
  7. Hard-gate checklist — Explicitly verify all hard-gate items, including resolver structure, type conventions, and dataloader priming.
  8. Language — Must be in English unless explicitly requested otherwise.

Integration

SkillWhen to chain
define-domain-languageType and field naming must match business language
plan-testsChoose first failing spec (mutation vs query vs resolver unit)
write-testsFull TDD cycle for resolvers and mutations
security-checkAuth, introspection disable, query depth/complexity limits

skills

api

README.md

tile.json