Automation::withCount(['steps', 'runs'])->latest()->paginate(20), 'recentRuns' => AutomationRun::with('automation')->latest()->limit(15)->get(), 'triggers' => $triggers->all(), 'actions' => $actions->all()]); } public function store(Request $request, TriggerRegistry $triggers): RedirectResponse { $data = $request->validate(['name' => ['required', 'string', 'max:255'], 'description' => ['nullable', 'string'], 'trigger_type' => ['required', 'string'], 'status' => ['required', 'in:draft,active,paused'], 'next_run_at' => ['nullable', 'date'], 'trigger_config' => ['nullable', 'json']]); abort_unless($triggers->has($data['trigger_type']), 422, 'Unknown trigger type.'); $data['trigger_config'] = filled($data['trigger_config'] ?? null) ? json_decode($data['trigger_config'], true, 512, JSON_THROW_ON_ERROR) : []; $data['stop_on_failure'] = $request->boolean('stop_on_failure'); $data['created_by'] = $request->user()->id; Automation::create($data); return back()->with('status', 'Automation created.'); } public function addStep(Request $request, Automation $automation, ActionRegistry $actions): RedirectResponse { $data = $request->validate(['action_type' => ['required', 'string'], 'name' => ['nullable', 'string', 'max:255'], 'configuration' => ['nullable', 'json']]); abort_unless(array_key_exists($data['action_type'], $actions->all()), 422, 'Unknown action type.'); $automation->steps()->create(['position' => (int) $automation->steps()->max('position') + 1, 'action_type' => $data['action_type'], 'name' => $data['name'] ?? null, 'configuration' => filled($data['configuration'] ?? null) ? json_decode($data['configuration'], true, 512, JSON_THROW_ON_ERROR) : [], 'is_enabled' => true]); return back()->with('status', 'Automation step added.'); } public function run(Automation $automation, AutomationRunner $runner): RedirectResponse { $run = $runner->dispatch($automation, ['initiated_by' => request()->user()->id], 'manual'); return back()->with('status', "Automation queued as {$run->execution_id}."); } public function toggle(Automation $automation): RedirectResponse { $automation->update(['status' => $automation->status === 'active' ? 'paused' : 'active']); return back()->with('status', 'Automation status updated.'); } public function destroy(Automation $automation): RedirectResponse { $automation->delete(); return back()->with('status','Automation deleted.'); } }