     1→{
     2→    "$schema": "https://getcomposer.org/schema.json",
     3→    "name": "laravel/livewire-starter-kit",
     4→    "type": "project",
     5→    "description": "The official Laravel starter kit for Livewire.",
     6→    "keywords": [
     7→        "laravel",
     8→        "framework"
     9→    ],
    10→    "license": "MIT",
    11→    "require": {
    12→        "php": "^8.2",
    13→        "laravel/fortify": "^1.30",
    14→        "laravel/framework": "^12.0",
    15→        "laravel/tinker": "^2.10.1",
    16→        "livewire/flux": "^2.9.0",
    17→        "livewire/livewire": "^4.0"
    18→    },
    19→    "require-dev": {
    20→        "deptrac/deptrac": "^4.6",
    21→        "fakerphp/faker": "^1.23",
    22→        "larastan/larastan": "^3.9",
    23→        "laravel/boost": "^1.0",
    24→        "laravel/pail": "^1.2.2",
    25→        "laravel/pint": "^1.24",
    26→        "laravel/sail": "^1.41",
    27→        "mockery/mockery": "^1.6",
    28→        "nunomaduro/collision": "^8.6",
    29→        "pestphp/pest": "^4.3",
    30→        "pestphp/pest-plugin-laravel": "^4.0",
    31→        "phpstan/phpstan": "^2.1"
    32→    },
    33→    "autoload": {
    34→        "psr-4": {
    35→            "App\\": "app/",
    36→            "Database\\Factories\\": "database/factories/",
    37→            "Database\\Seeders\\": "database/seeders/"
    38→        }
    39→    },
    40→    "autoload-dev": {
    41→        "psr-4": {
    42→            "Tests\\": "tests/"
    43→        }
    44→    },
    45→    "scripts": {
    46→        "setup": [
    47→            "composer install",
    48→            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"",
    49→            "@php artisan key:generate",
    50→            "@php artisan migrate --force",
    51→            "npm install",
    52→            "npm run build"
    53→        ],
    54→        "dev": [
    55→            "Composer\\Config::disableProcessTimeout",
    56→            "npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve\" \"php artisan queue:listen --tries=1 --timeout=0\" \"php artisan pail --timeout=0\" \"npm run dev\" --names=server,queue,logs,vite --kill-others"
    57→        ],
    58→        "lint": [
    59→            "pint --parallel"
    60→        ],
    61→        "test:lint": [
    62→            "pint --parallel --test"
    63→        ],
    64→        "test": [
    65→            "@php artisan config:clear --ansi",
    66→            "@test:lint",
    67→            "@php artisan test"
    68→        ],
    69→        "post-autoload-dump": [
    70→            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
    71→            "@php artisan package:discover --ansi"
    72→        ],
    73→        "post-update-cmd": [
    74→            "@php artisan vendor:publish --tag=laravel-assets --ansi --force"
    75→        ],
    76→        "post-root-package-install": [
    77→            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
    78→        ],
    79→        "post-create-project-cmd": [
    80→            "@php artisan key:generate --ansi",
    81→            "@php -r \"file_exists('database/database.sqlite') || touch('database/database.sqlite');\"",
    82→            "@php artisan migrate --graceful --ansi"
    83→        ],
    84→        "pre-package-uninstall": [
    85→            "Illuminate\\Foundation\\ComposerScripts::prePackageUninstall"
    86→        ]
    87→    },
    88→    "extra": {
    89→        "laravel": {
    90→            "dont-discover": []
    91→        }
    92→    },
    93→    "config": {
    94→        "optimize-autoloader": true,
    95→        "preferred-install": "dist",
    96→        "sort-packages": true,
    97→        "allow-plugins": {
    98→            "pestphp/pest-plugin": true,
    99→            "php-http/discovery": true
   100→        }
   101→    },
   102→    "minimum-stability": "stable",
   103→    "prefer-stable": true
   104→}
   105→

laravel/livewire-starter-kit

@php -r "file_exists('.env') || copy('.env.example', '.env');"

npx concurrently -c "#93c5fd,#c4b5fd,#fb7185,#fdba74" "php artisan serve" "php artisan queue:listen --tries=1 --timeout=0" "php artisan pail --timeout=0" "npm run dev" --names=server,queue,logs,vite --kill-others

@php artisan config:clear --ansi
@test:lint
@php artisan test

@php -r "file_exists('database/database.sqlite') || touch('database/database.sqlite');"


Deptrac 4.6 is installed. Now let me check its documentation for YAML config format and create the configuration.


Bash

vendor/bin/deptrac --help 2>&1 | head -30

Check Deptrac help output


Description:
  Display help for a command

Usage:
  help [options] [--] [<command_name>]

Arguments:
  command_name                   The command name [default: "help"]

Options:
      --format=FORMAT            The output format (txt, xml, json, or md) [default: "txt"]
      --raw                      To output raw command help
  -h, --help                     Display help for the given command. When no command is given display help for the analyse command
      --silent                   Do not output any message
  -q, --quiet                    Only errors are displayed. All other output is suppressed
  -V, --version                  Display this application version
      --ansi|--no-ansi           Force (or disable --no-ansi) ANSI output
  -n, --no-interaction           Do not ask any interactive question
      --no-cache                 Disable caching mechanisms (wins over --cache-file)
      --clear-cache              Clears cache file before run
      --cache-file=CACHE-FILE    Location where cache file will be stored
  -c, --config-file=CONFIG-FILE  Location of Depfile containing the configuration [default: "/Users/fabianwesner/Herd/shop/deptrac.yaml"]
  -v|vv|vvv, --verbose           Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Help:
  The help command displays help for a given command:

    vendor/bin/deptrac help list

  You can also output the help in other formats by using the --format option:


ls vendor/deptrac/deptrac/docs/ 2>/dev/null || ls vendor/deptrac/deptrac/*.md 2>/dev/null || echo "No docs found"

Look for Deptrac documentation


vendor/deptrac/deptrac/LICENCE.md
vendor/deptrac/deptrac/README.md


vendor/bin/deptrac analyse --help 2>&1 | head -40

Check Deptrac analyse command help


Command "analyse" is not defined.


List available Deptrac commands


deptrac 4.6.0

Usage:
  command [options] [arguments]

Options:
  -h, --help                     Display help for the given command. When no command is given display help for the analyse command
      --silent                   Do not output any message
  -q, --quiet                    Only errors are displayed. All other output is suppressed
  -V, --version                  Display this application version
      --ansi|--no-ansi           Force (or disable --no-ansi) ANSI output
  -n, --no-interaction           Do not ask any interactive question
      --no-cache                 Disable caching mechanisms (wins over --cache-file)
      --clear-cache              Clears cache file before run
      --cache-file=CACHE-FILE    Location where cache file will be stored
  -c, --config-file=CONFIG-FILE  Location of Depfile containing the configuration [default: "/Users/fabianwesner/Herd/shop/deptrac.yaml"]
  -v|vv|vvv, --verbose           Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Available commands:
  analyse             [analyze] Analyses your project using the provided depfile
  changed-files       Lists layers corresponding to the changed files
  completion          Dump the shell completion script
  help                Display help for a command
  init                Creates a depfile template
  list                List commands
 debug
  debug:dependencies  List layer dependencies
  debug:layer         Checks which tokens belong to the provided layer
  debug:token         [debug:class-like] Checks which layers the provided token belongs to
  debug:unassigned    Lists tokens that are not assigned to any layer
  debug:unused        Lists unused (or barely used) layer dependencies


Let me check Deptrac 4.6 config format with an init template and also look at some examples.


Generate Deptrac config template


Depfile dumped.


     1→deptrac:
     2→  paths:
     3→    - ./src
     4→  exclude_files:
     5→    - '#.*test.*#'
     6→  layers:
     7→    - name: Controller
     8→      collectors:
     9→        - type: classLike
    10→          value: .*Controller.*
    11→    - name: Repository
    12→      collectors:
    13→        - type: classLike
    14→          value: .*Repository.*
    15→    - name: Service
    16→      collectors:
    17→        - type: classLike
    18→          value: .*Service.*
    19→  ruleset:
    20→    Controller:
    21→      - Service
    22→    Service:
    23→      - Repository
    24→    Repository:
    25→

deptrac:
  paths:
    - ./src
  exclude_files:
    - '#.*test.*#'
  layers:
    - name: Controller
      collectors:
        - type: classLike
          value: .*Controller.*
    - name: Repository
      collectors:
        - type: classLike
          value: .*Repository.*
    - name: Service
      collectors:
        - type: classLike
          value: .*Service.*
  ruleset:
    Controller:
      - Service
    Service:
      - Repository
    Repository:


Good, I have the template format. Now let me create a proper Deptrac configuration for this Laravel app's architecture. Let me verify the exact directory/namespace structure first.


List top-level app directories


app/Actions/
app/Concerns/
app/Contracts/
app/Enums/
app/Events/
app/Exceptions/
app/Http/
app/Jobs/
app/Livewire/
app/Models/
app/Observers/
app/Policies/
app/Providers/
app/Services/
app/Support/
app/Traits/
app/ValueObjects/


ls -d app/Models/*/  2>/dev/null; echo "---"; ls -d app/Http/*/ 2>/dev/null; echo "---"; ls -d app/Livewire/*/ 2>/dev/null

List subdirectories of key namespaces


app/Models/Concerns/
app/Models/Scopes/
---
app/Http/Controllers/
app/Http/Middleware/
---
app/Livewire/Actions/
app/Livewire/Admin/
app/Livewire/Settings/
app/Livewire/Storefront/


Now I have the complete picture. Let me create the Deptrac configuration with proper architectural layers.


Write

