trypost/app/Actions/Automation/Run/AdvanceAutomationRun.php
Paulo Castellano 605261e1b8 Back fixed-set automation strings with enums and consts
Replace magic strings across the automation domain with backed PHP enums
(HttpMethod, AuthType, DelayUnit, ScheduleField) and mirrored TS consts
(http-method, auth-type, delay-unit, schedule-field, condition-operator,
publish-mode), plus the existing Condition\Handle / Operator / Publish\Mode.

Also:
- require scheduled_offset via concrete-index required_if instead of
  defaulting to 60 when the publish mode is scheduled
- fail the webhook node explicitly when the resolved url is empty
- localize node failure messages (fetch_rss/http/webhook)
- cast resolver/strtoupper inputs to string so a present-null config value
  degrades gracefully instead of crashing
- list automations with config('app.pagination.default'), drop the perPage param
2026-06-13 15:04:24 -03:00

79 lines
2.5 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Actions\Automation\Run;
use App\Enums\Automation\Run\Status;
use App\Jobs\Automation\ProcessAutomationNode;
use App\Models\Automation;
use App\Models\AutomationRun;
class AdvanceAutomationRun
{
public function __invoke(AutomationRun $run, string $fromNodeId, string $handle = 'default'): void
{
$targets = $this->targetsFor($run->automation, $fromNodeId, $handle);
if ($targets === []) {
$run->update([
'status' => Status::Completed,
'finished_at' => now(),
'current_node_id' => null,
'error' => [
'reason' => 'no_matching_edge',
'handle' => $handle,
'node_id' => $fromNodeId,
],
]);
return;
}
$this->dispatchBranches($run, $targets);
}
/**
* Every node id connected to `$fromNodeId` via the given handle. A node can
* fan out to several targets (e.g. a trigger calling RSS and HTTP at once).
*
* @return array<int, string>
*/
public function targetsFor(Automation $automation, string $fromNodeId, string $handle = 'default'): array
{
return collect($automation->connections ?? [])
->filter(fn ($c) => data_get($c, 'source') === $fromNodeId && data_get($c, 'source_handle', 'default') === $handle)
->pluck('target')
->filter()
->values()
->all();
}
/**
* Continues the run on the first branch and forks a sibling run — sharing the
* accumulated context — for every additional branch, so all targets execute.
*
* @param array<int, string> $targets
*/
public function dispatchBranches(AutomationRun $run, array $targets): void
{
$first = array_shift($targets);
foreach ($targets as $target) {
$sibling = AutomationRun::create([
'automation_id' => $run->automation_id,
'root_run_id' => $run->rootId(),
'trigger_item_id' => $run->trigger_item_id,
'generated_post_id' => $run->generated_post_id,
'is_manual' => $run->is_manual,
'is_dry_run' => $run->is_dry_run,
'status' => Status::Pending,
'context' => $run->context,
]);
ProcessAutomationNode::dispatch($sibling, $target);
}
ProcessAutomationNode::dispatch($run, $first);
}
}