{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "key": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100,
      "pattern": "^[a-zA-Z0-9_-]+$"
    },
    "title": {
      "type": "string"
    },
    "description": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ]
    },
    "position": {
      "anyOf": [
        {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991
        },
        {
          "type": "null"
        }
      ]
    },
    "archivedAt": {
      "anyOf": [
        {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        {
          "type": "null"
        }
      ]
    },
    "updatedAt": {
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "definition": {
      "type": "object",
      "properties": {
        "key": {
          "type": "string",
          "minLength": 1,
          "maxLength": 100,
          "pattern": "^[a-zA-Z0-9_-]+$"
        },
        "title": {
          "type": "string",
          "minLength": 1,
          "maxLength": 120
        },
        "description": {
          "type": "string",
          "minLength": 1,
          "maxLength": 500
        },
        "defaultRange": {
          "type": "string",
          "enum": ["7d", "30d", "90d", "all"]
        },
        "position": {
          "type": "integer",
          "minimum": 0,
          "maximum": 1000
        },
        "sections": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "title": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120
              },
              "panels": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "key": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100,
                      "pattern": "^[a-zA-Z0-9_-]+$"
                    },
                    "title": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 120
                    },
                    "description": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 500
                    },
                    "metric": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100
                    },
                    "breakdown": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100
                    },
                    "filter": {
                      "type": "object",
                      "propertyNames": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 100
                      },
                      "additionalProperties": {
                        "anyOf": [
                          {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 100,
                            "pattern": "^[a-zA-Z0-9_-]+$"
                          },
                          {
                            "minItems": 1,
                            "maxItems": 100,
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 100,
                              "pattern": "^[a-zA-Z0-9_-]+$"
                            }
                          }
                        ]
                      }
                    },
                    "ledger": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100,
                      "pattern": "^[a-zA-Z0-9_-]+$"
                    },
                    "chart": {
                      "type": "string",
                      "enum": ["number", "line", "bar", "table"]
                    },
                    "width": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 4
                    }
                  },
                  "required": ["key", "title", "metric", "chart", "width"]
                }
              }
            },
            "required": ["panels"]
          }
        }
      },
      "required": ["key", "title", "defaultRange", "sections"]
    },
    "range": {
      "type": "string",
      "enum": ["7d", "30d", "90d", "all"]
    },
    "panels": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "pattern": "^[a-zA-Z0-9_-]+$"
          },
          "result": {
            "type": "object",
            "properties": {
              "metric": {
                "type": "string"
              },
              "kind": {
                "type": "string",
                "enum": ["count", "distinct", "rate"]
              },
              "range": {
                "type": "object",
                "properties": {
                  "key": {
                    "type": "string",
                    "enum": ["7d", "30d", "90d", "all"]
                  },
                  "from": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                  },
                  "fromMs": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "to": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                  },
                  "toMs": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "bucket": {
                    "type": "string",
                    "enum": ["day", "week"]
                  },
                  "timeZone": {
                    "type": "string"
                  },
                  "buckets": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "key": {
                          "type": "string"
                        },
                        "start": {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                        },
                        "startMs": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        "end": {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                        },
                        "endMs": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        }
                      },
                      "required": ["key", "start", "end"]
                    }
                  }
                },
                "required": [
                  "key",
                  "from",
                  "to",
                  "bucket",
                  "timeZone",
                  "buckets"
                ]
              },
              "previous": {
                "type": "object",
                "properties": {
                  "from": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                  },
                  "fromMs": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "to": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                  },
                  "toMs": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  }
                },
                "required": ["from", "to"]
              },
              "ledger": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100,
                "pattern": "^[a-zA-Z0-9_-]+$"
              },
              "value": {
                "type": "object",
                "properties": {
                  "total": {
                    "anyOf": [
                      {
                        "type": "number"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "previousTotal": {
                    "anyOf": [
                      {
                        "type": "number"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "series": {
                    "type": "array",
                    "items": {
                      "anyOf": [
                        {
                          "type": "number"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  }
                },
                "required": ["total", "series"]
              },
              "breakdown": {
                "type": "object",
                "properties": {
                  "dimension": {
                    "type": "string"
                  },
                  "rows": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "key": {
                          "type": "string"
                        },
                        "title": {
                          "type": "string"
                        },
                        "archived": {
                          "type": "boolean"
                        },
                        "total": {
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "previousTotal": {
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "series": {
                          "type": "array",
                          "items": {
                            "anyOf": [
                              {
                                "type": "number"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          }
                        }
                      },
                      "required": [
                        "key",
                        "title",
                        "archived",
                        "total",
                        "series"
                      ]
                    }
                  },
                  "other": {
                    "type": "object",
                    "properties": {
                      "rows": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "total": {
                        "anyOf": [
                          {
                            "type": "number"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "previousTotal": {
                        "anyOf": [
                          {
                            "type": "number"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "series": {
                        "type": "array",
                        "items": {
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    },
                    "required": ["rows", "total", "series"]
                  }
                },
                "required": ["dimension", "rows"]
              }
            },
            "required": ["metric", "kind", "range", "value"]
          },
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            },
            "required": ["code", "message"]
          }
        },
        "required": ["key"]
      }
    }
  },
  "required": [
    "key",
    "title",
    "description",
    "position",
    "archivedAt",
    "updatedAt",
    "definition",
    "range",
    "panels"
  ]
}