deptrac:
  paths:
    - ./app
  exclude_files:
    - '#.*test.*#'

  layers:
    # Foundation layers - no upstream dependencies
    - name: Enums
      collectors:
        - type: directory
          value: app/Enums/.*

    - name: ValueObjects
      collectors:
        - type: directory
          value: app/ValueObjects/.*

    - name: Contracts
      collectors:
        - type: directory
          value: app/Contracts/.*

    - name: Exceptions
      collectors:
        - type: directory
          value: app/Exceptions/.*

    - name: Support
      collectors:
        - type: directory
          value: app/Support/.*

    - name: Events
      collectors:
        - type: directory
          value: app/Events/.*

    - name: Concerns
      collectors:
        - type: directory
          value: app/Concerns/.*

    - name: Traits
      collectors:
        - type: directory
          value: app/Traits/.*

    # Domain layer
    - name: Models
      collectors:
        - type: directory
          value: app/Models/.*

    # Business logic layer
    - name: Services
      collectors:
        - type: directory
          value: app/Services/.*

    # Authorization layer
    - name: Policies
      collectors:
        - type: directory
          value: app/Policies/.*

    # Observer layer
    - name: Observers
      collectors:
        - type: directory
          value: app/Observers/.*

    # Background processing layer
    - name: Jobs
      collectors:
        - type: directory
          value: app/Jobs/.*

    # HTTP layer
    - name: Controllers
      collectors:
        - type: directory
          value: app/Http/Controllers/.*

    - name: Middleware
      collectors:
        - type: directory
          value: app/Http/Middleware/.*

    # UI layer
    - name: Livewire
      collectors:
        - type: directory
          value: app/Livewire/.*

    # Actions layer (Fortify etc.)
    - name: Actions
      collectors:
        - type: directory
          value: app/Actions/.*

    # Infrastructure layer
    - name: Providers
      collectors:
        - type: directory
          value: app/Providers/.*

  ruleset:
    # Foundation layers - minimal dependencies
    Enums: ~
    ValueObjects:
      - Enums
    Contracts:
      - Enums
      - ValueObjects
      - Models
    Exceptions:
      - Enums
    Support: ~
    Events:
      - Enums
      - Models
    Concerns:
      - Enums
    Traits: ~

    # Domain layer - depends on foundation
    Models:
      - Enums
      - ValueObjects
      - Concerns
      - Traits
      - Events
      - Exceptions
      - Support

    # Business logic - depends on domain + foundation
    Services:
      - Models
      - Enums
      - ValueObjects
      - Contracts
      - Events
      - Exceptions
      - Support
      - Services

    # Authorization - depends on domain
    Policies:
      - Models
      - Enums

    # Observers - depends on services + domain
    Observers:
      - Models
      - Services
      - Enums

    # Jobs - depends on services + domain
    Jobs:
      - Models
      - Services
      - Enums
      - Events
      - Exceptions

    # HTTP layer - depends on services + domain
    Controllers:
      - Models
      - Services
      - Enums
      - ValueObjects

    Middleware:
      - Models
      - Enums
      - Exceptions

    # UI layer - depends on services + domain
    Livewire:
      - Models
      - Services
      - Enums
      - ValueObjects
      - Exceptions
      - Concerns
      - Traits
      - Events
      - Support

    # Actions - depends on domain
    Actions:
      - Models
      - Enums
      - Exceptions
      - Support

    # Providers - infrastructure, can wire everything
    Providers:
      - Models
      - Services
      - Enums
      - Contracts
      - Middleware
      - Support
      - Events


The file /Users/fabianwesner/Herd/shop/deptrac.yaml has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
     1→deptrac:
     2→  paths:
     3→    - ./app
     4→  exclude_files:
     5→    - '#.*test.*#'
     6→
     7→  layers:
     8→    # Foundation layers - no upstream dependencies
     9→    - name: Enums
    10→      collectors:
    11→        - type: directory
    12→          value: app/Enums/.*
    13→
    14→    - name: ValueObjects
    15→      collectors:
    16→        - type: directory
    17→          value: app/ValueObjects/.*
    18→
    19→    - name: Contracts
    20→      collectors:
    21→        - type: directory
    22→          value: app/Contracts/.*
    23→
    24→    - name: Exceptions
    25→      collectors:
    26→        - type: directory
    27→          value: app/Exceptions/.*
    28→
    29→    - name: Support
    30→      collectors:
    31→        - type: directory
    32→          value: app/Support/.*
    33→
    34→    - name: Events
    35→      collectors:
    36→        - type: directory
    37→          value: app/Events/.*
    38→
    39→    - name: Concerns
    40→      collectors:
    41→        - type: directory
    42→          value: app/Concerns/.*
    43→
    44→    - name: Traits
    45→      collectors:
    46→        - type: directory
    47→          value: app/Traits/.*
    48→
    49→    # Domain layer
    50→    - name: Models
    51→      collectors:
    52→        - type: directory
    53→          value: app/Models/.*
    54→
    55→    # Business logic layer
    56→    - name: Services
    57→      collectors:
    58→        - type: directory
    59→          value: app/Services/.*
    60→
    61→    # Authorization layer
    62→    - name: Policies
    63→      collectors:
    64→        - type: directory
    65→          value: app/Policies/.*
    66→
    67→    # Observer layer
    68→    - name: Observers
    69→      collectors:
    70→        - type: directory
    71→          value: app/Observers/.*
    72→
    73→    # Background processing layer
    74→    - name: Jobs
    75→      collectors:
    76→        - type: directory
    77→          value: app/Jobs/.*
    78→
    79→    # HTTP layer
    80→    - name: Controllers
    81→      collectors:
    82→        - type: directory
    83→          value: app/Http/Controllers/.*
    84→
    85→    - name: Middleware
    86→      collectors:
    87→        - type: directory
    88→          value: app/Http/Middleware/.*
    89→
    90→    # UI layer
    91→    - name: Livewire
    92→      collectors:
    93→        - type: directory
    94→          value: app/Livewire/.*
    95→
    96→    # Actions layer (Fortify etc.)
    97→    - name: Actions
    98→      collectors:
    99→        - type: directory
   100→          value: app/Actions/.*
   101→
   102→    # Infrastructure layer
   103→    - name: Providers
   104→      collectors:
   105→        - type: directory
   106→          value: app/Providers/.*
   107→
   108→  ruleset:
   109→    # Foundation layers - minimal dependencies
   110→    Enums: ~
   111→    ValueObjects:
   112→      - Enums
   113→    Contracts:
   114→      - Enums
   115→      - ValueObjects
   116→      - Models
   117→    Exceptions:
   118→      - Enums
   119→    Support: ~
   120→    Events:
   121→      - Enums
   122→      - Models
   123→    Concerns:
   124→      - Enums
   125→    Traits: ~
   126→
   127→    # Domain layer - depends on foundation
   128→    Models:
   129→      - Enums
   130→      - ValueObjects
   131→      - Concerns
   132→      - Traits
   133→      - Events
   134→      - Exceptions
   135→      - Support
   136→
   137→    # Business logic - depends on domain + foundation
   138→    Services:
   139→      - Models
   140→      - Enums
   141→      - ValueObjects
   142→      - Contracts
   143→      - Events
   144→      - Exceptions
   145→      - Support
   146→      - Services
   147→
   148→    # Authorization - depends on domain
   149→    Policies:
   150→      - Models
   151→      - Enums
   152→
   153→    # Observers - depends on services + domain
   154→    Observers:
   155→      - Models
   156→      - Services
   157→      - Enums
   158→
   159→    # Jobs - depends on services + domain
   160→    Jobs:
   161→      - Models
   162→      - Services
   163→      - Enums
   164→      - Events
   165→      - Exceptions
   166→
   167→    # HTTP layer - depends on services + domain
   168→    Controllers:
   169→      - Models
   170→      - Services
   171→      - Enums
   172→      - ValueObjects
   173→
   174→    Middleware:
   175→      - Models
   176→      - Enums
   177→      - Exceptions
   178→
   179→    # UI layer - depends on services + domain
   180→    Livewire:
   181→      - Models
   182→      - Services
   183→      - Enums
   184→      - ValueObjects
   185→      - Exceptions
   186→      - Concerns
   187→      - Traits
   188→      - Events
   189→      - Support
   190→
   191→    # Actions - depends on domain
   192→    Actions:
   193→      - Models
   194→      - Enums
   195→      - Exceptions
   196→      - Support
   197→
   198→    # Providers - infrastructure, can wire everything
   199→    Providers:
   200→      - Models
   201→      - Services
   202→      - Enums
   203→      - Contracts
   204→      - Middleware
   205→      - Support
   206→      - Events
   207→

deptrac:
  paths:
    - ./app
  exclude_files:
    - '#.*test.*#'

  layers:
    # Foundation layers - no upstream dependencies
    - name: Enums
      collectors:
        - type: directory
          value: app/Enums/.*

    - name: ValueObjects
      collectors:
        - type: directory
          value: app/ValueObjects/.*

    - name: Contracts
      collectors:
        - type: directory
          value: app/Contracts/.*

    - name: Exceptions
      collectors:
        - type: directory
          value: app/Exceptions/.*

    - name: Support
      collectors:
        - type: directory
          value: app/Support/.*

    - name: Events
      collectors:
        - type: directory
          value: app/Events/.*

    - name: Concerns
      collectors:
        - type: directory
          value: app/Concerns/.*

    - name: Traits
      collectors:
        - type: directory
          value: app/Traits/.*

    # Domain layer
    - name: Models
      collectors:
        - type: directory
          value: app/Models/.*

    # Business logic layer
    - name: Services
      collectors:
        - type: directory
          value: app/Services/.*

    # Authorization layer
    - name: Policies
      collectors:
        - type: directory
          value: app/Policies/.*

    # Observer layer
    - name: Observers
      collectors:
        - type: directory
          value: app/Observers/.*

    # Background processing layer
    - name: Jobs
      collectors:
        - type: directory
          value: app/Jobs/.*

    # HTTP layer
    - name: Controllers
      collectors:
        - type: directory
          value: app/Http/Controllers/.*

    - name: Middleware
      collectors:
        - type: directory
          value: app/Http/Middleware/.*

    # UI layer
    - name: Livewire
      collectors:
        - type: directory
          value: app/Livewire/.*

    # Actions layer (Fortify etc.)
    - name: Actions
      collectors:
        - type: directory
          value: app/Actions/.*

    # Infrastructure layer
    - name: Providers
      collectors:
        - type: directory
          value: app/Providers/.*

  ruleset:
    # Foundation layers - minimal dependencies
    Enums: ~
    ValueObjects:
      - Enums
    Contracts:
      - Enums
      - ValueObjects
      - Models
    Exceptions:
      - Enums
    Support: ~
    Events:
      - Enums
      - Models
    Concerns:
      - Enums
    Traits: ~

    # Domain layer - depends on foundation
    Models:
      - Enums
      - ValueObjects
      - Concerns
      - Traits
      - Events
      - Exceptions
      - Support

    # Business logic - depends on domain + foundation
    Services:
      - Models
      - Enums
      - ValueObjects
      - Contracts
      - Events
      - Exceptions
      - Support
      - Services

    # Authorization - depends on domain
    Policies:
      - Models
      - Enums

    # Observers - depends on services + domain
    Observers:
      - Models
      - Services
      - Enums

    # Jobs - depends on services + domain
    Jobs:
      - Models
      - Services
      - Enums
      - Events
      - Exceptions

    # HTTP layer - depends on services + domain
    Controllers:
      - Models
      - Services
      - Enums
      - ValueObjects

    Middleware:
      - Models
      - Enums
      - Exceptions

    # UI layer - depends on services + domain
    Livewire:
      - Models
      - Services
      - Enums
      - ValueObjects
      - Exceptions
      - Concerns
      - Traits
      - Events
      - Support

    # Actions - depends on domain
    Actions:
      - Models
      - Enums
      - Exceptions
      - Support

    # Providers - infrastructure, can wire everything
    Providers:
      - Models
      - Services
      - Enums
      - Contracts
      - Middleware
      - Support
      - Events

