# FreePBX Integration - Professional Implementation

## 🎯 Overview

This implementation replaces the legacy `pbxCore.php` file with a professional, scalable architecture using FreePBX REST API, Laravel service classes, encrypted credentials, and async job processing.

## 📁 Architecture

```
app/
├── Services/PBX/
│   ├── Contracts/
│   │   └── PBXServiceInterface.php         # Service contract
│   ├── PBXApiClient.php                     # HTTP client for REST API
│   ├── ExtensionManager.php                 # Extension management service
│   └── PBXCredentialManager.php             # Credential management
├── Jobs/PBX/
│   ├── CreateExtensionJob.php               # Async extension creation
│   ├── UpdateExtensionJob.php               # Async extension updates
│   └── DeleteExtensionJob.php               # Async extension deletion
├── Exceptions/PBX/
│   ├── PBXException.php                     # Base exception
│   ├── PBXConnectionException.php           # Connection errors
│   └── ExtensionException.php               # Extension errors
├── Models/
│   └── PBXApiCredential.php                 # Encrypted credential storage
└── Console/Commands/PBX/
    ├── GenerateCredentialsCommand.php       # Generate API credentials
    └── TestConnectionCommand.php            # Test API connection

config/
└── pbx.php                                   # PBX configuration

database/migrations/
├── 2026_03_07_000001_create_pbx_api_credentials_table.php
└── 2026_03_07_000002_add_pbx_sync_fields_to_user_extensions.php
```

## 🔐 Security Features

