Builder

/laravel-agent:module:make

Create reusable domain module with contracts, services, DTOs

Overview

The /module:make command generates a complete, reusable domain module under app/Modules/<Name> (or Modules/ if nwidart/laravel-modules is installed). It creates well-structured modules with contracts, services, DTOs, and tests following domain-driven design principles.

Usage

/laravel-agent:module:make <ModuleName> [specification]

Examples

# Create a basic pricing module
/laravel-agent:module:make Pricing

# Create a notification module with multiple channels
/laravel-agent:module:make Notification with email, SMS, and push channels

# Create a payment module with multiple strategies
/laravel-agent:module:make Payment with Stripe and PayPal strategies

# Create an inventory module with tracking
/laravel-agent:module:make Inventory with stock tracking and alerts

What Gets Created

A complete domain module includes the following components:

Component Location Description
Service Contract app/Modules/<Name>/Contracts/ Interface defining the module's public API
Service Implementation app/Modules/<Name>/Services/ Concrete implementation of the service contract
DTOs app/Modules/<Name>/DTOs/ Type-safe data transfer objects
Repository (optional) app/Modules/<Name>/Repositories/ Data access abstraction layer
Strategies (optional) app/Modules/<Name>/Strategies/ Interchangeable algorithm implementations
Service Provider app/Modules/<Name>/ Registers module services and bindings
Unit Tests tests/Unit/Modules/<Name>/ Pest PHP tests for the module

Design Patterns

The command will ask which patterns your module should use:

  • Strategy - Multiple interchangeable algorithms (e.g., payment gateways, notification channels)
  • Repository - Data access abstraction for database operations
  • DTO - Type-safe data transfer objects for input/output
  • None - Simple service class without additional patterns

Module Structure Example

For /laravel-agent:module:make Payment with Stripe using Strategy pattern:

app/Modules/Payment/
├── Contracts/
│   ├── PaymentServiceInterface.php
│   └── PaymentStrategyInterface.php
├── Services/
│   └── PaymentService.php
├── Strategies/
│   ├── StripeStrategy.php
│   └── PayPalStrategy.php
├── DTOs/
│   ├── PaymentRequest.php
│   └── PaymentResult.php
├── PaymentServiceProvider.php
└── README.md

tests/Unit/Modules/Payment/
├── PaymentServiceTest.php
└── StripeStrategyTest.php

Generated Service Contract Example

<?php

namespace App\Modules\Payment\Contracts;

use App\Modules\Payment\DTOs\PaymentRequest;
use App\Modules\Payment\DTOs\PaymentResult;

interface PaymentServiceInterface
{
    /**
     * Process a payment using the configured strategy
     */
    public function process(PaymentRequest $request): PaymentResult;

    /**
     * Refund a payment
     */
    public function refund(string $transactionId, float $amount): PaymentResult;

    /**
     * Get payment status
     */
    public function getStatus(string $transactionId): string;
}

Generated Service Implementation Example

<?php

namespace App\Modules\Payment\Services;

use App\Modules\Payment\Contracts\PaymentServiceInterface;
use App\Modules\Payment\Contracts\PaymentStrategyInterface;
use App\Modules\Payment\DTOs\PaymentRequest;
use App\Modules\Payment\DTOs\PaymentResult;

class PaymentService implements PaymentServiceInterface
{
    public function __construct(
        private PaymentStrategyInterface $strategy
    ) {}

    public function process(PaymentRequest $request): PaymentResult
    {
        return $this->strategy->charge(
            $request->amount,
            $request->currency,
            $request->token
        );
    }

    public function refund(string $transactionId, float $amount): PaymentResult
    {
        return $this->strategy->refund($transactionId, $amount);
    }

    public function getStatus(string $transactionId): string
    {
        return $this->strategy->getStatus($transactionId);
    }
}

Module Registration

After creation, register the module's service provider in config/app.php:

'providers' => [
    // ...
    App\Modules\Payment\PaymentServiceProvider::class,
],

Using Your Module

Inject the module's contract into your controllers or services:

<?php

namespace App\Http\Controllers;

use App\Modules\Payment\Contracts\PaymentServiceInterface;
use App\Modules\Payment\DTOs\PaymentRequest;

class CheckoutController extends Controller
{
    public function __construct(
        private PaymentServiceInterface $paymentService
    ) {}

    public function process(Request $request)
    {
        $paymentRequest = new PaymentRequest(
            amount: $request->amount,
            currency: 'USD',
            token: $request->payment_token
        );

        $result = $this->paymentService->process($paymentRequest);

        if ($result->isSuccessful()) {
            return response()->json([
                'success' => true,
                'transaction_id' => $result->transactionId
            ]);
        }

        return response()->json([
            'success' => false,
            'error' => $result->errorMessage
        ], 422);
    }
}

Common Use Cases

Command Patterns Result
/module:make Pricing DTO Pricing calculation module
/module:make Payment with Stripe Strategy Payment with gateway strategies
/module:make Inventory Repository Stock management module
/module:make Notification Strategy Multi-channel notifications

Best Practices

  1. Keep modules focused - Each module should have a single, well-defined responsibility
  2. Use contracts - Always program to interfaces for better testability and flexibility
  3. Leverage DTOs - Use data transfer objects for type safety and validation
  4. Choose patterns wisely - Use Strategy for multiple implementations, Repository for data access
  5. Write tests - Generated tests provide a starting point; add edge cases and integration tests
  6. Document usage - Each module includes a README with usage examples

nwidart/laravel-modules Integration

If you have nwidart/laravel-modules installed, the command will automatically create modules in the Modules/ directory following that package's structure and conventions.

Related Agent

This command uses the laravel-module-builder agent.

See Also