
# تصدير سيرورة العمل وإعادة تشغيلها

يمكن لـ Queuety تصدير سجل التنفيذ الكامل لسيرورة عمل إلى صيغة JSON قابلة للنقل، وإعادة تشغيله في بيئة أخرى. يفيد ذلك في إعادة إنتاج أخطاء الإنتاج محليًا، ونقل سيرورات العمل بين البيئات، والتدقيق.

## تصدير سيرورة عمل

### PHP API

استدعِ `Queuety::export_workflow()` باستخدام معرّف سيرورة العمل. يعيد مصفوفة قابلة للتسلسل إلى JSON:

```php
use Queuety\Queuety;

$data = Queuety::export_workflow( $workflow_id );
```

للحصول مباشرة على سلسلة JSON:

```php
$json = json_encode( $data, JSON_PRETTY_PRINT );
file_put_contents( '/tmp/workflow-42.json', $json );
```

### CLI

```bash
wp queuety workflow export <id> [--output=<file>]
```

| الخيار | الوصف |
|---|---|
| `<id>` | معرّف سير العمل (مطلوب) |
| `--output=<file>` | مسار الملف الذي سيُكتب فيه JSON. الإخراج الافتراضي إلى stdout. |

```bash
# Print to stdout
wp queuety workflow export 42

# Write to a file
wp queuety workflow export 42 --output=/tmp/workflow-42.json
```

## إعادة تشغيل سيرورة عمل

### PHP API

استدعِ `Queuety::replay_workflow()` باستخدام بيانات التصدير. يعيد معرّف سيرورة العمل الجديد:

```php
use Queuety\Queuety;

$json = file_get_contents( '/tmp/workflow-42.json' );
$data = json_decode( $json, true );

$new_id = Queuety::replay_workflow( $data );
```

### CLI

```bash
wp queuety workflow replay <file>
```

| الخيار | الوصف |
|---|---|
| `<file>` | مسار ملف JSON المُصدّر (مطلوب) |

```bash
wp queuety workflow replay /tmp/workflow-42.json
# Success: Workflow replayed. New workflow ID: 85.
```

## بنية JSON

يتضمن التصدير حالة سيرورة العمل كاملة، والمهام المرتبطة بها، وأحداث الأثر، وإدخالات السجل، والإشارات المخزنة، والملفات المرفقة، والأجزاء، وأي صفوف انتظار لتبعيات سيرورات العمل:

```json
{
    "workflow": {
        "id": 42,
        "name": "generate_report",
        "status": "failed",
        "state": { "user_id": 1, "_steps": [...], "_queue": "default" },
        "current_step": 2,
        "total_steps": 4,
        "parent_workflow_id": null,
        "parent_step_index": null,
        "started_at": "2026-03-28 10:00:00",
        "completed_at": null,
        "failed_at": "2026-03-28 10:05:00",
        "error_message": "API timeout",
        "deadline_at": null
    },
    "jobs": [
        {
            "id": 100,
            "queue": "default",
            "handler": "App\\Handlers\\FetchDataHandler",
            "payload": {},
            "status": "completed",
            "attempts": 1,
            "max_attempts": 3,
            "step_index": 0
        }
    ],
    "events": [
        {
            "id": 1,
            "job_id": 100,
            "step_index": 0,
            "step_name": "fetchData",
            "step_type": "single",
            "handler": "App\\Handlers\\FetchDataHandler",
            "event": "step_completed",
            "input": { "user_id": 1 },
            "output": { "records": 150 },
            "state_before": { "user_id": 1 },
            "state_after": { "user_id": 1, "records": 150 },
            "context": { "source": "api" },
            "error": null,
            "duration_ms": 230,
            "created_at": "2026-03-28 10:00:01"
        }
    ],
    "logs": [
        {
            "id": 1,
            "event": "workflow_started",
            "handler": "generate_report",
            "created_at": "2026-03-28 10:00:00"
        }
    ],
    "signals": [],
    "artifacts": [],
    "chunks": [],
    "wait_dependencies": [],
    "exported_at": "2026-03-28T12:00:00+00:00",
    "queuety_version": "0.22.0"
}
```

اختُصرت بعض الحقول في المثال أعلاه. يتضمن التصدير الفعلي جميع أعمدة الأثر من كل صف حدث.

تحافظ صادرات سيرورات العمل أيضًا على البيانات الوصفية مثل `definition_version` و`definition_hash` و`idempotency_key` عندما تكون قد عُيّنت في التشغيل الأصلي.

## آلية عمل إعادة التشغيل

عند إعادة تشغيل سيرورة عمل مصدّرة:

1. يُنشأ صف جديد لسيرورة العمل بالحالة المصدّرة وتعريفات الخطوات
2. يكون اسم سيرورة العمل الجديدة `{original_name}_replay_{timestamp}`
3. تُدرج أحداث سيرورة العمل السابقة وإدخالات السجل مجددًا في البيئة الجديدة
4. تُعاد الإشارات المخزنة وصفوف تبعيات انتظار سيرورات العمل كحالة سابقة
5. إذا كانت سيرورة العمل الأصلية لا تزال `running`، تُدرج الخطوة الحالية في قائمة الانتظار لمعالجتها. لا تُدرج خطوات التكرار و`start_workflows()` مجددًا، لذا تبقى إعادة التشغيل التي تتوقف عند إحداهما في حالة `running` دون مهمة ([#17](https://github.com/inline0/queuety/issues/17))
6. إذا كانت سيرورة العمل الأصلية في الحالة `waiting_for_signal` أو `waiting_for_workflows` أو `paused` أو `failed` أو `cancelled` أو `completed`، تُحفظ تلك الحالة في سيرورة العمل المعاد تشغيلها

تحصل سيرورة العمل المعاد تشغيلها على معرّف جديد وتعمل بشكل مستقل. ولا تؤثر في الأصلية.

بالنسبة إلى عمليات إعادة التشغيل `waiting_for_workflows`، تُنشأ صفوف التبعيات المصدّرة مجددًا باستخدام معرّفات سيرورات العمل نفسها. يفيد ذلك في التدقيق وفي البيئات التي توجد فيها سيرورات العمل التابعة أيضًا، لكنه لا يعيد تعيين معرّفات التبعيات تلقائيًا بين البيئات.

## حالات الاستخدام

### إعادة إنتاج أخطاء الإنتاج

صدّر سيرورة عمل متعثرة من بيئة الإنتاج وأعد تشغيلها محليًا:

```bash
# On production
wp queuety workflow export 42 --output=/tmp/workflow-42.json

# Copy the file to your local environment

# On local
wp queuety workflow replay /tmp/workflow-42.json
```

تحتفظ سيرورة العمل المعاد تشغيلها بالحالة نفسها وتعريفات الخطوات نفسها تمامًا. تعيد سيرورات العمل قيد التشغيل إدراج الخطوة الحالية في قائمة الانتظار، لتتمكن من مواصلة التنفيذ من النقطة التي توقفت عندها. أما سيرورات العمل المتوقفة مؤقتًا أو المنتظرة فتُنشأ مجددًا في تلك الحالة المتوقفة للفحص.

### نقل سيرورات العمل بين البيئات

انقل سيرورة عمل من بيئة التجهيز إلى الإنتاج أو بالعكس عبر التصدير وإعادة التشغيل:

```bash
# On staging
wp queuety workflow export 15 --output=workflow.json

# On production
wp queuety workflow replay workflow.json
```

### التدقيق والأرشفة

صدّر سيرورات العمل المكتملة للتخزين طويل الأمد أو الامتثال. يحتوي الملف JSON على سجل التنفيذ الكامل، بما يشمل المدخلات والمخرجات والحالة قبل التنفيذ وبعده وبيانات التوقيت وتفاصيل الأخطاء.

```php
$data = Queuety::export_workflow( $workflow_id );
// Store $data in your archive system, S3, etc.
```
