This skill should be used when the user asks to "work on the Laravel backend", "create a PHP module", "configure Laravel Sail", "write a Pest test", "set up Scramble API docs", "implement a ModuleApi interface", "configure Reverb WebSockets", "design module boundaries", or "follow Laravel architecture conventions".
How this skill is triggered — by the user, by Claude, or both
Slash command
/fullstack-project-skills:laravel-modular-monolithThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Expert in building maintainable Laravel 12 applications using a modular monolith architecture. Modules own their data, logic, and API surface. Communication between modules happens only through explicit contracts — never through direct class imports or shared database queries.
Expert in building maintainable Laravel 12 applications using a modular monolith architecture. Modules own their data, logic, and API surface. Communication between modules happens only through explicit contracts — never through direct class imports or shared database queries.
Documentation principle: The project's CLAUDE.md, module CLAUDE.md files, ADRs, and Scramble output MUST be updated whenever this skill is applied. Code changes without documentation updates are incomplete.
ModuleApi interfaces and Shared/Events contracts.sail pint --test must pass before every commit.Result types and coordinate domain eventspestphp/pest)laravel)dedoc/scramble) — OpenAPI 3.1.0app/Modules/[Module]/
├── CLAUDE.md
├── [Module]ServiceProvider.php
├── [Module]ModuleApi.php # interface (only if consumed by other modules)
├── Models/
│ └── [Entity].php # Eloquent + Value Objects + invariants
├── Services/
│ └── [Module]Service.php # one public method = one use case
├── Http/
│ ├── Controllers/[Module]Controller.php
│ ├── Requests/[Action][Entity]Request.php
│ └── Resources/[Entity]Resource.php
├── Events/
│ └── [SomethingHappened].php
├── Listeners/
│ └── [HandleExternalEvent].php
├── Routes/
│ └── api.php
├── Database/
│ ├── Migrations/
│ ├── Factories/
│ └── Seeders/
│ ├── [Module]LocalSeeder.php
│ └── [Module]TestingSeeder.php
└── Tests/
├── Unit/
└── Feature/
// app/Modules/Auth/AuthModuleApi.php
interface AuthModuleApi
{
public function getUserById(int $id): ?UserDto;
public function userExists(int $id): bool;
}
// app/Modules/Auth/AuthServiceProvider.php
$this->app->bind(AuthModuleApi::class, AuthService::class);
// app/Modules/Blog/Services/BlogService.php
public function __construct(private AuthModuleApi $auth) {}
// ✅ Injects interface — never the concrete AuthService
// app/Shared/Base/Result.php
final class Result
{
private function __construct(
public readonly bool $success,
public readonly mixed $value = null,
public readonly ?string $error = null,
) {}
public static function ok(mixed $value = null): self { ... }
public static function fail(string $error): self { ... }
}
// In a service:
public function register(array $data): Result
{
if (User::where('email', $data['email'])->exists()) {
return Result::fail('email_taken');
}
$user = User::create($data);
return Result::ok($user);
}
// In the controller:
$result = $this->service->register($request->validated());
if (!$result->success) {
return response()->json(['error' => $result->error], 409);
}
return new UserResource($result->value);
uses(RefreshDatabase::class);
it('creates an order for authenticated user', function () {
$user = User::factory()->create();
$response = actingAs($user)
->postJson('/api/orders', ['product_id' => 1, 'quantity' => 2]);
$response->assertStatus(201);
expect(Order::where('user_id', $user->id)->count())->toBe(1);
});
// Emitter (after completing the operation):
event(new OrderPlaced($order->id, $order->user_id, $order->total));
// Listener in another module registers in its own ServiceProvider:
$this->app['events']->listen(OrderPlaced::class, SendOrderConfirmationEmail::class);
// Channel naming: [module].[resource].[id]
class OrderStatusUpdated implements ShouldBroadcast
{
public function broadcastOn(): Channel
{
return new PrivateChannel("orders.{$this->order->user_id}");
}
}
// WRONG — imports Auth model inside Blog module
public function user(): BelongsTo
{
return $this->belongsTo(\App\Modules\Auth\Models\User::class);
}
// WRONG — business rule in controller
public function store(Request $request): JsonResponse
{
if (Order::where('user_id', auth()->id())->where('status', 'pending')->count() > 3) {
return response()->json(['error' => 'Too many pending orders'], 422);
}
// ... more logic
}
// WRONG — PHPUnit class-based test
class OrderTest extends TestCase
{
public function test_order_creation(): void
{
$this->assertTrue(true);
}
}
# WRONG
php artisan migrate
composer require some/package
./vendor/bin/pest
try {
$this->externalService->charge($amount);
} catch (\Exception $e) {
// WRONG — swallowed silently
}
Works well with: prd-analysis, backend-module-dev, api-contract-sync, project-orchestration
This skill applies when working in the Laravel backend repository — creating modules, implementing services, writing tests, configuring Sail, managing database migrations, or designing inter-module communication patterns. For frontend work, use nextjs-feature-based. For cross-repo coordination, use api-contract-sync.
This skill activates when working in the Laravel backend repository. Superpowers has no equivalent — it is technology-agnostic and does not define Laravel architecture conventions. This skill complements any Superpowers phase by applying Laravel Modular Monolith conventions.
If Superpowers is not installed, this skill works identically.
npx claudepluginhub juan-apscreativas/fullstack-project-skills --plugin fullstack-project-skillsGuides runner selection in Laravel (Sail vs non-Sail), core workflows like TDD with Pest, migrations, queues, and applying superpowers skills platform-agnostically.
Provides Laravel expertise including Eloquent ORM optimization, service container patterns, queues, events, Sanctum/Passport auth, and Pest testing. Activates on /godmode:laravel or Laravel/eloquent/artisan/blade mentions.
Design Laravel app architecture with services, repositories, actions, and clean code patterns. Use when structuring projects, creating services, implementing DI, or organizing code layers.