Example of Custom validation rules in firefly-iii/firefly-iii

File app/Rules/IsBoolean.php (link to Github)
use Illuminate\Contracts\Validation\Rule;

class IsBoolean implements Rule
{
    public function message(): string
    {
        return (string)trans('validation.boolean');
    }

    public function passes($attribute, $value): bool
    {
        if (is_bool($value)) {
            return true;
        }
        if (is_int($value) && 0 === $value) {
            return true;
        }
        if (is_int($value) && 1 === $value) {
            return true;
        }
        if (is_string($value) && in_array($value, ['0', '1', 'true', 'false', 'on', 'off', 'yes', 'no', 'y', 'n'])) {
            return true;
        }

        return false;
    }
}
File app/Api/V1/Requests/Models/Rule/StoreRequest.php (link to Github)
use FireflyIII\Rules\IsBoolean;
use Illuminate\Foundation\Http\FormRequest;

class StoreRequest extends FormRequest
{
    //
    public function rules(): array
    {
        $validTriggers = $this->getTriggers();
        $validActions  = array_keys(config('firefly.rule-actions'));

        $contextTriggers = implode(',', $this->getTriggersWithContext());
        $contextActions  = implode(',', config('firefly.context-rule-actions'));

        return [
            'title'                      => 'required|between:1,100|uniqueObjectForUser:rules,title',
            'description'                => 'between:1,5000|nullable',
            'rule_group_id'              => 'belongsToUser:rule_groups|required_without:rule_group_title',
            'rule_group_title'           => 'nullable|between:1,255|required_without:rule_group_id|belongsToUser:rule_groups,title',
            'trigger'                    => 'required|in:store-journal,update-journal',
            'triggers.*.type'            => 'required|in:' . implode(',', $validTriggers),
            'triggers.*.value'           => 'required_if:actions.*.type,' . $contextTriggers . '|min:1|ruleTriggerValue',
            'triggers.*.stop_processing' => [new IsBoolean],
            'triggers.*.active'          => [new IsBoolean],
            'actions.*.type'             => 'required|in:' . implode(',', $validActions),
            'actions.*.value'            => 'required_if:actions.*.type,' . $contextActions . '|ruleActionValue',
            'actions.*.stop_processing'  => [new IsBoolean],
            'actions.*.active'           => [new IsBoolean],
            'strict'                     => [new IsBoolean],
            'stop_processing'            => [new IsBoolean],
            'active'                     => [new IsBoolean],
        ];
    }
    //
}

Additional resources on custom validation rules: