{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://petcostplanner.com/data/schema-v1.json",
  "title": "Pet Cost Planner model dataset schema",
  "description": "Validation contract for model-v1.json. Additional documented fields may be added in backward-compatible releases.",
  "type": "object",
  "required": [
    "schemaVersion",
    "dataset",
    "scope",
    "formula",
    "inflationFactors",
    "nationalRegionalPriceParity2024",
    "stateRegionalPriceParities",
    "careBaselines2021",
    "insuranceBenchmarks2024",
    "heuristics",
    "sources"
  ],
  "properties": {
    "schemaVersion": {
      "type": "string",
      "const": "1.0"
    },
    "dataset": {
      "type": "object",
      "required": [
        "id",
        "name",
        "version",
        "datePublished",
        "dateModified",
        "publisher",
        "currency",
        "methodology",
        "schema",
        "referenceEstimates",
        "releaseManifest",
        "license",
        "citation",
        "disclaimer"
      ],
      "properties": {
        "id": {
          "type": "string",
          "format": "uri"
        },
        "name": {
          "type": "string"
        },
        "version": {
          "type": "string"
        },
        "datePublished": {
          "type": "string",
          "format": "date"
        },
        "dateModified": {
          "type": "string",
          "format": "date"
        },
        "publisher": {
          "type": "string"
        },
        "currency": {
          "type": "string",
          "const": "USD"
        },
        "methodology": {
          "type": "string",
          "format": "uri"
        },
        "schema": {
          "type": "string",
          "format": "uri"
        },
        "referenceEstimates": {
          "type": "string",
          "format": "uri"
        },
        "releaseManifest": {
          "type": "string",
          "format": "uri"
        },
        "license": {
          "type": "string",
          "format": "uri"
        },
        "citation": {
          "type": "string"
        },
        "disclaimer": {
          "type": "string"
        }
      }
    },
    "scope": {
      "type": "object",
      "required": [
        "petTypes",
        "locations",
        "estimateType",
        "exclusions"
      ],
      "properties": {
        "petTypes": {
          "type": "array",
          "prefixItems": [
            {
              "const": "dog"
            },
            {
              "const": "cat"
            }
          ],
          "minItems": 2,
          "maxItems": 2
        },
        "locations": {
          "type": "string"
        },
        "estimateType": {
          "type": "string"
        },
        "exclusions": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      }
    },
    "formula": {
      "type": "object",
      "required": [
        "expression",
        "insuranceException",
        "visitorOverride",
        "rounding"
      ],
      "properties": {
        "expression": {
          "type": "string"
        },
        "insuranceException": {
          "type": "string"
        },
        "visitorOverride": {
          "type": "string"
        },
        "rounding": {
          "type": "string"
        }
      }
    },
    "inflationFactors": {
      "type": "array",
      "minItems": 4,
      "maxItems": 4,
      "items": {
        "type": "object",
        "required": [
          "key",
          "value",
          "blsSeriesId",
          "basePeriodMean2021",
          "comparisonPeriod",
          "comparisonPeriodMean"
        ],
        "properties": {
          "key": {
            "enum": [
              "food",
              "goods",
              "services",
              "veterinary"
            ]
          },
          "value": {
            "type": "number",
            "exclusiveMinimum": 0
          },
          "blsSeriesId": {
            "type": "string",
            "pattern": "^CUUR[0-9A-Z]+$"
          },
          "basePeriodMean2021": {
            "type": "number",
            "exclusiveMinimum": 0
          },
          "comparisonPeriod": {
            "type": "string"
          },
          "comparisonPeriodMean": {
            "type": "number",
            "exclusiveMinimum": 0
          }
        }
      }
    },
    "nationalRegionalPriceParity2024": {
      "type": "object",
      "required": [
        "goods",
        "otherServices"
      ],
      "properties": {
        "goods": {
          "type": "number",
          "exclusiveMinimum": 0
        },
        "otherServices": {
          "type": "number",
          "exclusiveMinimum": 0
        }
      }
    },
    "stateRegionalPriceParities": {
      "type": "array",
      "minItems": 52,
      "items": {
        "type": "object",
        "required": [
          "location",
          "year",
          "goods",
          "otherServices"
        ],
        "properties": {
          "location": {
            "type": "string"
          },
          "year": {
            "type": "integer",
            "const": 2024
          },
          "goods": {
            "type": "number",
            "exclusiveMinimum": 0
          },
          "otherServices": {
            "type": "number",
            "exclusiveMinimum": 0
          }
        }
      }
    },
    "careBaselines2021": {
      "type": "object",
      "description": "ASPCA-derived annual and setup amounts in U.S. dollars per pet before model adjustments.",
      "required": [
        "dog",
        "cat"
      ],
      "properties": {
        "dog": {
          "$ref": "#/$defs/careBaseline"
        },
        "cat": {
          "$ref": "#/$defs/careBaseline"
        }
      }
    },
    "insuranceBenchmarks2024": {
      "type": "object",
      "required": [
        "coverageType",
        "unit",
        "dog",
        "cat"
      ],
      "properties": {
        "coverageType": {
          "type": "string"
        },
        "unit": {
          "const": "USD per pet per year"
        },
        "dog": {
          "type": "number",
          "minimum": 0
        },
        "cat": {
          "type": "number",
          "minimum": 0
        }
      }
    },
    "heuristics": {
      "type": "object",
      "required": [
        "dogSizeFactors",
        "dogSizeAppliesTo",
        "professionalGroomingFactors",
        "planningRangeFactors",
        "longTermScenario",
        "lifeStageEffect"
      ],
      "properties": {
        "dogSizeFactors": {
          "type": "object",
          "required": [
            "small",
            "medium",
            "large"
          ]
        },
        "dogSizeAppliesTo": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "professionalGroomingFactors": {
          "type": "object",
          "required": [
            "none",
            "occasional",
            "regular"
          ]
        },
        "planningRangeFactors": {
          "type": "object",
          "required": [
            "low",
            "high",
            "statisticalConfidenceInterval"
          ],
          "properties": {
            "low": {
              "type": "number",
              "const": 0.85
            },
            "high": {
              "type": "number",
              "const": 1.25
            },
            "statisticalConfidenceInterval": {
              "type": "boolean",
              "const": false
            }
          }
        },
        "longTermScenario": {
          "type": "string"
        },
        "lifeStageEffect": {
          "type": "string"
        }
      }
    },
    "sources": {
      "type": "array",
      "minItems": 7,
      "items": {
        "type": "object",
        "required": [
          "id",
          "name",
          "publisher",
          "url",
          "usedFor",
          "retrievedDate"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "publisher": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "usedFor": {
            "type": "string"
          },
          "retrievedDate": {
            "type": "string",
            "format": "date"
          }
        }
      }
    }
  },
  "$defs": {
    "careBaseline": {
      "type": "object",
      "required": [
        "food",
        "routineVeterinary",
        "preventiveMedication",
        "litter",
        "toys",
        "treats",
        "license",
        "groomingSupplies",
        "boardingNight",
        "professionalGrooming",
        "dental",
        "setupVeterinary",
        "setupGoods",
        "setupTraining"
      ],
      "properties": {
        "food": {
          "type": "number",
          "minimum": 0
        },
        "routineVeterinary": {
          "type": "number",
          "minimum": 0
        },
        "preventiveMedication": {
          "type": "number",
          "minimum": 0
        },
        "litter": {
          "type": "number",
          "minimum": 0
        },
        "toys": {
          "type": "number",
          "minimum": 0
        },
        "treats": {
          "type": "number",
          "minimum": 0
        },
        "license": {
          "type": "number",
          "minimum": 0
        },
        "groomingSupplies": {
          "type": "number",
          "minimum": 0
        },
        "boardingNight": {
          "type": "number",
          "minimum": 0
        },
        "professionalGrooming": {
          "type": "number",
          "minimum": 0
        },
        "dental": {
          "type": "number",
          "minimum": 0
        },
        "setupVeterinary": {
          "type": "number",
          "minimum": 0
        },
        "setupGoods": {
          "type": "number",
          "minimum": 0
        },
        "setupTraining": {
          "type": "number",
          "minimum": 0
        }
      }
    }
  }
}
