CtrlK
BlogDocsLog inGet started
Tessl Logo

igmarin/rails-agent-skills

Curated library of 41 public AI agent skills for Ruby on Rails development. Organized by category: planning, testing, code-quality, ddd, engines, infrastructure, api, patterns, context, and orchestration. Covers code review, architecture, security, testing (RSpec), engines, service objects, DDD patterns, and TDD automation. Repository workflows remain documented in GitHub but are intentionally excluded from the Tessl tile.

95

1.77x
Quality

93%

Does it follow best practices?

Impact

96%

1.77x

Average score across 41 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

server.json

tile.json