Add CLAUDE.md - AI agent instructions for module development

Created comprehensive anti-hallucination documentation:
- EXACT file templates with full code examples
- Precise naming conventions (PascalCase, snake_case, kebab-case)
- Step-by-step module creation checklist
- Common mistakes to avoid section
- Filament form/table component reference
- Debugging commands and troubleshooting
- Updated AI_CONTEXT.md and README.md to reference CLAUDE.md
This commit is contained in:
2026-03-11 07:59:39 +02:00
parent e4c7d09109
commit 12027d9e98
3 changed files with 785 additions and 1 deletions

View File

@@ -1,5 +1,8 @@
# AI Assistant Context # AI Assistant Context
> **🚨 CRITICAL: For detailed module development instructions, see [CLAUDE.md](CLAUDE.md)**
> That document contains EXACT file templates, naming conventions, and step-by-step instructions.
This document provides context for AI coding assistants working on projects built with this template. This document provides context for AI coding assistants working on projects built with this template.
## Template Overview ## Template Overview
@@ -331,6 +334,7 @@ make restore file=... # Restore database
## Documentation Links ## Documentation Links
- **[CLAUDE.md](CLAUDE.md)** - 🚨 **AI AGENTS: START HERE** - Exact module templates
- [GETTING_STARTED.md](GETTING_STARTED.md) - Setup walkthrough - [GETTING_STARTED.md](GETTING_STARTED.md) - Setup walkthrough
- [README.md](README.md) - Overview - [README.md](README.md) - Overview
- [docs/modules.md](docs/modules.md) - Module system - [docs/modules.md](docs/modules.md) - Module system

779
CLAUDE.md Normal file
View File

