<< All versions

Skill v1.0.1

currentAutomated scan100/100
leeovery/agentic-skills/laravel-architecture

+3 new

──Details
PublishedOctober 27, 2026 at 12:31 PM
Content Hashsha256:f1d0043e74749c2d...
Git SHA84ba4fc56528
Bump Typepatch
Compare with v1.0.0
──Files
Files (1 file, 7.9 KB)
SKILL.md7.9 KBactive
SKILL.md · 100 lines · 7.9 KB

name: laravel-architecture description: Where each kind of class lives and which pattern does which job in a Laravel app; follow the project's layout, flat app/ for new ones. Use when adding a class or file, choosing the pattern for a job, or restructuring code. metadata: version: "1.0.1"


Laravel Architecture

This skill is the map. Every kind of class has one job and one home, and the skill that owns it says how to write it. Business logic lives in actions; everything around them (HTTP, queues, events, the console) gathers input, calls an action and hands back the result. The layout follows the project you're in: new projects use flat app/, and older projects keep the layout they have.

Rules

  • Follow the project's existing layout. Put a new class where its kind already lives. New projects use flat app/; projects on src/{App,Domain,Support} keep it (see structure.md). Two layouts in one codebase means every class has two possible homes.
  • Business logic lives in actions. Controllers, jobs, listeners, commands and the scheduler gather input and call one action. The operation then has one home whatever triggers it, and can be tested without its trigger.
  • Group by entity or subsystem, never by verb. Actions/Order/CancelOrderAction, States/Order/. Everything about orders is in one place.
  • Mirror each HTTP surface wherever it appears. A surface is the app's own frontend (Web, unversioned) or a public API (Api/V1, versioned). Each has its own Http/{Surface}/ and route file, and its transformers and feature tests sit under the same name (Data/Transformers/{Surface}/, tests/Feature/{Surface}/), so a surface can change, or gain a new version, without touching another.
  • Typed data between layers. Models, DTOs, enums and value objects cross boundaries. Request arrays never leave the HTTP layer.
  • Declarative code. Short methods named in the domain's language. When a block needs a comment to say what it does, extract it into a method whose name says it. Comments are for why.
  • `resolve()`, never `app()`. One way to reach the container, everywhere.

Which pattern for which job

JobReach forLives in (flat app/)How to write it
A business operation: any write, or a read that computes, caches or calls a serviceAction, CancelOrderActionActions/{Entity}/laravel-actions
Handle an HTTP requestController that calls one actionHttp/{Surface}/Controllers/laravel-controllers
A filterable, sortable, paginated listingQuery classHttp/{Surface}/Queries/laravel-controllers
Shape a JSON responseAPI resourceHttp/{Surface}/Resources/laravel-controllers
Validate inputForm requestHttp/{Surface}/Requests/laravel-validation
Route a surface, bind models, authorizeOne route file per surfaceroutes/{surface}.phplaravel-routing
Carry typed data between layersDTO and its transformerData/, Data/Transformers/{Surface}/laravel-dtos
Persistence, relationships, castsModelModels/laravel-models
Reusable query constraintsCustom builder, OrderBuilderBuilders/laravel-query-builders
A fixed set of valuesBacked enumEnums/laravel-enums
A status whose transitions have rules or side effectsModel statesStates/{Model}/laravel-state-machines
A domain value with behaviourValue objectValues/laravel-value-objects
A third-party API, or an implementation that swapsService behind a facadeServices/{Name}/laravel-services
Work off the request, or a reaction to something that happenedJob, or event and listener, calling an actionJobs/, Events/, Listeners/laravel-jobs
Who may do whatPolicyPolicies/laravel-policies
A business rule that failedOne exception per entity, named constructorsExceptions/laravel-exceptions
Middleware, exception handling, schedule, model defaultsBooters and providersBooters/, Providers/laravel-providers
Self-contained infrastructure worth reusingPackageits own repositorylaravel-packages
An event-sourced model's state, transitions and read modelsAggregate, projector, reactorAggregates/, Projectors/, Reactors/laravel-event-sourcing
A process that waits on outside signals or long timersWorkflow and its activitiesWorkflows/, Workflows/Activities/laravel-workflows

A multi-step process is actions composed in one call, a chain or batch of jobs when its steps need their own retries or progress (laravel-jobs), or a workflow when it waits on outside signals or long timers (laravel-workflows). Which fits depends on the project.

Read structure.md when creating a directory, placing a class whose home isn't in the table, or working in a project on the src/{App,Domain,Support} layout.

Example

Cancelling an order through the public API, in a flat app/ project:

app/
├── Actions/Order/CancelOrderAction.php
├── Data/
│ ├── CancelOrderData.php
│ └── Transformers/Api/V1/CancelOrderDataTransformer.php
├── Exceptions/OrderException.php
├── Http/Api/V1/
│ ├── Controllers/CancelOrderController.php
│ ├── Requests/CancelOrderRequest.php
│ └── Resources/OrderResource.php
└── States/Order/
├── OrderCancelled.php
└── Transitions/PaidToCancelled.php
routes/api_v1.php
tests/
├── Feature/Api/V1/CancelOrderTest.php
└── Unit/Actions/Order/CancelOrderActionTest.php

The controller, request, resource, transformer, route file and feature test belong to the Api/V1 surface. The action, DTO, exception and states belong to the domain, and any surface can reuse them.

Reach for these when the situation calls for it

A public API needs a breaking change. Add the next version as a surface beside the old one: Http/Api/V2/, routes/api_v2.php, Data/Transformers/Api/V2/, tests/Feature/Api/V2/. V1 stays as it is until its consumers move. Actions, DTOs and models are shared by both.

A class serves several surfaces. Middleware or query filters used by more than one surface sit at Http/Middleware/ or Http/Queries/Filters/, outside any surface. Surface-only middleware goes in Http/{Surface}/Middleware/.

Anti-patterns

  • ❌ Moving an existing project to a different layout, or adding flat app/ classes to a src/Domain project.
  • ❌ Scaffolding the full directory tree up front. A directory appears when its first class does.
  • ❌ Grouping by verb: Actions/Create/, Actions/Update/.
  • ❌ Business logic in a controller, job, listener, command or model.
  • ❌ One controller serving two surfaces.
  • ❌ A public API with no version.
  • ❌ An array of request data passed beyond the controller.
  • ❌ app(CancelOrderAction::class).

Related

  • laravel-quality — strict types, Pint, Rector and the arch tests that hold these lines
  • laravel-testing — what goes in tests/Unit and tests/Feature
  • laravel-multi-tenancy — layout and boundaries in a tenant-aware app
  • The skills in the table above, one per pattern
← v1.0.0All versions