Skip to content

Pulsar's three layers

Pulsar separates audience delivery, shared Laravel-aware business capability, and concrete outbound integrations into Service, Domain, and Infrastructure. Delivery points inward to Domain, while Infrastructure implements Domain-owned Contracts.

Read the generated tree

LayerRootResponsibility
Serviceapp/Pulsar/Services/{Service}Consumer-audience delivery and workflow.
Domainapp/Pulsar/Domain/{Domain}Shared Laravel-aware business capability.
Infrastructureapp/Pulsar/Infrastructure/{Area}Concrete outbound Adapter area.
The Service layer contains a UseCase that points to Domain capabilities and a Domain Contract; an Infrastructure Adapter points back to that Contract by implementing it.
Pulsar's three-layer dependency direction. Service workflows use the Laravel-first Domain; Infrastructure Adapters implement Domain-owned Contracts.

Interpretation. A Service Module supplies the inbound delivery and workflow tree; it calls inward to a shared Domain. Infrastructure supplies a concrete Adapter only by implementing the Contract the Domain owns.

Keep Service work Module-scoped

A Service answers an audience question, not a deployment, database, schema, bounded-context, or microservice question. Its feature work belongs under Modules/{Module}. Controllers, Requests, Resources, UseCases, Operations, Jobs, and Commands therefore live beneath the same Service Module. The Service generator also produces its provider and route surface at Providers and Routes/api.php, with Routes/web.php when the Service is generated for web delivery.

Give each layer one responsibility

Service code receives HTTP, CLI, queue, or scheduled Job delivery and enters a UseCase. A Domain is a shared Laravel-aware capability; it contains its Models, values, Contracts, Actions, Queries, Events, and reactions. Infrastructure holds concrete outbound Adapters. The Domain is independent of delivery, not independent of Laravel.

The layer names are placement tools, not a promise of operational separation. The architecture boundary decides whether a type participates in Pulsar first. Placement then supplies the complete type-by-type answer.

See the compact taxonomy

The current manifest declares 7 Service records, 16 Domain records, and 1 Infrastructure record. The placement table is normative for every generated record and Laravel-owned seam; the dependency matrix decides behavioral calls.

Continue with the next decision

Use Placement to locate a type, Dependencies to distinguish a data mention from a call, or Preset to see the small structural subset Pest can inspect.