235 lines
4.2 KiB
Markdown
235 lines
4.2 KiB
Markdown
|
|
# Laravel Coding Standards for Copilot (With Examples)
|
||
|
|
## Version 1.0
|
||
|
|
|
||
|
|
This document defines the official Laravel coding standards enforced by Copilot for writing clean, secure, readable, and optimized code.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# 1. General Coding Rules
|
||
|
|
|
||
|
|
- Follow PSR-12 formatting.
|
||
|
|
- Use camelCase for variables & methods.
|
||
|
|
- Use PascalCase for classes.
|
||
|
|
- Use snake_case for database columns and tables.
|
||
|
|
- Limit functions to a clear, single responsibility.
|
||
|
|
|
||
|
|
### Example
|
||
|
|
```php
|
||
|
|
class UserProfileService
|
||
|
|
{
|
||
|
|
public function getFullName(User $user): string
|
||
|
|
{
|
||
|
|
return "{$user->first_name} {$user->last_name}";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# 2. Controller Standards
|
||
|
|
|
||
|
|
- Must remain thin.
|
||
|
|
- Use FormRequest for validation.
|
||
|
|
- Wrap logic in try/catch.
|
||
|
|
- Return standardized JSON responses.
|
||
|
|
- Use correct HTTP status codes.
|
||
|
|
|
||
|
|
### Example
|
||
|
|
```php
|
||
|
|
class UserController extends Controller
|
||
|
|
{
|
||
|
|
use ApiResponseTrait;
|
||
|
|
|
||
|
|
public function update(UpdateUserRequest $request, User $user)
|
||
|
|
{
|
||
|
|
try {
|
||
|
|
$updated = $this->service->updateProfile($user, $request->validated());
|
||
|
|
return $this->success($updated, 'Profile updated', 200);
|
||
|
|
} catch (\Throwable $e) {
|
||
|
|
Log::error('Update failed: '.$e->getMessage());
|
||
|
|
return $this->error('Unable to update profile', 500);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# 3. FormRequest Validation
|
||
|
|
|
||
|
|
- All inputs must be validated.
|
||
|
|
- No inline validator inside controllers.
|
||
|
|
|
||
|
|
### Example
|
||
|
|
```php
|
||
|
|
class UpdateUserRequest extends FormRequest
|
||
|
|
{
|
||
|
|
public function rules(): array
|
||
|
|
{
|
||
|
|
return [
|
||
|
|
'first_name' => 'required|string|max:150',
|
||
|
|
'last_name' => 'required|string|max:150',
|
||
|
|
'phone' => 'nullable|digits_between:10,12'
|
||
|
|
];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# 4. Service Layer Standards
|
||
|
|
|
||
|
|
- Wrap heavy logic in try/catch.
|
||
|
|
- Log exceptions.
|
||
|
|
- Use DB transactions for multi-step operations.
|
||
|
|
- Use optimized Eloquent queries.
|
||
|
|
|
||
|
|
### Example
|
||
|
|
```php
|
||
|
|
class UserProfileService
|
||
|
|
{
|
||
|
|
public function updateProfile(User $user, array $data)
|
||
|
|
{
|
||
|
|
try {
|
||
|
|
return DB::transaction(function () use ($user, $data) {
|
||
|
|
$user->update($data);
|
||
|
|
return $user->fresh();
|
||
|
|
});
|
||
|
|
} catch (\Throwable $e) {
|
||
|
|
Log::error('Service error: '.$e->getMessage());
|
||
|
|
throw $e;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# 5. Models
|
||
|
|
|
||
|
|
- Use fillable/guarded.
|
||
|
|
- Use casts.
|
||
|
|
- Use accessors/mutators where needed.
|
||
|
|
- Use query scopes.
|
||
|
|
|
||
|
|
### Example
|
||
|
|
```php
|
||
|
|
class User extends Model
|
||
|
|
{
|
||
|
|
protected $fillable = ['first_name','last_name','email','phone'];
|
||
|
|
|
||
|
|
protected $casts = [
|
||
|
|
'is_active' => 'boolean',
|
||
|
|
'email_verified_at' => 'datetime'
|
||
|
|
];
|
||
|
|
|
||
|
|
public function scopeActive($query)
|
||
|
|
{
|
||
|
|
return $query->where('is_active', true);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# 6. API Response Formatting
|
||
|
|
|
||
|
|
Use a shared trait.
|
||
|
|
|
||
|
|
### Example
|
||
|
|
```php
|
||
|
|
trait ApiResponseTrait
|
||
|
|
{
|
||
|
|
protected function success($data = null, $message = 'Success', $code = 200)
|
||
|
|
{
|
||
|
|
return response()->json([
|
||
|
|
'status' => true,
|
||
|
|
'message' => $message,
|
||
|
|
'data' => $data
|
||
|
|
], $code);
|
||
|
|
}
|
||
|
|
|
||
|
|
protected function error($message = 'Error', $code = 500)
|
||
|
|
{
|
||
|
|
return response()->json([
|
||
|
|
'status' => false,
|
||
|
|
'message' => $message
|
||
|
|
], $code);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# 7. Jobs & Queue Standards
|
||
|
|
|
||
|
|
- Heavy tasks must be queued.
|
||
|
|
- Wrap in try/catch.
|
||
|
|
|
||
|
|
### Example
|
||
|
|
```php
|
||
|
|
class SendReportJob implements ShouldQueue
|
||
|
|
{
|
||
|
|
public function handle()
|
||
|
|
{
|
||
|
|
try {
|
||
|
|
// generate report
|
||
|
|
} catch (\Throwable $e) {
|
||
|
|
Log::error('Report job failed: ' . $e->getMessage());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# 8. Linting (Pint)
|
||
|
|
|
||
|
|
### Install
|
||
|
|
```
|
||
|
|
composer require laravel/pint --dev
|
||
|
|
```
|
||
|
|
|
||
|
|
### Run
|
||
|
|
```
|
||
|
|
./vendor/bin/pint
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# 9. Static Analysis (PHPStan)
|
||
|
|
|
||
|
|
### Install
|
||
|
|
```
|
||
|
|
composer require --dev phpstan/phpstan
|
||
|
|
```
|
||
|
|
|
||
|
|
### Run
|
||
|
|
```
|
||
|
|
vendor/bin/phpstan analyse
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# 10. OpenTelemetry (Monitoring & Logs)
|
||
|
|
|
||
|
|
### Install
|
||
|
|
```
|
||
|
|
composer require open-telemetry/opentelemetry-laravel
|
||
|
|
```
|
||
|
|
|
||
|
|
### Publish
|
||
|
|
```
|
||
|
|
php artisan vendor:publish --provider="OpenTelemetry\Laravel\ServiceProvider"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Enable auto-instrumentation
|
||
|
|
```
|
||
|
|
php artisan otel:install
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# Final Notes
|
||
|
|
This standard ensures Copilot always writes clean, secure, maintainable, and production-ready Laravel code.
|