*/ public function schema(JsonSchema $schema): array { return [ 'automation_rule_id' => $schema->string()->description('Id of the automation rule to edit.')->required(), 'title' => $schema->string()->description('New rule name.'), 'priority' => $schema->integer()->min(0)->description('New priority (lower is evaluated first).'), 'rules_json' => $schema->object()->description('New JsonLogic condition object.'), 'action_category_id' => $schema->string()->description('New category id to assign, or null to clear.'), 'action_label_ids' => $schema->array()->items($schema->string())->description('Replacement set of label ids (replaces all existing labels).'), 'action_note' => $schema->string()->description('New note to append, or null to clear.'), 'space' => $schema->string()->description('Space id. Defaults to the personal space.'), ]; } protected function write(Request $request, User $user): Response { $request->validate([ 'title' => ['sometimes', 'string', 'max:255'], 'priority' => ['sometimes', 'integer', 'min:0'], 'action_note' => ['sometimes', 'nullable', 'string'], ]); $space = $this->resolveSpace($request, $user); $rule = $this->ruleInSpace($request, $space); if ($request->has('title')) { $rule->title = $request->string('title')->toString(); } if ($request->has('priority')) { $rule->priority = $request->integer('priority'); } if ($request->has('rules_json')) { $rule->rules_json = $this->rulesJson($request); } if ($request->has('action_category_id')) { $rule->action_category_id = $request->filled('action_category_id') ? $this->categoryInSpace($request, $space, 'action_category_id')->id : null; } if ($request->has('action_note')) { $rule->action_note = $request->filled('action_note') ? $request->string('action_note')->toString() : null; } $newLabels = $request->has('action_label_ids') ? $this->labelsInSpace($request, $space, 'action_label_ids') : null; // The rule must keep at least one action. Compare against the labels it // would have after this edit (the new set if provided, else current). $labelCount = $newLabels !== null ? $newLabels->count() : $rule->labels()->count(); if ($rule->action_category_id === null && $labelCount === 0) { throw ValidationException::withMessages([ 'action_category_id' => 'An automation rule must keep at least one action: a category or labels.', ]); } $rule->save(); if ($newLabels !== null) { $rule->labels()->sync($newLabels->pluck('id')->all()); } $rule->touch(); return $this->json(['automation_rule' => $this->presentAutomationRule($rule->refresh())]); } private function ruleInSpace(Request $request, Space $space): AutomationRule { $id = $request->string('automation_rule_id')->toString(); $rule = AutomationRule::query()->forSpace($space)->whereKey($id)->first(); if ($rule === null) { throw ValidationException::withMessages([ 'automation_rule_id' => "No automation rule with id {$id} in space {$space->id}.", ]); } return $rule; } }