Laravel Boost Guidelines - Aiku ERP
Comprehensive guidelines for building Laravel applications following the Aiku white-label ERP conventions, with emphasis on code clarity, testing discipline, and Laravel ecosystem best practices.
Core Principles
1. **Self-Explanatory Code**: Write clear, descriptive code without comments. Use meaningful variable and method names like `isRegisteredForDiscounts` instead of `discount()`.
2. **Test Everything**: Every change must be programmatically tested. Write or update tests and run them before finalizing.
3. **Follow Existing Conventions**: Check sibling files for structure, approach, and naming patterns before creating new files.
4. **No Formatting Commands**: Do not run `vendor/bin/pint --dirty` - let the environment handle formatting.
Technology Stack
This application uses:
**Backend**: PHP 8.4, Laravel 12, Sanctum 4, Horizon 5, Octane 2, Scout 10, Telescope 5**Frontend**: Inertia.js v2, Vue 3, Tailwind 3, Ziggy 2**Testing**: Pest 4, PHPUnit 12**Tooling**: Pint 1, Sail 1, Envoy 2PHP Standards
Type Safety
Always use explicit return type declarations for methods and functionsUse appropriate PHP type hints for method parametersUse PHP 8 constructor property promotion```php
public function __construct(public GitHub $github) { }
protected function isAccessible(User $user, ?string $path = null): bool
{
// Implementation
}
```
Control Structures
Always use curly braces for control structures, even single-line blocksDo not allow empty `__construct()` methods with zero parametersEnums
Use TitleCase for enum keys: `FavoritePerson`, `BestLake`, `Monthly`Documentation
Prefer PHPDoc blocks over inline commentsAdd useful array shape type definitions where appropriateNever use comments within code unless extremely complexLaravel Best Practices
File Creation
Use `php artisan make:` commands for all new files (migrations, controllers, models, etc.)Pass `--no-interaction` to Artisan commands to ensure non-interactive executionFor generic PHP classes, use `php artisan make:class`Database & Eloquent
**Always** use Eloquent relationship methods with return type hintsPrefer `Model::query()` over `DB::`Prevent N+1 queries with eager loadingUse Laravel's query builder for complex operations onlyWhen modifying columns in migrations, include all previous attributes to prevent data lossModels
Define casts in `casts()` method rather than `$casts` property (follow existing conventions)When creating new models, also create factories and seedersUse relationship methods before raw queries or manual joinsControllers & Validation
**Always** create Form Request classes for validation (never inline validation)Include both validation rules and custom error messagesCheck sibling Form Requests to match array vs string validation styleAPIs
Default to Eloquent API Resources and API versioningFollow existing API conventions if already establishedConfiguration
Use environment variables **only** in config filesNever use `env()` directly outside config filesAlways use `config('app.name')`, not `env('APP_NAME')`URL Generation
Prefer named routes and the `route()` functionUse `get-absolute-url` tool to ensure correct scheme, domain, and portQueues
Use queued jobs with `ShouldQueue` interface for time-consuming operationsAuthentication & Authorization
Use Laravel's built-in features: gates, policies, SanctumLaravel 12 Specific
This project uses **Laravel 10 structure** (not migrated to Laravel 12's streamlined structure):
Middleware lives in `app/Http/Middleware/`Service providers in `app/Providers/`Middleware registration in `app/Http/Kernel.php`Exception handling in `app/Exceptions/Handler.php`Console commands in `app/Console/Kernel.php`No `bootstrap/app.php` configuration file**Do not migrate** to Laravel 12 structure unless explicitly requested.
Laravel 12 Features
Limit eagerly loaded records natively: `$query->latest()->limit(10)`Inertia.js v2
Core Conventions
Components live in `resources/js/Pages/` (unless vite.config.js specifies otherwise)Use `Inertia::render()` for server-side routing instead of Blade views```php
// routes/web.php
Route::get('/users', function () {
return Inertia::render('Users/Index', [
'users' => User::all()
]);
});
```
Inertia v2 Features
**Polling**: Auto-refresh data at intervals**Prefetching**: Load data before navigation**Deferred props**: Lazy-load expensive data**Infinite scrolling**: Use merging props and `WhenVisible`**Lazy loading**: Load data on scrollForms
Use `<Form>` component (recommended) - search docs with query `form component`Alternative: `useForm` helper for programmatic control - search docs with query `useForm helper`Available form options: `resetOnError`, `resetOnSuccess`, `setDefaultsOnSuccess`Deferred Props
When using deferred props, add animated skeleton/empty statesTesting with Pest
Test Requirements
**Every change must be tested** - write new tests or update existing onesRun minimum necessary tests using filters for speedAll tests must use Pest syntaxTests live in `tests/Feature/` and `tests/Unit/`Creating Tests
```bash
php artisan make:test --pest FeatureName # Feature test
php artisan make:test --pest --unit ClassName # Unit test
```
Test Structure
```php
it('returns all users', function () {
$response = $this->postJson('/api/users', []);
$response->assertSuccessful();
});
```
Running Tests
```bash
php artisan test # All tests
php artisan test tests/Feature/ExampleTest.php # Single file
php artisan test --filter=testName # Filtered (recommended)
```
Test Coverage
Test happy paths, failure paths, and edge casesUse model factories for test dataFollow existing faker conventions (`$this->faker` or `fake()`)Use specific assertions: `assertForbidden`, `assertNotFound` (not `assertStatus(403)`)Mocking
Import: `use function Pest\Laravel\mock;`Or use `$this->mock()` if existing tests doImportant
**Never remove tests** without approval - they are core to the applicationFeature Flags (Laravel Pennant)
This application uses Laravel Pennant for feature flag managementControls feature availability across organizations and user typesUse `search-docs` tool for feature flag guidanceCode Formatting (Laravel Pint)
Run `vendor/bin/pint --dirty` before finalizing changesDo not run `vendor/bin/pint --test`Let Pint fix formatting issues automaticallyFrontend Bundling
If frontend changes aren't reflected:
User may need to run `npm run build`, `npm run dev`, or `composer run dev`Ask them to run the appropriate commandDebugging Tools
Tinker
Use `tinker` tool to execute PHP and query Eloquent modelsUse `database-query` tool for read-only database queriesBrowser Logs
Use `browser-logs` tool to read browser logs, errors, and exceptionsOnly recent logs are useful - ignore old logsDocumentation Search
Critical: Use `search-docs` Tool First
This tool returns version-specific documentation for installed packagesPerfect for Laravel, Inertia, Livewire, Filament, Tailwind, Pest, Nova, etc.**Always search docs before making code changes**Search Syntax
Pass multiple queries at once:
1. **Simple words**: `authentication` (finds 'authenticate', 'auth')
2. **Multiple words**: `rate limit` (finds both "rate" AND "limit")
3. **Exact phrases**: `"infinite scroll"` (exact position required)
4. **Mixed**: `middleware "rate limit"`
5. **Multiple queries**: `["authentication", "middleware"]`
Search Tips
Use broad, simple, topic-based queries: `['rate limiting', 'routing']`Do not include package names in queries (already filtered)Example: Use `test resource table`, not `filament 4 test resource table`Application Structure
Follow existing directory structure - no new base folders without approvalDo not change dependencies without approvalCheck sibling files for correct patterns before creating new filesReuse existing components before writing new onesCommunication
Be concise - focus on important details, not obvious onesOnly create documentation files if explicitly requestedUse `list-artisan-commands` tool to verify Artisan command parametersError Handling
Vite Manifest Error
If you see "Unable to locate file in Vite manifest":
Run `npm run build` or ask user to run `npm run dev` or `composer run dev`Verification
Do not create verification scripts when tests already cover functionalityUnit and feature tests are more important than tinker scripts