Backend
Core vs Domains
- Core (
app/Core/) — Cross-cutting: Middleware, Models (Language, Setting, FeatureFlag), Observers, Policies, Providers, Services (PagePropsService, SupportedLocalesService), Contracts, Exceptions, Traits. Core/Inertia/ containsTestingViewFinderfor resolving Inertia page component names in PHP tests. - Domains (
app/Domains/<Name>/) — Vertical slices: Auth, Blog, Contact, Dashboard, Faq, Landing, Page, Profile, Search, Testimonial. Each may have Http/Controllers, Http/Requests, Models, Observers, Policies, Queries, Services, Actions, DTOs, Search, Jobs/. Example: Blog hasJobs/(e.g.GenerateBlogPostsJob) andServices/(e.g.BlogPostGenerationService) for queued AI-powered post generation.
There is no global app/Models/ or app/Jobs/; models live in Core/Models/ or Domains/<Name>/Models/, jobs in Domains/<Name>/Jobs/ or Core/Jobs/. Artisan commands live in app/Core/Console/Commands/ (scaffolding, translations) or app/Domains/<Name>/Console/Commands/ (e.g. Blog: blog:run-scheduled-series). Paths are registered in bootstrap/app.php via withCommands().
Controllers and requests
- Controllers live in
Domains/<Name>/Http/Controllers/and extendApp\Core\Http\Controllers\Controller. The base controller and core-only controllers (e.g. TranslationsCsvController) live inapp/Core/Http/Controllers/. They are thin: call Queries/Services/Actions, merge with PagePropsService when needed, returnInertia::render(...). - FormRequests live in
Domains/<Name>/Http/Requests/. Routes inroutes/web.phppoint to domain controllers (e.g.App\Domains\Blog\Http\Controllers\BlogController).
Models and IDE Helper
- Add new model paths to
config/ide-helper.php→model_locations(e.g.app/Domains/Product/Models). Runphp artisan ide-helper:models -Mafter adding or moving models.
Soft deletes and cascading
- CMS and domain models use
SoftDeletes. Cascaded soft deletes via observers/events; cascaded force deletes via DB foreign keys and observers. Document parent/child and force-delete behavior when adding relations (see ARCHITECTURE in the repo).
Adding a new domain
- Create
app/Domains/<Name>/with Http, Models, etc. as needed. - Register routes (in the locale group in
routes/web.phporroutes/settings.php) and register the policy inAppServiceProvider::registerPolicies(). - If the domain has models: add the path to
config/ide-helper.phpand runide-helper:models -M.
Or use php artisan boilerplate:domain to scaffold (see Scaffolding).