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
> **🚨 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.
## Template Overview
@@ -331,6 +334,7 @@ make restore file=... # Restore database
## Documentation Links
- **[CLAUDE.md](CLAUDE.md)** - 🚨 **AI AGENTS: START HERE** - Exact module templates
- [GETTING_STARTED.md](GETTING_STARTED.md) - Setup walkthrough
- [README.md](README.md) - Overview
- [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.
>
> **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