mcpField
L
layered-rails

layered-rails

github.com/palkanDevelopment476188 installsUpdated 8w ago
Repository

About layered-rails

layered-rails is a skill for applying layered architecture principles to Rails development. It provides workflows for codebase audits, reviews, refactoring plans, and pattern selection.

Key features

  1. 01Audit architecture and layer boundaries
  2. 02Review code changes for violations
  3. 03Test whether code belongs in its layer
  4. 04Plan gradual architecture adoption
  5. 05Generate ArchSpec checks for CI

Use cases

  1. 01Auditing a Rails codebase
  2. 02Reviewing a diff for layer violations
  3. 03Planning a phased refactor
  4. 04Enforcing boundaries in CI

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/palkan/layered-rails-skills --skill layered-rails

After installing, type/layered-railsin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

examples/
authorization-to-policy.md
callbacks-to-service.md
complex-input-to-form-object.md
current-from-model.md
god-object-decomposition.md
implicit-to-explicit-state-machine.md
query-to-query-object.md
view-logic-to-presenter.md
references/anti-patterns/
callbacks.md
concerns.md
helpers.md
jobs.md
layer-violations.md
service-objects.md
testing.md
references/core/
architecture-layers.md
extraction-signals.md
specification-test.md
references/gems/
action-policy.md
active-agent.md
active-delivery.md
active-job-performs.md
alba.md
anyway-config.md
archspec.md
rubanok.md
view-component.md
workflow.md
references/patterns/
collaborator-objects.md
concerns.md

Details

From the project README

Layered Rails

Design and review Rails applications using layered architecture principles.

Quick Start

Rails applications are organized into four architecture layers with unidirectional data flow:

┌─────────────────────────────────────────┐
│           PRESENTATION LAYER            │
│   Controllers, Views, Channels, Jobs*   │
│ Forms, Filters, Presenters, Serializers │
└─────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────┐
│           APPLICATION LAYER             │
│ Services, Policies, Mailers, Deliveries │
└─────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────┐
│             DOMAIN LAYER                │
│  Models, Value Objects, Query Objects   │
└─────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────┐
│          INFRASTRUCTURE LAYER           │
│  Active Record, API Clients, Storage    │
└─────────────────────────────────────────┘

* Jobs are internal inbound entry points: design-wise they follow the same rules as controllers, minus authentication and user-input handling.

Core Rule: Lower layers must never depend on higher layers.

See Architecture Layers Reference for the full layer responsibilities and the Four Rules deep-dive.

What this skill is for

Use this skill when:

  1. Analyzing a codebase — apply the architecture analysis for a full audit, or zoom in with the service-layer audit, callback analysis, or god-object analysis.
  2. Reviewing code changes — run the code review workflow on a diff, file, or branch.
  3. Running the specification test — use the spec-test workflow on a single file or directory to evaluate whether code belongs in its current layer.
  4. Planning gradual adoption — generate a phased roadmap with the layerification plan workflow, focused on a goal like "introduce authorization" or "decompose god objects."
  5. Planning a feature — I'll apply the layered principles below to whichever code you're about to write.
  6. Implementing a specific pattern — authorization, notifications, view components, AI integration, etc. — see the Pattern Catalog and Topic References below.

In Claude Code with this skill installed as a plugin (/plugin install layered-rails@layered-rails-skills), each workflow above is also reachable as a slash command — see Slash Commands. Natural-language requests ("review this file with layered-rails", "run the specification test on app/models/order.rb") work in any environment that has the skill loaded.

Workflows

Reusable procedures bundled inside this skill. Read the file and apply it to the target code:

Core Principles

The Four Rules
  1. Unidirectional Data Flow - Data flows top-to-bottom only
  2. No Reverse Dependencies - Lower layers never depend on higher layers
  3. Abstraction Boundaries - Each abstraction belongs to exactly one layer
  4. Minimize Connections - Fewer inter-layer connections = looser coupling