### 1. **Encrypted Credential Storage**
- Credentials stored in Laravel database (encrypted using Laravel's encryption)
- No hardcoded passwords in code or `.env`
- Automatic decryption only at runtime
- Credentials activated in FreePBX `asterisk.rest_users` table

### 2. **Credential Rotation**
```bash
php artisan pbx:generate-credentials --rotate
```

### 3. **Audit Logging**
- All PBX operations logged via Laravel's logging system
- Activity tracking using Spatie ActivityLog (already installed)
- Sync status tracking in `user_extensions` table

## 🚀 Setup Instructions

### Step 1: Run Migrations
```bash
cd /var/www/ccsystem
php artisan migrate
```

### Step 2: Generate API Credentials
```bash
php artisan pbx:generate-credentials
```

This command will:
1. Generate a secure random username and secret
2. Store credentials encrypted in `pbx_api_credentials` table
3. Insert credentials into FreePBX `asterisk.rest_users` table
4. Display credential information

### Step 3: Test Connection
```bash
php artisan pbx:test-connection
```

### Step 4: Configure Queue Worker (Optional but Recommended)
The system uses Laravel queues for async processing:

```bash
# Start queue worker
php artisan queue:work redis --queue=pbx

# Or use supervisor for production
```

**Supervisor configuration** (`/etc/supervisor/conf.d/pbx-queue-worker.conf`):
```ini
[program:pbx-queue-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/ccsystem/artisan queue:work redis --queue=pbx --tries=3 --timeout=90
autostart=true
autorestart=true
user=www-data
numprocs=2
redirect_stderr=true
stdout_logfile=/var/www/ccsystem/storage/logs/pbx-queue-worker.log
```

### Step 5: Update .env (Optional Configurations)
```env
# FreePBX API Settings
FREEPBX_API_URL=http://127.0.0.1
FREEPBX_API_TIMEOUT=30

# Queue settings
FREEPBX_QUEUE_CONNECTION=redis
FREEPBX_QUEUE_NAME=pbx

# Retry settings
FREEPBX_MAX_ATTEMPTS=3
FREEPBX_BACKOFF=30

# WebRTC
FREEPBX_WEBRTC_ENABLED=true

# Logging
FREEPBX_LOG_LEVEL=info
```

## 📝 Usage Examples

### Create Extension (Async)
```php
use App\Jobs\PBX\CreateExtensionJob;

$extensionData = [
    'extension' => '1001',
    'secret' => 'securePassword123',
    'firstname' => 'John',
    'lastname' => 'Doe',
];

// Dispatch to queue (recommended)
CreateExtensionJob::dispatch($extensionData);

// Or dispatch immediately
CreateExtensionJob::dispatchSync($extensionData);
```

### Create Extension (Synchronous)
```php
use App\Services\PBX\ExtensionManager;

$extensionManager = new ExtensionManager();

$response = $extensionManager->createExtension([
    'extension' => '1001',
    'secret' => 'securePassword123',
    'firstname' => 'John',
    'lastname' => 'Doe',
]);

// Apply changes
$extensionManager->applyChanges();
```

### Update Extension
```php
use App\Jobs\PBX\UpdateExtensionJob;

UpdateExtensionJob::dispatch('1001', [
    'secret' => 'newPassword456',
    'firstname' => 'Jane',
]);
```

### Delete Extension
```php
use App\Jobs\PBX\DeleteExtensionJob;

DeleteExtensionJob::dispatch('1001');
```

### Check Sync Status
```php
use Modules\Platform\User\Entities\UserExtension;

$extension = UserExtension::where('sip_extension', '1001')->first();

echo $extension->pbx_sync_status;      // pending|syncing|synced|failed
echo $extension->pbx_last_synced_at;   // Carbon timestamp
echo $extension->pbx_sync_error;       // Error message if failed
```

## 🔧 Extension Configuration

The system preserves all important configuration from the original `pbxCore.php`:

### Recording Settings (as required)
```php
'recording_in_external' => 'force',   // Force recording on inbound external
'recording_out_external' => 'force',  // Force recording on outbound external
'recording_in_internal' => 'force',   // Force recording on inbound internal
'recording_out_internal' => 'force',  // Force recording on outbound internal
```

### PJSIP Settings
- Context: `from-internal`
- DTMF Mode: `rfc4733`
- Direct Media: `yes`
- WebRTC Support: Configurable
- Call Recording: Enforced
- And 60+ other PJSIP parameters

### Override Defaults
```php
$extensionManager->createExtension([
    'extension' => '1001',
    'secret' => 'password',
    'firstname' => 'John',
    'lastname' => 'Doe',
    // Override defaults
    'recording_in_external' => 'dontcare',
    'dtmfmode' => 'auto',
    'context' => 'custom-context',
]);
```

## 🔄 Migration from Old System

### Old Way (Deprecated)
```php
// ❌ OLD - Using pbxCore.php
$options = [
    'extension' => '1001',
    'secret' => 'password',
    'firstname' => 'John',
    'lastname' => 'Doe',
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://127.0.0.1/pbxCore.php");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($options));
```

### New Way (Current)
```php
// ✅ NEW - Using PBX Service
use App\Jobs\PBX\CreateExtensionJob;

CreateExtensionJob::dispatch([
    'extension' => '1001',
    'secret' => 'password',
    'firstname' => 'John',
    'lastname' => 'Doe',
]);
```

### UserService Integration
The `UserService` has been updated:
- `addAsteriskUser()` - Now uses `CreateExtensionJob`
- `updateAsteriskUser()` - Now uses `UpdateExtensionJob`
- `updateAsteriskPass()` - Now uses `UpdateExtensionJob`
- `curlCore()` - Deprecated with warning log

## 📊 Monitoring & Debugging

### Check Queue Status
```bash
# View failed jobs
php artisan queue:failed

# Retry failed job
php artisan queue:retry {job-id}

# Retry all failed jobs
php artisan queue:retry all
```

### Check Logs
```bash
tail -f storage/logs/laravel.log | grep PBX
```

### Check Sync Status
```sql
SELECT 
    sip_extension,
    pbx_sync_status,
    pbx_last_synced_at,
    pbx_sync_error,
    pbx_sync_attempts
FROM user_extensions
WHERE pbx_sync_status != 'synced';
```

## 🛠 Troubleshooting

### Connection Issues
1. Verify FreePBX REST API module is installed:
   ```bash
   fwconsole ma list | grep restapps
   ```

2. Test credentials manually:
   ```bash
   curl -u "username:secret" http://127.0.0.1/admin/api/api/system/status
   ```

3. Check API credentials in database:
   ```sql
   SELECT id, name, api_user, is_active, last_used_at 
   FROM pbx_api_credentials 
   WHERE is_active = 1;
   ```

### Jobs Not Processing
1. Ensure queue worker is running
2. Check Redis connection
3. Verify queue configuration in `.env`

### Extension Not Created
1. Check job status: `php artisan queue:failed`
2. Check logs: `storage/logs/laravel.log`
3. Check sync status in `user_extensions` table
4. Test connection: `php artisan pbx:test-connection`

## 🗑 Deprecation Notice

### Files to Remove (After Testing)
- ❌ `/public/pbxCore.php` - Old insecure implementation

### Methods Deprecated
- ❌ `UserService::curlCore()` - Use jobs instead

## 🎓 Benefits Over Old System

| Feature | Old System | New System |
|---------|-----------|------------|
| **Security** | Hardcoded password in file | Encrypted in database |
| **Authentication** | IP check only | API token authentication |
| **Error Handling** | None | Comprehensive with retry |
| **Logging** | None | Full audit trail |
| **Async Processing** | Blocking | Queue-based async |
| **Scalability** | Single threaded | Multi-worker support |
| **Testing** | Impossible | Unit testable |
| **Maintenance** | Hardcoded config | Centralized config |
| **Monitoring** | None | Status tracking |

## 📚 Additional Resources

- [FreePBX REST API Documentation](https://wiki.freepbx.org/display/FOP/REST+API)
- [Laravel Queue Documentation](https://laravel.com/docs/queues)
- [Laravel Encryption](https://laravel.com/docs/encryption)

## 🤝 Support

For issues or questions:
1. Check logs: `storage/logs/laravel.log`
2. Run diagnostics: `php artisan pbx:test-connection`
3. Review this documentation
4. Check FreePBX logs: `/var/log/asterisk/full`
