( ′∀`)σ≡σ☆))Д′)レ(゚∀゚;)ヘ=З=З=Зε≡(ノ´_ゝ`)ノ HEX
HEX
Server: Apache/2.4.58 (Ubuntu)
System: Linux mail.thebrand.ai 6.8.0-107-generic #107-Ubuntu SMP PREEMPT_DYNAMIC Fri Mar 13 19:51:50 UTC 2026 x86_64
User: www-data (33)
PHP: 8.3.6
Disabled: NONE
Upload Files
File: /var/www/html/tmpr/../tmpr/../tmpr/../tmpr/../tmpr/..//tmpr/..//n8nphp/CLAUDE.md
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

Laravel N8N is a Laravel package that provides a fluent client for the n8n public REST API and webhook triggering. It enables Laravel applications to interact with n8n workflows, executions, credentials, users, projects, and other n8n resources.

- **Namespace**: `KayedSpace\N8n`
- **PHP Version**: >=8.2
- **Laravel Version**: >=10

## Project Structure

```
src/
├── Client/
│   ├── Api/               # API resource classes (Workflows, Executions, etc.)
│   │   └── AbstractApi.php  # Base class with logging, caching, events, metrics
│   ├── Webhook/
│   │   └── Webhooks.php   # Webhook triggering with async queue support
│   └── N8nClient.php      # Main client class
├── Concerns/
│   └── HasPagination.php  # Trait for auto-pagination (all(), listIterator())
├── Console/               # Artisan commands for n8n management
│   ├── HealthCheckCommand.php
│   ├── ListWorkflowsCommand.php
│   ├── ActivateWorkflowCommand.php
│   ├── DeactivateWorkflowCommand.php
│   ├── ExecutionStatusCommand.php
│   └── TestWebhookCommand.php
├── Events/                # Laravel events for observability
│   ├── N8nEvent.php       # Base event class
│   ├── WorkflowCreated.php, WorkflowUpdated.php, etc.
│   ├── ExecutionCompleted.php, ExecutionFailed.php
│   ├── WebhookTriggered.php
│   ├── ApiRequestCompleted.php
│   └── RateLimitEncountered.php
├── Exceptions/            # Domain-specific exceptions
│   ├── N8nException.php   # Base exception with response context
│   ├── WorkflowNotFoundException.php
│   ├── ExecutionFailedException.php
│   ├── RateLimitException.php
│   └── AuthenticationException.php
├── Http/
│   └── Middleware/
│       └── VerifyN8nWebhook.php  # Webhook signature verification middleware
├── Jobs/
│   └── TriggerN8nWebhook.php     # Queue job for async webhooks
├── Facades/
│   └── N8nClient.php      # Laravel facade
├── Enums/
│   └── RequestMethod.php  # HTTP method enum
└── N8nServiceProvider.php # Service provider

config/
└── n8n.php               # Comprehensive configuration file

tests/
├── Unit/                 # Unit tests organized by class
└── Architecture/         # Architecture tests
```

## Architecture

### Client Design

The package follows a resource-based architecture with extensive features:

1. **N8nClient**: Main entry point that instantiates resource classes
2. **AbstractApi**: Enhanced base class for API resources that handles:
   - Authentication via `X-N8N-API-KEY` header
   - Request preparation (query parameter cleaning, boolean conversion)
   - **Logging**: PSR-3 compatible logging with configurable channels
   - **Caching**: Response caching with automatic invalidation on mutations
   - **Events**: Dispatches Laravel events for all operations
   - **Metrics**: Tracks request counts, duration, and status codes
   - **Retry Strategy**: Exponential/linear backoff with configurable delays
   - **Rate Limiting**: Auto-wait functionality for 429 responses
   - **Middleware**: Request pipeline customization via `middleware()` method
   - **Macros**: Extensibility via Laravel's Macroable trait
   - **Debug Mode**: Verbose request/response dumping
3. **Resource Classes**: Each n8n API resource extends AbstractApi and includes:
   - **Pagination Helpers**: `all()` and `listIterator()` methods
   - **Batch Operations**: `activateMany()`, `deleteMany()`, etc.
   - **Event Dispatching**: Resource-specific events (WorkflowCreated, etc.)
