{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://quay.local/schemas/planner-output.schema.json",
  "title": "QUAY PlannerOutput",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema",
    "schemaVersion",
    "summary",
    "composition",
    "placements",
    "relations",
    "groups",
    "excludedInstances",
    "warnings"
  ],
  "properties": {
    "schema": { "const": "quay.plan" },
    "schemaVersion": { "const": "1.0.0" },
    "summary": { "type": "string", "minLength": 1, "maxLength": 1000 },
    "composition": { "$ref": "#/$defs/composition" },
    "placements": {
      "type": "array",
      "maxItems": 200,
      "items": { "$ref": "#/$defs/placement" }
    },
    "relations": {
      "type": "array",
      "maxItems": 500,
      "items": { "$ref": "#/$defs/relation" }
    },
    "groups": {
      "type": "array",
      "maxItems": 50,
      "items": { "$ref": "#/$defs/group" }
    },
    "excludedInstances": {
      "type": "array",
      "maxItems": 200,
      "items": { "$ref": "#/$defs/excluded" }
    },
    "warnings": {
      "type": "array",
      "maxItems": 100,
      "items": { "$ref": "#/$defs/warning" }
    }
  },
  "$defs": {
    "composition": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "density",
        "asymmetry",
        "negativeSpace",
        "focalInstanceId",
        "styleNotes"
      ],
      "properties": {
        "density": { "type": "number", "minimum": 0, "maximum": 1 },
        "asymmetry": { "type": "number", "minimum": 0, "maximum": 1 },
        "negativeSpace": { "type": "number", "minimum": 0, "maximum": 1 },
        "focalInstanceId": { "type": ["string", "null"], "format": "uuid" },
        "styleNotes": { "type": "string", "maxLength": 1000 }
      }
    },
    "placement": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "instanceId",
        "role",
        "importance",
        "preferredRegion",
        "facing",
        "facingTargetInstanceId",
        "allowFloorFallback",
        "notes"
      ],
      "properties": {
        "instanceId": { "type": "string", "format": "uuid" },
        "role": {
          "enum": [
            "architectural",
            "primary_furniture",
            "secondary_furniture",
            "functional_prop",
            "decorative_prop",
            "focal_prop"
          ]
        },
        "importance": { "type": "integer", "minimum": 0, "maximum": 100 },
        "preferredRegion": {
          "enum": [
            "any",
            "center",
            "front",
            "back",
            "left",
            "right",
            "front_left",
            "front_right",
            "back_left",
            "back_right",
            "perimeter"
          ]
        },
        "facing": {
          "enum": [
            "free",
            "preserve",
            "toward_room_center",
            "away_from_wall",
            "toward_target"
          ]
        },
        "facingTargetInstanceId": {
          "type": ["string", "null"],
          "format": "uuid"
        },
        "allowFloorFallback": { "type": "boolean" },
        "notes": { "type": "string", "maxLength": 500 }
      }
    },
    "relation": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "relationId",
        "type",
        "subjectInstanceId",
        "targetInstanceId",
        "strength",
        "zone",
        "minimumM",
        "maximumM",
        "notes"
      ],
      "properties": {
        "relationId": { "type": "string", "format": "uuid" },
        "type": {
          "enum": [
            "ON",
            "NEAR",
            "LEFT_OF",
            "RIGHT_OF",
            "IN_FRONT_OF",
            "BEHIND",
            "FACING",
            "CENTERED_ON",
            "ALIGNED_WITH",
            "AGAINST_WALL",
            "KEEP_CLEAR_OF"
          ]
        },
        "subjectInstanceId": { "type": "string", "format": "uuid" },
        "targetInstanceId": { "type": ["string", "null"], "format": "uuid" },
        "strength": { "enum": ["hard", "soft"] },
        "zone": { "enum": ["any", "left", "right", "front", "back", "center"] },
        "minimumM": { "type": ["number", "null"], "minimum": 0 },
        "maximumM": { "type": ["number", "null"], "exclusiveMinimum": 0 },
        "notes": { "type": "string", "maxLength": 500 }
      }
    },
    "group": {
      "type": "object",
      "additionalProperties": false,
      "required": ["groupId", "label", "instanceIds", "cohesion"],
      "properties": {
        "groupId": { "type": "string", "format": "uuid" },
        "label": { "type": "string", "minLength": 1, "maxLength": 100 },
        "instanceIds": {
          "type": "array",
          "minItems": 2,
          "maxItems": 100,
          "items": { "type": "string", "format": "uuid" }
        },
        "cohesion": { "type": "number", "minimum": 0, "maximum": 1 }
      }
    },
    "excluded": {
      "type": "object",
      "additionalProperties": false,
      "required": ["instanceId", "reason"],
      "properties": {
        "instanceId": { "type": "string", "format": "uuid" },
        "reason": { "type": "string", "minLength": 1, "maxLength": 500 }
      }
    },
    "warning": {
      "type": "object",
      "additionalProperties": false,
      "required": ["code", "message", "instanceIds"],
      "properties": {
        "code": { "type": "string", "pattern": "^[A-Z][A-Z0-9_]{1,63}$" },
        "message": { "type": "string", "minLength": 1, "maxLength": 500 },
        "instanceIds": {
          "type": "array",
          "maxItems": 20,
          "items": { "type": "string", "format": "uuid" }
        }
      }
    }
  }
}
