*/ public function schema(JsonSchema $schema): array { return [ 'title' => $schema->string()->description('Human-readable rule name.')->required(), 'priority' => $schema->integer()->min(0)->description('Lower numbers are evaluated first.')->required(), 'rules_json' => $schema->object()->description(<<<'TEXT' JsonLogic condition object, evaluated against these lowercase variables: description, notes, creditor_name, debtor_name, account_name, bank_name, category, transaction_date (YYYY-MM-DD) and amount. Note: amount here is in MAJOR units (e.g. 12.50), not cents. Example: {"and":[{">":[{"var":"amount"},100]},{"in":["grocery",{"var":"description"}]}]} TEXT)->required(), 'action_category_id' => $schema->string()->description('Category id to assign to matching transactions.'), 'action_label_ids' => $schema->array()->items($schema->string())->description('Label ids to attach to matching transactions.'), 'action_note' => $schema->string()->description('Note to append to matching transactions.'), 'space' => $schema->string()->description('Space id. Defaults to the personal space.'), ]; } protected function write(Request $request, User $user): Response { $request->validate([ 'title' => ['required', 'string', 'max:255'], 'priority' => ['required', 'integer', 'min:0'], 'action_note' => ['sometimes', 'nullable', 'string'], ]); $space = $this->resolveSpace($request, $user); $rulesJson = $this->rulesJson($request); $labels = $this->labelsInSpace($request, $space, 'action_label_ids'); $categoryId = $request->filled('action_category_id') ? $this->categoryInSpace($request, $space, 'action_category_id')->id : null; if ($categoryId === null && $labels->isEmpty()) { throw ValidationException::withMessages([ 'action_category_id' => 'At least one action is required: pass action_category_id and/or action_label_ids.', ]); } $rule = new AutomationRule([ 'user_id' => $user->id, 'space_id' => $space->id, 'title' => $request->string('title')->toString(), 'priority' => $request->integer('priority'), 'origin' => RuleOrigin::User->value, 'rules_json' => $rulesJson, 'action_category_id' => $categoryId, 'action_note' => $request->filled('action_note') ? $request->string('action_note')->toString() : null, ]); $rule->save(); if ($labels->isNotEmpty()) { $rule->labels()->sync($labels->pluck('id')->all()); $rule->touch(); } return $this->json(['automation_rule' => $this->presentAutomationRule($rule)]); } }