4. **Webhooks**: Enhanced webhook class with:
   - Async queue support via `async()` method
   - Signature verification (HMAC SHA-256)
   - Event dispatching for webhook triggers
   - Middleware for route protection

### Response Format

**Backward Compatible**: All methods return `Collection|array` union types:
- Returns `Collection` when `n8n.return_type = 'collection'` (default)
- Returns `array` when `n8n.return_type = 'array'`
- **Collections implement `ArrayAccess`** so `$data['key']` still works!
- This means **zero breaking changes** - existing code continues to work

### HTTP Client

- Uses Laravel's HTTP client (`Illuminate\Http\Client\PendingRequest`)
- Comprehensive configuration via `config/n8n.php`:
  - Timeout, retry count, throw on errors
  - Smart retry strategies (exponential, linear, constant)
  - Rate limit auto-wait with configurable max wait time
  - Request/response logging with body inclusion control
- API resources automatically add API key authentication
- Webhooks support Basic Auth with per-request override

### Events System

All operations dispatch Laravel events for observability:
- **Workflow Events**: WorkflowCreated, WorkflowUpdated, WorkflowDeleted, WorkflowActivated, WorkflowDeactivated
- **Execution Events**: ExecutionCompleted, ExecutionFailed, ExecutionDeleted
- **Webhook Events**: WebhookTriggered
- **API Events**: ApiRequestCompleted (every request), RateLimitEncountered
- Events can be disabled via `n8n.events.enabled = false`

### Exception Hierarchy

Domain-specific exceptions with response context:
- `N8nException` - Base exception with response data and context
- `WorkflowNotFoundException` - 404 workflow errors
- `ExecutionNotFoundException` - 404 execution errors
- `ExecutionFailedException` - Failed/crashed executions
- `CredentialException` - Credential-related errors
- `RateLimitException` - 429 responses with retry-after info
- `AuthenticationException` - 401/403 errors
- `ValidationException` - 422 validation errors with error details

### Configuration

Comprehensive configuration structure:
```
n8n.api.base_url          # n8n REST API URL
n8n.api.key               # API authentication key
n8n.api.version           # API version (default: v1)
n8n.webhook.base_url      # Webhook trigger URL
n8n.webhook.username      # Basic auth username
n8n.webhook.password      # Basic auth password
n8n.webhook.signature_key # HMAC signature verification key
n8n.timeout               # Request timeout (seconds)
n8n.throw                 # Throw exceptions on errors
n8n.retry                 # Number of retry attempts
n8n.retry_strategy        # Retry configuration
n8n.rate_limiting         # Auto-wait configuration
n8n.logging               # Logging configuration
n8n.events                # Events toggle
n8n.cache                 # Caching configuration
n8n.queue                 # Async webhook queue config
n8n.debug                 # Debug mode toggle
n8n.return_type           # 'collection' or 'array'
n8n.metrics               # Metrics tracking config
```

## Common Commands

### Artisan Commands

The package provides CLI commands for n8n management:

```bash
# Check n8n instance connectivity
php artisan n8n:health

# List workflows
php artisan n8n:workflows:list --limit=20 --active=true

# Activate/deactivate workflows
php artisan n8n:workflows:activate {workflow-id}
php artisan n8n:workflows:deactivate {workflow-id}

# Check execution status
php artisan n8n:executions:status {execution-id}

# Test webhook trigger
php artisan n8n:test-webhook {path} --data='{"key":"value"}'
```

### Testing
```bash
# Run all tests
composer test
# or
vendor/bin/pest

# Run without coverage
vendor/bin/pest --no-coverage

# Run specific test file
vendor/bin/pest tests/Unit/Client/Api/WorkflowsTest.php
```

### Code Style
```bash
# Run Laravel Pint to fix code style
composer pint
# or
vendor/bin/pint
```

### Publishing Config
```bash
php artisan vendor:publish --tag=n8n-config
```

## Development Guidelines

### Adding New API Resources

