Files
Laravel-Docker-Dev-Template/docs/modules.md

317 lines
7.7 KiB
Markdown

# Modular Architecture
> **🤖 AI Agents**: For EXACT file templates and copy-paste code, see [CLAUDE.md](../CLAUDE.md).
> This document explains concepts; CLAUDE.md provides strict implementation patterns.
This template uses a modular architecture to organize features into self-contained modules. Each module has its own admin panel, routes, views, and permissions.
## Quick Start
```bash
# Create a new module
php artisan make:module StockManagement
# Create with a model
php artisan make:module StockManagement --model=Product
# Create with API routes
php artisan make:module StockManagement --api
# Skip Filament admin
php artisan make:module StockManagement --no-filament
```
## Module Structure
```
app/Modules/StockManagement/
├── Config/
│ └── stock_management.php # Module configuration
├── Database/
│ ├── Migrations/ # Module-specific migrations
│ └── Seeders/
│ └── StockManagementPermissionSeeder.php
├── Filament/
│ └── Resources/ # Admin panel resources
│ ├── StockManagementDashboardResource.php
│ └── ProductResource.php # If --model used
├── Http/
│ ├── Controllers/
│ │ └── StockManagementController.php
│ ├── Middleware/
│ └── Requests/
├── Models/
│ └── Product.php # If --model used
├── Policies/
├── Services/ # Business logic
├── Routes/
│ ├── web.php # Frontend routes
│ └── api.php # API routes (if --api)
├── Resources/
│ ├── views/
│ │ ├── index.blade.php # Module landing page
│ │ ├── layouts/
│ │ └── filament/
│ ├── css/
│ │ └── stock-management.css # Module-specific styles
│ └── lang/en/
├── Permissions.php # Module permissions
└── StockManagementServiceProvider.php
```
## How Modules Work
### Auto-Loading
The `ModuleServiceProvider` automatically:
- Discovers all modules in `app/Modules/`
- Registers each module's service provider
- Loads routes, views, migrations, and translations
### Routes
Module routes are prefixed and named automatically:
```php
// Routes/web.php
Route::prefix('stock-management')
->name('stock-management.')
->middleware(['web', 'auth'])
->group(function () {
Route::get('/', [StockManagementController::class, 'index'])
->name('index');
});
```
Access: `http://localhost:8080/stock-management`
### Views
Module views use a namespace based on the module slug:
```php
// In controller
return view('stock-management::index');
// In Blade
@include('stock-management::partials.header')
```
### Filament Admin
Each module gets its own navigation group in the admin panel:
```
📦 Stock Management
├── Dashboard
├── Products
└── Inventory
```
Resources are automatically discovered from `Filament/Resources/`.
## Permissions
### Defining Permissions
Each module has a `Permissions.php` file:
```php
// app/Modules/StockManagement/Permissions.php
return [
'stock_management.view' => 'View Stock Management',
'stock_management.create' => 'Create stock records',
'stock_management.edit' => 'Edit stock records',
'stock_management.delete' => 'Delete stock records',
'stock_management.export' => 'Export stock data',
];
```
### Seeding Permissions
After creating a module, run:
```bash
php artisan db:seed --class=PermissionSeeder
```
This registers all module permissions and assigns them to the admin role.
### Using Permissions
In Blade:
```blade
@can('stock_management.view')
<a href="{{ route('stock-management.index') }}">Stock Management</a>
@endcan
```
In Controllers:
```php
public function index()
{
$this->authorize('stock_management.view');
// ...
}
```
In Filament Resources:
```php
public static function canAccess(): bool
{
return auth()->user()?->can('stock_management.view') ?? false;
}
```
## Module Assets
### App-Wide CSS/JS
Use the main `resources/css/app.css` and `resources/js/app.js` for shared styles.
### Module-Specific Styles
Each module has its own CSS file at `Resources/css/{module-slug}.css`.
Include in Blade:
```blade
@push('module-styles')
<link href="{{ asset('modules/stock-management/css/stock-management.css') }}" rel="stylesheet">
@endpush
```
Or inline in the view:
```blade
@push('module-styles')
<style>
.stock-table { /* ... */ }
</style>
@endpush
```
## Creating Models
### With Module Command
```bash
php artisan make:module StockManagement --model=Product
```
Creates:
- `Models/Product.php`
- Migration in `Database/Migrations/`
- Filament resource with CRUD pages
### Adding Models Later
```bash
# From project root
php artisan make:model Modules/StockManagement/Models/Inventory -m
```
Then create the Filament resource:
```bash
php artisan make:filament-resource Inventory \
--model=App\\Modules\\StockManagement\\Models\\Inventory
```
Move the resource to your module's `Filament/Resources/` directory.
## Example: Stock Management Module
### 1. Create the Module
```bash
php artisan make:module StockManagement --model=Product --api
```
### 2. Edit the Migration
```php
// Database/Migrations/xxxx_create_products_table.php
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('sku')->unique();
$table->text('description')->nullable();
$table->decimal('price', 10, 2);
$table->integer('quantity')->default(0);
$table->timestamps();
});
```
### 3. Update the Model
```php
// Models/Product.php
protected $fillable = [
'name',
'sku',
'description',
'price',
'quantity',
];
protected $casts = [
'price' => 'decimal:2',
];
```
### 4. Update Filament Resource
```php
// Filament/Resources/ProductResource.php
public static function form(Form $form): Form
{
return $form->schema([
Forms\Components\TextInput::make('name')->required(),
Forms\Components\TextInput::make('sku')->required()->unique(ignoreRecord: true),
Forms\Components\Textarea::make('description'),
Forms\Components\TextInput::make('price')->numeric()->prefix('$'),
Forms\Components\TextInput::make('quantity')->numeric()->default(0),
]);
}
```
### 5. Run Migrations & Seed
```bash
php artisan migrate
php artisan db:seed --class=PermissionSeeder
```
### 6. Access
- Frontend: `http://localhost:8080/stock-management`
- Admin: `http://localhost:8080/admin` → Stock Management section
## Best Practices
1. **Keep modules independent** - Avoid tight coupling between modules
2. **Use services** - Put business logic in `Services/` not controllers
3. **Define clear permissions** - One permission per action
4. **Use policies** - For complex authorization rules
5. **Module-specific migrations** - Keep data schema with the module
6. **Test modules** - Create tests in `tests/Modules/ModuleName/`
## Troubleshooting
### Module not loading
1. Check service provider exists and is named correctly
2. Clear cache: `php artisan config:clear && php artisan cache:clear`
3. Check `ModuleServiceProvider` is in `bootstrap/providers.php`
### Views not found
1. Verify view namespace matches module slug (kebab-case)
2. Check views are in `Resources/views/`
### Permissions not working
1. Run `php artisan db:seed --class=PermissionSeeder`
2. Clear permission cache: `php artisan permission:cache-reset`
3. Verify user has role with permissions
### Filament resources not showing
1. Check resource is in `Filament/Resources/`
2. Verify `canAccess()` returns true for your user
3. Clear Filament cache: `php artisan filament:cache-components`