Skip to content

How inbound adapters enter a workflow

Inbound adapters call one UseCase. Every Controller method, Job, and Command validates, authorizes, establishes context, and takes its one permitted UseCase entrypoint. Controllers use that same route for reads; they never call Queries directly.

The exact entrypoint rule

BoundaryEntry and boundary workMust not do
ControllerCall exactly one UseCase, then assemble HTTP, Inertia, Resource, or redirect delivery.Call a Query, Operation, or Action; open a transaction; branch business work.
JobCarry durable IDs, scalars, DTOs, or Value Objects; restore context, authorize, and call one UseCase in handle().Carry a live Model, own a transaction, or branch workflow logic.
CommandValidate CLI input, establish context, authorize, call one UseCase, and choose the CLI exit.Call Action, Operation, Query, or another UseCase.
SchedulerHand timing to one Command or Job.Invoke workflow types directly or make scheduling a business branch.
A client request enters Laravel, is validated, reaches one Controller and one UseCase, persists an Order through an Action inside the UseCase transaction, and returns shaped JSON through an OrderResource.
Place an order through the HTTP workflow. The Client Service handles HTTP delivery while the Orders Domain owns typed data and the atomic persistence action.

Interpretation. Client delivery validates through Laravel, enters `OrderController` once, and lets `CreateOrder` own the transaction before `OrderResource` shapes the completed result.

Keep delivery work at the boundary

Read-only UseCase responses

Constructors receive stable dependencies. Runtime DTOs, IDs, Value Objects, scalars, and already-prepared boundary data belong to execute(). A UseCase returns a Model, collection, DTO, Value Object, primitive, array, or void; the Adapter turns that value into its delivery format.

Context: Controller delivery boundary — One Request path enters one UseCase and shapes its returned value.

php
$order = $createOrder->execute($data);

return OrderResource::make($order);

Carry durable runtime data

Thin Job and Command one UseCase rules

Jobs have no Form Request. They must restore actor and tenant context from durable payload data and authorize on the worker. Queues are at-least-once: a retry must use the same application-owned idempotency guard. This guidance does not prescribe its storage algorithm, and it does not turn context restoration into a tenant-isolation or authorization guarantee; those guarantees remain with PRD 18.

A CLI caller reaches one Command, which validates input, establishes context, authorizes, calls exactly one UseCase, and turns its delivery-neutral return into a success exit.
Enter one UseCase from a CLI Command. CLI validation, context, authorization, and exit status stay at the Command boundary; workflow authority stays with the UseCase.

Interpretation. The CLI caller reaches `ReconcileLedgerCommand::handle()`, which validates, establishes context, authorizes with `Gate::authorize`, enters one UseCase, and produces `SUCCESS`; failure has no success exit.

A worker receives durable identifiers or values, restores context, authorizes, calls one UseCase with runtime data, and retries through the same idempotency guard.
Enter one UseCase from a queued Job. A queued Job carries durable runtime data and delegates the workflow without owning a transaction or business branch.

Interpretation. A worker receives actor ID, tenant ID, an idempotency key, and business ID, DTO, or Value Object data; it restores context, authorizes, calls one UseCase, and every retry uses the same guard.

Laravel Scheduler supplies timing to one Command or Job, whose boundary work leads to exactly one UseCase and its delivery-specific exit or completion.
Enter a workflow from the scheduler. Scheduling supplies time only; a Command or Job remains the inbound adapter that enters the UseCase.

Interpretation. Laravel Scheduler supplies time to one Command or Job. That Adapter validates, establishes context, authorizes, invokes exactly one UseCase, and produces its exit or completion without scheduling business orchestration.

Scheduler workflow handoff

A scheduler supplies timing to one Command or Job and stops there. The selected Adapter performs its own validation, context establishment, and authorization before its exactly-one-UseCase call; a scheduled closure must not invoke workflow types or encode business branching.

Correct the Controller Query shortcut

Context: ❌ Prohibited Controller read — A Controller must not select a Query as a second application entrypoint.

php
return $ordersQuery->execute($filter);

Context: ✅ Correct Controller read — A read-only UseCase owns Query calls; the Controller owns delivery shaping.

php
$orders = $listOrders->execute($filter);

return OrderResource::collection($orders);

The same correction removes transactions and business branches from a Controller, Job, or Command: move workflow sequencing into the one UseCase, or into an Operation when several UseCases reuse the branch.