89 lines
3.2 KiB
PHP
89 lines
3.2 KiB
PHP
<?php
|
|
|
|
namespace App\Jobs;
|
|
|
|
use App\Models\Activity;
|
|
use App\Models\Event as DecisionEventModel;
|
|
use App\Services\DecisionEvents\DecisionEventContext;
|
|
use App\Services\DecisionEvents\Registry;
|
|
use Illuminate\Bus\Queueable;
|
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
use Illuminate\Foundation\Bus\Dispatchable;
|
|
use Illuminate\Queue\InteractsWithQueue;
|
|
use Illuminate\Queue\SerializesModels;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class RunDecisionEvent implements ShouldQueue
|
|
{
|
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
|
|
|
public function __construct(
|
|
public int $activityId,
|
|
public int $eventId,
|
|
public string $eventKey,
|
|
public array $config = [],
|
|
) {}
|
|
|
|
public function handle(): void
|
|
{
|
|
// Basic idempotency key per activity+event
|
|
$idempotencyKey = sha1($this->activityId.'|'.$this->eventId.'|'.$this->eventKey);
|
|
|
|
// Ensure log table record and uniqueness
|
|
$exists = DB::table('decision_event_logs')->where('idempotency_key', $idempotencyKey)->first();
|
|
if ($exists && ($exists->status ?? null) === 'succeeded') {
|
|
return; // already processed successfully
|
|
}
|
|
try {
|
|
$activity = Activity::with(['decision', 'contract', 'clientCase.client', 'user'])->findOrFail($this->activityId);
|
|
|
|
if (! $exists) {
|
|
DB::table('decision_event_logs')->insert([
|
|
'decision_id' => optional($activity->decision)->id,
|
|
'event_id' => $this->eventId,
|
|
'activity_id' => $this->activityId,
|
|
'handler' => $this->eventKey,
|
|
'status' => 'queued',
|
|
'idempotency_key' => $idempotencyKey,
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
$exists = (object) ['status' => 'queued'];
|
|
}
|
|
|
|
DB::table('decision_event_logs')->where('idempotency_key', $idempotencyKey)->update([
|
|
'status' => 'running',
|
|
'started_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
$event = DecisionEventModel::findOrFail($this->eventId);
|
|
|
|
$handler = Registry::resolve($this->eventKey);
|
|
$context = new DecisionEventContext(
|
|
activity: $activity,
|
|
decision: $activity->decision,
|
|
contract: $activity->contract,
|
|
clientCase: $activity->clientCase,
|
|
client: optional($activity->clientCase)->client,
|
|
user: $activity->user,
|
|
);
|
|
|
|
$handler->handle($context, $this->config);
|
|
|
|
DB::table('decision_event_logs')->where('idempotency_key', $idempotencyKey)->update([
|
|
'status' => 'succeeded',
|
|
'finished_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
} catch (\Throwable $e) {
|
|
DB::table('decision_event_logs')->where('idempotency_key', $idempotencyKey)->update([
|
|
'status' => 'failed',
|
|
'message' => substr($e->getMessage(), 0, 2000),
|
|
'finished_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
throw $e; // allow retry
|
|
}
|
|
}
|
|
}
|