# Console Plugin — Job Activity Monitor

The Console plugin adds a real-time job monitor to the Cydekick admin panel.

- **Header widget** — a dark pill in the topbar showing the currently running job with a pulsing green dot. Click it to open the panel.
- **Console panel** — a slide-in right panel with a terminal aesthetic showing all job activity, grouped by time, with tabs for Running / Errors / All.

---

## Architecture

```
plugins/webkul/console/
├── src/
│   ├── ConsoleServiceProvider.php   — registers everything
│   ├── Models/JobActivityLog.php    — DB model for log entries
│   ├── Services/JobLogger.php       — static helper used by jobs
│   └── Livewire/
│       ├── JobStatusBar.php         — header widget (polls every 3s)
│       └── JobConsolePanel.php      — slide-in panel (polls when open)
├── database/migrations/
│   └── 2026_05_11_100001_create_job_activity_logs_table.php
└── resources/views/
    ├── livewire/
    │   ├── job-status-bar.blade.php
    │   └── job-console-panel.blade.php
    └── components/
        ├── status-bar-hook.blade.php   — injected via GLOBAL_SEARCH_BEFORE
        └── console-panel-hook.blade.php — injected via BODY_END
```

The `job_activity_logs` table stores every log entry:

| Column | Description |
|---|---|
| `display_name` | Human-readable message shown in the console |
| `status` | `running` / `ok` / `error` / `info` / `warn` |
| `progress` | JSON `{done, total, percent}` for progress bars |
| `started_at` / `finished_at` | Timestamps for duration calculation |
| `duration_ms` | Auto-calculated on completion |
| `job_class` | PHP class name for filtering |

---

## Adding Console Logs to a New Plugin or Job

### 1. Import the logger

```php
use Webkul\Console\Services\JobLogger;
```

### 2. Basic one-shot entries

```php
// Green OK
JobLogger::ok('SKU mapping refreshed · 9,088 variants');

// Blue INFO
JobLogger::info('Scheduled sync started · every-15-min');

// Yellow WARN
JobLogger::warn('Shopify rate-limit at 30/40 · backing off');

// Red ERROR
JobLogger::error('Connection failed: timeout after 30s');
```

### 3. Long-running job with progress bar

```php
public function handle(): void
{
    // 1. Open a running entry — save the returned ID
    $logId = JobLogger::running('Importing Shopify products · starting…');

    $total = count($items);

    foreach ($items as $i => $item) {
        // do work...

        // 2. Update progress every N items
        if ($i % 50 === 0) {
            JobLogger::progress(
                $logId,
                "Importing Shopify products · {$i} / {$total}",
                done: $i,
                total: $total,
            );
        }
    }

    // 3. Mark complete
    JobLogger::ok("Import complete · {$total} products synced", $logId);
}
```

If the job throws an exception, close the log entry with an error:

```php
} catch (\Throwable $e) {
    JobLogger::error('Import failed: ' . $e->getMessage(), $logId);
    throw $e;
}
```

### 4. One-shot entries anywhere (not just jobs)

`JobLogger` works from any class — controllers, scheduled commands, event listeners:

```php
// In a console command:
JobLogger::info('Nightly inventory snapshot complete');

// In a webhook handler:
JobLogger::ok('Order #1083 imported · 3 line items');
```

---

## Auto-logging (no code needed)

Any queued job that is **not** in the `$skipClasses` list in `ConsoleServiceProvider` is automatically logged:
- `JobProcessing` → creates a `running` entry
- `JobProcessed` → updates to `ok`
- `JobFailed` → updates to `error` with the exception message

Jobs that manage their own logging (like `ScrapeAllmakesPsp`, `ImportShopifyProductsJob`) are in the skip list to avoid duplicate entries. Add your job to the skip list if you use `JobLogger` calls directly within it:

```php
// In ConsoleServiceProvider::registerQueueListeners():
$skipClasses = [
    \Webkul\AllmakesPsp\Jobs\ScrapeAllmakesPsp::class,
    \Webkul\Channel\Jobs\ImportShopifyProductsJob::class,
    \YourPlugin\Jobs\YourJob::class,  // ← add here
];
```

---

## Status Badge Reference

| Status | Colour | When to use |
|---|---|---|
| `running` | Green | Job is actively processing |
| `ok` | Light green | Job completed successfully |
| `error` | Red | Job failed or threw an exception |
| `warn` | Yellow | Non-fatal issue (rate limit, retry, skip) |
| `info` | Blue | Informational milestone (sync started, count) |

---

## Pruning old logs

Logs older than 7 days should be pruned. Add to your scheduler in `app/Console/Kernel.php`:

```php
$schedule->call(fn () => \Webkul\Console\Services\JobLogger::prune(7))->daily();
```

Or call manually:
```php
JobLogger::prune(days: 3); // delete entries older than 3 days
```

---

## Production deployment

After deploying, run the migration on the server:

```bash
php artisan migrate --path=plugins/webkul/console/database/migrations --force
```