1. Create a new class in `src/Client/Api/` extending `AbstractApi`
2. Use `HasPagination` trait if the resource supports pagination
3. Add the resource method to `N8nClient.php`
4. Create corresponding tests in `tests/Unit/Client/Api/`
5. Use the `request()` method from AbstractApi for all HTTP calls
6. Type hint with `RequestMethod` enum
7. Return `Collection|array` for backward compatibility

Example:
```php
class MyResource extends AbstractApi
{
    use HasPagination;  // Adds all() and listIterator() methods

    public function list(array $filters = []): Collection|array
    {
        return $this->request(RequestMethod::Get, '/my-resource', $filters);
    }

    public function deleteMany(array $ids): array
    {
        $results = [];
        foreach ($ids as $id) {
            try {
                $result = $this->delete($id);
                $results[$id] = ['success' => true, 'data' => $result];
            } catch (\Exception $e) {
                $results[$id] = ['success' => false, 'error' => $e->getMessage()];
            }
        }
        return $results;
    }
}
```

### Enhanced Features Usage

#### Caching
```php
// Cache this request
$workflows = N8nClient::workflows()->cached()->list();

// Force fresh data
$workflow = N8nClient::workflows()->fresh()->get($id);
```

#### Pagination
```php
// Auto-paginate all items
$allWorkflows = N8nClient::workflows()->all(['active' => true]);

// Memory-efficient iterator
foreach (N8nClient::workflows()->listIterator() as $workflow) {
    // Process one at a time
}
```

#### Middleware
```php
N8nClient::workflows()
    ->middleware(fn($client) => $client->withHeaders(['X-Custom' => 'value']))
    ->list();
```

#### Batch Operations
```php
// Activate multiple workflows
$results = N8nClient::workflows()->activateMany(['id1', 'id2', 'id3']);

// Delete multiple executions
$results = N8nClient::executions()->deleteMany([101, 102, 103]);
```

#### Async Webhooks
```php
// Queue webhook trigger
N8nClient::webhooks()->async()->request('/my-webhook', $data);

// Synchronous (default)
N8nClient::webhooks()->sync()->request('/my-webhook', $data);
```

#### Execution Polling
```php
// Wait for execution to complete (max 60s, poll every 2s)
$execution = N8nClient::executions()->wait($executionId, timeout: 60, interval: 2);
```

### Testing Approach

- Uses Pest PHP for testing
- Tests extend `Tests\TestCase` (Orchestra Testbench)
- Mock HTTP responses using Laravel's HTTP fake
- All API methods should have corresponding tests
- Test both array and Collection response formats

### Query Parameter Handling

AbstractApi automatically handles:
- Null values are removed from query strings
- Boolean values converted to 'true'/'false' strings
- Nested arrays are recursively processed

### Error Handling

Enhanced exception handling:
- Domain-specific exceptions with response context
- `RateLimitException` includes retry-after information
- All exceptions provide `getResponse()` and `getContext()` methods
- Automatic conversion of HTTP errors to domain exceptions

## Environment Variables

### Required for API Access
```env
N8N_API_BASE_URL=https://your-n8n-instance.com/api/v1
N8N_API_KEY=your_api_key
```

### Webhooks Configuration
```env
N8N_WEBHOOK_BASE_URL=https://your-n8n-instance.com/webhook
N8N_WEBHOOK_USERNAME=username                    # Basic auth username
N8N_WEBHOOK_PASSWORD=password                    # Basic auth password
N8N_WEBHOOK_SIGNATURE_KEY=your_secret_key        # For signature verification
```

### HTTP Client Configuration
```env
N8N_TIMEOUT=120                                  # Request timeout (seconds)
N8N_THROW=true                                   # Throw exceptions on errors
N8N_RETRY=3                                      # Number of retry attempts
N8N_RETRY_STRATEGY=exponential                   # constant, linear, exponential
N8N_RETRY_MAX_DELAY=10000                       # Max retry delay (ms)
```

### Rate Limiting
```env
N8N_RATE_LIMIT_AUTO_WAIT=true                   # Auto-wait on 429 responses
N8N_RATE_LIMIT_MAX_WAIT=60                      # Max wait time (seconds)
```

