Cross-module ACL (sync)
Purpose: when a Use Case needs another module’s answer in the same request.
Illustrative example: Ordering checks stock via WarehouseAvailabilityPortInterface → WarehouseAvailabilityAclAdapter → thin WarehouseAvailabilityModuleInterface (or a small WarehouseModuleInterface).
Failure / transaction rules: Transactions and failures. Façade thinness: Cross-module contracts.
Two different ports
| Port | Name pattern | Owned by | Injected into |
|---|---|---|---|
| Local (inbound need) | {Need}PortInterface | Consumer | Consumer Use Cases |
| Outbound façade | {This}ModuleInterface or capability-sized *ModuleInterface | Provider | Peer ACL adapters only — never peer Use Cases |
Keep façades thin and HTTP-mappable. Split when the surface grows (contracts).
Sequence — place order checks availability
Why mapping exists
Warehouse speaks Warehouse language (location codes, reservation statuses). Ordering Application/Domain must not import those types. The adapter converts:
- Peer codes → values Ordering stores on lines
- Availability flags → booleans or local result DTOs
- Failures → exceptions / results the Ordering Use Case can apply policy to
Folder layout (both sides)
# Consumer (Ordering)
Domain/Ports/Acl/WarehouseAvailabilityPortInterface.php
Infrastructure/ExternalServices/WarehouseAvailabilityAclAdapter.php
Application/Providers/… # bind local port → adapter
# Provider (Warehouse)
Domain/Ports/Module/WarehouseAvailabilityModuleInterface.php
Application/Providers/… # bind ModuleInterface → implementation
Replaceability test
If Ordering Use Cases already type-hint the Warehouse *ModuleInterface, the test fails.
Anti-patterns
| Anti-pattern | Fix |
|---|---|
use …Warehouse\… inside Ordering Use Case | Local port + ACL |
Injecting peer *ModuleInterface into Ordering Use Case | Same |
God WarehouseModuleInterface with dozens of unrelated methods | Split capability façades |
| Conversion logic in Use Case with foreign enums | Keep conversion in adapter |
| Shared business enum in Shared kernel “for reuse” | Never Shared for business concepts |
| Peer write + local commit with no failure story | Transactions |
Next: cross-module events · contracts.