@@ -0,0 +1,779 @@
# AI Agent Instructions for Laravel Module Development
> **CRITICAL**: This document provides EXACT specifications for building modules in this Laravel template.
> Follow these instructions PRECISELY. Do NOT deviate, guess, or improvise.
> When in doubt, READ THE EXISTING CODE before making changes.
---
## 🚨 BEFORE YOU START - MANDATORY STEPS
### 1. Always Check Existing Patterns First
```bash
# List existing modules to see patterns
ls -la src/app/Modules/
# Read an existing module's structure
find src/app/Modules/[ExistingModule]/ -type f -name "*.php"
```
### 2. Always Check Logs After Errors
```bash
docker-compose exec app tail -n 100 storage/logs/laravel.log
```
### 3. Never Guess at Solutions
- If you encounter an error, READ the full stack trace
- Find the EXACT file and line number causing the issue
- Understand what the code is trying to do before fixing
---
## 📁 PROJECT STRUCTURE - EXACT PATHS
```
Laravel-Docker-Dev-Template/
├── src/ # ← ALL Laravel code goes here
│ ├── app/
│ │ ├── Filament/
│ │ │ ├── Pages/
│ │ │ │ └── Settings.php # Site settings page
│ │ │ └── Resources/ # Core Filament resources
│ │ │ ├── UserResource.php
│ │ │ ├── RoleResource.php
│ │ │ └── PermissionResource.php
│ │ ├── Http/
│ │ │ ├── Controllers/
│ │ │ └── Middleware/
│ │ ├── Models/
│ │ │ ├── User.php
│ │ │ └── Setting.php
│ │ ├── Modules/ # ← ALL modules go here
│ │ │ └── [ModuleName]/ # ← Each module is a folder
│ │ ├── Providers/
│ │ │ └── AppServiceProvider.php
│ │ └── Traits/
│ │ └── ModuleAuditable.php
│ ├── bootstrap/
│ │ └── app.php # Middleware registration
│ ├── config/
│ ├── database/
│ │ ├── migrations/
│ │ └── seeders/
│ │ ├── DatabaseSeeder.php
│ │ └── RolePermissionSeeder.php
│ ├── resources/
│ │ └── views/
│ │ ├── layouts/
│ │ │ ├── app.blade.php # Authenticated layout
│ │ │ └── guest.blade.php # Guest layout
│ │ └── components/
│ └── routes/
│ ├── web.php
│ ├── api.php
│ └── auth.php
├── docker-compose.yml
├── setup.bat # Windows setup
└── setup.sh # Linux/Mac setup
```
---
## 🔧 MODULE STRUCTURE - EXACT SPECIFICATION
When creating a module named `[ModuleName]` (e.g., `StockManagement`):
```
src/app/Modules/[ModuleName]/
├── Config/
│ └── [module_name].php # snake_case filename
├── Database/
│ ├── Migrations/
│ │ └── YYYY_MM_DD_HHMMSS_create_[table_name]_table.php
│ └── Seeders/
│ └── [ModuleName]Seeder.php
├── Filament/
│ └── Resources/
│ ├── [ModelName]Resource.php
│ └── [ModelName]Resource/
│ └── Pages/
│ ├── List[ModelName]s.php
│ ├── Create[ModelName].php
│ └── Edit[ModelName].php
├── Http/
│ ├── Controllers/
│ │ └── [ModuleName]Controller.php
│ ├── Middleware/
│ └── Requests/
│ └── [ModelName]Request.php
├── Models/
│ └── [ModelName].php
├── Policies/
│ └── [ModelName]Policy.php
├── Services/
│ └── [ModelName]Service.php
├── Routes/
│ ├── web.php
│ └── api.php
├── Resources/
│ └── views/
│ ├── index.blade.php
│ └── layouts/
│ └── module.blade.php
├── Permissions.php
└── [ModuleName]ServiceProvider.php
```
---
## 📝 EXACT FILE TEMPLATES
### 1. Service Provider (REQUIRED)
**File**: `src/app/Modules/[ModuleName]/[ModuleName]ServiceProvider.php`
```php
<?php
namespace App\Modules\[ModuleName];
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Route;
class [ModuleName]ServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->mergeConfigFrom(
__DIR__ . '/Config/[module_name].php',
'[module_name]'
);
}
public function boot(): void
{
$this->loadMigrationsFrom(__DIR__ . '/Database/Migrations');
$this->loadViewsFrom(__DIR__ . '/Resources/views', '[module-slug]');
$this->registerRoutes();
}
protected function registerRoutes(): void
{
Route::middleware(['web', 'auth'])
->prefix('[module-slug]')
->name('[module-slug].')
->group(__DIR__ . '/Routes/web.php');
if (file_exists(__DIR__ . '/Routes/api.php')) {
Route::middleware(['api', 'auth:sanctum'])
->prefix('api/[module-slug]')
->name('api.[module-slug].')
->group(__DIR__ . '/Routes/api.php');
}
}
}
```
**NAMING RULES**:
- `[ModuleName]` = PascalCase (e.g., `StockManagement`)
- `[module_name]` = snake_case (e.g., `stock_management`)
- `[module-slug]` = kebab-case (e.g., `stock-management`)
### 2. Config File (REQUIRED)
**File**: `src/app/Modules/[ModuleName]/Config/[module_name].php`
```php
<?php
return [
'name' => '[Module Display Name]',
'slug' => '[module-slug]',
'version' => '1.0.0',
'audit' => [
'enabled' => true,
'strategy' => 'all', // 'all', 'include', 'exclude', 'none'
'include' => [],
'exclude' => [],
],
];
```
### 3. Model (REQUIRED for data modules)
**File**: `src/app/Modules/[ModuleName]/Models/[ModelName].php`
```php
<?php
namespace App\Modules\[ModuleName]\Models;
use App\Traits\ModuleAuditable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use OwenIt\Auditing\Contracts\Auditable;
class [ModelName] extends Model implements Auditable
{
use HasFactory, ModuleAuditable;
protected $fillable = [
// List ALL fields that can be mass-assigned
];
protected $casts = [
// Type casts for fields
];
// Define relationships here
}
```
### 4. Migration (REQUIRED for data modules)
**File**: `src/app/Modules/[ModuleName]/Database/Migrations/YYYY_MM_DD_HHMMSS_create_[table_name]_table.php`
```php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('[table_name]', function (Blueprint $table) {
$table->id();
// Define ALL columns here
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('[table_name]');
}
};
```
### 5. Permissions (REQUIRED)
**File**: `src/app/Modules/[ModuleName]/Permissions.php`
```php
<?php
return [
'[module_name].view' => 'View [Module Name]',
'[module_name].create' => 'Create [Module Name] records',
'[module_name].edit' => 'Edit [Module Name] records',
'[module_name].delete' => 'Delete [Module Name] records',
];
```
### 6. Filament Resource (REQUIRED for admin)
**File**: `src/app/Modules/[ModuleName]/Filament/Resources/[ModelName]Resource.php`
```php
<?php
namespace App\Modules\[ModuleName]\Filament\Resources;
use App\Modules\[ModuleName]\Filament\Resources\[ModelName]Resource\Pages;
use App\Modules\[ModuleName]\Models\[ModelName];
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
class [ModelName]Resource extends Resource
{
protected static ?string $model = [ModelName]::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationGroup = '[Module Display Name]';
protected static ?int $navigationSort = 1;
public static function canAccess(): bool
{
return auth()->user()?->can('[module_name].view') ?? false;
}
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Section::make('[Model Name] Details')
->schema([
// Add form fields here
]),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
// Add table columns here
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\DeleteAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\List[ModelName]s::route('/'),
'create' => Pages\Create[ModelName]::route('/create'),
'edit' => Pages\Edit[ModelName]::route('/{record}/edit'),
];
}
}
```
### 7. Filament Resource Pages (REQUIRED)
**File**: `src/app/Modules/[ModuleName]/Filament/Resources/[ModelName]Resource/Pages/List[ModelName]s.php`
```php
<?php
namespace App\Modules\[ModuleName]\Filament\Resources\[ModelName]Resource\Pages;
use App\Modules\[ModuleName]\Filament\Resources\[ModelName]Resource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
class List[ModelName]s extends ListRecords
{
protected static string $resource = [ModelName]Resource::class;
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}
```
**File**: `src/app/Modules/[ModuleName]/Filament/Resources/[ModelName]Resource/Pages/Create[ModelName].php`
```php
<?php
namespace App\Modules\[ModuleName]\Filament\Resources\[ModelName]Resource\Pages;
use App\Modules\[ModuleName]\Filament\Resources\[ModelName]Resource;
use Filament\Resources\Pages\CreateRecord;
class Create[ModelName] extends CreateRecord
{
protected static string $resource = [ModelName]Resource::class;
}
```
**File**: `src/app/Modules/[ModuleName]/Filament/Resources/[ModelName]Resource/Pages/Edit[ModelName].php`
```php
<?php
namespace App\Modules\[ModuleName]\Filament\Resources\[ModelName]Resource\Pages;
use App\Modules\[ModuleName]\Filament\Resources\[ModelName]Resource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
class Edit[ModelName] extends EditRecord
{
protected static string $resource = [ModelName]Resource::class;
protected function getHeaderActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}
```
### 8. Routes (REQUIRED)
**File**: `src/app/Modules/[ModuleName]/Routes/web.php`
```php
<?php
use App\Modules\[ModuleName]\Http\Controllers\[ModuleName]Controller;
use Illuminate\Support\Facades\Route;
Route::get('/', [[ModuleName]Controller::class, 'index'])->name('index');
```
**File**: `src/app/Modules/[ModuleName]/Routes/api.php` (if API needed)
```php
<?php
use Illuminate\Support\Facades\Route;
Route::middleware('auth:sanctum')->group(function () {
// API routes here
});
```
### 9. Controller (REQUIRED)
**File**: `src/app/Modules/[ModuleName]/Http/Controllers/[ModuleName]Controller.php`
```php
<?php
namespace App\Modules\[ModuleName]\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class [ModuleName]Controller extends Controller
{
public function index()
{
$this->authorize('[module_name].view');
return view('[module-slug]::index');
}
}
```
### 10. Index View (REQUIRED)
**File**: `src/app/Modules/[ModuleName]/Resources/views/index.blade.php`
```blade
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
{{ __('[Module Display Name]') }}
</h2>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 text-gray-900 dark:text-gray-100">
{{ __('[Module Display Name] content goes here.') }}
</div>
</div>
</div>
</div>
</x-app-layout>
```
---
## ✅ MODULE REGISTRATION
After creating all files, register the module in `src/config/app.php` providers array:
```php
'providers' => ServiceProvider::defaultProviders()->merge([
// ...existing providers...
App\Modules\[ModuleName]\[ModuleName]ServiceProvider::class,
])->toArray(),
```
Or add to `src/bootstrap/providers.php`:
```php
return [
App\Providers\AppServiceProvider::class,
// ...existing providers...
App\Modules\[ModuleName]\[ModuleName]ServiceProvider::class,
];
```
---
## 🔄 AFTER MODULE CREATION - REQUIRED COMMANDS
```bash
# 1. Run migrations
docker-compose exec app php artisan migrate
# 2. Clear all caches
docker-compose exec app php artisan optimize:clear
# 3. Seed permissions (if using permissions)
docker-compose exec app php artisan db:seed --class=RolePermissionSeeder
# 4. Reset permission cache
docker-compose exec app php artisan permission:cache-reset
```
---
## ⚠️ COMMON MISTAKES TO AVOID
### 1. Wrong Namespace
`namespace App\Modules\StockManagement\Models;`
`namespace App\Modules\StockManagement\Models;`
The namespace MUST match the folder structure EXACTLY.
### 2. Wrong View Namespace
`return view('stockmanagement::index');`
`return view('StockManagement::index');`
`return view('stock-management::index');`
View namespace is ALWAYS kebab-case.
### 3. Wrong Permission Names
`'StockManagement.view'`
`'stock-management.view'`
`'stock_management.view'`
Permissions are ALWAYS snake_case.
### 4. Forgetting to Register Provider
The module WILL NOT LOAD if you forget to add its ServiceProvider.
### 5. Wrong Import Paths
`use App\Models\Product;`
`use App\Modules\StockManagement\Models\Product;`
Module models are in the MODULE namespace, not the core App namespace.
### 6. Missing Fillable Array
❌ Empty `$fillable` array causes mass-assignment errors
✅ List ALL fields that should be mass-assignable
### 7. Forgetting to Run Migrations
Always run `php artisan migrate` after creating migrations.
---
## 🎨 FILAMENT FORM FIELD REFERENCE
```php
// Text
Forms\Components\TextInput::make('name')
->required()
->maxLength(255);
// Email
Forms\Components\TextInput::make('email')
->email()
->required();
// Password
Forms\Components\TextInput::make('password')
->password()
->required();
// Textarea
Forms\Components\Textarea::make('description')
->rows(3);
// Select
Forms\Components\Select::make('status')
->options([
'active' => 'Active',
'inactive' => 'Inactive',
])
->required();
// Checkbox
Forms\Components\Toggle::make('is_active')
->default(true);
// Date
Forms\Components\DatePicker::make('date');
// DateTime
Forms\Components\DateTimePicker::make('published_at');
// Number
Forms\Components\TextInput::make('price')
->numeric()
->prefix('$');
// File Upload
Forms\Components\FileUpload::make('image')
->image()
->directory('uploads');
// Relationship Select
Forms\Components\Select::make('category_id')
->relationship('category', 'name')
->searchable()
->preload();
```
---
## 📊 FILAMENT TABLE COLUMN REFERENCE
```php
// Text
Tables\Columns\TextColumn::make('name')
->searchable()
->sortable();
// Badge
Tables\Columns\TextColumn::make('status')
->badge()
->color(fn (string $state): string => match ($state) {
'active' => 'success',
'inactive' => 'danger',
default => 'gray',
});
// Boolean Icon
Tables\Columns\IconColumn::make('is_active')
->boolean();
// Image
Tables\Columns\ImageColumn::make('avatar')
->circular();
// Date
Tables\Columns\TextColumn::make('created_at')
->dateTime()
->sortable();
// Money
Tables\Columns\TextColumn::make('price')
->money('USD');
```
---
## 🔐 EXISTING CORE RESOURCES
### User Management (already exists in template)
- `src/app/Filament/Resources/UserResource.php` - User CRUD with role assignment
- `src/app/Filament/Resources/RoleResource.php` - Role CRUD with permissions
- `src/app/Filament/Resources/PermissionResource.php` - Permission CRUD
### Settings (already exists)
- `src/app/Filament/Pages/Settings.php` - Site settings (name, logo, colors, registration toggle)
- `src/app/Models/Setting.php` - Settings model with get/set helpers
### Authentication (pre-installed)
- Laravel Breeze with Blade templates
- Login: `/login`
- Register: `/register` (controlled by enable_registration setting)
- Admin: `/admin`
---
## 🧪 TESTING MODULES
Create tests in `src/tests/Feature/Modules/[ModuleName]/`:
```php
<?php
namespace Tests\Feature\Modules\[ModuleName];
use App\Models\User;
use App\Modules\[ModuleName]\Models\[ModelName];
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class [ModelName]Test extends TestCase
{
use RefreshDatabase;
public function test_user_can_view_[model_name]s(): void
{
$user = User::factory()->create();
$user->givePermissionTo('[module_name].view');
$this->actingAs($user)
->get('/[module-slug]')
->assertStatus(200);
}
}
```
---
## 📋 CHECKLIST FOR NEW MODULES
Before considering a module complete:
- [ ] ServiceProvider created and registered
- [ ] Config file created
- [ ] Model created with fillable and casts
- [ ] Migration created and run
- [ ] Permissions.php created
- [ ] Filament Resource created with all pages
- [ ] Controller created
- [ ] Routes (web.php and optionally api.php) created
- [ ] Index view created
- [ ] `php artisan migrate` run
- [ ] `php artisan optimize:clear` run
- [ ] `php artisan db:seed --class=RolePermissionSeeder` run
- [ ] Module accessible at `/[module-slug]`
- [ ] Admin panel shows module in navigation
- [ ] CRUD operations work in admin
---
## 🆘 DEBUGGING
### Module Not Loading
```bash
# Check if provider is registered
docker-compose exec app php artisan about
# Clear everything
docker-compose exec app php artisan optimize:clear
```
### Filament Resource Not Showing
```bash
# Clear Filament cache
docker-compose exec app php artisan filament:cache-components
# Check canAccess() method returns true
# Check user has required permission
```
### Permission Denied
```bash
# Reset permission cache
docker-compose exec app php artisan permission:cache-reset
# Verify permissions exist
docker-compose exec app php artisan tinker
>>> \Spatie\Permission\Models\Permission::pluck('name');
```
### View Not Found
```bash
# Verify view namespace (must be kebab-case)
# Check file exists in Resources/views/
```
---
**Remember**: When in doubt, look at existing code in the codebase. The patterns are already established - follow them exactly.

View File

@@ -4,7 +4,8 @@ A comprehensive Laravel development environment with Docker for local developmen
> **New here?** Start with [GETTING_STARTED.md](GETTING_STARTED.md) for a step-by-step setup guide. > **New here?** Start with [GETTING_STARTED.md](GETTING_STARTED.md) for a step-by-step setup guide.
> >
> **AI Assistant?** See [AI_CONTEXT.md](AI_CONTEXT.md) for project context and conventions. > **AI Assistant?** See [CLAUDE.md](CLAUDE.md) for EXACT module templates and step-by-step instructions.
> Also see [AI_CONTEXT.md](AI_CONTEXT.md) for project context and conventions.
## Architecture Overview ## Architecture Overview