{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://tidybank.org/contracts/recipe-v01.schema.json",
  "title": "RecipeV01",
  "description": "Structural schema for a TidyBank/tidycell RecipeV01 document.",
  "$comment": "Address validity, expanded-range size, duplicate names, and output-key collision refinements are enforced only by the normative TypeScript validator introduced in PRD 003.",
  "type": "object",
  "required": ["version", "sheet", "tables"],
  "properties": {
    "version": { "const": "0.1" },
    "sheet": { "type": "string", "minLength": 1 },
    "tables": {
      "type": "array",
      "minItems": 1,
      "items": { "$ref": "#/$defs/table" }
    },
    "options": { "$ref": "#/$defs/options" }
  },
  "patternProperties": { "^\\.": true },
  "additionalProperties": false,
  "$defs": {
    "dataType": {
      "enum": ["blank", "string", "numeric", "boolean", "date", "error"]
    },
    "headerDirection": { "enum": ["N", "W", "NNW", "WNW"] },
    "fillDirection": { "enum": ["right", "down"] },
    "address": { "type": "string", "minLength": 1 },
    "range": { "type": "string", "minLength": 1 },
    "predicate": {
      "type": "object",
      "properties": {
        "data_type": {
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/$defs/dataType" }
        },
        "non_blank": { "type": "boolean" },
        "has_formula": { "type": "boolean" },
        "has_comment": { "type": "boolean" },
        "style_id": {
          "type": "array",
          "minItems": 1,
          "items": { "type": "string", "minLength": 1 }
        }
      },
      "patternProperties": { "^\\.": true },
      "additionalProperties": false
    },
    "selectorObject": {
      "type": "object",
      "properties": {
        "range": { "$ref": "#/$defs/range" },
        "cells": {
          "type": "array",
          "items": { "$ref": "#/$defs/address" }
        },
        "where": { "$ref": "#/$defs/predicate" }
      },
      "anyOf": [{ "required": ["range"] }, { "required": ["cells"] }],
      "patternProperties": { "^\\.": true },
      "additionalProperties": false
    },
    "cellSelector": {
      "oneOf": [
        { "type": "string", "minLength": 1 },
        {
          "type": "array",
          "items": { "$ref": "#/$defs/address" }
        },
        { "$ref": "#/$defs/selectorObject" }
      ]
    },
    "options": {
      "type": "object",
      "properties": {
        "include_blank_values": { "type": "boolean" },
        "preserve_source_address": { "type": "boolean" },
        "preserve_header_source_address": { "type": "boolean" },
        "preserve_formatted_value": { "type": "boolean" },
        "preserve_non_table_cells": { "type": "boolean" },
        "include_blank_non_table_cells": { "type": "boolean" }
      },
      "patternProperties": { "^\\.": true },
      "additionalProperties": false
    },
    "values": {
      "type": "object",
      "required": ["name", "cells"],
      "properties": {
        "name": { "type": "string", "minLength": 1 },
        "cells": { "$ref": "#/$defs/cellSelector" }
      },
      "patternProperties": { "^\\.": true },
      "additionalProperties": false
    },
    "directionOverrides": {
      "type": "object",
      "patternProperties": {
        "^\\.": true,
        "^(?!\\.).+$": { "$ref": "#/$defs/headerDirection" }
      },
      "additionalProperties": false
    },
    "header": {
      "type": "object",
      "required": ["name", "direction", "cells"],
      "properties": {
        "name": { "type": "string", "minLength": 1 },
        "direction": { "$ref": "#/$defs/headerDirection" },
        "direction_overrides": { "$ref": "#/$defs/directionOverrides" },
        "cells": { "$ref": "#/$defs/cellSelector" },
        "fill": { "$ref": "#/$defs/fillDirection" },
        "required": { "type": "boolean" }
      },
      "patternProperties": { "^\\.": true },
      "additionalProperties": false
    },
    "table": {
      "type": "object",
      "required": ["name", "values", "headers"],
      "properties": {
        "name": { "type": "string", "minLength": 1 },
        "values": { "$ref": "#/$defs/values" },
        "headers": {
          "type": "array",
          "items": { "$ref": "#/$defs/header" }
        },
        "options": { "$ref": "#/$defs/options" }
      },
      "patternProperties": { "^\\.": true },
      "additionalProperties": false
    }
  }
}
