{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://yarramate.org/schema/likec4-project/v1",
  "title": "YarraMate LikeC4 project definition",
  "type": "object",
  "additionalProperties": false,
  "required": ["format", "id", "version", "title", "mapping", "views"],
  "properties": {
    "format": {
      "const": "yarramate/likec4-project/v1"
    },
    "id": {
      "$ref": "#/$defs/id"
    },
    "version": {
      "type": "string",
      "pattern": "^[0-9]+\\.[0-9]+$"
    },
    "title": {
      "type": "string",
      "minLength": 1
    },
    "mapping": {
      "$ref": "#/$defs/path"
    },
    "kindMapping": {
      "$ref": "#/$defs/path"
    },
    "views": {
      "type": "array",
      "minItems": 1,
      "items": {
        "$ref": "#/$defs/view"
      }
    }
  },
  "$defs": {
    "id": {
      "type": "string",
      "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$"
    },
    "path": {
      "type": "string",
      "description": "Path resolved from the project-definition document's directory, matching workspace-manifest semantics. Parent traversal, absolute paths, and backslashes are rejected, so references stay beneath the project document.",
      "pattern": "^(?!/)(?!.*(?:^|/)\\.\\.(?:/|$))(?!.*\\\\).+$"
    },
    "subjectIdentity": {
      "type": "string",
      "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$"
    },
    "comparison": {
      "type": "object",
      "additionalProperties": false,
      "required": ["from", "to"],
      "properties": {
        "from": {
          "$ref": "#/$defs/subjectIdentity"
        },
        "to": {
          "$ref": "#/$defs/subjectIdentity"
        }
      }
    },
    "view": {
      "type": "object",
      "additionalProperties": false,
      "required": ["projection"],
      "properties": {
        "id": {
          "$ref": "#/$defs/id"
        },
        "projection": {
          "$ref": "#/$defs/path"
        },
        "folder": {
          "type": "string",
          "description": "Sidebar folder for the rendered view, emitted as a LikeC4 title path ('Folder / Title'). Nest with '/' separators; folders appear in the order their first view appears in the views list.",
          "pattern": "^[^/]+(?:/[^/]+)*$"
        },
        "compare": {
          "$ref": "#/$defs/comparison"
        },
        "dynamic": {
          "$ref": "#/$defs/dynamic"
        },
        "deployment": {
          "$ref": "#/$defs/deployment"
        }
      },
      "not": {
        "required": ["dynamic", "deployment"]
      }
    },
    "dynamic": {
      "type": "object",
      "additionalProperties": false,
      "required": ["steps"],
      "properties": {
        "steps": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/$defs/dynamicStep"
          }
        }
      }
    },
    "dynamicStep": {
      "type": "object",
      "additionalProperties": false,
      "required": ["relationship"],
      "properties": {
        "relationship": {
          "$ref": "#/$defs/subjectIdentity"
        },
        "title": {
          "type": "string",
          "minLength": 1
        }
      }
    },
    "deployment": {
      "type": "object",
      "additionalProperties": false,
      "required": ["nodes", "instances"],
      "properties": {
        "nodes": {
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/$defs/deploymentNode" }
        },
        "instances": {
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/$defs/deploymentInstance" }
        }
      }
    },
    "deploymentNode": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "kind", "name"],
      "properties": {
        "id": { "$ref": "#/$defs/id" },
        "kind": {
          "enum": ["environment", "zone", "host", "runtime"]
        },
        "name": {
          "type": "string",
          "minLength": 1
        },
        "parent": { "$ref": "#/$defs/id" }
      }
    },
    "deploymentInstance": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "subject", "node"],
      "properties": {
        "id": { "$ref": "#/$defs/id" },
        "subject": { "$ref": "#/$defs/subjectIdentity" },
        "node": { "$ref": "#/$defs/id" }
      }
    }
  }
}
