{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "bone-flow-definition.schema.json",
  "title": "Bone Flow Canonical Definition v1.0",
  "description": "Canonical .bflow.json only. sourceMap/validation/runtime are intentionally excluded.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schemaVersion",
    "meta",
    "settings",
    "nodes",
    "joints"
  ],
  "properties": {
    "schemaVersion": {
      "const": "1.0"
    },
    "meta": {
      "$ref": "#/$defs/meta"
    },
    "settings": {
      "$ref": "#/$defs/settings"
    },
    "nodes": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/node"
      }
    },
    "joints": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/joint"
      }
    }
  },
  "$defs": {
    "meta": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "id",
        "title",
        "version",
        "formatVersion"
      ],
      "properties": {
        "id": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^[A-Za-z_][A-Za-z0-9_-]*$"
        },
        "title": {
          "type": "string"
        },
        "version": {
          "type": "string",
          "minLength": 1
        },
        "formatVersion": {
          "const": "1.0"
        }
      }
    },
    "settings": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "flow",
        "theme",
        "shape",
        "joint",
        "layout"
      ],
      "properties": {
        "flow": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "direction"
          ],
          "properties": {
            "direction": {
              "enum": [
                "LR",
                "RL",
                "TB",
                "BT"
              ]
            }
          }
        },
        "theme": {
          "enum": [
            "light",
            "dark",
            "neon"
          ]
        },
        "shape": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "scale"
          ],
          "properties": {
            "scale": {
              "type": "number",
              "minimum": 0.25,
              "maximum": 2.0
            }
          }
        },
        "joint": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "line",
            "animate",
            "speed",
            "intersection",
            "lineStyle",
            "lineWidth"
          ],
          "properties": {
            "line": {
              "enum": [
                "straight",
                "curve",
                "orthogonal"
              ]
            },
            "curveSide": {
              "enum": [
                "auto",
                "left",
                "right"
              ]
            },
            "animate": {
              "type": "boolean"
            },
            "speed": {
              "enum": [
                "slow",
                "normal",
                "fast"
              ]
            },
            "intersection": {
              "enum": [
                "jump",
                "none"
              ]
            },
            "lineStyle": {
              "const": "solid"
            },
            "lineWidth": {
              "const": 4
            }
          }
        },
        "layout": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "mode",
            "gap",
            "branchGap"
          ],
          "properties": {
            "mode": {
              "enum": [
                "auto",
                "manual"
              ]
            },
            "gap": {
              "type": "number",
              "minimum": 0
            },
            "branchGap": {
              "type": "number",
              "minimum": 0
            }
          }
        }
      }
    },
    "fieldAttributes": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "pk",
        "fk",
        "required",
        "unique",
        "nullable"
      ],
      "properties": {
        "pk": {
          "type": "boolean"
        },
        "fk": {
          "type": "boolean"
        },
        "required": {
          "type": "boolean"
        },
        "unique": {
          "type": "boolean"
        },
        "nullable": {
          "type": "boolean"
        }
      },
      "allOf": [
        {
          "if": {
            "properties": {
              "required": {
                "const": true
              }
            },
            "required": [
              "required"
            ]
          },
          "then": {
            "properties": {
              "nullable": {
                "const": false
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "required": {
                "const": false
              }
            },
            "required": [
              "required"
            ]
          },
          "then": {
            "properties": {
              "nullable": {
                "const": true
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "pk": {
                "const": true
              }
            },
            "required": [
              "pk"
            ]
          },
          "then": {
            "properties": {
              "required": {
                "const": true
              },
              "nullable": {
                "const": false
              }
            }
          }
        }
      ]
    },
    "field": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "id",
        "label",
        "alias",
        "type",
        "attributes"
      ],
      "properties": {
        "id": {
          "type": "string",
          "pattern": "^[A-Za-z_][A-Za-z0-9_-]*$"
        },
        "label": {
          "type": "string"
        },
        "alias": {
          "type": [
            "string",
            "null"
          ]
        },
        "type": {
          "type": "string",
          "minLength": 1
        },
        "attributes": {
          "$ref": "#/$defs/fieldAttributes"
        }
      }
    },
    "nodeProperties": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "comment": {
          "type": [
            "string",
            "null"
          ],
          "minLength": 1
        },
        "tooltip": {
          "type": [
            "string",
            "null"
          ],
          "minLength": 1
        },
        "theme": {
          "type": [
            "string",
            "null"
          ],
          "enum": [
            "light",
            "dark",
            "neon",
            null
          ]
        },
        "scale": {
          "type": [
            "number",
            "null"
          ],
          "minimum": 0.25,
          "maximum": 2.0
        },
        "fields": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/field"
          }
        }
      }
    },
    "position": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "mode",
        "x",
        "y"
      ],
      "properties": {
        "mode": {
          "enum": [
            "auto",
            "manual"
          ]
        },
        "x": {
          "type": [
            "number",
            "null"
          ]
        },
        "y": {
          "type": [
            "number",
            "null"
          ]
        }
      },
      "allOf": [
        {
          "if": {
            "properties": {
              "mode": {
                "const": "manual"
              }
            },
            "required": [
              "mode"
            ]
          },
          "then": {
            "properties": {
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "mode": {
                "const": "auto"
              }
            },
            "required": [
              "mode"
            ]
          },
          "then": {
            "properties": {
              "x": {
                "type": "null"
              },
              "y": {
                "type": "null"
              }
            }
          }
        }
      ]
    },
    "node": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "id",
        "idOrigin",
        "type",
        "text",
        "properties",
        "position"
      ],
      "properties": {
        "id": {
          "type": "string",
          "pattern": "^[A-Za-z_][A-Za-z0-9_-]*$"
        },
        "idOrigin": {
          "const": "explicit"
        },
        "type": {
          "type": "string",
          "minLength": 1
        },
        "text": {
          "type": "string"
        },
        "properties": {
          "$ref": "#/$defs/nodeProperties"
        },
        "position": {
          "$ref": "#/$defs/position"
        }
      },
      "allOf": [
        {
          "if": {
            "properties": {
              "type": {
                "const": "TABLE_DETAIL"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "properties": {
              "properties": {
                "allOf": [
                  {
                    "required": [
                      "fields"
                    ]
                  }
                ]
              }
            }
          },
          "else": {
            "properties": {
              "properties": {
                "not": {
                  "required": [
                    "fields"
                  ]
                }
              }
            }
          }
        }
      ]
    },
    "selector": {
      "oneOf": [
        {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "kind"
          ],
          "properties": {
            "kind": {
              "const": "auto"
            }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "kind",
            "role"
          ],
          "properties": {
            "kind": {
              "const": "shape-role"
            },
            "role": {
              "enum": [
                "IN",
                "OUT"
              ]
            }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "kind",
            "position"
          ],
          "properties": {
            "kind": {
              "const": "shape-position"
            },
            "position": {
              "enum": [
                "TOP",
                "RIGHT",
                "BOTTOM",
                "LEFT"
              ]
            }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "kind",
            "fieldId",
            "role"
          ],
          "properties": {
            "kind": {
              "const": "field"
            },
            "fieldId": {
              "type": "string",
              "pattern": "^[A-Za-z_][A-Za-z0-9_-]*$"
            },
            "role": {
              "enum": [
                "IN",
                "OUT"
              ]
            }
          }
        }
      ]
    },
    "endpoint": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "nodeId",
        "selector"
      ],
      "properties": {
        "nodeId": {
          "type": "string",
          "pattern": "^[A-Za-z_][A-Za-z0-9_-]*$"
        },
        "selector": {
          "$ref": "#/$defs/selector"
        }
      }
    },
    "requested": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "line",
        "animate",
        "speed",
        "intersection",
        "lineStyle",
        "lineWidth"
      ],
      "properties": {
        "line": {
          "enum": [
            "default",
            "straight",
            "curve",
            "orthogonal"
          ]
        },
        "curveSide": {
          "type": [
            "string",
            "null"
          ],
          "enum": [
            "auto",
            "left",
            "right",
            null
          ]
        },
        "animate": {
          "type": [
            "boolean",
            "null"
          ]
        },
        "speed": {
          "type": [
            "string",
            "null"
          ],
          "enum": [
            "slow",
            "normal",
            "fast",
            null
          ]
        },
        "intersection": {
          "type": [
            "string",
            "null"
          ],
          "enum": [
            "jump",
            "none",
            null
          ]
        },
        "lineStyle": {
          "type": [
            "string",
            "null"
          ],
          "enum": [
            "solid",
            "dashed",
            "dotted",
            "dash-dot",
            null
          ]
        },
        "lineWidth": {
          "type": [
            "number",
            "null"
          ],
          "minimum": 1,
          "maximum": 12
        },
        "lineColor": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^#[0-9A-Fa-f]{6}$"
        },
        "clearance": {
          "type": [
            "number",
            "null"
          ],
          "minimum": 0,
          "maximum": 120
        }
      }
    },
    "resolved": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "line",
        "animate",
        "speed",
        "intersection",
        "lineStyle",
        "lineWidth"
      ],
      "properties": {
        "line": {
          "enum": [
            "straight",
            "curve",
            "orthogonal"
          ]
        },
        "curveSide": {
          "enum": [
            "auto",
            "left",
            "right"
          ]
        },
        "animate": {
          "type": "boolean"
        },
        "speed": {
          "enum": [
            "slow",
            "normal",
            "fast"
          ]
        },
        "intersection": {
          "enum": [
            "jump",
            "none"
          ]
        },
        "lineStyle": {
          "enum": [
            "solid",
            "dashed",
            "dotted",
            "dash-dot"
          ]
        },
        "lineWidth": {
          "type": "number",
          "minimum": 1,
          "maximum": 12
        },
        "lineColor": {
          "type": "string",
          "pattern": "^#[0-9A-Fa-f]{6}$"
        },
        "clearance": {
          "type": "number",
          "minimum": 0,
          "maximum": 120
        }
      }
    },
    "joint": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "id",
        "from",
        "to",
        "label",
        "branchKey",
        "requested",
        "resolved"
      ],
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1
        },
        "from": {
          "$ref": "#/$defs/endpoint"
        },
        "to": {
          "$ref": "#/$defs/endpoint"
        },
        "label": {
          "type": [
            "string",
            "null"
          ]
        },
        "branchKey": {
          "type": [
            "string",
            "null"
          ]
        },
        "requested": {
          "$ref": "#/$defs/requested"
        },
        "resolved": {
          "$ref": "#/$defs/resolved"
        }
      }
    }
  }
}