+    # Foundation layers - no upstream dependencies

+          value: app/Http/Controllers/.*

+          value: app/Http/Middleware/.*

+    # Foundation layers - minimal dependencies

+    # Domain layer - depends on foundation

+    # Business logic - depends on domain + foundation

+    # Authorization - depends on domain

+    # Observers - depends on services + domain

+    # Jobs - depends on services + domain

+    # HTTP layer - depends on services + domain

+    # UI layer - depends on services + domain

+    # Providers - infrastructure, can wire everything

deptrac:
  paths:
    - ./src
  exclude_files:
    - '#.*test.*#'
  layers:
    - name: Controller
      collectors:
        - type: classLike
          value: .*Controller.*
    - name: Repository
      collectors:
        - type: classLike
          value: .*Repository.*
    - name: Service
      collectors:
        - type: classLike
          value: .*Service.*
  ruleset:
    Controller:
      - Service
    Service:
      - Repository
    Repository:


Now let me run Deptrac and see what violations exist.


Bash

vendor/bin/deptrac analyse --no-cache 2>&1

Run Deptrac architectural analysis


Error: Exit code 1
   0/180 [░░░░░░░░░░░░░░░░░░░░░░░░░░░░]   0%
  72/180 [▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░░]  40%
 108/180 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░]  60%
 162/180 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░]  90%
 180/180 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

 -------------------------- --------------------------------------------------------------------------------------------------------
  Reason                     Actions
 -------------------------- --------------------------------------------------------------------------------------------------------
  DependsOnDisallowedLayer   App\Actions\Fortify\CreateNewUser must not depend on App\Concerns\PasswordValidationRules
                             You are depending on token that is a part of a layer that you are not allowed to depend on. (Concerns)
                             /Users/fabianwesner/Herd/shop/app/Actions/Fortify/CreateNewUser.php:13
  DependsOnDisallowedLayer   App\Actions\Fortify\CreateNewUser must not depend on App\Concerns\ProfileValidationRules
                             You are depending on token that is a part of a layer that you are not allowed to depend on. (Concerns)
                             /Users/fabianwesner/Herd/shop/app/Actions/Fortify/CreateNewUser.php:13
  DependsOnDisallowedLayer   App\Actions\Fortify\ResetUserPassword must not depend on App\Concerns\PasswordValidationRules
                             You are depending on token that is a part of a layer that you are not allowed to depend on. (Concerns)
                             /Users/fabianwesner/Herd/shop/app/Actions/Fortify/ResetUserPassword.php:12
 -------------------------- --------------------------------------------------------------------------------------------------------

 -------------------------- ------------------------------------------------------------------------------------------------------
  Reason                     Concerns
 -------------------------- ------------------------------------------------------------------------------------------------------
  DependsOnDisallowedLayer   App\Concerns\ProfileValidationRules must not depend on App\Models\User
                             You are depending on token that is a part of a layer that you are not allowed to depend on. (Models)
                             /Users/fabianwesner/Herd/shop/app/Concerns/ProfileValidationRules.php:46
  DependsOnDisallowedLayer   App\Concerns\ProfileValidationRules must not depend on App\Models\User
                             You are depending on token that is a part of a layer that you are not allowed to depend on. (Models)
                             /Users/fabianwesner/Herd/shop/app/Concerns/ProfileValidationRules.php:47
 -------------------------- ------------------------------------------------------------------------------------------------------

 -------------------------- ------------------------------------------------------------------------------------------------------
  Reason                     Policies
 -------------------------- ------------------------------------------------------------------------------------------------------
  DependsOnDisallowedLayer   App\Policies\CollectionPolicy must not depend on App\Traits\ChecksStoreRole
                             You are depending on token that is a part of a layer that you are not allowed to depend on. (Traits)
                             /Users/fabianwesner/Herd/shop/app/Policies/CollectionPolicy.php:10
  DependsOnDisallowedLayer   App\Policies\CustomerPolicy must not depend on App\Traits\ChecksStoreRole
                             You are depending on token that is a part of a layer that you are not allowed to depend on. (Traits)
                             /Users/fabianwesner/Herd/shop/app/Policies/CustomerPolicy.php:10
  DependsOnDisallowedLayer   App\Policies\DiscountPolicy must not depend on App\Traits\ChecksStoreRole
                             You are depending on token that is a part of a layer that you are not allowed to depend on. (Traits)
                             /Users/fabianwesner/Herd/shop/app/Policies/DiscountPolicy.php:10
  DependsOnDisallowedLayer   App\Policies\FulfillmentPolicy must not depend on App\Traits\ChecksStoreRole

... [6424 characters truncated] ...

ding on token that is a part of a layer that you are not allowed to depend on. (Models)
                             /Users/fabianwesner/Herd/shop/app/Traits/ChecksStoreRole.php:11
  DependsOnDisallowedLayer   App\Traits\ChecksStoreRole must not depend on App\Enums\StoreUserRole
                             You are depending on token that is a part of a layer that you are not allowed to depend on. (Enums)
                             /Users/fabianwesner/Herd/shop/app/Traits/ChecksStoreRole.php:11
  DependsOnDisallowedLayer   App\Traits\ChecksStoreRole must not depend on App\Enums\StoreUserRole
                             You are depending on token that is a part of a layer that you are not allowed to depend on. (Enums)
                             /Users/fabianwesner/Herd/shop/app/Traits/ChecksStoreRole.php:25
  DependsOnDisallowedLayer   App\Traits\ChecksStoreRole must not depend on App\Models\User
                             You are depending on token that is a part of a layer that you are not allowed to depend on. (Models)
                             /Users/fabianwesner/Herd/shop/app/Traits/ChecksStoreRole.php:23
  DependsOnDisallowedLayer   App\Traits\ChecksStoreRole must not depend on App\Enums\StoreUserRole
                             You are depending on token that is a part of a layer that you are not allowed to depend on. (Enums)
                             /Users/fabianwesner/Herd/shop/app/Traits/ChecksStoreRole.php:30
  DependsOnDisallowedLayer   App\Traits\ChecksStoreRole must not depend on App\Enums\StoreUserRole
                             You are depending on token that is a part of a layer that you are not allowed to depend on. (Enums)
                             /Users/fabianwesner/Herd/shop/app/Traits/ChecksStoreRole.php:30
  DependsOnDisallowedLayer   App\Traits\ChecksStoreRole must not depend on App\Models\User
                             You are depending on token that is a part of a layer that you are not allowed to depend on. (Models)
                             /Users/fabianwesner/Herd/shop/app/Traits/ChecksStoreRole.php:28
  DependsOnDisallowedLayer   App\Traits\ChecksStoreRole must not depend on App\Enums\StoreUserRole
                             You are depending on token that is a part of a layer that you are not allowed to depend on. (Enums)
                             /Users/fabianwesner/Herd/shop/app/Traits/ChecksStoreRole.php:36
  DependsOnDisallowedLayer   App\Traits\ChecksStoreRole must not depend on App\Enums\StoreUserRole
                             You are depending on token that is a part of a layer that you are not allowed to depend on. (Enums)
                             /Users/fabianwesner/Herd/shop/app/Traits/ChecksStoreRole.php:37
  DependsOnDisallowedLayer   App\Traits\ChecksStoreRole must not depend on App\Enums\StoreUserRole
                             You are depending on token that is a part of a layer that you are not allowed to depend on. (Enums)
                             /Users/fabianwesner/Herd/shop/app/Traits/ChecksStoreRole.php:38
  DependsOnDisallowedLayer   App\Traits\ChecksStoreRole must not depend on App\Models\User
                             You are depending on token that is a part of a layer that you are not allowed to depend on. (Models)
                             /Users/fabianwesner/Herd/shop/app/Traits/ChecksStoreRole.php:33
  DependsOnDisallowedLayer   App\Traits\ChecksStoreRole must not depend on App\Models\User
                             You are depending on token that is a part of a layer that you are not allowed to depend on. (Models)
                             /Users/fabianwesner/Herd/shop/app/Traits/ChecksStoreRole.php:42
 -------------------------- ------------------------------------------------------------------------------------------------------

 -------------------- -----
  Report
 -------------------- -----
  Violations           32
  Skipped violations   0
  Uncovered            656
  Allowed              773
  Warnings             0
  Errors               0
 -------------------- -----


32 violations. These are mostly about the ruleset being too strict for shared traits/concerns. The violations fall into clear categories:

1. **Actions -> Concerns** (3): CreateNewUser uses PasswordValidationRules/ProfileValidationRules
2. **Concerns -> Models** (2): ProfileValidationRules references User model
3. **Policies -> Traits** (8): All policies use ChecksStoreRole trait
4. **Traits -> Models/Enums** (many): ChecksStoreRole uses User model and StoreUserRole enum
5. **Livewire -> Contracts** (1): Checkout/Index uses PaymentProvider contract

