{
  "title": "UK Tender Pipeline Monitor",
  "type": "object",
  "schemaVersion": 1,
  "description": "Track official Find a Tender procedures, deadlines, values and award changes. Export one compiled record per OCID with source links and optional saved comparisons. No credentials required. Start with the small sample, then set an exact watchlist and optional comparison.",
  "properties": {
    "ocids": {
      "title": "Procedure watchlist (OCIDs)",
      "type": "array",
      "description": "Optional exact official OCIDs, at most 50. Leave empty to discover recent releases. Date and stage filters apply only to discovery.",
      "editor": "stringList",
      "prefill": []
    },
    "keywords": {
      "title": "Title, description or buyer keywords",
      "type": "array",
      "description": "Optional literal case-insensitive OR terms, applied after fetching current records. May return no matches within the bounded window.",
      "editor": "stringList"
    },
    "cpvPrefixes": {
      "title": "CPV classification prefixes",
      "type": "array",
      "description": "Optional OR list of 2-8 digit prefixes, checked against published item CPV codes.",
      "editor": "stringList"
    },
    "stages": {
      "title": "Discovery notice stages",
      "type": "array",
      "description": "Optional planning, tender or award stages. A stage selects release discovery; current compiled records can have a later status.",
      "editor": "select",
      "items": {
        "type": "string",
        "enum": [
          "planning",
          "tender",
          "award"
        ]
      }
    },
    "updatedFrom": {
      "title": "Source update time from",
      "type": "string",
      "description": "Optional source last-update bound, YYYY-MM-DDTHH:MM:SS with no timezone, exactly as the official API requires. This is not a tender deadline.",
      "editor": "textfield"
    },
    "updatedTo": {
      "title": "Source update time to",
      "type": "string",
      "description": "Optional source last-update upper bound in YYYY-MM-DDTHH:MM:SS. Use a fixed pair for a repeatable discovery window.",
      "editor": "textfield"
    },
    "maxSourcePages": {
      "title": "Release pages to inspect",
      "type": "integer",
      "description": "Discovery only. Each official page contains up to 20 notices; duplicate OCIDs are checked once. This is a bounded window, not full coverage.",
      "minimum": 1,
      "maximum": 5,
      "default": 1
    },
    "maxResults": {
      "title": "Maximum saved observations",
      "type": "integer",
      "description": "Stops after this many confirmed dataset rows. Unchanged rows skipped by onlyChanges do not count.",
      "minimum": 1,
      "maximum": 100,
      "default": 3,
      "prefill": 3
    },
    "comparePrevious": {
      "title": "Compare with saved history",
      "type": "boolean",
      "description": "Enable a private named history. First observations are new; history advances only after output is saved. Use one writer per snapshot namespace.",
      "default": false
    },
    "onlyChanges": {
      "title": "Save only new or changed observations",
      "type": "boolean",
      "description": "Implies comparison. Unchanged observations are counted in SUMMARY and produce no paid dataset row.",
      "default": false
    },
    "snapshotName": {
      "title": "History namespace",
      "type": "string",
      "description": "1-80 letters, numbers, hyphens or underscores. Changing filters creates a separate scope. Use a new namespace to reset history.",
      "editor": "textfield",
      "default": "default"
    },
    "maxRunSeconds": {
      "title": "Run time budget in seconds",
      "type": "integer",
      "description": "Own time budget, also bounded by the platform timeout with a 25-second reserve.",
      "minimum": 30,
      "maximum": 900,
      "default": 240
    }
  }
}