### Logging
```env
N8N_LOGGING_ENABLED=false                        # Enable API request logging
N8N_LOGGING_CHANNEL=stack                        # Laravel log channel
N8N_LOGGING_LEVEL=debug                          # debug, info, error
N8N_LOG_REQUEST_BODY=true                        # Include request bodies
N8N_LOG_RESPONSE_BODY=true                       # Include response bodies
```

### Events
```env
N8N_EVENTS_ENABLED=true                          # Enable Laravel events
```

### Caching
```env
N8N_CACHE_ENABLED=false                          # Enable response caching
N8N_CACHE_STORE=default                          # Cache store to use
N8N_CACHE_TTL=300                                # Cache TTL (seconds)
N8N_CACHE_PREFIX=n8n                             # Cache key prefix
```

### Queue (Async Webhooks)
```env
N8N_QUEUE_ENABLED=false                          # Enable async webhooks
N8N_QUEUE_CONNECTION=default                     # Queue connection
N8N_QUEUE_NAME=default                           # Queue name
```

### General
```env
N8N_DEBUG=false                                  # Enable debug mode
N8N_RETURN_TYPE=collection                       # collection or array
N8N_METRICS_ENABLED=false                        # Enable metrics tracking
N8N_METRICS_STORE=default                        # Metrics cache store
```

## Advanced Features

### Event Listeners

Listen to n8n events in your Laravel application:

```php
// In EventServiceProvider
protected $listen = [
    WorkflowCreated::class => [
        LogWorkflowCreation::class,
        NotifyTeam::class,
    ],
    ExecutionFailed::class => [
        SendFailureAlert::class,
    ],
    RateLimitEncountered::class => [
        LogRateLimit::class,
    ],
];
```

### Webhook Signature Verification

Protect your webhook endpoints:

```php
// In routes/web.php or api.php
Route::post('/n8n/webhook', function (Request $request) {
    // Webhook data is verified by middleware
    $data = $request->all();
    // Process webhook...
})->middleware('n8n.webhook');

// Register middleware in Http/Kernel.php
protected $routeMiddleware = [
    'n8n.webhook' => \KayedSpace\N8n\Http\Middleware\VerifyN8nWebhook::class,
];
```

Manual verification:
```php
use KayedSpace\N8n\Client\Webhook\Webhooks;

if (Webhooks::verifySignature($request)) {
    // Valid signature
}
```

### Macros for Extensibility

Extend the client with custom methods:

```php
// In a service provider
use KayedSpace\N8n\Client\Api\Workflows;

Workflows::macro('findByName', function (string $name) {
    $workflows = $this->list(['name' => $name]);
    return $workflows[0] ?? null;
});

// Usage
$workflow = N8nClient::workflows()->findByName('My Workflow');
```

### Metrics Tracking

Track API usage metrics:

```php
// Metrics are automatically stored in cache
// Access via cache store
$totalRequests = Cache::get('n8n:metrics:'.date('Y-m-d-H').':total');
$avgDuration = Cache::get('n8n:metrics:'.date('Y-m-d-H').':duration');
```

## CI/CD

The project uses GitHub Actions for:
- **Tests**: Runs on PHP 8.2, 8.3, 8.4 with Laravel 10+
- **Linting**: Automatically runs Pint and commits fixes
- **Changelog**: Automated changelog updates

## Backward Compatibility

**All enhancements maintain 100% backward compatibility:**

1. **Return Types**: Methods return `Collection|array` union types
   - Collections implement `ArrayAccess` so `$data['key']` works
   - Set `n8n.return_type = 'array'` for pure arrays

2. **Method Signatures**: All existing methods maintain same parameters
   - New methods are additions, not replacements
   - Optional parameters have sensible defaults

3. **Configuration**: New config keys have defaults
   - Existing configs remain unchanged
   - New features opt-in via config

4. **Events**: Can be disabled via `n8n.events.enabled = false`

5. **Logging**: Disabled by default (`n8n.logging.enabled = false`)

6. **Caching**: Disabled by default (`n8n.cache.enabled = false`)

**Migration from v1.x**: No code changes required! Just update and optionally enable new features via config.