{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://www.rubyschema.org/rails/recurring.json",
  "title": "SolidQueue Recurring Configuration",
  "markdownDescription": "Configuration for recurring tasks (cron-like jobs) in Solid Queue.\n\nRecurring tasks are managed by the scheduler component, which enqueues jobs for them when they're due based on their schedule. Tasks can be defined either as commands (Ruby code evaluated in the context of a job) or as Active Job classes with arguments.\n\n[Recurring Tasks Documentation](https://github.com/rails/solid_queue#recurring-tasks)",
  "type": "object",
  "definitions": {
    "environment": {
      "markdownDescription": "Environment-specific recurring task definitions.\n\nEach property name represents a unique task identifier, and its value defines either a task (with `command`) or a job (with `class`).\n\n[Recurring Tasks Documentation](https://guides.rubyonrails.org/active_job_basics.html#recurring-tasks)",
      "additionalProperties": {
        "oneOf": [
          {
            "$ref": "#/definitions/task"
          },
          {
            "$ref": "#/definitions/job"
          }
        ]
      }
    },
    "schedule": {
      "type": "string",
      "markdownDescription": "Natural language cron schedule expression.\n\nSupports formats like:\n- `\"every 5 minutes\"`\n- `\"every day at 5pm\"`\n- `\"0 0 * * *\"` (standard cron syntax)\n- `\"*/15 * * * *\"` (every 15 minutes)\n\nSchedules can include a time zone (e.g. `\"0 9 * * * America/New_York\"` or `\"every day at 9am America/New_York\"`). Without one, the application's `config.time_zone` is used by default (configurable via `config.solid_queue.time_zone`).\n\nParsed with Fugit and must resolve to a single cron schedule.\n\n[Fugit Cron Documentation](https://github.com/floraison/fugit?tab=readme-ov-file#fugitcron)"
    },
    "priority": {
      "markdownDescription": "Numeric priority value used when enqueuing the job.\n\nThe smaller the value, the higher the priority. `0` is the highest priority.\n\nDefault: `0`\n\n**Note:** Within the same queue, jobs will be picked in order of priority, but in a list of queues, the queue order takes precedence.",
      "type": "integer",
      "minimum": 0
    },
    "task_description": {
      "type": "string",
      "markdownDescription": "A human-readable description of the recurring task."
    },
    "task": {
      "markdownDescription": "A recurring task defined by a Ruby command string.\n\nUse this when you need to run simple Ruby code on a schedule without creating a dedicated Active Job class.",
      "properties": {
        "command": {
          "type": "string",
          "markdownDescription": "Ruby code that will be evaluated in the context of a job (`SolidQueue::RecurringJob`).\n\nExample: `\"Product.sync_inventory\"` or `\"User.where(active: false).delete_all\"`\n\n**Security Warning:** This code is evaluated directly, so ensure it comes from trusted configuration sources only."
        },
        "schedule": {
          "$ref": "#/definitions/schedule"
        },
        "priority": {
          "$ref": "#/definitions/priority"
        },
        "queue": {
          "type": "string",
          "markdownDescription": "The queue name where the recurring task will be enqueued.\n\nDefault: `\"solid_queue_recurring\"` (the queue of `SolidQueue::RecurringJob`)\n\nYou can use this to route recurring tasks to specific workers."
        },
        "description": {
          "$ref": "#/definitions/task_description"
        }
      },
      "required": ["command", "schedule"],
      "additionalProperties": false
    },
    "job": {
      "markdownDescription": "A recurring task defined by an Active Job class with arguments.\n\nUse this when you have a dedicated Active Job class that you want to run on a schedule with specific arguments.",
      "properties": {
        "class": {
          "type": "string",
          "pattern": "^(?:::)?[A-Z][a-zA-Z0-9_]*(?:::[A-Z][a-zA-Z0-9_]*)*$",
          "markdownDescription": "The fully-qualified Active Job class name (e.g., `\"CleanupOldRecordsJob\"` or `\"Reports::GenerateDailySummaryJob\"`). Must correspond to an existing class.\n\nJobs using a different queue adapter are enqueued via `perform_later`."
        },
        "args": {
          "type": ["array", "object", "string", "number", "boolean"],
          "markdownDescription": "Arguments to pass to the job's `perform` method.\n\nCan be a single argument, a hash, or an array of arguments. To pass keyword arguments, add a hash as the last element of the array.\n\nExamples:\n- Single: `42`\n- Array: `[\"2024-01-01\", true]`\n- Array with kwargs: `[42, { status: \"custom_status\" }]` (enqueued as `MyJob.perform_later(42, status: \"custom_status\")`)"
        },
        "schedule": {
          "$ref": "#/definitions/schedule"
        },
        "priority": {
          "$ref": "#/definitions/priority"
        },
        "queue": {
          "type": "string",
          "markdownDescription": "The queue name where the recurring job will be enqueued.\n\nDefault: Uses the queue specified in the job class (via `queue_as`), or `\"default\"` if not specified.\n\nYou can use this to override the job's default queue for recurring executions."
        },
        "description": {
          "$ref": "#/definitions/task_description"
        }
      },
      "required": ["class", "schedule"],
      "additionalProperties": false
    }
  },
  "properties": {
    "production": {
      "$ref": "#/definitions/environment"
    }
  },
  "additionalProperties": {
    "anyOf": [
      {
        "$ref": "#/definitions/environment"
      },
      {
        "$ref": "#/definitions/task"
      },
      {
        "$ref": "#/definitions/job"
      }
    ]
  }
}
