# AIPT Module Development Guide
## Complete Guide for Creating and Extending Modules

---

## Table of Contents

1. [Overview](#overview)
2. [Module Architecture](#module-architecture)
3. [Creating a New Module](#creating-a-new-module)
4. [Module Structure](#module-structure)
5. [Development Best Practices](#development-best-practices)
6. [Integration Patterns](#integration-patterns)
7. [Testing Modules](#testing-modules)
8. [Deployment](#deployment)
9. [Troubleshooting](#troubleshooting)
10. [Examples](#examples)

---

## Overview

The AIPT system uses a modular architecture based on the `nwidart/laravel-modules` package. This allows for:
- **Separation of Concerns**: Each module handles specific functionality
- **Scalability**: Easy to add new features without affecting existing code
- **Maintainability**: Modules can be developed and maintained independently
- **Reusability**: Modules can be shared across different projects

### Available Modules
- **Accounting**: Financial management and transactions
- **HR**: Human resources and employee management
- **Litigation**: Legal case management
- **Patent**: Patent application and management
- **TeamWatch**: Team monitoring and collaboration
- **TradeMarks**: Trademark management
- **Translation**: Translation services

---

## Module Architecture

### High-Level Architecture

```mermaid
graph TB
    subgraph "AIPT Core"
        A[Laravel Application]
        B[Core Models]
        C[Core Controllers]
        D[Core Views]
    end
    
    subgraph "Module Layer"
        E[Accounting Module]
        F[HR Module]
        G[Litigation Module]
        H[Patent Module]
        I[TeamWatch Module]
        J[TradeMarks Module]
        K[Translation Module]
    end
    
    subgraph "Shared Services"
        L[Authentication]
        M[Permissions]
        N[Notifications]
        O[File Management]
    end
    
    A --> E
    A --> F
    A --> G
    A --> H
    A --> I
    A --> J
    A --> K
    
    E --> L
    F --> L
    G --> L
    H --> L
    I --> L
    J --> L
    K --> L
```

### Module Dependencies

```mermaid
graph LR
    A[Core System] --> B[Authentication]
    A --> C[Permissions]
    A --> D[Database]
    
    B --> E[All Modules]
    C --> E
    D --> E
    
    E --> F[Accounting]
    E --> G[HR]
    E --> H[Litigation]
    E --> I[Patent]
    E --> J[TeamWatch]
    E --> K[TradeMarks]
    E --> L[Translation]
```

---

## Creating a New Module

### Prerequisites
- Laravel 9.x installed
- nwidart/laravel-modules package
- PHP 8.0+
- Composer

### Step 1: Generate Module
```bash
php artisan module:make YourModuleName
```

This creates the basic module structure:
```
Modules/YourModuleName/
├── Config/
│   └── config.php
├── Console/
├── Database/
│   ├── Migrations/
│   ├── Seeders/
│   └── factories/
├── Entities/
├── Http/
│   ├── Controllers/
│   ├── Middleware/
│   └── Requests/
├── Providers/
│   ├── YourModuleServiceProvider.php
│   └── RouteServiceProvider.php
├── Resources/
│   ├── assets/
│   ├── lang/
│   └── views/
├── Routes/
│   ├── api.php
│   └── web.php
├── Tests/
│   ├── Feature/
│   └── Unit/
├── composer.json
├── module.json
└── webpack.mix.js
```

### Step 2: Configure Module
Update `module.json`:
```json
{
    "name": "YourModuleName",
    "alias": "yourmodule",
    "description": "Your module description",
    "keywords": ["module", "aipt"],
    "priority": 0,
    "providers": [
        "Modules\\YourModuleName\\Providers\\YourModuleServiceProvider"
    ],
    "aliases": {},
    "files": [],
    "requires": []
}
```

### Step 3: Enable Module
```bash
php artisan module:enable YourModuleName
```

---

## Module Structure

### Directory Structure

```
Modules/YourModuleName/
├── Config/                    # Configuration files
│   └── config.php            # Module configuration
├── Console/                   # Artisan commands
│   └── Commands/             # Custom commands
├── Database/                  # Database related files
│   ├── Migrations/           # Database migrations
│   ├── Seeders/              # Database seeders
│   └── factories/            # Model factories
├── Entities/                  # Eloquent models
│   ├── YourEntity.php        # Main entity
│   └── YourEntityRelation.php # Related entities
├── Http/                      # HTTP layer
│   ├── Controllers/          # Controllers
│   │   ├── YourController.php
│   │   └── Api/              # API controllers
│   ├── Middleware/           # Custom middleware
│   ├── Requests/             # Form request validation
│   └── Resources/            # API resources
├── Providers/                 # Service providers
│   ├── YourModuleServiceProvider.php
│   └── RouteServiceProvider.php
├── Resources/                 # Views and assets
│   ├── assets/               # CSS, JS, images
│   │   ├── js/
│   │   ├── sass/
│   │   └── images/
│   ├── lang/                 # Language files
│   │   ├── en/
│   │   └── ar/
│   └── views/                # Blade templates
│       ├── layouts/
│       ├── components/
│       └── pages/
├── Routes/                    # Route definitions
│   ├── api.php              # API routes
│   └── web.php              # Web routes
├── Services/                  # Business logic services
│   ├── YourService.php
│   └── YourRepository.php
├── Tests/                     # Test files
│   ├── Feature/              # Feature tests
│   └── Unit/                 # Unit tests
├── composer.json             # Module dependencies
├── module.json              # Module metadata
└── webpack.mix.js           # Asset compilation
```

### Key Files Explained

#### Service Provider
```php
<?php

namespace Modules\YourModuleName\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Database\Eloquent\Factory;

class YourModuleServiceProvider extends ServiceProvider
{
    /**
     * @var string $moduleName
     */
    protected $moduleName = 'YourModuleName';

    /**
     * @var string $moduleNameLower
     */
    protected $moduleNameLower = 'yourmodulename';

    /**
     * Boot the application events.
     */
    public function boot()
    {
        $this->registerTranslations();
        $this->registerConfig();
        $this->registerViews();
        $this->loadMigrationsFrom(module_path($this->moduleName, 'Database/Migrations'));
    }

    /**
     * Register the service provider.
     */
    public function register()
    {
        $this->app->register(RouteServiceProvider::class);
    }

    /**
     * Register config.
     */
    protected function registerConfig()
    {
        $this->publishes([
            module_path($this->moduleName, 'Config/config.php') => config_path($this->moduleNameLower . '.php'),
        ], 'config');
        $this->mergeConfigFrom(
            module_path($this->moduleName, 'Config/config.php'), $this->moduleNameLower
        );
    }

    /**
     * Register views.
     */
    public function registerViews()
    {
        $viewPath = resource_path('views/modules/' . $this->moduleNameLower);

        $sourcePath = module_path($this->moduleName, 'Resources/views');

        $this->publishes([
            $sourcePath => $viewPath
        ], ['views', $this->moduleNameLower . '-module-views']);

        $this->loadViewsFrom(array_merge($this->getPublishableViewPaths(), [$sourcePath]), $this->moduleNameLower);
    }

    /**
     * Register translations.
     */
    public function registerTranslations()
    {
        $langPath = resource_path('lang/modules/' . $this->moduleNameLower);

        if (is_dir($langPath)) {
            $this->loadTranslationsFrom($langPath, $this->moduleNameLower);
        } else {
            $this->loadTranslationsFrom(module_path($this->moduleName, 'Resources/lang'), $this->moduleNameLower);
        }
    }

    /**
     * Get the services provided by the provider.
     */
    public function provides()
    {
        return [];
    }

    private function getPublishableViewPaths(): array
    {
        $paths = [];
        foreach (\Config::get('view.paths') as $path) {
            if (is_dir($path . '/modules/' . $this->moduleNameLower)) {
                $paths[] = $path . '/modules/' . $this->moduleNameLower;
            }
        }
        return $paths;
    }
}
```

#### Route Service Provider
```php
<?php

namespace Modules\YourModuleName\Providers;

use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;

class RouteServiceProvider extends ServiceProvider
{
    /**
     * The module namespace to assume when generating URLs to actions.
     */
    protected $moduleNamespace = 'Modules\YourModuleName\Http\Controllers';

    /**
     * Called before routes are registered.
     */
    public function boot()
    {
        parent::boot();
    }

    /**
     * Define the routes for the application.
     */
    public function map()
    {
        $this->mapApiRoutes();
        $this->mapWebRoutes();
    }

    /**
     * Define the "web" routes for the application.
     */
    protected function mapWebRoutes()
    {
        Route::middleware('web')
            ->namespace($this->moduleNamespace)
            ->group(module_path('YourModuleName', '/Routes/web.php'));
    }

    /**
     * Define the "api" routes for the application.
     */
    protected function mapApiRoutes()
    {
        Route::prefix('api')
            ->middleware('api')
            ->namespace($this->moduleNamespace)
            ->group(module_path('YourModuleName', '/Routes/api.php'));
    }
}
```

---

## Development Best Practices

### 1. Naming Conventions

#### Controllers
```php
// Use descriptive names
class TrademarkManagementController extends Controller
{
    // Methods should be descriptive
    public function createTrademark()
    public function updateTrademarkStatus()
    public function generateTrademarkReport()
}
```

#### Models (Entities)
```php
// Use singular, descriptive names
class TrademarkApplication extends Model
{
    // Use camelCase for attributes
    protected $fillable = [
        'trademarkName',
        'applicationNumber',
        'filingDate',
        'registrationDate'
    ];
}
```

#### Views
```
// Use kebab-case for view files
trademark-applications/
├── index.blade.php
├── create.blade.php
├── edit.blade.php
└── show.blade.php
```

### 2. Code Organization

#### Controller Structure
```php
<?php

namespace Modules\YourModuleName\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Routing\Controller;
use Modules\YourModuleName\Entities\YourEntity;
use Modules\YourModuleName\Http\Requests\YourRequest;

class YourController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        // Implementation
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        // Implementation
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(YourRequest $request)
    {
        // Implementation
    }

    /**
     * Display the specified resource.
     */
    public function show(YourEntity $entity)
    {
        // Implementation
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(YourEntity $entity)
    {
        // Implementation
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(YourRequest $request, YourEntity $entity)
    {
        // Implementation
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(YourEntity $entity)
    {
        // Implementation
    }
}
```

#### Model Structure
```php
<?php

namespace Modules\YourModuleName\Entities;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class YourEntity extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = [
        'name',
        'description',
        'status',
        'created_by',
        'updated_by'
    ];

    protected $casts = [
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
        'deleted_at' => 'datetime'
    ];

    // Relationships
    public function creator()
    {
        return $this->belongsTo(\App\Models\User::class, 'created_by');
    }

    public function updater()
    {
        return $this->belongsTo(\App\Models\User::class, 'updated_by');
    }

    // Scopes
    public function scopeActive($query)
    {
        return $query->where('status', 'active');
    }

    // Accessors & Mutators
    public function getNameAttribute($value)
    {
        return ucfirst($value);
    }

    public function setNameAttribute($value)
    {
        $this->attributes['name'] = strtolower($value);
    }
}
```

### 3. Validation

#### Form Request Classes
```php
<?php

namespace Modules\YourModuleName\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class YourRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize()
    {
        return true; // Implement authorization logic
    }

    /**
     * Get the validation rules that apply to the request.
     */
    public function rules()
    {
        $rules = [
            'name' => 'required|string|max:255',
            'description' => 'nullable|string|max:1000',
            'status' => 'required|in:active,inactive,pending'
        ];

        // Add conditional rules
        if ($this->isMethod('POST')) {
            $rules['name'] .= '|unique:your_entities,name';
        } else {
            $rules['name'] .= '|unique:your_entities,name,' . $this->route('entity')->id;
        }

        return $rules;
    }

    /**
     * Get custom messages for validator errors.
     */
    public function messages()
    {
        return [
            'name.required' => 'The name field is required.',
            'name.unique' => 'The name has already been taken.',
            'status.in' => 'The status must be active, inactive, or pending.'
        ];
    }
}
```

### 4. Error Handling

#### Controller Error Handling
```php
public function store(YourRequest $request)
{
    try {
        $entity = YourEntity::create($request->validated());
        
        return redirect()
            ->route('yourmodule.entities.index')
            ->with('success', 'Entity created successfully.');
            
    } catch (\Exception $e) {
        \Log::error('Error creating entity: ' . $e->getMessage());
        
        return redirect()
            ->back()
            ->withInput()
            ->with('error', 'An error occurred while creating the entity.');
    }
}
```

#### API Error Handling
```php
public function store(YourRequest $request)
{
    try {
        $entity = YourEntity::create($request->validated());
        
        return response()->json([
            'success' => true,
            'data' => $entity,
            'message' => 'Entity created successfully.'
        ], 201);
        
    } catch (\Exception $e) {
        \Log::error('API Error creating entity: ' . $e->getMessage());
        
        return response()->json([
            'success' => false,
            'error' => [
                'code' => 'CREATION_ERROR',
                'message' => 'An error occurred while creating the entity.'
            ]
        ], 500);
    }
}
```

---

## Integration Patterns

### 1. Core System Integration

#### Using Core Models
```php
use App\Models\User;
use App\Models\Department;

class YourEntity extends Model
{
    public function creator()
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    public function department()
    {
        return $this->belongsTo(Department::class);
    }
}
```

#### Using Core Services
```php
use App\Services\NotificationService;
use App\Services\AuditService;

class YourController extends Controller
{
    protected $notificationService;
    protected $auditService;

    public function __construct(NotificationService $notificationService, AuditService $auditService)
    {
        $this->notificationService = $notificationService;
        $this->auditService = $auditService;
    }

    public function store(YourRequest $request)
    {
        $entity = YourEntity::create($request->validated());
        
        // Send notification
        $this->notificationService->send('entity.created', $entity);
        
        // Log audit
        $this->auditService->log('entity.created', $entity);
        
        return redirect()->route('yourmodule.entities.index');
    }
}
```

### 2. Module-to-Module Integration

#### Cross-Module Relationships
```php
// In YourModule Entity
class YourEntity extends Model
{
    public function trademarkTickets()
    {
        return $this->hasMany(\Modules\TradeMarks\Entities\TradeMarkTicket::class, 'your_entity_id');
    }

    public function accountingTransactions()
    {
        return $this->hasMany(\Modules\Accounting\Entities\AccTransaction::class, 'related_id')
            ->where('related_table', 'your_entities');
    }
}
```

#### Event-Driven Integration
```php
// In YourModule Service
use Modules\TradeMarks\Events\TrademarkCreated;
use Modules\Accounting\Events\TransactionCreated;

class YourService
{
    public function createEntity($data)
    {
        $entity = YourEntity::create($data);
        
        // Fire events for other modules
        event(new TrademarkCreated($entity));
        event(new TransactionCreated($entity));
        
        return $entity;
    }
}
```

### 3. API Integration

#### API Resources
```php
<?php

namespace Modules\YourModuleName\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class YourEntityResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'description' => $this->description,
            'status' => $this->status,
            'created_at' => $this->created_at,
            'updated_at' => $this->updated_at,
            'creator' => new UserResource($this->whenLoaded('creator')),
            'relationships' => [
                'trademark_tickets' => TrademarkTicketResource::collection($this->whenLoaded('trademarkTickets')),
                'accounting_transactions' => AccTransactionResource::collection($this->whenLoaded('accountingTransactions'))
            ]
        ];
    }
}
```

#### API Controllers
```php
<?php

namespace Modules\YourModuleName\Http\Controllers\Api;

use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Routing\Controller;
use Modules\YourModuleName\Entities\YourEntity;
use Modules\YourModuleName\Http\Resources\YourEntityResource;

class YourEntityController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index(Request $request)
    {
        $entities = YourEntity::with(['creator', 'trademarkTickets'])
            ->when($request->search, function ($query, $search) {
                return $query->where('name', 'like', "%{$search}%");
            })
            ->when($request->status, function ($query, $status) {
                return $query->where('status', $status);
            })
            ->paginate($request->per_page ?? 15);

        return YourEntityResource::collection($entities);
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'description' => 'nullable|string|max:1000',
            'status' => 'required|in:active,inactive,pending'
        ]);

        $entity = YourEntity::create($validated);

        return new YourEntityResource($entity);
    }

    /**
     * Display the specified resource.
     */
    public function show(YourEntity $entity)
    {
        $entity->load(['creator', 'trademarkTickets', 'accountingTransactions']);

        return new YourEntityResource($entity);
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, YourEntity $entity)
    {
        $validated = $request->validate([
            'name' => 'sometimes|required|string|max:255',
            'description' => 'nullable|string|max:1000',
            'status' => 'sometimes|required|in:active,inactive,pending'
        ]);

        $entity->update($validated);

        return new YourEntityResource($entity);
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(YourEntity $entity)
    {
        $entity->delete();

        return response()->json([
            'success' => true,
            'message' => 'Entity deleted successfully.'
        ]);
    }
}
```

---

## Testing Modules

### 1. Unit Tests

#### Model Tests
```php
<?php

namespace Modules\YourModuleName\Tests\Unit;

use Tests\TestCase;
use Modules\YourModuleName\Entities\YourEntity;
use Illuminate\Foundation\Testing\RefreshDatabase;

class YourEntityTest extends TestCase
{
    use RefreshDatabase;

    /** @test */
    public function it_can_create_an_entity()
    {
        $entity = YourEntity::create([
            'name' => 'Test Entity',
            'description' => 'Test Description',
            'status' => 'active'
        ]);

        $this->assertDatabaseHas('your_entities', [
            'name' => 'Test Entity',
            'status' => 'active'
        ]);
    }

    /** @test */
    public function it_can_soft_delete_an_entity()
    {
        $entity = YourEntity::create([
            'name' => 'Test Entity',
            'status' => 'active'
        ]);

        $entity->delete();

        $this->assertSoftDeleted('your_entities', [
            'id' => $entity->id
        ]);
    }

    /** @test */
    public function it_can_scope_active_entities()
    {
        YourEntity::create(['name' => 'Active Entity', 'status' => 'active']);
        YourEntity::create(['name' => 'Inactive Entity', 'status' => 'inactive']);

        $activeEntities = YourEntity::active()->get();

        $this->assertCount(1, $activeEntities);
        $this->assertEquals('Active Entity', $activeEntities->first()->name);
    }
}
```

### 2. Feature Tests

#### Controller Tests
```php
<?php

namespace Modules\YourModuleName\Tests\Feature;

use Tests\TestCase;
use Modules\YourModuleName\Entities\YourEntity;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;

class YourEntityControllerTest extends TestCase
{
    use RefreshDatabase, WithFaker;

    /** @test */
    public function it_can_display_entities_index()
    {
        $entities = YourEntity::factory()->count(3)->create();

        $response = $this->get(route('yourmodule.entities.index'));

        $response->assertStatus(200);
        $response->assertViewIs('yourmodule::entities.index');
        $response->assertViewHas('entities');
    }

    /** @test */
    public function it_can_create_an_entity()
    {
        $data = [
            'name' => $this->faker->name,
            'description' => $this->faker->sentence,
            'status' => 'active'
        ];

        $response = $this->post(route('yourmodule.entities.store'), $data);

        $response->assertRedirect(route('yourmodule.entities.index'));
        $this->assertDatabaseHas('your_entities', $data);
    }

    /** @test */
    public function it_validates_required_fields()
    {
        $response = $this->post(route('yourmodule.entities.store'), []);

        $response->assertSessionHasErrors(['name', 'status']);
    }
}
```

### 3. API Tests

#### API Controller Tests
```php
<?php

namespace Modules\YourModuleName\Tests\Feature;

use Tests\TestCase;
use Modules\YourModuleName\Entities\YourEntity;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;

class YourEntityApiTest extends TestCase
{
    use RefreshDatabase, WithFaker;

    /** @test */
    public function it_can_list_entities_via_api()
    {
        $entities = YourEntity::factory()->count(3)->create();

        $response = $this->getJson('/api/yourmodule/entities');

        $response->assertStatus(200);
        $response->assertJsonStructure([
            'data' => [
                '*' => ['id', 'name', 'description', 'status', 'created_at']
            ]
        ]);
    }

    /** @test */
    public function it_can_create_entity_via_api()
    {
        $data = [
            'name' => $this->faker->name,
            'description' => $this->faker->sentence,
            'status' => 'active'
        ];

        $response = $this->postJson('/api/yourmodule/entities', $data);

        $response->assertStatus(201);
        $response->assertJsonStructure([
            'data' => ['id', 'name', 'description', 'status', 'created_at']
        ]);
        $this->assertDatabaseHas('your_entities', $data);
    }

    /** @test */
    public function it_can_update_entity_via_api()
    {
        $entity = YourEntity::factory()->create();
        $data = ['name' => 'Updated Name'];

        $response = $this->putJson("/api/yourmodule/entities/{$entity->id}", $data);

        $response->assertStatus(200);
        $this->assertDatabaseHas('your_entities', [
            'id' => $entity->id,
            'name' => 'Updated Name'
        ]);
    }

    /** @test */
    public function it_can_delete_entity_via_api()
    {
        $entity = YourEntity::factory()->create();

        $response = $this->deleteJson("/api/yourmodule/entities/{$entity->id}");

        $response->assertStatus(200);
        $this->assertSoftDeleted('your_entities', ['id' => $entity->id]);
    }
}
```

---

## Deployment

### 1. Development Environment

#### Local Development
```bash
# Enable module
php artisan module:enable YourModuleName

# Run migrations
php artisan migrate

# Compile assets
npm run dev

# Run tests
php artisan test --testsuite=YourModuleName
```

#### Docker Development
```dockerfile
# Dockerfile for module development
FROM php:8.0-fpm

# Install dependencies
RUN apt-get update && apt-get install -y \
    git \
    curl \
    libpng-dev \
    libonig-dev \
    libxml2-dev \
    zip \
    unzip

# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd

# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Set working directory
WORKDIR /var/www

# Copy application files
COPY . .

# Install dependencies
RUN composer install --no-dev --optimize-autoloader

# Set permissions
RUN chown -R www-data:www-data /var/www
```

### 2. Production Deployment

#### Module Installation
```bash
# Install module dependencies
composer install --no-dev --optimize-autoloader

# Enable module
php artisan module:enable YourModuleName

# Run migrations
php artisan migrate --force

# Clear caches
php artisan config:cache
php artisan route:cache
php artisan view:cache

# Compile assets
npm run production
```

#### Environment Configuration
```env
# .env configuration for module
MODULE_YOURMODULENAME_ENABLED=true
MODULE_YOURMODULENAME_API_KEY=your_api_key
MODULE_YOURMODULENAME_WEBHOOK_URL=https://your-webhook-url.com
```

---

## Troubleshooting

### Common Issues

#### 1. Module Not Loading
**Problem**: Module routes not accessible
**Solution**:
```bash
# Check if module is enabled
php artisan module:list

# Enable module
php artisan module:enable YourModuleName

# Clear caches
php artisan config:cache
php artisan route:cache
```

#### 2. Class Not Found Errors
**Problem**: `Class 'Modules\YourModuleName\Entities\YourEntity' not found`
**Solution**:
```bash
# Regenerate autoloader
composer dump-autoload

# Clear caches
php artisan config:cache
```

#### 3. View Not Found Errors
**Problem**: `View [yourmodule::entities.index] not found`
**Solution**:
```bash
# Publish views
php artisan vendor:publish --tag=yourmodule-views

# Clear view cache
php artisan view:clear
```

#### 4. Migration Errors
**Problem**: Migration fails to run
**Solution**:
```bash
# Check migration status
php artisan migrate:status

# Run specific migration
php artisan migrate --path=Modules/YourModuleName/Database/Migrations

# Rollback if needed
php artisan migrate:rollback
```

### Debugging Tips

#### 1. Enable Debug Mode
```env
APP_DEBUG=true
LOG_LEVEL=debug
```

#### 2. Check Logs
```bash
# View Laravel logs
tail -f storage/logs/laravel.log

# View module-specific logs
tail -f storage/logs/yourmodule.log
```

#### 3. Test Module Loading
```php
// In tinker
php artisan tinker

// Check if module is loaded
app('modules')->find('YourModuleName');

// Check module configuration
config('yourmodule');
```

---

## Examples

### Complete Module Example

#### 1. Module Structure
```
Modules/ProjectManagement/
├── Config/
│   └── config.php
├── Database/
│   ├── Migrations/
│   │   └── 2024_01_01_000000_create_projects_table.php
│   └── Seeders/
│       └── ProjectSeeder.php
├── Entities/
│   ├── Project.php
│   └── ProjectTask.php
├── Http/
│   ├── Controllers/
│   │   ├── ProjectController.php
│   │   └── Api/
│   │       └── ProjectController.php
│   ├── Requests/
│   │   └── ProjectRequest.php
│   └── Resources/
│       └── ProjectResource.php
├── Resources/
│   └── views/
│       └── projects/
│           ├── index.blade.php
│           ├── create.blade.php
│           ├── edit.blade.php
│           └── show.blade.php
├── Routes/
│   ├── web.php
│   └── api.php
├── Services/
│   └── ProjectService.php
├── Tests/
│   ├── Feature/
│   │   └── ProjectControllerTest.php
│   └── Unit/
│       └── ProjectTest.php
├── composer.json
└── module.json
```

#### 2. Project Entity
```php
<?php

namespace Modules\ProjectManagement\Entities;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class Project extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = [
        'name',
        'description',
        'status',
        'start_date',
        'end_date',
        'budget',
        'client_id',
        'manager_id',
        'created_by',
        'updated_by'
    ];

    protected $casts = [
        'start_date' => 'date',
        'end_date' => 'date',
        'budget' => 'decimal:2',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
        'deleted_at' => 'datetime'
    ];

    // Relationships
    public function client()
    {
        return $this->belongsTo(\App\Models\Client::class);
    }

    public function manager()
    {
        return $this->belongsTo(\App\Models\User::class, 'manager_id');
    }

    public function creator()
    {
        return $this->belongsTo(\App\Models\User::class, 'created_by');
    }

    public function updater()
    {
        return $this->belongsTo(\App\Models\User::class, 'updated_by');
    }

    public function tasks()
    {
        return $this->hasMany(ProjectTask::class);
    }

    // Scopes
    public function scopeActive($query)
    {
        return $query->where('status', 'active');
    }

    public function scopeCompleted($query)
    {
        return $query->where('status', 'completed');
    }

    // Accessors & Mutators
    public function getProgressAttribute()
    {
        $totalTasks = $this->tasks()->count();
        $completedTasks = $this->tasks()->where('status', 'completed')->count();
        
        return $totalTasks > 0 ? round(($completedTasks / $totalTasks) * 100, 2) : 0;
    }
}
```

#### 3. Project Controller
```php
<?php

namespace Modules\ProjectManagement\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Routing\Controller;
use Modules\ProjectManagement\Entities\Project;
use Modules\ProjectManagement\Http\Requests\ProjectRequest;
use Modules\ProjectManagement\Services\ProjectService;

class ProjectController extends Controller
{
    protected $projectService;

    public function __construct(ProjectService $projectService)
    {
        $this->projectService = $projectService;
    }

    /**
     * Display a listing of the resource.
     */
    public function index(Request $request)
    {
        $projects = $this->projectService->getProjects($request);
        
        return view('projectmanagement::projects.index', compact('projects'));
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        $clients = \App\Models\Client::all();
        $managers = \App\Models\User::where('role_id', 2)->get(); // Manager role
        
        return view('projectmanagement::projects.create', compact('clients', 'managers'));
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(ProjectRequest $request)
    {
        try {
            $project = $this->projectService->createProject($request->validated());
            
            return redirect()
                ->route('projectmanagement.projects.index')
                ->with('success', 'Project created successfully.');
                
        } catch (\Exception $e) {
            \Log::error('Error creating project: ' . $e->getMessage());
            
            return redirect()
                ->back()
                ->withInput()
                ->with('error', 'An error occurred while creating the project.');
        }
    }

    /**
     * Display the specified resource.
     */
    public function show(Project $project)
    {
        $project->load(['client', 'manager', 'tasks']);
        
        return view('projectmanagement::projects.show', compact('project'));
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(Project $project)
    {
        $clients = \App\Models\Client::all();
        $managers = \App\Models\User::where('role_id', 2)->get();
        
        return view('projectmanagement::projects.edit', compact('project', 'clients', 'managers'));
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(ProjectRequest $request, Project $project)
    {
        try {
            $this->projectService->updateProject($project, $request->validated());
            
            return redirect()
                ->route('projectmanagement.projects.index')
                ->with('success', 'Project updated successfully.');
                
        } catch (\Exception $e) {
            \Log::error('Error updating project: ' . $e->getMessage());
            
            return redirect()
                ->back()
                ->withInput()
                ->with('error', 'An error occurred while updating the project.');
        }
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(Project $project)
    {
        try {
            $this->projectService->deleteProject($project);
            
            return redirect()
                ->route('projectmanagement.projects.index')
                ->with('success', 'Project deleted successfully.');
                
        } catch (\Exception $e) {
            \Log::error('Error deleting project: ' . $e->getMessage());
            
            return redirect()
                ->back()
                ->with('error', 'An error occurred while deleting the project.');
        }
    }
}
```

---

## Conclusion

This guide provides a comprehensive overview of module development in the AIPT system. By following these patterns and best practices, you can create robust, maintainable, and well-integrated modules that extend the system's functionality.

### Key Takeaways

1. **Follow Laravel Conventions**: Use standard Laravel patterns and conventions
2. **Implement Proper Validation**: Always validate input data
3. **Handle Errors Gracefully**: Implement proper error handling and logging
4. **Write Tests**: Create comprehensive test coverage
5. **Document Your Code**: Maintain clear documentation
6. **Follow Security Best Practices**: Implement proper authorization and validation

### Next Steps

1. Review existing modules for reference
2. Set up your development environment
3. Create your first module following this guide
4. Implement tests and documentation
5. Deploy and monitor your module

---

*This module development guide is maintained by the AIPT development team. For the most up-to-date information, always refer to the latest version of this guide.*

**Last Updated**: [Current Date]  
**Guide Version**: 1.0  
**Laravel Version**: 9.x  
**Module Package**: nwidart/laravel-modules
