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 actionsapp/Models/Traits/- shared model traitsapp/Livewire/Forms/- Livewire form objectstests/Feature/Actions/Tickets/- mirrors app structure