Skip to content

Where a Pulsar type belongs

After the app/Pulsar boundary decision, place each governed type in a Service Module, Domain, or Infrastructure area; keep Laravel-owned seams in their stock locations. The complete table is the normative placement source, and the resolver only selects from it.

For “where does this class go” and “Pulsar placement” questions, use this table before inventing a directory.

Start after the boundary question

The architecture boundary answers whether a type participates in a Pulsar dependency edge. This page starts after that answer. A Service is audience delivery, a Module is a feature slice within that Service, a Domain is a shared capability, and Infrastructure is a concrete outbound Adapter area.

After the app/Pulsar boundary question, inbound audience delivery and workflow go to a Service Module, shared capability or vocabulary goes to Domain, a concrete Domain Contract implementation goes to Infrastructure, and every other concern remains in stock Laravel or needs table review.
Choose the next placement after the app/Pulsar boundary. The decision tree orients a placement decision; the complete static table remains normative for exact types and exceptions.

Interpretation. The tree is a navigational map after the boundary decision. It directs delivery to a Service Module, shared capability to Domain, and a concrete Contract implementation to Infrastructure; use the complete table for exact records and stock-Laravel exits.

Pulsar placement: use the complete table

Placement resolver

Selected placement result

Layer: domain

Generated path: app/Pulsar/Domain/{Domain}/Actions/{Name}.php

Command: make:action

Rule pages: Placement

Complete placement decision table
ConcernDecision questionPlacement/layerGenerated path or stock locationGenerator commandGoverning page
ActionPlace this generated atomic business operation.domainapp/Pulsar/Domain/{Domain}/Actions/{Name}.phpmake:action
AdapterPlace this generated concrete outbound Contract implementation.infrastructureapp/Pulsar/Infrastructure/{Area}/{Name}.phpmake:adapter
CommandPlace this generated CLI or scheduler inbound adapter.serviceapp/Pulsar/Services/{Service}/Modules/{Module}/Commands/{Name}.phpmake:command
ContractPlace this generated Domain-owned port.domainapp/Pulsar/Domain/{Domain}/Contracts/{Name}.phpmake:contract
ControllerPlace this generated thin HTTP inbound adapter.serviceapp/Pulsar/Services/{Service}/Modules/{Module}/Controllers/{Name}.phpmake:controller
DomainPlace this generated shared Laravel-aware capability.domainapp/Pulsar/Domain/{Domain}make:domain
Domain ExceptionPlace this generated business-rule violation.domainapp/Pulsar/Domain/{Domain}/Exceptions/{Name}.phpmake:exception
DTOPlace this generated data transfer value.domainapp/Pulsar/Domain/{Domain}/DTOs/{Name}.phpmake:dto
EnumPlace this generated closed state set.domainapp/Pulsar/Domain/{Domain}/Enums/{Name}.phpmake:enum
EventPlace this generated immutable Domain fact.domainapp/Pulsar/Domain/{Domain}/Events/{Name}.phpmake:event
JobPlace this generated queued inbound adapter.serviceapp/Pulsar/Services/{Service}/Modules/{Module}/Jobs/{Name}.phpmake:job
ListenerPlace this generated Domain reaction.domainapp/Pulsar/Domain/{Domain}/Listeners/{Name}.phpmake:listener
MailablePlace this generated outbound mail representation.domainapp/Pulsar/Domain/{Domain}/Mail/{Name}.phpmake:mailable
ModelPlace this generated Eloquent entity.domainapp/Pulsar/Domain/{Domain}/Models/{Name}.phpmake:model
ModulePlace this generated feature slice within a Service.serviceapp/Pulsar/Services/{Service}/Modules/{Module}No Pulsar command
NotificationPlace this generated outbound notification.domainapp/Pulsar/Domain/{Domain}/Notifications/{Name}.phpmake:notification
OperationPlace this generated reusable workflow fragment.serviceapp/Pulsar/Services/{Service}/Modules/{Module}/Operations/{Name}.phpmake:operation
PolicyPlace this generated model-aware authorization.domainapp/Pulsar/Domain/{Domain}/Policies/{Name}.phpmake:policy
QueryPlace this generated read-only Domain query.domainapp/Pulsar/Domain/{Domain}/Queries/{Name}.phpmake:query
RequestPlace this generated HTTP validation and authorization.serviceapp/Pulsar/Services/{Service}/Modules/{Module}/Requests/{Name}.phpmake:request
ResourcePlace this generated HTTP response shaping.serviceapp/Pulsar/Services/{Service}/Modules/{Module}/Resources/{Name}.phpmake:resource
ServicePlace this generated consumer-audience delivery boundary; also emits Providers and Routes/api.php or optional Routes/web.php.serviceapp/Pulsar/Services/{Service}make:service
UseCasePlace this generated application workflow.serviceapp/Pulsar/Services/{Service}/Modules/{Module}/UseCases/{Name}.phpmake:use-case
Value ObjectPlace this generated immutable validated primitive.domainapp/Pulsar/Domain/{Domain}/ValueObjects/{Name}.phpmake:value-object
bootstrap/app.phpKeep Laravel bootstrap application wiring.laravel-defaultbootstrap/app.phpNo Pulsar command
bootstrap/providers.phpKeep Laravel provider registration.laravel-defaultbootstrap/providers.phpNo Pulsar command
PulsarServiceProviderRegister application bindings at the Laravel seam.laravel-defaultapp/Providers/PulsarServiceProvider.phpNo Pulsar command
configurationConfigure the Laravel application.laravel-defaultconfig/No Pulsar command
stock routesDefine application-owned routes.laravel-defaultroutes/No Pulsar command
migrationChange the database schema.laravel-defaultdatabase/migrationsNo Pulsar command
factoryCreate test or seed model data.laravel-defaultdatabase/factoriesNo Pulsar command
seederSeed application data.laravel-defaultdatabase/seedersNo Pulsar command
testTest a public boundary or unit.laravel-defaulttests/No Pulsar command
middlewareApply HTTP middleware under Laravel convention and review any Pulsar call.extension-pointapp/Http/MiddlewareNo Pulsar command
castKeep an application cast under Laravel convention and review any Pulsar call.extension-pointapplication castsNo Pulsar command
observerWire an observer through an application provider and review any Pulsar call.extension-pointapplication observer/provider wiringNo Pulsar command

Keep Laravel-owned seams in Laravel

bootstrap/app.php, bootstrap/providers.php, the application PulsarServiceProvider, config, stock routes, database, and tests remain Laravel-owned. Generated providers and Service providers need explicit Laravel registration; this page names their location but does not define later bootstrap mechanics.

Middleware, casts, and observers have no current Pulsar generator or prescribed app/Pulsar home. Keep the relevant Laravel convention, then apply the dependency rules to any Pulsar call. These rows are review-only; they do not establish an Extensions namespace or a Command.

Treat the static table as the fallback

The complete table is server-rendered and remains available without JavaScript. The resolver cannot add, hide, or alter rows: an unmatched pair reports no result while the same static table remains available for review.