定制 creativecrafts/laravel-domain-driven-design-lite 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

creativecrafts/laravel-domain-driven-design-lite

最新稳定版本:0.0.1

Composer 安装命令:

composer require creativecrafts/laravel-domain-driven-design-lite

包简介

Domain‑Driven Design (DDD)‑lite scaffolding for Laravel. This package generates a lightweight, opinionated module structure under Modules/[Module] and provides Artisan commands to scaffold common artifacts (Actions, Queries, DTOs, Repositories, Models, Controllers, Requests, Mappers, Migrations, Fac

README 文档

README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

Pragmatic, Laravel-native DDD modules with generators, safety rails, and CI helpers – without drowning you in ceremony.

🧭 What is DDD-Lite?

DDD-Lite is a developer-tooling package that helps you organise your Laravel 12+ application into modular, domain-oriented boundaries.

It gives you:

  • A module structure (modules/<ModuleName>) with a clear split between:
    • App/ – adapters & Laravel-specific glue (controllers, requests, models, providers, repositories)
    • Domain/ – pure PHP domain code (DTOs, actions, contracts, queries, value objects)
  • Generators for:
    • DTOs, Actions, Contracts, Repositories, Value Objects
    • Queries and Query Builders
    • Aggregate Roots
    • Controllers, Requests, Models, Migrations, Providers, Routes
  • A conversion engine to move existing app/* code into modules:
    • Discovers move candidates (controllers, models, requests, actions, DTOs, contracts)
    • Applies moves with AST-based namespace rewrites
  • Safety rails for all file operations:
    • Every run produces a Manifest (with creates/updates/deletes/moves/mkdirs)
    • --dry-run on everything
    • Rollback by manifest id
  • Quality & CI tooling:
    • Publishable PHPStan & Deptrac configs
    • Optional Pest architecture tests
    • ddd-lite:doctor / ddd-lite:doctor:domain / ddd-lite:doctor-ci to keep modules healthy

The goal is: clean seams, safer refactors, better testability – without requiring you to rewrite your entire app in one go.

🧱 Architecture Overview

A DDD-Lite module lives under modules/<ModuleName>:

modules/<ModuleName>/
├─ App/
│  ├─ Http/
│  │  ├─ Controllers/
│  │  └─ Requests/
│  ├─ Models/
│  ├─ Providers/
│  └─ Repositories/
├─ Domain/
│  ├─ Actions/
│  ├─ Contracts/
│  ├─ DTO/
│  ├─ Queries/
│  └─ ValueObjects/
├─ Database/
│  └─ migrations/
├─ Routes/
│  ├─ api.php
│  └─ web.php
└─ tests/
   ├─ Feature/
   └─ Unit/
└─ Unit/

✅ Rules of thumb

Domain:

  • Pure PHP, no hard dependency on Laravel.
  • Orchestrates use cases with Actions (e.g. CreateTripAction).
  • Talks to the outside world through Contracts (e.g. TripRepositoryContract).
  • Uses DTOs and Value Objects for data.

App:

  • Typical Laravel adapters (controllers, form requests, models).
  • Implements contracts using Eloquent (e.g. TripRepository).
  • Wires things together using module service providers.

⚙️ Requirements

  • PHP: ^8.3
  • Laravel (Illuminate components): ^12.0
  • Composer

Recommended dev dependencies in your app (for quality tooling integration):

  • larastan/larastan
  • deptrac/deptrac
  • pestphp/pest
  • pestphp/pest-plugin-laravel
  • pestphp/pest-plugin-arch

⚙️ Installation

Require the package in your Laravel app (usually as a dev dependency):

composer require creativecrafts/laravel-domain-driven-design-lite --dev

This package is primarily a developer tool (scaffolding, conversion, quality helpers), so installing under --dev is recommended. Laravel’s package discovery will automatically register the service provider.

📦 Provider & Publishing

DDD-Lite ships with stubs and quality configs you can copy into your app.

Stubs (module scaffolding & generators)

To publish the stubs:

php artisan vendor:publish --tag=ddd-lite
php artisan vendor:publish --tag=ddd-lite-stubs

This will create:

  • stubs/ddd-lite/*.stub – templates for:
  • DTOs, Actions, Contracts, Repositories, Value Objects, Aggregates
  • Controllers (including an --inertia variant)
  • Requests
  • Models & migrations
  • Module providers and route/event providers
  • Routes (web & api)

You typically don’t need to touch these unless you want to customise the generated code style.

Quality tooling

To seed PHPStan, Deptrac and Pest architecture tests into your application:

php artisan ddd-lite:publish:quality --target=all

This will (in your app):

  • Create phpstan.app.neon with sensible defaults for app/ + modules/
  • Create deptrac.app.yaml describing layer boundaries (Http, Models, Domain, Modules, etc.)
  • Add tests/ArchitectureTest.php with some baseline rules:
  • No debug helpers (dd, dump, var_dump, …)
  • No stray env() calls
  • Enforce strict types

You can also publish selectively:

php artisan ddd-lite:publish:quality --target=phpstan
php artisan ddd-lite:publish:quality --target=deptrac
php artisan ddd-lite:publish:quality --target=pest-arch

🚀 Getting Started (QuickStart)

We’ll build a simple Planner module with a Trip aggregate.

1) Scaffold a module

php artisan ddd-lite:module Planner --aggregate=Trip

This creates modules/Planner with:

  • Providers (module, route, event) under App/Providers
  • Routes in Routes/api.php and Routes/web.php
  • A ULID Eloquent model (App/Models/Trip.php) plus migrations in Database/migrations
  • Domain DTOs and a repository contract
  • Tests folders

Core flags:

  • --dry-run – preview actions without writing
  • --fix-psr4 – auto-rename lowercased module folders to proper PascalCase
  • --rollback= – undo a previous scaffold
  • --force – overwrite content when needed (with backups)

For full details see: docs/module-scaffold.md

2) Generate a DTO

php artisan ddd-lite:make:dto Planner CreateTripData \
  --props="id:Ulid|nullable,title:string,startsAt:CarbonImmutable,endsAt:CarbonImmutable"

This generates modules/Planner/Domain/DTO/CreateTripData.php:

  • Properly typed constructor
  • readonly by default
  • Optional unit test (unless --no-test is passed)

3) Generate a domain Action

php artisan ddd-lite:make:action Planner CreateTrip \
  --in=Trip \
  --input=FQCN --param=data \
  --returns=ulid

This creates Domain/Actions/Trip/CreateTripAction.php similar to:

namespace Modules\Planner\Domain\Actions\Trip;

use Modules\Planner\Domain\Contracts\TripRepositoryContract;
use Modules\Planner\Domain\DTO\CreateTripData;

final class CreateTripAction
{
    public function __construct(
        private TripRepositoryContract $repo,
    ) {}

    public function __invoke(CreateTripData $data): string
    {
        // Domain invariants live here
        return $this->repo->create($data);
    }
}

4) Implement the repository & bind it Create an Eloquent repository in modules/Planner/App/Repositories/TripRepository.php (or let ddd-lite:make:repository scaffold it):

php artisan ddd-lite:make:repository Planner Trip

Then wire the contract to the implementation:

php artisan ddd-lite:bind Planner TripRepositoryContract TripRepository

ddd-lite:bind edits your module provider so that:

$this->app->bind(
    TripRepositoryContract::class,
    TripRepository::class,
);

is registered.

5) Expose via HTTP Generate a controller + request:

php artisan ddd-lite:make:controller Planner Trip --resource
php artisan ddd-lite:make:request Planner StoreTrip

🧠 DDD-Lite in Practice: Example Flow

A typical “vertical slice” in a module:

  • DTO: CreateTripData – validated input from HTTP or CLI.
  • Action: CreateTripAction – orchestrates creation, enforces invariants.
  • Contract: TripRepositoryContract – interface for persistence.
  • Repository: TripRepository (Eloquent) – implements contract.
  • Controller: TripController@store – adapts HTTP to the action.

Generators help you keep this shape consistent across modules without hand-rolling boilerplate every time.

🧰 Command Reference

All commands share a consistent UX:

  • --dry-run – print what would happen; no files written; no manifest saved.
  • --force – overwrite when content changes (backups are tracked in manifests).
  • --rollback= – revert a previous run (see Manifest section below).

1. Module scaffolding & conversion

ddd-lite:module Scaffold a new module skeleton:

php artisan ddd-lite:module Planner

Key flags:

  • name (required) – module name in PascalCase.
  • --dry-run – preview only.
  • --force – overwrite files if they exist.
  • --fix-psr4 – rename existing lowercased module folders to PSR-4 PascalCase.
  • --rollback= – rollback a previous scaffold.

See docs/module-scaffold.md for details.

ddd-lite:convert Discover and optionally apply moves from app/* into modules:

php artisan ddd-lite:convert Planner \
  --plan-moves \
  --paths=app/Http/Controllers,app/Models

To use the namespace rewriting and AST-based moves, install nikic/php-parser:

composer require --dev nikic/php-parser

Important options:

  • module – target module name.
  • --plan-moves – discover move candidates and print a plan (no writes).
  • --apply-moves – actually apply moves (AST-safe namespace rewrites).
  • --review – interactive confirmation per move (with --apply-moves).
  • --all – apply all moves without prompts.
  • --only=controllers,models,requests,actions,dto,contracts – include kinds.
  • --except=... – exclude kinds.
  • --paths=... – comma-separated paths to scan.
  • --with-shims – include shim suggestions in the printed plan.
  • --export-plan=path.json – write discovered move plan to JSON.
  • --dry-run, --force, --rollback=.

Use this to gradually migrate a legacy app into DDD-Lite modules.

2. Domain generators

ddd-lite:make:dto Generate a DTO under Domain/DTO:

php artisan ddd-lite:make:dto Planner CreateTripData \
  --in=Trip \
  --props="id:Ulid|nullable,title:string,startsAt:CarbonImmutable"
  • module – module name.
  • name – DTO class name.
  • --in= – optional subnamespace inside Domain/DTO.
  • --props= – name:type[|nullable] comma-separated.
  • --readonly – enforce readonly class (default: true).
  • --no-test – skip generating a test.

ddd-lite:make:action Generate a domain action in Domain/Actions:

php artisan ddd-lite:make:action Planner CreateTrip \
  --in=Trip \
  --input=FQCN --param=data \
  --returns=ulid
  • --in= – optional subnamespace.
  • --method= – method name (default __invoke).
  • --input= – parameter type preset: none|ulid|FQCN.
  • --param= – parameter variable name.
  • --returns= – void|ulid|FQCN.
  • --no-test – skip test.

ddd-lite:make:contract Generate a domain contract:

php artisan ddd-lite:make:contract Planner TripRepository \
  --in=Trip \
  --methods="find:TripData|null(id:Ulid); create:TripData(data:TripCreateData)"
  • --methods= – semi-colon separated: name:ReturnType(args...).
  • --with-fake – generate a Fake implementation under tests/Unit/fakes.
  • --no-test – skip the contract test.

ddd-lite:make:repository Generate an Eloquent repository for an aggregate:

php artisan ddd-lite:make:repository Planner Trip

Creates:

  • App/Repositories/TripRepository.php
  • Optional tests (unless --no-test).

ddd-lite:make:value-object Generate a value object:

php artisan ddd-lite:make:value-object Planner Email \
  --scalar=string
  • --scalar= – backing scalar type: string|int|float|bool.

ddd-lite:make:aggregate-root Generate an aggregate root base:

php artisan ddd-lite:make:aggregate-root Planner Trip

Useful for richer domain modelling around key aggregates.

Query side

  • ddd-lite:make:query – generate a Query class in Domain/Queries.
  • ddd-lite:make:query-builder – generate a QueryBuilder helper.
  • ddd-lite:make:aggregator – generate an Aggregator to combine queries.

Example:

php artisan ddd-lite:make:query Planner TripIndexQuery
php artisan ddd-lite:make:query-builder Planner Trip
php artisan ddd-lite:make:aggregator Planner TripIndexAggregator

3. App-layer generators

ddd-lite:make:model Generate an Eloquent model in App/Models:

php artisan ddd-lite:make:model Planner Trip \
  --table=trips \
  --fillable="title,starts_at,ends_at"

Options:

  • --table=, --fillable=, --guarded=
  • --soft-deletes
  • --no-timestamps

ddd-lite:make:migration Generate a migration under Database/migrations:

php artisan ddd-lite:make:migration Planner create_trips_table --create=trips
  • module? – module name (optional).
  • name? – migration base name.
  • --table= – table name.
  • --create= – shortcut for table creation.
  • --path= – override path (defaults to module migrations).
  • --force, --dry-run, --rollback=.

ddd-lite:make:controller Generate a controller:

php artisan ddd-lite:make:controller Planner Trip --resource
  • --resource – standard Laravel resource methods.
  • --inertia – generate methods that return Inertia pages.
  • --suffix= – class suffix (default Controller).

ddd-lite:make:request Generate a form request:

php artisan ddd-lite:make:request Planner StoreTrip
  • --suffix= – class suffix (default Request).

4. Binding & wiring

ddd-lite:bind Bind a domain contract to an implementation in the module provider:

php artisan ddd-lite:bind Planner TripRepositoryContract TripRepository
  • module – module name.
  • contract – contract short name or FQCN.
  • implementation – implementation short name or FQCN.
  • --force – skip class existence checks (e.g. when generating ahead of time).

5. Manifest commands Every write operation (scaffolding, generate, convert, publish, doctor fixes) is tracked via a Manifest.

ddd-lite:manifest:list List manifests:

php artisan ddd-lite:manifest:list --module=Planner --type=create --json

Options:

  • --module= – filter by module.
  • --type= – mkdir|create|update|delete|move.
  • --after=, --before= – ISO8601 bounds for created_at.
  • --json – machine-readable output.

ddd-lite:manifest:show Inspect a single manifest:

php artisan ddd-lite:manifest:show 2025-11-24-13-54-01 --json

Shows the tracked operations for that run (created files, backups, moves, deletions, etc.).

6. Doctor & Quality commands

ddd-lite:publish:quality (Described earlier) – publishes PHPStan, Deptrac, and Pest Arch configuration/stubs into your app.

ddd-lite:doctor Run structural checks on your modules and wiring:

php artisan ddd-lite:doctor --module=Planner --json

Checks things like:

  • Module provider registration
  • Route/service provider wiring
  • PSR-4 inconsistencies
  • Missing or mis-wired module components

Flags:

  • --module= – limit to a specific module.
  • --fix – attempt automatic fixes (provider edits, PSR-4 renames, etc.).
  • --json – JSON report for tooling.
  • --prefer=file|class – strategy when class and filename mismatch.
  • --rollback= – undo fixes.

ddd-lite:doctor:domain Run domain purity checks via Deptrac:

php artisan ddd-lite:doctor:domain \
  --config=deptrac.app.yaml \
  --bin=vendor/bin/deptrac \
  --json \
  --fail-on=violations

Options:

  • --config= – Deptrac YAML config.
  • --bin= – path to deptrac executable.
  • --json – JSON summary.
  • --strict – treat uncovered as failure.
  • --stdin-report= – use pre-generated Deptrac JSON report.
  • --fail-on= – violations|errors|uncovered|any.

ddd-lite:doctor-ci Run both structural and domain checks in CI:

php artisan ddd-lite:doctor-ci --json --fail-on=error
  • --paths= – paths to scan (defaults to modules/ and bootstrap/app.php).
  • --fail-on=none|any|error – CI failure policy.
  • --json – CI-friendly JSON result.

Use this in your CI pipeline to enforce module health.

🧪 Safety Rails: Manifest & Rollback

DDD-Lite never silently edits your app.

For each command run that changes files:

  • A Manifest is written with:
  • mkdir, create, update, delete, move records
  • Backups of overwritten files
  • You can inspect manifests with:
  • ddd-lite:manifest:list
  • ddd-lite:manifest:show {id}
  • You can revert a run by passing --rollback= to the original command (e.g. ddd-lite:module, ddd-lite:convert, ddd-lite:publish:quality, ddd-lite:doctor).

This makes DDD-Lite safe to use on large, existing codebases.

🧮 Package Quality: PHPStan, Deptrac & Pest

Inside this package:

  • phpstan.neon.dist – strict rules for the package itself.
  • deptrac.package.yaml – package-level dependency rules.
  • tests/ArchTest.php – baseline architecture checks via Pest.

In your application, use:

php artisan ddd-lite:publish:quality --target=all

and then:

# In your app
vendor/bin/phpstan analyse -c phpstan.app.neon
vendor/bin/deptrac --config=deptrac.app.yaml
php artisan test tests/ArchitectureTest.php

Combine this with ddd-lite:doctor-ci in CI for a tight feedback loop.

🧩 Common Workflows

Greenfield project

  • Install DDD-Lite.
  • Scaffold your first module: ddd-lite:module.
  • Generate DTOs, Actions, Contracts, Repositories, Controllers, Requests.
  • Set up quality tooling with ddd-lite:publish:quality.
  • Wire ddd-lite:doctor-ci into your CI.

Migrating a legacy app

  • Install DDD-Lite.
  • Scaffold a module for a coherent slice (e.g. Planner, Billing, Users).
  • Use ddd-lite:convert with --plan-moves on a subset of app/*.
  • Iterate with --apply-moves and --review, keeping an eye on manifests.
  • Introduce contracts + repositories for areas you want to harden.
  • Run ddd-lite:doctor and ddd-lite:doctor:domain regularly during the migration.

🧪 Testing Philosophy

The package itself is tested with:

  • Pest for:
    • Feature tests of console commands
    • Unit tests for internals (filesystem, manifests, planners)
  • Architecture tests to protect boundaries.

You’re encouraged to:

  • Keep module tests close to modules (under modules//tests).
  • Use the provided stubs for DTO / Action / Contract / Repository tests to keep patterns consistent.

🔒 Design Principles

  • Domain purity – Domain/ should know nothing about Laravel.
  • Explicit boundaries – Domain <-> App contracts are interfaces, not facades.
  • Safety first – manifests, backups, --dry-run, --rollback.
  • Deterministic generators – running a command twice should be safe and idempotent.
  • CI-friendly – all checks and reports can be consumed by automation via JSON / exit codes.

🧰 Troubleshooting

  • “Nothing seems to happen when I run a command”
    • Check if you passed --dry-run.
    • Inspect manifests using ddd-lite:manifest:list.
  • “I messed up my module structure”
    • Find the relevant manifest id: ddd-lite:manifest:list.
    • Rerun the original command with --rollback=.
  • “Deptrac or PHPStan fail after publishing quality configs”
    • Make sure you installed the suggested dev dependencies in your app.
    • Tweak phpstan.app.neon / deptrac.app.yaml to match your project’s structure.

Changelog

Please see CHANGELOG for more information on what has changed recently.

Security

Please review our security policy on how to report security vulnerabilities.

🙌 Credits

📄 License

The MIT License (MIT). Please see License File for more information.

统计信息

  • 总下载量: 41
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 1
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-11-25