The proper fix is to update the ruleset to allow these legitimate architectural dependencies, rather than restructuring the code. These are all valid cross-layer references in a Laravel application.


     1→deptrac:
     2→  paths:
     3→    - ./app
     4→  exclude_files:
     5→    - '#.*test.*#'
     6→
     7→  layers:
     8→    # Foundation layers - no upstream dependencies
     9→    - name: Enums
    10→      collectors:
    11→        - type: directory
    12→          value: app/Enums/.*
    13→
    14→    - name: ValueObjects
    15→      collectors:
    16→        - type: directory
    17→          value: app/ValueObjects/.*
    18→
    19→    - name: Contracts
    20→      collectors:
    21→        - type: directory
    22→          value: app/Contracts/.*
    23→
    24→    - name: Exceptions
    25→      collectors:
    26→        - type: directory
    27→          value: app/Exceptions/.*
    28→
    29→    - name: Support
    30→      collectors:
    31→        - type: directory
    32→          value: app/Support/.*
    33→
    34→    - name: Events
    35→      collectors:
    36→        - type: directory
    37→          value: app/Events/.*
    38→
    39→    - name: Concerns
    40→      collectors:
    41→        - type: directory
    42→          value: app/Concerns/.*
    43→
    44→    - name: Traits
    45→      collectors:
    46→        - type: directory
    47→          value: app/Traits/.*
    48→
    49→    # Domain layer
    50→    - name: Models
    51→      collectors:
    52→        - type: directory
    53→          value: app/Models/.*
    54→
    55→    # Business logic layer
    56→    - name: Services
    57→      collectors:
    58→        - type: directory
    59→          value: app/Services/.*
    60→
    61→    # Authorization layer
    62→    - name: Policies
    63→      collectors:
    64→        - type: directory
    65→          value: app/Policies/.*
    66→
    67→    # Observer layer
    68→    - name: Observers
    69→      collectors:
    70→        - type: directory
    71→          value: app/Observers/.*
    72→
    73→    # Background processing layer
    74→    - name: Jobs
    75→      collectors:
    76→        - type: directory
    77→          value: app/Jobs/.*
    78→
    79→    # HTTP layer
    80→    - name: Controllers
    81→      collectors:
    82→        - type: directory
    83→          value: app/Http/Controllers/.*
    84→
    85→    - name: Middleware
    86→      collectors:
    87→        - type: directory
    88→          value: app/Http/Middleware/.*
    89→
    90→    # UI layer
    91→    - name: Livewire
    92→      collectors:
    93→        - type: directory
    94→          value: app/Livewire/.*
    95→
    96→    # Actions layer (Fortify etc.)
    97→    - name: Actions
    98→      collectors:
    99→        - type: directory
   100→          value: app/Actions/.*
   101→
   102→    # Infrastructure layer
   103→    - name: Providers
   104→      collectors:
   105→        - type: directory
   106→          value: app/Providers/.*
   107→
   108→  ruleset:
   109→    # Foundation layers - minimal dependencies
   110→    Enums: ~
   111→    ValueObjects:
   112→      - Enums
   113→    Contracts:
   114→      - Enums
   115→      - ValueObjects
   116→      - Models
   117→    Exceptions:
   118→      - Enums
   119→    Support: ~
   120→    Events:
   121→      - Enums
   122→      - Models
   123→    Concerns:
   124→      - Enums
   125→    Traits: ~
   126→
   127→    # Domain layer - depends on foundation
   128→    Models:
   129→      - Enums
   130→      - ValueObjects
   131→      - Concerns
   132→      - Traits
   133→      - Events
   134→      - Exceptions
   135→      - Support
   136→
   137→    # Business logic - depends on domain + foundation
   138→    Services:
   139→      - Models
   140→      - Enums
   141→      - ValueObjects
   142→      - Contracts
   143→      - Events
   144→      - Exceptions
   145→      - Support
   146→      - Services
   147→
   148→    # Authorization - depends on domain
   149→    Policies:
   150→      - Models
   151→      - Enums
   152→
   153→    # Observers - depends on services + domain
   154→    Observers:
   155→      - Models
   156→      - Services
   157→      - Enums
   158→
   159→    # Jobs - depends on services + domain
   160→    Jobs:
   161→      - Models
   162→      - Services
   163→      - Enums
   164→      - Events
   165→      - Exceptions
   166→
   167→    # HTTP layer - depends on services + domain
   168→    Controllers:
   169→      - Models
   170→      - Services
   171→      - Enums
   172→      - ValueObjects
   173→
   174→    Middleware:
   175→      - Models
   176→      - Enums
   177→      - Exceptions
   178→
   179→    # UI layer - depends on services + domain
   180→    Livewire:
   181→      - Models
   182→      - Services
   183→      - Enums
   184→      - ValueObjects
   185→      - Exceptions
   186→      - Concerns
   187→      - Traits
   188→      - Events
   189→      - Support
   190→
   191→    # Actions - depends on domain
   192→    Actions:
   193→      - Models
   194→      - Enums
   195→      - Exceptions
   196→      - Support
   197→
   198→    # Providers - infrastructure, can wire everything
   199→    Providers:
   200→      - Models
   201→      - Services
   202→      - Enums
   203→      - Contracts
   204→      - Middleware
   205→      - Support
   206→      - Events
   207→


Now I need to fix the ruleset. The violations are all legitimate architectural patterns:

- **Traits/Concerns** are mixins - they naturally reference Models/Enums since they're composed into those layers
- **Policies** use the ChecksStoreRole trait
- **Actions** use Concerns (validation rules)
- **Livewire** needs Contracts (PaymentProvider)


Edit

    Concerns:
      - Enums
    Traits: ~

    Concerns:
      - Enums
      - Models
    Traits:
      - Models
      - Enums


The file /Users/fabianwesner/Herd/shop/deptrac.yaml has been updated successfully.

    Concerns:
      - Enums
    Traits: ~

    Concerns:
      - Enums
      - Models
    Traits:
      - Models
      - Enums

deptrac:
  paths:
    - ./app
  exclude_files:
    - '#.*test.*#'

  layers:
    # Foundation layers - no upstream dependencies
    - name: Enums
      collectors:
        - type: directory
          value: app/Enums/.*

    - name: ValueObjects
      collectors:
        - type: directory
          value: app/ValueObjects/.*

    - name: Contracts
      collectors:
        - type: directory
          value: app/Contracts/.*

    - name: Exceptions
      collectors:
        - type: directory
          value: app/Exceptions/.*

    - name: Support
      collectors:
        - type: directory
          value: app/Support/.*

    - name: Events
      collectors:
        - type: directory
          value: app/Events/.*

    - name: Concerns
      collectors:
        - type: directory
          value: app/Concerns/.*

    - name: Traits
      collectors:
        - type: directory
          value: app/Traits/.*

    # Domain layer
    - name: Models
      collectors:
        - type: directory
          value: app/Models/.*

    # Business logic layer
    - name: Services
      collectors:
        - type: directory
          value: app/Services/.*

    # Authorization layer
    - name: Policies
      collectors:
        - type: directory
          value: app/Policies/.*

    # Observer layer
    - name: Observers
      collectors:
        - type: directory
          value: app/Observers/.*

    # Background processing layer
    - name: Jobs
      collectors:
        - type: directory
          value: app/Jobs/.*

    # HTTP layer
    - name: Controllers
      collectors:
        - type: directory
          value: app/Http/Controllers/.*

    - name: Middleware
      collectors:
        - type: directory
          value: app/Http/Middleware/.*

    # UI layer
    - name: Livewire
      collectors:
        - type: directory
          value: app/Livewire/.*

    # Actions layer (Fortify etc.)
    - name: Actions
      collectors:
        - type: directory
          value: app/Actions/.*

    # Infrastructure layer
    - name: Providers
      collectors:
        - type: directory
          value: app/Providers/.*

  ruleset:
    # Foundation layers - minimal dependencies
    Enums: ~
    ValueObjects:
      - Enums
    Contracts:
      - Enums
      - ValueObjects
      - Models
    Exceptions:
      - Enums
    Support: ~
    Events:
      - Enums
      - Models
    Concerns:
      - Enums
    Traits: ~

    # Domain layer - depends on foundation
    Models:
      - Enums
      - ValueObjects
      - Concerns
      - Traits
      - Events
      - Exceptions
      - Support

    # Business logic - depends on domain + foundation
    Services:
      - Models
      - Enums
      - ValueObjects
      - Contracts
      - Events
      - Exceptions
      - Support
      - Services

    # Authorization - depends on domain
    Policies:
      - Models
      - Enums

    # Observers - depends on services + domain
    Observers:
      - Models
      - Services
      - Enums

    # Jobs - depends on services + domain
    Jobs:
      - Models
      - Services
      - Enums
      - Events
      - Exceptions

    # HTTP layer - depends on services + domain
    Controllers:
      - Models
      - Services
      - Enums
      - ValueObjects

    Middleware:
      - Models
      - Enums
      - Exceptions

    # UI layer - depends on services + domain
    Livewire:
      - Models
      - Services
      - Enums
      - ValueObjects
      - Exceptions
      - Concerns
      - Traits
      - Events
      - Support

    # Actions - depends on domain
    Actions:
      - Models
      - Enums
      - Exceptions
      - Support

    # Providers - infrastructure, can wire everything
    Providers:
      - Models
      - Services
      - Enums
      - Contracts
      - Middleware
      - Support
      - Events


    # Authorization - depends on domain
    Policies:
      - Models
      - Enums

    # Authorization - depends on domain
    Policies:
      - Models
      - Enums
      - Traits


    # Authorization - depends on domain
    Policies:
      - Models
      - Enums
      - Traits

deptrac:
  paths:
    - ./app
  exclude_files:
    - '#.*test.*#'

  layers:
    # Foundation layers - no upstream dependencies
    - name: Enums
      collectors:
        - type: directory
          value: app/Enums/.*

    - name: ValueObjects
      collectors:
        - type: directory
          value: app/ValueObjects/.*

    - name: Contracts
      collectors:
        - type: directory
          value: app/Contracts/.*

    - name: Exceptions
      collectors:
        - type: directory
          value: app/Exceptions/.*

    - name: Support
      collectors:
        - type: directory
          value: app/Support/.*

    - name: Events
      collectors:
        - type: directory
          value: app/Events/.*

    - name: Concerns
      collectors:
        - type: directory
          value: app/Concerns/.*

    - name: Traits
      collectors:
        - type: directory
          value: app/Traits/.*

    # Domain layer
    - name: Models
      collectors:
        - type: directory
          value: app/Models/.*

    # Business logic layer
    - name: Services
      collectors:
        - type: directory
          value: app/Services/.*

    # Authorization layer
    - name: Policies
      collectors:
        - type: directory
          value: app/Policies/.*

    # Observer layer
    - name: Observers
      collectors:
        - type: directory
          value: app/Observers/.*

    # Background processing layer
    - name: Jobs
      collectors:
        - type: directory
          value: app/Jobs/.*

    # HTTP layer
    - name: Controllers
      collectors:
        - type: directory
          value: app/Http/Controllers/.*

    - name: Middleware
      collectors:
        - type: directory
          value: app/Http/Middleware/.*

    # UI layer
    - name: Livewire
      collectors:
        - type: directory
          value: app/Livewire/.*

    # Actions layer (Fortify etc.)
    - name: Actions
      collectors:
        - type: directory
          value: app/Actions/.*

    # Infrastructure layer
    - name: Providers
      collectors:
        - type: directory
          value: app/Providers/.*

  ruleset:
    # Foundation layers - minimal dependencies
    Enums: ~
    ValueObjects:
      - Enums
    Contracts:
      - Enums
      - ValueObjects
      - Models
    Exceptions:
      - Enums
    Support: ~
    Events:
      - Enums
      - Models
    Concerns:
      - Enums
      - Models
    Traits:
      - Models
      - Enums

    # Domain layer - depends on foundation
    Models:
      - Enums
      - ValueObjects
      - Concerns
      - Traits
      - Events
      - Exceptions
      - Support

    # Business logic - depends on domain + foundation
    Services:
      - Models
      - Enums
      - ValueObjects
      - Contracts
      - Events
      - Exceptions
      - Support
      - Services

    # Authorization - depends on domain
    Policies:
      - Models
      - Enums

    # Observers - depends on services + domain
    Observers:
      - Models
      - Services
      - Enums

    # Jobs - depends on services + domain
    Jobs:
      - Models
      - Services
      - Enums
      - Events
      - Exceptions

    # HTTP layer - depends on services + domain
    Controllers:
      - Models
      - Services
      - Enums
      - ValueObjects

    Middleware:
      - Models
      - Enums
      - Exceptions

    # UI layer - depends on services + domain
    Livewire:
      - Models
      - Services
      - Enums
      - ValueObjects
      - Exceptions
      - Concerns
      - Traits
      - Events
      - Support

    # Actions - depends on domain
    Actions:
      - Models
      - Enums
      - Exceptions
      - Support

    # Providers - infrastructure, can wire everything
    Providers:
      - Models
      - Services
      - Enums
      - Contracts
      - Middleware
      - Support
      - Events


    # Actions - depends on domain
    Actions:
      - Models
      - Enums
      - Exceptions
      - Support

    # Actions - depends on domain
    Actions:
      - Models
      - Enums
      - Exceptions
      - Support
      - Concerns


    # Actions - depends on domain
    Actions:
      - Models
      - Enums
      - Exceptions
      - Support
      - Concerns