Common Violations
ViolationExampleFix
Model uses CurrentCurrent.user in modelPass user as explicit parameter
Service accepts requestparam :request in serviceExtract value object from request
Controller has business logicPricing calculations in actionExtract to service or model
Anemic modelsAll logic in servicesKeep domain logic in models
CategoryReference
Layer violations (Current in models, request in services, notifications in models, business logic in controllers)layer-violations.md
Service objects (anemic models, bag of random objects, premature abstraction)service-objects.md
Callbacks (operation callbacks, skip callbacks, control flags)callbacks.md
Concerns (code-slicing, overgrown)concerns.md
Helpers (HTML construction in helpers)helpers.md
Jobs (anemic jobs)jobs.md
Testing (testing wrong layer)testing.md
The Specification Test

If the specification of an object describes features beyond the primary responsibility of its abstraction layer, such features should be extracted into lower layers.

How to apply:

  1. List responsibilities the code handles
  2. Evaluate each against the layer's primary concern
  3. Extract misplaced responsibilities to appropriate layers

See Specification Test Reference for detailed guide.

Pattern Catalog

PatternLayerUse WhenReference
Service ObjectApplicationOrchestrating domain operationsservice-objects.md
Query ObjectDomainComplex, reusable queriesquery-objects.md
Form ObjectPresentationMulti-model forms, complex validationform-objects.md
Filter ObjectPresentationRequest parameter transformationfilter-objects.md
PresenterPresentationView-specific logic, multiple modelspresenters.md
SerializerPresentationAPI response formattingserializers.md
Policy ObjectApplicationAuthorization decisionspolicy-objects.md
Value ObjectDomainImmutable, identity-less conceptsvalue-objects.md
Collaborator ObjectDomainA slice of one model's behavior in a typed delegatecollaborator-objects.md
State MachineDomainStates, events, transitionsstate-machines.md
ConcernDomainShared behavioral extractionconcerns.md
RepositoryDomainLast resort — returning custom domain objects mapped from AR data, after AR scopes (simple) and query objects (query building) are insufficientrepositories.md
Pattern Selection Guide

"Where should this code go?"

If you have...Consider...
Complex multi-model formForm Object
Request parameter filtering/transformationFilter Object
View-specific formattingPresenter
Complex database query used in multiple placesQuery Object
Business operation spanning multiple modelsService Object (as waiting room)
Authorization rulesPolicy Object
Multi-channel notificationsDelivery Object (Active Delivery)

Remember: Services are a "waiting room" for code until proper abstractions emerge. Don't let app/services become a bag of random objects.

Refactoring Scenarios

Canonical before/after transformations for the most common layerification moves. The layerification plan workflow uses these as reference templates when proposing phases.

ScenarioGoal areaReference
Extract callbacks to servicecallbacks, after_create chainscallbacks-to-service.md
Extract authorization to policyauthorization, permissionsauthorization-to-policy.md
Extract query logic to query objectcomplex scopes, reporting queriesquery-to-query-object.md
Extract Current from modelCurrent.* in domaincurrent-from-model.md
Decompose god object with associated objectsgod model, large User/Accountgod-object-decomposition.md
Replace implicit state machinetimestamp-based statusimplicit-to-explicit-state-machine.md
Extract view logic to presentertemplate logic, formattingview-logic-to-presenter.md
Form object for complex inputfat controllers, multi-model formscomplex-input-to-form-object.md

Slash Commands

These slash commands are available only when this skill is installed as a Claude Code plugin (/plugin install layered-rails@layered-rails-skills). When the skill is installed via skills.sh or any other path that delivers skills/layered-rails/ without the surrounding plugin, the commands won't be present — invoke the corresponding workflow directly (see Workflows) or just ask in plain language.

