{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/ismalicious-com/json-schema/ismalicious-com-blocklist-schedule-schema.json",
  "title": "BlocklistSchedule",
  "description": "When the blocklists are regenerated (`api/blocklist.rs::schedule_body`).",
  "x-generated": "2026-11-12",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/ismalicious-com-openapi.json#/components/schemas/BlocklistSchedule",
  "type": "object",
  "required": [
    "intervalHours",
    "schedulerEnabled",
    "overdue"
  ],
  "properties": {
    "expectedNextRunAt": {
      "type": [
        "string",
        "null"
      ],
      "description": "When the next run is expected; `null` when it cannot be known (the\nscheduler is off, a run is in flight or was cut short, or the last run\nwas started by hand and the worker has not published its next tick)"
    },
    "expectedNextRunBasis": {
      "type": [
        "string",
        "null"
      ],
      "description": "Where `expectedNextRunAt` comes from: `armedTick` (the tick the\nworker's scheduler armed) or `lastScheduledRun` (computed from the\nlast run the scheduler started); `null` with no date"
    },
    "intervalHours": {
      "type": "integer",
      "format": "int64",
      "description": "Hours between two runs of the generation job\n(`BLOCKLIST_SCHEDULER_INTERVAL_HOURS`)",
      "minimum": 0
    },
    "lastRegeneratedAt": {
      "type": [
        "string",
        "null"
      ],
      "description": "The newest `lastUpdated` among the lists; `null` when none was ever\ngenerated"
    },
    "lastRun": {
      "oneOf": [
        {
          "type": "null"
        },
        {
          "$ref": "#/$defs/BlocklistLastRun",
          "description": "`null` with no run history"
        }
      ]
    },
    "overdue": {
      "type": "boolean",
      "description": "More than an hour past `expectedNextRunAt`"
    },
    "schedulerEnabled": {
      "type": "boolean",
      "description": "Whether the scheduler is on (`BLOCKLIST_SCHEDULER_ENABLED`)"
    }
  },
  "$defs": {
    "BlocklistLastRun": {
      "type": "object",
      "description": "The last run of the blocklist generation job\n(`jobs:last-run:generate-blocklists`).",
      "required": [
        "startedAt",
        "status"
      ],
      "properties": {
        "completedAt": {
          "type": [
            "string",
            "null"
          ],
          "description": "`null` while the run is in flight"
        },
        "initiator": {
          "type": [
            "string",
            "null"
          ],
          "description": "Who started it: `interval-scheduler` (the worker's ticker),\n`blocklist-api` (`POST /blocklist`), …; `null` when not recorded"
        },
        "startedAt": {
          "type": "string"
        },
        "status": {
          "type": "string",
          "description": "`running` | `success` | `failed` | `timeout` | `interrupted`"
        }
      }
    }
  }
}