deptrac:
  paths:
    - ./app
  exclude_files:
    - '#.*test.*#'

  layers:
    # Foundation layers - no upstream dependencies
    - name: Enums
      collectors:
        - type: directory
          value: app/Enums/.*

    - name: ValueObjects
      collectors:
        - type: directory
          value: app/ValueObjects/.*

    - name: Contracts
      collectors:
        - type: directory
          value: app/Contracts/.*

    - name: Exceptions
      collectors:
        - type: directory
          value: app/Exceptions/.*

    - name: Support
      collectors:
        - type: directory
          value: app/Support/.*

    - name: Events
      collectors:
        - type: directory
          value: app/Events/.*

    - name: Concerns
      collectors:
        - type: directory
          value: app/Concerns/.*

    - name: Traits
      collectors:
        - type: directory
          value: app/Traits/.*

    # Domain layer
    - name: Models
      collectors:
        - type: directory
          value: app/Models/.*

    # Business logic layer
    - name: Services
      collectors:
        - type: directory
          value: app/Services/.*

    # Authorization layer
    - name: Policies
      collectors:
        - type: directory
          value: app/Policies/.*

    # Observer layer
    - name: Observers
      collectors:
        - type: directory
          value: app/Observers/.*

    # Background processing layer
    - name: Jobs
      collectors:
        - type: directory
          value: app/Jobs/.*

    # HTTP layer
    - name: Controllers
      collectors:
        - type: directory
          value: app/Http/Controllers/.*

    - name: Middleware
      collectors:
        - type: directory
          value: app/Http/Middleware/.*

    # UI layer
    - name: Livewire
      collectors:
        - type: directory
          value: app/Livewire/.*

    # Actions layer (Fortify etc.)
    - name: Actions
      collectors:
        - type: directory
          value: app/Actions/.*

    # Infrastructure layer
    - name: Providers
      collectors:
        - type: directory
          value: app/Providers/.*

  ruleset:
    # Foundation layers - minimal dependencies
    Enums: ~
    ValueObjects:
      - Enums
    Contracts:
      - Enums
      - ValueObjects
      - Models
    Exceptions:
      - Enums
    Support: ~
    Events:
      - Enums
      - Models
    Concerns:
      - Enums
      - Models
    Traits:
      - Models
      - Enums

    # Domain layer - depends on foundation
    Models:
      - Enums
      - ValueObjects
      - Concerns
      - Traits
      - Events
      - Exceptions
      - Support

    # Business logic - depends on domain + foundation
    Services:
      - Models
      - Enums
      - ValueObjects
      - Contracts
      - Events
      - Exceptions
      - Support
      - Services

    # Authorization - depends on domain
    Policies:
      - Models
      - Enums
      - Traits

    # Observers - depends on services + domain
    Observers:
      - Models
      - Services
      - Enums

    # Jobs - depends on services + domain
    Jobs:
      - Models
      - Services
      - Enums
      - Events
      - Exceptions

    # HTTP layer - depends on services + domain
    Controllers:
      - Models
      - Services
      - Enums
      - ValueObjects

    Middleware:
      - Models
      - Enums
      - Exceptions

    # UI layer - depends on services + domain
    Livewire:
      - Models
      - Services
      - Enums
      - ValueObjects
      - Exceptions
      - Concerns
      - Traits
      - Events
      - Support

    # Actions - depends on domain
    Actions:
      - Models
      - Enums
      - Exceptions
      - Support

    # Providers - infrastructure, can wire everything
    Providers:
      - Models
      - Services
      - Enums
      - Contracts
      - Middleware
      - Support
      - Events


    # UI layer - depends on services + domain
    Livewire:
      - Models
      - Services
      - Enums
      - ValueObjects
      - Exceptions
      - Concerns
      - Traits
      - Events
      - Support

    # UI layer - depends on services + domain
    Livewire:
      - Models
      - Services
      - Enums
      - ValueObjects
      - Contracts
      - Exceptions
      - Concerns
      - Traits
      - Events
      - Support


    # UI layer - depends on services + domain
    Livewire:
      - Models
      - Services
      - Enums
      - ValueObjects
      - Contracts
      - Exceptions
      - Concerns
      - Traits
      - Events
      - Support

deptrac:
  paths:
    - ./app
  exclude_files:
    - '#.*test.*#'

  layers:
    # Foundation layers - no upstream dependencies
    - name: Enums
      collectors:
        - type: directory
          value: app/Enums/.*

    - name: ValueObjects
      collectors:
        - type: directory
          value: app/ValueObjects/.*

    - name: Contracts
      collectors:
        - type: directory
          value: app/Contracts/.*

    - name: Exceptions
      collectors:
        - type: directory
          value: app/Exceptions/.*

    - name: Support
      collectors:
        - type: directory
          value: app/Support/.*

    - name: Events
      collectors:
        - type: directory
          value: app/Events/.*

    - name: Concerns
      collectors:
        - type: directory
          value: app/Concerns/.*

    - name: Traits
      collectors:
        - type: directory
          value: app/Traits/.*

    # Domain layer
    - name: Models
      collectors:
        - type: directory
          value: app/Models/.*

    # Business logic layer
    - name: Services
      collectors:
        - type: directory
          value: app/Services/.*

    # Authorization layer
    - name: Policies
      collectors:
        - type: directory
          value: app/Policies/.*

    # Observer layer
    - name: Observers
      collectors:
        - type: directory
          value: app/Observers/.*

    # Background processing layer
    - name: Jobs
      collectors:
        - type: directory
          value: app/Jobs/.*

    # HTTP layer
    - name: Controllers
      collectors:
        - type: directory
          value: app/Http/Controllers/.*

    - name: Middleware
      collectors:
        - type: directory
          value: app/Http/Middleware/.*

    # UI layer
    - name: Livewire
      collectors:
        - type: directory
          value: app/Livewire/.*

    # Actions layer (Fortify etc.)
    - name: Actions
      collectors:
        - type: directory
          value: app/Actions/.*

    # Infrastructure layer
    - name: Providers
      collectors:
        - type: directory
          value: app/Providers/.*

  ruleset:
    # Foundation layers - minimal dependencies
    Enums: ~
    ValueObjects:
      - Enums
    Contracts:
      - Enums
      - ValueObjects
      - Models
    Exceptions:
      - Enums
    Support: ~
    Events:
      - Enums
      - Models
    Concerns:
      - Enums
      - Models
    Traits:
      - Models
      - Enums

    # Domain layer - depends on foundation
    Models:
      - Enums
      - ValueObjects
      - Concerns
      - Traits
      - Events
      - Exceptions
      - Support

    # Business logic - depends on domain + foundation
    Services:
      - Models
      - Enums
      - ValueObjects
      - Contracts
      - Events
      - Exceptions
      - Support
      - Services

    # Authorization - depends on domain
    Policies:
      - Models
      - Enums
      - Traits

    # Observers - depends on services + domain
    Observers:
      - Models
      - Services
      - Enums

    # Jobs - depends on services + domain
    Jobs:
      - Models
      - Services
      - Enums
      - Events
      - Exceptions

    # HTTP layer - depends on services + domain
    Controllers:
      - Models
      - Services
      - Enums
      - ValueObjects

    Middleware:
      - Models
      - Enums
      - Exceptions

    # UI layer - depends on services + domain
    Livewire:
      - Models
      - Services
      - Enums
      - ValueObjects
      - Exceptions
      - Concerns
      - Traits
      - Events
      - Support

    # Actions - depends on domain
    Actions:
      - Models
      - Enums
      - Exceptions
      - Support
      - Concerns

    # Providers - infrastructure, can wire everything
    Providers:
      - Models
      - Services
      - Enums
      - Contracts
      - Middleware
      - Support
      - Events

- Services
- Enums
- ValueObjects
+      - Contracts
- Exceptions
- Concerns
- Traits


Now let me run Deptrac again.


Bash

vendor/bin/deptrac analyse --no-cache 2>&1

Run Deptrac analysis after ruleset fixes