CommandWorkflowPurpose
/layered-rails:reviewreviewReview code changes from a layered architecture perspective
/layered-rails:spec-testspec-testRun specification test on specific files
/layered-rails:analyzeanalyzeFull codebase abstraction-layer analysis
/layered-rails:analyze-servicesanalyze-servicesAudit app/services/ and service-like classes — conventions, clusters, layer hygiene, test consequences
/layered-rails:analyze-callbacksanalyze-callbacksScore model callbacks, find extraction candidates
/layered-rails:analyze-godsanalyze-godsFind god objects via churn × complexity
/layered-rails:plan [goal]planPlan gradual adoption of layered patterns
/layered-rails:archspecarchspecGenerate and verify an Archspec.rb enforcing layer boundaries in CI

Topic References

For deep dives on specific topics:

TopicReference
Authorization (RBAC, ABAC, policies)authorization.md
Notifications (multi-channel delivery)notifications.md
View Componentsview-components.md
AI Integration (LLM, agents, RAG, MCP)ai-integration.md
Configurationconfiguration.md
Callbacks (scoring, extraction)callbacks.md
Current Attributescurrent-attributes.md
Instrumentation (logging, metrics)instrumentation.md

Gem References

For library-specific guidance:

GemPurposeReference
action_policyAuthorization frameworkaction-policy.md
view_componentComponent frameworkview-component.md
anyway_configTyped configurationanyway-config.md
active_deliveryMulti-channel notificationsactive-delivery.md
albaJSON serializationalba.md
workflowState machinesworkflow.md
rubanokFilter/transformation DSLrubanok.md
active_agentAI agent frameworkactive-agent.md
active_job-performsEliminate anemic jobsactive-job-performs.md
archspecEnforce layer boundaries in CI (reference Archspec.rb config)archspec.md

Extraction Signals

When to extract from models:

SignalMetricAction
God objectHigh churn × complexityDecompose into concerns, delegates, or separate models
Operation callbackScore 1-2/5Extract to service or event handler
Code-slicing concernGroups by artifact typeConvert to behavioral concern or extract
Current dependencyModel reads Current.*Pass as explicit parameter

Callback Scoring:

TypeScoreKeep?
Transformer (compute values)5/5Yes
Normalizer (sanitize input)4/5Yes
Utility (counter caches)4/5Yes
Observer (side effects)2/5Maybe
Operation (business steps)1/5Extract

See Extraction Signals Reference for detailed guide.

Model Organization

Recommended order within model files:

class User < ApplicationRecord
  # 1. Gems/DSL extensions
  has_secure_password

  # 2. Associations
  belongs_to :account
  has_many :posts

  # 3. Enums
  enum :status, { pending: 0, active: 1 }

  # 4. Normalization
  normalizes :email, with: -> { _1.strip.downcase }

  # 5. Validations
  validates :email, presence: true

  # 6. Scopes
  scope :active, -> { where(status: :active) }

  # 7. Callbacks (transformers only)
  before_validation :set_defaults

  # 8. Delegations
  delegate :name, to: :account, prefix: true

  # 9. Public methods
  def full_name = "#{first_name} #{last_name}"

  # 10. Private methods
  private

  def set_defaults
    self.locale ||= I18n.default_locale
  end
end

Success Checklist

Well-layered code:

  • No reverse dependencies (lower layers don't depend on higher)
  • Models don't access Current attributes
  • Services don't accept request objects
  • Controllers are thin (HTTP concerns only)
  • Domain logic lives in models, not services
  • Callbacks score 4+ or are extracted
  • Concerns are behavioral, not code-slicing
  • Abstractions don't span multiple layers
  • Tests verify appropriate layer responsibilities

Guidelines

  • Use domain language - Name models after business concepts (Participant, not User; Cloud, not GeneratedImage)
  • Patterns before abstractions - Let code age before extracting; premature abstraction is worse than duplication
  • Services as waiting room - Don't let app/services become permanent residence for code
  • Explicit over implicit - Prefer explicit parameters over Current attributes
  • Extraction thresholds - Consider extraction when methods exceed 15 lines or call external APIs

Comments

Markdown supported