Architecture

Directory Structure Standards

Standard Laravel Structure

app/
├── Actions/              # Business logic action classes
├── Data/                 # Spatie LaravelData DTOs
├── Enums/                # PHP 8.1+ Enums
├── Http/
│   ├── Controllers/      # HTTP controllers (minimal with Livewire)
│   ├── Middleware/       # Custom middleware
│   └── Requests/         # Form request validation
├── Livewire/
│   ├── Actions/          # Livewire-specific actions
│   └── Forms/            # Livewire form classes
├── Models/
│   └── Traits/           # Reusable model traits
├── Observers/            # Model lifecycle observers
├── Providers/            # Service providers
├── View/
│   └── Components/       # Blade component classes
└── ViewData/             # View-specific data classes (optional)

database/
├── factories/            # Model factories for testing
├── migrations/           # Database migrations
└── seeders/              # Database seeders

resources/
└── views/
    ├── components/       # Anonymous Blade components
    ├── layouts/          # Layout templates
    └── livewire/         # Livewire component views

routes/
├── web.php               # Web routes
├── auth.php              # Authentication routes (required in web.php)
└── console.php           # Artisan commands

tests/
├── Feature/
│   ├── Actions/          # Action tests (mirrors app/Actions/)
│   ├── Models/           # Model tests
│   └── Auth/             # Authentication tests
├── Unit/
│   └── ArchitectureTest.php
├── Browser/              # Dusk tests (if needed)
├── Pest.php              # Pest configuration
└── TestCase.php          # Base test case

Directory Guidelines

When to Create app/Actions/

Create action classes when logic:

  • Is reusable across controllers/Livewire components
  • Involves multiple steps or complex business rules
  • Needs to be independently testable
app/Actions/
├── Tickets/
│   ├── CreateTicket.php
│   └── UpdateTicket.php
├── Users/
│   └── BuildUserSettingDefaults.php
└── Conversions/
    └── ConvertKilogramsToPounds.php

When to Create app/Data/

Use for DTOs when passing multiple related parameters:

app/Data/
├── TicketData.php
├── StoreData.php
└── Plan/
    ├── PlanData.php
    └── WorkoutData.php

When to Create app/Enums/

Use for finite sets of values:

app/Enums/
├── Status.php
├── DBType.php
└── WeightTypes.php

When to Create Subdirectories

Create subdirectories when:

  • More than 5-7 related files exist
  • Logical grouping improves navigation
  • Domain boundaries are clear

Examples:

  • app/Actions/Tickets/ - ticket-related actions
  • app/Models/Traits/ - shared model traits
  • app/Livewire/Forms/ - Livewire form objects
  • tests/Feature/Actions/Tickets/ - mirrors app structure