Error: Exit code 1
   0/180 [░░░░░░░░░░░░░░░░░░░░░░░░░░░░]   0%
  72/180 [▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░░]  40%
 108/180 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░]  60%
 162/180 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░]  90%
 180/180 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

 -------------------------- ---------------------------------------------------------------------------------------------------------
  Reason                     Providers
 -------------------------- ---------------------------------------------------------------------------------------------------------
  DependsOnDisallowedLayer   App\Providers\AppServiceProvider must not depend on App\Observers\ProductObserver
                             You are depending on token that is a part of a layer that you are not allowed to depend on. (Observers)
                             /Users/fabianwesner/Herd/shop/app/Providers/AppServiceProvider.php:46
  DependsOnDisallowedLayer   App\Providers\FortifyServiceProvider must not depend on App\Actions\Fortify\ResetUserPassword
                             You are depending on token that is a part of a layer that you are not allowed to depend on. (Actions)
                             /Users/fabianwesner/Herd/shop/app/Providers/FortifyServiceProvider.php:39
  DependsOnDisallowedLayer   App\Providers\FortifyServiceProvider must not depend on App\Actions\Fortify\CreateNewUser
                             You are depending on token that is a part of a layer that you are not allowed to depend on. (Actions)
                             /Users/fabianwesner/Herd/shop/app/Providers/FortifyServiceProvider.php:40
 -------------------------- ---------------------------------------------------------------------------------------------------------

 -------------------------- ----------------------------------------------------------------------------------------------------
  Reason                     Services
 -------------------------- ----------------------------------------------------------------------------------------------------
  DependsOnDisallowedLayer   App\Services\WebhookService must not depend on App\Jobs\DeliverWebhook
                             You are depending on token that is a part of a layer that you are not allowed to depend on. (Jobs)
                             /Users/fabianwesner/Herd/shop/app/Services/WebhookService.php:31
 -------------------------- ----------------------------------------------------------------------------------------------------

 -------------------- -----
  Report
 -------------------- -----
  Violations           4
  Skipped violations   0
  Uncovered            656
  Allowed              801
  Warnings             0
  Errors               0
 -------------------- -----


Down to 4 violations. Let me fix these:

1. **Providers -> Observers/Actions**: Providers need to wire observers and actions - this is their job as infrastructure
2. **Services -> Jobs**: WebhookService dispatches DeliverWebhook job - this is a legitimate pattern, but architecturally we should fix it

Let me first fix the Providers ruleset (legitimate wiring), then address the Services -> Jobs violation.


Edit

    # Providers - infrastructure, can wire everything
    Providers:
      - Models
      - Services
      - Enums
      - Contracts
      - Middleware
      - Support
      - Events

    # Providers - infrastructure, can wire everything
    Providers:
      - Models
      - Services
      - Enums
      - Contracts
      - Middleware
      - Observers
      - Actions
      - Support
      - Events


    # Providers - infrastructure, can wire everything
    Providers:
      - Models
      - Services
      - Enums
      - Contracts
      - Middleware
      - Observers
      - Actions
      - Support
      - Events

deptrac:
  paths:
    - ./app
  exclude_files:
    - '#.*test.*#'

  layers:
    # Foundation layers - no upstream dependencies
    - name: Enums
      collectors:
        - type: directory
          value: app/Enums/.*

    - name: ValueObjects
      collectors:
        - type: directory
          value: app/ValueObjects/.*

    - name: Contracts
      collectors:
        - type: directory
          value: app/Contracts/.*

    - name: Exceptions
      collectors:
        - type: directory
          value: app/Exceptions/.*

    - name: Support
      collectors:
        - type: directory
          value: app/Support/.*

    - name: Events
      collectors:
        - type: directory
          value: app/Events/.*

    - name: Concerns
      collectors:
        - type: directory
          value: app/Concerns/.*

    - name: Traits
      collectors:
        - type: directory
          value: app/Traits/.*

    # Domain layer
    - name: Models
      collectors:
        - type: directory
          value: app/Models/.*

    # Business logic layer
    - name: Services
      collectors:
        - type: directory
          value: app/Services/.*

    # Authorization layer
    - name: Policies
      collectors:
        - type: directory
          value: app/Policies/.*

    # Observer layer
    - name: Observers
      collectors:
        - type: directory
          value: app/Observers/.*

    # Background processing layer
    - name: Jobs
      collectors:
        - type: directory
          value: app/Jobs/.*

    # HTTP layer
    - name: Controllers
      collectors:
        - type: directory
          value: app/Http/Controllers/.*

    - name: Middleware
      collectors:
        - type: directory
          value: app/Http/Middleware/.*

    # UI layer
    - name: Livewire
      collectors:
        - type: directory
          value: app/Livewire/.*

    # Actions layer (Fortify etc.)
    - name: Actions
      collectors:
        - type: directory
          value: app/Actions/.*

    # Infrastructure layer
    - name: Providers
      collectors:
        - type: directory
          value: app/Providers/.*

  ruleset:
    # Foundation layers - minimal dependencies
    Enums: ~
    ValueObjects:
      - Enums
    Contracts:
      - Enums
      - ValueObjects
      - Models
    Exceptions:
      - Enums
    Support: ~
    Events:
      - Enums
      - Models
    Concerns:
      - Enums
      - Models
    Traits:
      - Models
      - Enums

    # Domain layer - depends on foundation
    Models:
      - Enums
      - ValueObjects
      - Concerns
      - Traits
      - Events
      - Exceptions
      - Support

    # Business logic - depends on domain + foundation
    Services:
      - Models
      - Enums
      - ValueObjects
      - Contracts
      - Events
      - Exceptions
      - Support
      - Services

    # Authorization - depends on domain
    Policies:
      - Models
      - Enums
      - Traits

    # Observers - depends on services + domain
    Observers:
      - Models
      - Services
      - Enums

    # Jobs - depends on services + domain
    Jobs:
      - Models
      - Services
      - Enums
      - Events
      - Exceptions

    # HTTP layer - depends on services + domain
    Controllers:
      - Models
      - Services
      - Enums
      - ValueObjects

    Middleware:
      - Models
      - Enums
      - Exceptions

    # UI layer - depends on services + domain
    Livewire:
      - Models
      - Services
      - Enums
      - ValueObjects
      - Contracts
      - Exceptions
      - Concerns
      - Traits
      - Events
      - Support

    # Actions - depends on domain
    Actions:
      - Models
      - Enums
      - Exceptions
      - Support
      - Concerns

    # Providers - infrastructure, can wire everything
    Providers:
      - Models
      - Services
      - Enums
      - Contracts
      - Middleware
      - Support
      - Events

- Enums
- Contracts
- Middleware
+      - Observers
+      - Actions
- Support
- Events


Now for the Services -> Jobs violation, let me look at how WebhookService dispatches the job.


     1→<?php
     2→
     3→namespace App\Services;
     4→
     5→use App\Jobs\DeliverWebhook;
     6→use App\Models\Store;
     7→use App\Models\WebhookDelivery;
     8→use App\Models\WebhookSubscription;
     9→
    10→class WebhookService
    11→{
    12→    /**
    13→     * @param  array<string, mixed>  $payload
    14→     */
    15→    public function dispatch(Store $store, string $eventType, array $payload): void
    16→    {
    17→        $subscriptions = WebhookSubscription::withoutGlobalScopes()
    18→            ->where('store_id', $store->id)
    19→            ->where('event_type', $eventType)
    20→            ->where('status', 'active')
    21→            ->get();
    22→
    23→        foreach ($subscriptions as $subscription) {
    24→            $delivery = WebhookDelivery::create([
    25→                'subscription_id' => $subscription->id,
    26→                'event_type' => $eventType,
    27→                'payload_json' => $payload,
    28→                'status' => 'pending',
    29→            ]);
    30→
    31→            DeliverWebhook::dispatch($delivery);
    32→        }
    33→    }
    34→
    35→    public function sign(string $payload, string $secret): string
    36→    {
    37→        return hash_hmac('sha256', $payload, $secret);
    38→    }
    39→
    40→    public function verify(string $payload, string $signature, string $secret): bool
    41→    {
    42→        return hash_equals($this->sign($payload, $secret), $signature);
    43→    }
    44→}
    45→

<?php

namespace App\Services;

use App\Jobs\DeliverWebhook;
use App\Models\Store;
use App\Models\WebhookDelivery;
use App\Models\WebhookSubscription;

class WebhookService
{
    /**
     * @param  array<string, mixed>  $payload
     */
    public function dispatch(Store $store, string $eventType, array $payload): void
    {
        $subscriptions = WebhookSubscription::withoutGlobalScopes()
            ->where('store_id', $store->id)
            ->where('event_type', $eventType)
            ->where('status', 'active')
            ->get();

        foreach ($subscriptions as $subscription) {
            $delivery = WebhookDelivery::create([
                'subscription_id' => $subscription->id,
                'event_type' => $eventType,
                'payload_json' => $payload,
                'status' => 'pending',
            ]);

            DeliverWebhook::dispatch($delivery);
        }
    }

    public function sign(string $payload, string $secret): string
    {
        return hash_hmac('sha256', $payload, $secret);
    }

    public function verify(string $payload, string $signature, string $secret): bool
    {
        return hash_equals($this->sign($payload, $secret), $signature);
    }
}


The WebhookService dispatches a Job. In strict layered architecture, Services shouldn't depend on Jobs (Jobs should depend on Services, not the other way around). There are two options:

1. Allow Services -> Jobs in the ruleset (pragmatic)
2. Refactor to use an event/listener pattern instead

The pragmatic approach for a Laravel app is to allow Services to dispatch Jobs - this is very common in Laravel. Job dispatching from a Service is a standard pattern. Let me just add Jobs to the Services allowed list.

Actually, wait - the issue is that this creates a potential circular dependency path: Services -> Jobs -> Services. But Deptrac checks direct layer dependencies, and we already have Jobs -> Services allowed.

I'm going to allow the bidirectional dependency here. While it's not strictly layered, dispatching a job from a service is idiomatic Laravel and won't create actual circular dependencies in practice since we're just triggering the job, not importing its logic. I'll add Jobs to the Services ruleset.


In Laravel, dispatching jobs from services is standard practice. The job is just a dispatch wrapper - no circular logic. Let me allow this.


    # Business logic - depends on domain + foundation
    Services:
      - Models
      - Enums
      - ValueObjects
      - Contracts
      - Events
      - Exceptions
      - Support
      - Services

    # Business logic - depends on domain + foundation
    Services:
      - Models
      - Enums
      - ValueObjects
      - Contracts
      - Events
      - Exceptions
      - Support
      - Jobs
      - Services


    # Business logic - depends on domain + foundation
    Services:
      - Models
      - Enums
      - ValueObjects
      - Contracts
      - Events
      - Exceptions
      - Support
      - Jobs
      - Services

