{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://pitgun.io/schemas/pipeline-manifest/v1",
  "title": "Pitgun Pipeline Manifest v1",
  "type": "object",
  "additionalProperties": false,
  "required": ["manifest_version", "source", "processors", "sink"],
  "properties": {
    "manifest_version": {
      "type": "integer",
      "enum": [1]
    },

    "name": {
      "type": "string",
      "description": "Optional human-readable pipeline name"
    },

    "description": {
      "type": "string",
      "description": "Optional description of the pipeline"
    },

    "source": {
      "type": "object",
      "required": ["type"],
      "additionalProperties": true,
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "udp",
            "tcp",
            "file",
            "stdin",
            "kafka",
            "websocket",
            "other"
          ]
        }
      }
    },

    "processors": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "required": ["type"],
        "additionalProperties": true,
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "channel_filter",
              "scale",
              "stats",
              "segment_aggregate",
              "map",
              "throttle",
              "other"
            ]
          },
          "id": {
            "type": "string",
            "description": "Optional processor identifier"
          },
          "segment_key": {
            "type": "string",
            "description": "Channel whose value defines the active segment/window; a change closes the current segment and opens a new one"
          },
          "targets": {
            "type": "array",
            "description": "Channels to aggregate within each segment and the metrics to compute",
            "items": {
              "type": "object",
              "required": ["channel"],
              "properties": {
                "channel": {
                  "type": "string"
                },
                "metrics": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "enum": ["count", "min", "max", "mean", "sum", "stddev"]
                  }
                }
              }
            }
          },
          "emit_on_change": {
            "type": "boolean",
            "description": "When true, emit an aggregate row as soon as the segment key changes"
          },
          "emit_last_segment_on_eof": {
            "type": "boolean",
            "description": "Emit the final open segment when the source reports end-of-stream"
          }
        }
      }
    },

    "sink": {
      "type": "object",
      "required": ["type"],
      "additionalProperties": true,
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "console",
            "file",
            "udp",
            "tcp",
            "kafka",
            "websocket",
            "other"
          ]
        }
      }
    }
  }
}