deptrac:
  paths:
    - ./app
  exclude_files:
    - '#.*test.*#'

  layers:
    # Foundation layers - no upstream dependencies
    - name: Enums
      collectors:
        - type: directory
          value: app/Enums/.*

    - name: ValueObjects
      collectors:
        - type: directory
          value: app/ValueObjects/.*

    - name: Contracts
      collectors:
        - type: directory
          value: app/Contracts/.*

    - name: Exceptions
      collectors:
        - type: directory
          value: app/Exceptions/.*

    - name: Support
      collectors:
        - type: directory
          value: app/Support/.*

    - name: Events
      collectors:
        - type: directory
          value: app/Events/.*

    - name: Concerns
      collectors:
        - type: directory
          value: app/Concerns/.*

    - name: Traits
      collectors:
        - type: directory
          value: app/Traits/.*

    # Domain layer
    - name: Models
      collectors:
        - type: directory
          value: app/Models/.*

    # Business logic layer
    - name: Services
      collectors:
        - type: directory
          value: app/Services/.*

    # Authorization layer
    - name: Policies
      collectors:
        - type: directory
          value: app/Policies/.*

    # Observer layer
    - name: Observers
      collectors:
        - type: directory
          value: app/Observers/.*

    # Background processing layer
    - name: Jobs
      collectors:
        - type: directory
          value: app/Jobs/.*

    # HTTP layer
    - name: Controllers
      collectors:
        - type: directory
          value: app/Http/Controllers/.*

    - name: Middleware
      collectors:
        - type: directory
          value: app/Http/Middleware/.*

    # UI layer
    - name: Livewire
      collectors:
        - type: directory
          value: app/Livewire/.*

    # Actions layer (Fortify etc.)
    - name: Actions
      collectors:
        - type: directory
          value: app/Actions/.*

    # Infrastructure layer
    - name: Providers
      collectors:
        - type: directory
          value: app/Providers/.*

  ruleset:
    # Foundation layers - minimal dependencies
    Enums: ~
    ValueObjects:
      - Enums
    Contracts:
      - Enums
      - ValueObjects
      - Models
    Exceptions:
      - Enums
    Support: ~
    Events:
      - Enums
      - Models
    Concerns:
      - Enums
      - Models
    Traits:
      - Models
      - Enums

    # Domain layer - depends on foundation
    Models:
      - Enums
      - ValueObjects
      - Concerns
      - Traits
      - Events
      - Exceptions
      - Support

    # Business logic - depends on domain + foundation
    Services:
      - Models
      - Enums
      - ValueObjects
      - Contracts
      - Events
      - Exceptions
      - Support
      - Services

    # Authorization - depends on domain
    Policies:
      - Models
      - Enums
      - Traits

    # Observers - depends on services + domain
    Observers:
      - Models
      - Services
      - Enums

    # Jobs - depends on services + domain
    Jobs:
      - Models
      - Services
      - Enums
      - Events
      - Exceptions

    # HTTP layer - depends on services + domain
    Controllers:
      - Models
      - Services
      - Enums
      - ValueObjects

    Middleware:
      - Models
      - Enums
      - Exceptions

    # UI layer - depends on services + domain
    Livewire:
      - Models
      - Services
      - Enums
      - ValueObjects
      - Contracts
      - Exceptions
      - Concerns
      - Traits
      - Events
      - Support

    # Actions - depends on domain
    Actions:
      - Models
      - Enums
      - Exceptions
      - Support
      - Concerns

    # Providers - infrastructure, can wire everything
    Providers:
      - Models
      - Services
      - Enums
      - Contracts
      - Middleware
      - Observers
      - Actions
      - Support
      - Events


Bash

vendor/bin/deptrac analyse --no-cache 2>&1

Run Deptrac analysis - expect 0 violations


   0/180 [░░░░░░░░░░░░░░░░░░░░░░░░░░░░]   0%
  72/180 [▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░░]  40%
 108/180 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░]  60%
 162/180 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░]  90%
 180/180 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

 -------------------- -----
  Report
 -------------------- -----
  Violations           0
  Skipped violations   0
  Uncovered            656
  Allowed              805
  Warnings             0
  Errors               0
 -------------------- -----


**0 violations!** Now let me address the 656 uncovered tokens. These are classes that Deptrac found but couldn't assign to any layer. Let me check what they are.


vendor/bin/deptrac debug:unassigned --no-cache 2>&1 | head -60

List unassigned tokens


There are no unassigned tokens.


Good - no unassigned tokens. The 656 "uncovered" are dependencies on external/framework classes (Laravel, PHP built-ins, etc.) which Deptrac correctly doesn't try to layer. Let me verify tests still pass and then commit.


Run full test suite


Output:
  ✓ it lists orders with status filter                                   0.02s
  ✓ it shows order detail page                                           0.03s
  ✓ it creates a fulfillment from order detail                           0.08s
  ✓ it processes a refund from order detail                              0.08s
  ✓ it restricts order management by role                                0.01s

   PASS  Tests\Unit\CartVersionTest
  ✓ it starts at version 1                                               0.23s
  ✓ it increments version on add line                                    0.01s
  ✓ it increments version on update quantity                             0.01s
  ✓ it increments version on remove line                                 0.01s
  ✓ it detects version mismatch                                          0.01s
   PASS  Tests\Unit\DiscountCalculatorTest
  ✓ it validates an active discount code                                 0.02s
  ✓ it rejects an expired discount code                                  0.01s
  ✓ it rejects a not-yet-active discount code                            0.02s
  ✓ it rejects a discount that has reached its usage limit               0.01s
  ✓ it rejects an unknown discount code                                  0.01s
  ✓ it performs case-insensitive code lookup                             0.01s
  ✓ it enforces minimum purchase amount rule                             0.01s
  ✓ it passes minimum purchase when cart meets threshold                 0.01s
  ✓ it calculates percent discount amount                                0.01s
  ✓ it calculates fixed discount amount                                  0.01s
  ✓ it handles free shipping discount type                               0.01s
  ✓ it allocates discount proportionally across multiple lines           0.01s
  ✓ it distributes rounding remainder to the last qualifying line        0.01s
   PASS  Tests\Unit\ExampleTest
  ✓ that true is true
   PASS  Tests\Unit\HandleGeneratorTest
  ✓ it generates a slug from title                                       0.01s
  ✓ it appends suffix on collision                                       0.01s
  ✓ it increments suffix on multiple collisions                          0.01s
  ✓ it handles special characters                                        0.01s
  ✓ it excludes current record when updating                             0.01s
  ✓ it scopes handle uniqueness to store                                 0.01s
   PASS  Tests\Unit\PricingEngineTest
  ✓ it calculates subtotal from line items                               0.01s
  ✓ it calculates subtotal for a single line                             0.01s
  ✓ it returns zero subtotal for empty cart                              0.01s
  ✓ it applies percent discount correctly                                0.01s
  ✓ it applies fixed discount correctly                                  0.01s
  ✓ it caps fixed discount at subtotal so it never goes negative         0.01s
  ✓ it applies free shipping discount by zeroing shipping                0.02s
  ✓ it calculates tax exclusive correctly                                0.01s
  ✓ it extracts tax from inclusive price correctly                       0.01s
  ✓ it returns zero tax when rate is zero                                0.01s
  ✓ it calculates shipping flat rate                                     0.01s
  ✓ it calculates full checkout totals end to end                        0.01s
  ✓ it handles rounding correctly with odd cent amounts                  0.01s
  ✓ it produces identical results for identical inputs                   0.02s
   PASS  Tests\Unit\ShippingCalculatorTest
  ✓ it matches a zone by country code                                    0.02s
  ✓ it matches a zone by region code                                     0.01s
  ✓ it returns empty when no zone matches                                0.01s
  ✓ it calculates a flat rate                                            0.01s
  ✓ it calculates a weight-based rate                                    0.01s
  ✓ it calculates a price-based rate                                     0.01s
  ✓ it returns zero shipping when no items require shipping              0.01s
  ✓ it returns correct rates when multiple zones match                   0.01s
  ✓ it skips inactive rates                                              0.01s
   PASS  Tests\Unit\TaxCalculatorTest
  ✓ it calculates manual tax exclusive
  ✓ it extracts manual tax from inclusive amount
  ✓ it returns zero tax when no rate configured
  ✓ it handles zero amount lines
  ✓ it calculates tax with non-standard rate
  ✓ it extracts tax correctly for small amounts
  ✓ it handles high tax rates
   PASS  Tests\Feature\Admin\DashboardTest
  ✓ it renders the admin dashboard                                       0.05s
  ✓ it shows KPI tiles with correct data                                 0.02s
  ✓ it restricts dashboard to authenticated admins                       0.02s
  ✓ it filters metrics by date range                                     0.04s
   PASS  Tests\Feature\Admin\DiscountManagementTest
  ✓ it lists discounts                                                   0.02s
  ✓ it creates a percent discount                                        0.08s
  ✓ it creates a fixed discount                                          0.07s
  ✓ it validates discount code uniqueness within store                   0.08s
  ✓ it edits a discount                                                  0.04s
  ✓ it disables a discount                                               0.03s
   PASS  Tests\Feature\Admin\OrderManagementTest
  ✓ it lists orders with status filter                                   0.02s
  ✓ it shows order detail page                                           0.03s
  ✓ it creates a fulfillment from order detail                           0.08s
  ✓ it processes a refund from order detail                              0.08s
  ✓ it restricts order management by role                                0.01s


Output:
  ✓ it tracks a page view event                                          0.01s
  ✓ it tracks an add to cart event                                       0.01s
  ✓ it scopes events to current store                                    0.01s
  ✓ it includes session ID when available                                0.01s
  ✓ it includes customer ID when authenticated                           0.01s

   PASS  Tests\Unit\DiscountCalculatorTest
  ✓ it validates an active discount code                                 0.02s
  ✓ it rejects an expired discount code                                  0.01s
  ✓ it rejects a not-yet-active discount code                            0.02s
  ✓ it rejects a discount that has reached its usage limit               0.01s
  ✓ it rejects an unknown discount code                                  0.01s
  ✓ it performs case-insensitive code lookup                             0.01s
  ✓ it enforces minimum purchase amount rule                             0.01s
  ✓ it passes minimum purchase when cart meets threshold                 0.01s
  ✓ it calculates percent discount amount                                0.01s
  ✓ it calculates fixed discount amount                                  0.01s
  ✓ it handles free shipping discount type                               0.01s
  ✓ it allocates discount proportionally across multiple lines           0.01s
  ✓ it distributes rounding remainder to the last qualifying line        0.01s
   PASS  Tests\Unit\ExampleTest
  ✓ that true is true
   PASS  Tests\Unit\HandleGeneratorTest
  ✓ it generates a slug from title                                       0.01s
  ✓ it appends suffix on collision                                       0.01s
  ✓ it increments suffix on multiple collisions                          0.01s
  ✓ it handles special characters                                        0.01s
  ✓ it excludes current record when updating                             0.01s
  ✓ it scopes handle uniqueness to store                                 0.01s
   PASS  Tests\Unit\PricingEngineTest
  ✓ it calculates subtotal from line items                               0.01s
  ✓ it calculates subtotal for a single line                             0.01s
  ✓ it returns zero subtotal for empty cart                              0.01s
  ✓ it applies percent discount correctly                                0.01s
  ✓ it applies fixed discount correctly                                  0.01s
  ✓ it caps fixed discount at subtotal so it never goes negative         0.01s
  ✓ it applies free shipping discount by zeroing shipping                0.02s
  ✓ it calculates tax exclusive correctly                                0.01s
  ✓ it extracts tax from inclusive price correctly                       0.01s
  ✓ it returns zero tax when rate is zero                                0.01s
  ✓ it calculates shipping flat rate                                     0.01s
  ✓ it calculates full checkout totals end to end                        0.01s
  ✓ it handles rounding correctly with odd cent amounts                  0.01s
  ✓ it produces identical results for identical inputs                   0.02s
   PASS  Tests\Unit\ShippingCalculatorTest
  ✓ it matches a zone by country code                                    0.02s
  ✓ it matches a zone by region code                                     0.01s
  ✓ it returns empty when no zone matches                                0.01s
  ✓ it calculates a flat rate                                            0.01s
  ✓ it calculates a weight-based rate                                    0.01s
  ✓ it calculates a price-based rate                                     0.01s
  ✓ it returns zero shipping when no items require shipping              0.01s
  ✓ it returns correct rates when multiple zones match                   0.01s
  ✓ it skips inactive rates                                              0.01s
   PASS  Tests\Unit\TaxCalculatorTest
  ✓ it calculates manual tax exclusive
  ✓ it extracts manual tax from inclusive amount
  ✓ it returns zero tax when no rate configured
  ✓ it handles zero amount lines
  ✓ it calculates tax with non-standard rate
  ✓ it extracts tax correctly for small amounts
  ✓ it handles high tax rates
   PASS  Tests\Feature\Admin\DashboardTest
  ✓ it renders the admin dashboard                                       0.05s
  ✓ it shows KPI tiles with correct data                                 0.02s
  ✓ it restricts dashboard to authenticated admins                       0.02s
  ✓ it filters metrics by date range                                     0.04s
   PASS  Tests\Feature\Admin\DiscountManagementTest
  ✓ it lists discounts                                                   0.02s
  ✓ it creates a percent discount                                        0.08s
  ✓ it creates a fixed discount                                          0.07s
  ✓ it validates discount code uniqueness within store                   0.08s
  ✓ it edits a discount                                                  0.04s
  ✓ it disables a discount                                               0.03s
   PASS  Tests\Feature\Admin\OrderManagementTest
  ✓ it lists orders with status filter                                   0.02s
  ✓ it shows order detail page                                           0.03s
  ✓ it creates a fulfillment from order detail                           0.08s
  ✓ it processes a refund from order detail                              0.08s
  ✓ it restricts order management by role                                0.01s
   PASS  Tests\Feature\Admin\ProductManagementTest
  ✓ it lists products with pagination                                    0.03s
  ✓ it creates a product via admin form                                  0.07s
  ✓ it edits a product via admin form                                    0.03s
  ✓ it bulk archives selected products                                   0.03s
  ✓ it uploads media from the product form                               0.07s
  ✓ it manages variants from the product form                            0.07s
  ✓ it restricts product management to authorized roles                  0.01s
  ✓ it staff can create but not delete products                          0.04s
   PASS  Tests\Feature\Admin\SettingsTest
  ✓ it renders the settings page                                         0.02s
  ✓ it updates general store settings                                    0.03s
  ✓ it configures shipping zones                                         0.04s
  ✓ it configures tax settings                                           0.04s
  ✓ it restricts settings to owner and admin roles                       0.02s
  ✓ it manages store domains                                             0.03s
   PASS  Tests\Feature\Analytics\AggregationTest
  ✓ it aggregates daily metrics from raw events                          0.01s
  ✓ it calculates revenue and AOV correctly                              0.01s
  ✓ it runs idempotently                                                 0.01s
   PASS  Tests\Feature\Analytics\EventIngestionTest
  ✓ it tracks a page view event                                          0.01s
  ✓ it tracks an add to cart event                                       0.01s
  ✓ it scopes events to current store                                    0.01s
  ✓ it includes session ID when available                                0.01s
  ✓ it includes customer ID when authenticated                           0.01s


Output:
  ✓ it tracks a page view event                                          0.01s
  ✓ it tracks an add to cart event                                       0.01s
  ✓ it scopes events to current store                                    0.01s
  ✓ it includes session ID when available                                0.01s
  ✓ it includes customer ID when authenticated                           0.01s


Output:
  ✓ email can be verified                                                0.01s
  ✓ email is not verified with invalid hash                              0.01s
  ✓ already verified user visiting verification link is redirected with… 0.01s
   PASS  Tests\Feature\Auth\PasswordConfirmationTest
  ✓ confirm password screen can be rendered                              0.02s

  ✓ it applies percent discount correctly                                0.01s
  ✓ it applies fixed discount correctly                                  0.01s
  ✓ it caps fixed discount at subtotal so it never goes negative         0.01s
  ✓ it applies free shipping discount by zeroing shipping                0.02s
  ✓ it calculates tax exclusive correctly                                0.01s
  ✓ it extracts tax from inclusive price correctly                       0.01s
  ✓ it returns zero tax when rate is zero                                0.01s
  ✓ it calculates shipping flat rate                                     0.01s
  ✓ it calculates full checkout totals end to end                        0.01s
  ✓ it handles rounding correctly with odd cent amounts                  0.01s
  ✓ it produces identical results for identical inputs                   0.02s
   PASS  Tests\Unit\ShippingCalculatorTest
  ✓ it matches a zone by country code                                    0.02s
  ✓ it matches a zone by region code                                     0.01s
  ✓ it returns empty when no zone matches                                0.01s
  ✓ it calculates a flat rate                                            0.01s
  ✓ it calculates a weight-based rate                                    0.01s
  ✓ it calculates a price-based rate                                     0.01s
  ✓ it returns zero shipping when no items require shipping              0.01s
  ✓ it returns correct rates when multiple zones match                   0.01s
  ✓ it skips inactive rates                                              0.01s
   PASS  Tests\Unit\TaxCalculatorTest
  ✓ it calculates manual tax exclusive
  ✓ it extracts manual tax from inclusive amount
  ✓ it returns zero tax when no rate configured
  ✓ it handles zero amount lines
  ✓ it calculates tax with non-standard rate
  ✓ it extracts tax correctly for small amounts
  ✓ it handles high tax rates
   PASS  Tests\Feature\Admin\DashboardTest
  ✓ it renders the admin dashboard                                       0.05s
  ✓ it shows KPI tiles with correct data                                 0.02s
  ✓ it restricts dashboard to authenticated admins                       0.02s
  ✓ it filters metrics by date range                                     0.04s
   PASS  Tests\Feature\Admin\DiscountManagementTest
  ✓ it lists discounts                                                   0.02s
  ✓ it creates a percent discount                                        0.08s
  ✓ it creates a fixed discount                                          0.07s
  ✓ it validates discount code uniqueness within store                   0.08s
  ✓ it edits a discount                                                  0.04s
  ✓ it disables a discount                                               0.03s
   PASS  Tests\Feature\Admin\OrderManagementTest
  ✓ it lists orders with status filter                                   0.02s
  ✓ it shows order detail page                                           0.03s
  ✓ it creates a fulfillment from order detail                           0.08s
  ✓ it processes a refund from order detail                              0.08s
  ✓ it restricts order management by role                                0.01s
   PASS  Tests\Feature\Admin\ProductManagementTest
  ✓ it lists products with pagination                                    0.03s
  ✓ it creates a product via admin form                                  0.07s
  ✓ it edits a product via admin form                                    0.03s
  ✓ it bulk archives selected products                                   0.03s
  ✓ it uploads media from the product form                               0.07s
  ✓ it manages variants from the product form                            0.07s
  ✓ it restricts product management to authorized roles                  0.01s
  ✓ it staff can create but not delete products                          0.04s
   PASS  Tests\Feature\Admin\SettingsTest
  ✓ it renders the settings page                                         0.02s
  ✓ it updates general store settings                                    0.03s
  ✓ it configures shipping zones                                         0.04s
  ✓ it configures tax settings                                           0.04s
  ✓ it restricts settings to owner and admin roles                       0.02s
  ✓ it manages store domains                                             0.03s
   PASS  Tests\Feature\Analytics\AggregationTest
  ✓ it aggregates daily metrics from raw events                          0.01s
  ✓ it calculates revenue and AOV correctly                              0.01s
  ✓ it runs idempotently                                                 0.01s
   PASS  Tests\Feature\Analytics\EventIngestionTest
  ✓ it tracks a page view event                                          0.01s
  ✓ it tracks an add to cart event                                       0.01s
  ✓ it scopes events to current store                                    0.01s
  ✓ it includes session ID when available                                0.01s
  ✓ it includes customer ID when authenticated                           0.01s
   PASS  Tests\Feature\Auth\AdminAuthTest
  ✓ it shows admin login page                                            0.02s
  ✓ it authenticates admin user with valid credentials                   0.03s
  ✓ it fails authentication with invalid credentials                     0.23s
  ✓ it validates email is required                                       0.03s
  ✓ it validates password is required                                    0.03s
  ✓ it rate limits login attempts                                        1.14s
   PASS  Tests\Feature\Auth\AuthenticationTest
  ✓ login screen can be rendered                                         0.02s
  ✓ users can authenticate using the login screen                        0.02s
  ✓ users can not authenticate with invalid password                     0.01s
  ✓ users with two factor enabled are redirected to two factor challeng… 0.01s
  ✓ users can logout                                                     0.01s
   PASS  Tests\Feature\Auth\CustomerAuthTest
  ✓ it shows customer login page                                         0.02s
  ✓ it shows customer register page                                      0.02s
  ✓ it validates login email is required                                 0.03s
  ✓ it validates login password is required                              0.03s
  ✓ it validates registration fields are required                        0.06s
  ✓ it validates registration password confirmation                      0.05s
   PASS  Tests\Feature\Auth\EmailVerificationTest
  ✓ email verification screen can be rendered                            0.01s
  ✓ email can be verified                                                0.01s
  ✓ email is not verified with invalid hash                              0.01s
  ✓ already verified user visiting verification link is redirected with… 0.01s
   PASS  Tests\Feature\Auth\PasswordConfirmationTest
  ✓ confirm password screen can be rendered                              0.02s