{
  "openapi": "3.1.0",
  "info": {
    "title": "Aspen FlowSim CAD 图块公开接口",
    "version": "1.4.0",
    "description": "读取完整 CAD 矢量模板、插入基点、设备占位矩形和 inN/outN 连接点，并计算世界放置结果。配置化设备由调用方先从 Aspen 拓扑给出 inlet_count/outlet_count，服务端再按端口优先级与图元绑定返回匹配实例。公开 GET 接口无需鉴权。"
  },
  "servers": [
    {
      "url": "https://api.aspenflowsim.top"
    }
  ],
  "externalDocs": {
    "description": "中文调用指南",
    "url": "https://api.aspenflowsim.top/cad-api/"
  },
  "paths": {
    "/api/v1/cad-blocks": {
      "get": {
        "summary": "读取 CAD 图块目录",
        "operationId": "listCadBlocks",
        "responses": {
          "200": {
            "description": "成功；请检查 fallback 字段判断是否使用万能块回退。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CadBlockCatalog"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/cad-blocks/{template_id}": {
      "get": {
        "summary": "先给实际进出口数量，再读取匹配 CAD 实例",
        "description": "若模板含 connection_configuration，调用方应先从 Aspen 拓扑确定 inlet_count/outlet_count 并成对传入；不传数量返回完整母模板。",
        "operationId": "getCadBlock",
        "parameters": [
          {
            "name": "template_id",
            "in": "path",
            "required": true,
            "description": "图块模板 ID；未知 ID 回退 GenericEquipmentBlock_01，HTTP 仍为 200。",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]+$"
            }
          },
          {
            "name": "inlet_count",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            },
            "description": "调用方从 Aspen 拓扑统计得到的实际入口数量；服务端不推测。仅配置化图块支持，必须与 outlet_count 同时提供。"
          },
          {
            "name": "outlet_count",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            },
            "description": "调用方从 Aspen 拓扑统计得到的实际出口数量；服务端不推测。仅配置化图块支持，必须与 inlet_count 同时提供。"
          }
        ],
        "responses": {
          "200": {
            "description": "成功；请检查 fallback 字段判断是否使用万能块回退。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CadBlock"
                }
              }
            }
          },
          "422": {
            "description": "坐标、缩放或旋转参数无效；scale_x/scale_y 不能为 0。"
          }
        }
      }
    },
    "/api/v1/cad-blocks/{template_id}/ports": {
      "get": {
        "summary": "按实际进出口数量读取启用端口",
        "description": "配置化设备传入 inlet_count/outlet_count 后只返回本次启用端口；不传数量返回母模板全部端口。",
        "operationId": "getCadBlockPorts",
        "parameters": [
          {
            "name": "template_id",
            "in": "path",
            "required": true,
            "description": "图块模板 ID；未知 ID 回退 GenericEquipmentBlock_01，HTTP 仍为 200。",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]+$"
            }
          },
          {
            "name": "inlet_count",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            },
            "description": "调用方从 Aspen 拓扑统计得到的实际入口数量；服务端不推测。仅配置化图块支持，必须与 outlet_count 同时提供。"
          },
          {
            "name": "outlet_count",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            },
            "description": "调用方从 Aspen 拓扑统计得到的实际出口数量；服务端不推测。仅配置化图块支持，必须与 inlet_count 同时提供。"
          }
        ],
        "responses": {
          "200": {
            "description": "成功；请检查 fallback 字段判断是否使用万能块回退。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConnectionPortsResponse"
                }
              }
            }
          },
          "422": {
            "description": "坐标、缩放或旋转参数无效；scale_x/scale_y 不能为 0。"
          }
        }
      }
    },
    "/api/v1/cad-blocks/{template_id}/occupancy": {
      "get": {
        "summary": "读取设备局部占位矩形与面积",
        "operationId": "getCadBlockOccupancy",
        "parameters": [
          {
            "name": "template_id",
            "in": "path",
            "required": true,
            "description": "图块模板 ID；未知 ID 回退 GenericEquipmentBlock_01，HTTP 仍为 200。",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]+$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "成功；请检查 fallback 字段判断是否使用万能块回退。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OccupancyResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/cad-blocks/{template_id}/placement": {
      "get": {
        "summary": "按实际进出口数量生成并放置匹配实例",
        "description": "推荐接口。配置化设备由调用方先从 Aspen 拓扑确定 inlet_count/outlet_count，服务端按绑定裁剪图形后再计算世界占位框和世界端口。",
        "operationId": "placeCadBlock",
        "parameters": [
          {
            "name": "template_id",
            "in": "path",
            "required": true,
            "description": "图块模板 ID；未知 ID 回退 GenericEquipmentBlock_01，HTTP 仍为 200。",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]+$"
            }
          },
          {
            "name": "inlet_count",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            },
            "description": "调用方从 Aspen 拓扑统计得到的实际入口数量；服务端不推测。仅配置化图块支持，必须与 outlet_count 同时提供。"
          },
          {
            "name": "outlet_count",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            },
            "description": "调用方从 Aspen 拓扑统计得到的实际出口数量；服务端不推测。仅配置化图块支持，必须与 inlet_count 同时提供。"
          },
          {
            "name": "insertion_x",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "default": 0
            },
            "description": "插入基点世界 X"
          },
          {
            "name": "insertion_y",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "default": 0
            },
            "description": "插入基点世界 Y"
          },
          {
            "name": "insertion_z",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "default": 0
            },
            "description": "插入基点世界 Z"
          },
          {
            "name": "scale_x",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "default": 1
            },
            "description": "X 缩放，不能为 0"
          },
          {
            "name": "scale_y",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "default": 1
            },
            "description": "Y 缩放，不能为 0"
          },
          {
            "name": "rotation_deg",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "default": 0
            },
            "description": "逆时针旋转角度"
          }
        ],
        "responses": {
          "200": {
            "description": "成功；请检查 fallback 字段判断是否使用万能块回退。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BlockPlacement"
                }
              }
            }
          },
          "422": {
            "description": "坐标、缩放或旋转参数无效；scale_x/scale_y 不能为 0。"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Vector3": {
        "type": "array",
        "minItems": 3,
        "maxItems": 3,
        "items": {
          "type": "number"
        },
        "description": "[x, y, z] 三维坐标；PFD 通常 z=0。"
      },
      "ApiResolution": {
        "type": "object",
        "required": [
          "requested_template_id",
          "template_id",
          "resolved_template_id",
          "fallback"
        ],
        "properties": {
          "requested_template_id": {
            "type": "string"
          },
          "template_id": {
            "type": "string"
          },
          "resolved_template_id": {
            "type": "string"
          },
          "fallback": {
            "type": "boolean"
          },
          "fallback_reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "fallback_template_id": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "ReferenceInsertionPoint": {
        "type": "object",
        "required": [
          "local"
        ],
        "properties": {
          "local": {
            "$ref": "#/components/schemas/Vector3"
          },
          "coordinate_system": {
            "type": "string"
          },
          "source_anchor": {
            "type": "string"
          },
          "web_preview": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "additionalProperties": true
      },
      "CadEntity": {
        "type": "object",
        "required": [
          "type",
          "geometry"
        ],
        "properties": {
          "handle": {
            "type": [
              "string",
              "null"
            ]
          },
          "type": {
            "type": "string",
            "description": "LINE、ARC、CIRCLE、LWPOLYLINE、INSERT、TEXT 等 CAD 实体类型。"
          },
          "layer": {
            "type": [
              "string",
              "null"
            ]
          },
          "linetype": {
            "type": [
              "string",
              "null"
            ]
          },
          "lineweight": {
            "type": [
              "number",
              "integer",
              "string",
              "null"
            ]
          },
          "color": {
            "type": [
              "object",
              "integer",
              "string",
              "null"
            ]
          },
          "transparency": {
            "type": [
              "object",
              "integer",
              "number",
              "string",
              "null"
            ]
          },
          "geometry": {
            "type": "object",
            "additionalProperties": true
          },
          "rendering": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "additionalProperties": true
      },
      "ConnectionPort": {
        "type": "object",
        "required": [
          "id",
          "flow",
          "local",
          "normal"
        ],
        "properties": {
          "port_uid": {
            "type": [
              "string",
              "null"
            ],
            "description": "跨端口重排的稳定身份；存在时优先用于保存绑定。"
          },
          "id": {
            "type": "string",
            "pattern": "^(in|out)[1-9][0-9]*$"
          },
          "flow": {
            "type": "string",
            "enum": [
              "in",
              "out"
            ]
          },
          "local": {
            "$ref": "#/components/schemas/Vector3"
          },
          "normal": {
            "$ref": "#/components/schemas/Vector3"
          },
          "world": {
            "$ref": "#/components/schemas/Vector3"
          },
          "world_normal": {
            "$ref": "#/components/schemas/Vector3"
          },
          "side": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "left",
              "right",
              "top",
              "bottom",
              "custom",
              null
            ]
          },
          "service": {
            "type": [
              "string",
              "null"
            ]
          },
          "role": {
            "type": [
              "string",
              "null"
            ]
          },
          "selection_priority": {
            "type": [
              "number",
              "integer",
              "null"
            ]
          },
          "confidence": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1
          },
          "snap": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "additionalProperties": true
      },
      "ConnectionPorts": {
        "type": "object",
        "required": [
          "status",
          "connectable",
          "review_required",
          "ports"
        ],
        "properties": {
          "schema": {
            "type": [
              "string",
              "null"
            ]
          },
          "coordinate_system": {
            "type": [
              "string",
              "null"
            ]
          },
          "coordinate_reference": {
            "type": [
              "string",
              "null"
            ],
            "const": "insertion_base_local"
          },
          "status": {
            "type": [
              "string",
              "null"
            ]
          },
          "connectable": {
            "type": "boolean"
          },
          "review_required": {
            "type": "boolean"
          },
          "world_transform": {
            "type": [
              "string",
              "null"
            ]
          },
          "ports": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConnectionPort"
            }
          }
        },
        "additionalProperties": true
      },
      "ConnectionConfiguration": {
        "type": "object",
        "required": [
          "schema",
          "mode",
          "default",
          "constraints",
          "bindings"
        ],
        "properties": {
          "schema": {
            "type": "string",
            "const": "cad-aspen-connection-configuration/v2"
          },
          "mode": {
            "type": "string",
            "const": "count_priority"
          },
          "default": {
            "type": "object",
            "required": [
              "inlet_count",
              "outlet_count"
            ],
            "additionalProperties": {
              "type": "integer"
            }
          },
          "constraints": {
            "type": "object",
            "additionalProperties": {
              "type": "object",
              "required": [
                "min",
                "max"
              ],
              "additionalProperties": {
                "type": "integer"
              }
            }
          },
          "bindings": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "port_uid",
                "flow",
                "priority",
                "geometry_binding"
              ],
              "properties": {
                "port_uid": {
                  "type": "string"
                },
                "flow": {
                  "type": "string",
                  "enum": [
                    "in",
                    "out"
                  ]
                },
                "priority": {
                  "type": "integer"
                },
                "geometry_binding": {
                  "type": "object",
                  "required": [
                    "mode",
                    "entity_handles"
                  ],
                  "properties": {
                    "mode": {
                      "type": "string",
                      "enum": [
                        "none",
                        "linked_entities"
                      ]
                    },
                    "entity_handles": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "additionalProperties": false
                }
              },
              "additionalProperties": true
            }
          }
        },
        "additionalProperties": true
      },
      "InstanceConfiguration": {
        "type": [
          "object",
          "null"
        ],
        "properties": {
          "schema": {
            "type": "string",
            "const": "cad-aspen-block-instance-configuration/v1"
          },
          "applied": {
            "type": "boolean"
          },
          "requested": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": {
              "type": "integer"
            }
          },
          "effective": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": {
              "type": "integer"
            }
          },
          "active_port_ids": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "active_port_uids": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "removed_port_ids": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "removed_port_uids": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "geometry_filter_applied": {
            "type": "boolean"
          },
          "source_template_complete": {
            "type": "boolean"
          }
        },
        "additionalProperties": true
      },
      "EquipmentOccupancyFrame": {
        "type": "object",
        "required": [
          "schema",
          "coordinate_system",
          "reference",
          "limits_from_insertion_base",
          "size"
        ],
        "properties": {
          "schema": {
            "type": "string"
          },
          "coordinate_system": {
            "type": "string"
          },
          "reference": {
            "type": "string",
            "const": "insertion_base_local"
          },
          "limits_from_insertion_base": {
            "type": "object",
            "required": [
              "left",
              "bottom",
              "right",
              "top"
            ],
            "properties": {
              "left": {
                "type": "number"
              },
              "bottom": {
                "type": "number"
              },
              "right": {
                "type": "number"
              },
              "top": {
                "type": "number"
              }
            }
          },
          "size": {
            "type": "object",
            "required": [
              "width",
              "height"
            ],
            "properties": {
              "width": {
                "type": "number",
                "minimum": 0
              },
              "height": {
                "type": "number",
                "minimum": 0
              }
            }
          },
          "padding": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "additionalProperties": true
      },
      "CadBlock": {
        "type": "object",
        "required": [
          "schema",
          "catalog",
          "bounds_local",
          "insertion_base_local",
          "reference_insertion_point",
          "entity_count",
          "entities",
          "layer_styles",
          "linetype_styles",
          "nested_block_dependencies",
          "connection_ports",
          "api_resolution"
        ],
        "properties": {
          "schema": {
            "type": "string"
          },
          "catalog": {
            "type": "object",
            "additionalProperties": true
          },
          "bounds_local": {
            "type": "array",
            "minItems": 4,
            "items": {
              "type": "number"
            }
          },
          "insertion_base_local": {
            "$ref": "#/components/schemas/Vector3"
          },
          "reference_insertion_point": {
            "$ref": "#/components/schemas/ReferenceInsertionPoint"
          },
          "entity_count": {
            "type": "integer",
            "minimum": 0
          },
          "entities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CadEntity"
            }
          },
          "layer_styles": {
            "type": [
              "object",
              "array"
            ],
            "additionalProperties": true
          },
          "linetype_styles": {
            "type": [
              "object",
              "array"
            ],
            "additionalProperties": true
          },
          "nested_block_dependencies": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "equipment_occupancy_frame": {
            "$ref": "#/components/schemas/EquipmentOccupancyFrame"
          },
          "connection_ports": {
            "$ref": "#/components/schemas/ConnectionPorts"
          },
          "connection_configuration": {
            "$ref": "#/components/schemas/ConnectionConfiguration"
          },
          "instance_configuration": {
            "$ref": "#/components/schemas/InstanceConfiguration"
          },
          "api_resolution": {
            "$ref": "#/components/schemas/ApiResolution"
          }
        },
        "additionalProperties": true
      },
      "CadBlockCatalog": {
        "type": "object",
        "required": [
          "schema",
          "version",
          "count",
          "fallback_template_id",
          "endpoint_templates",
          "blocks"
        ],
        "properties": {
          "schema": {
            "type": "string"
          },
          "version": {
            "type": "string"
          },
          "count": {
            "type": "integer"
          },
          "fallback_template_id": {
            "type": "string"
          },
          "endpoint_templates": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "blocks": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        },
        "additionalProperties": true
      },
      "ConnectionPortsResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ApiResolution"
          },
          {
            "type": "object",
            "required": [
              "connection_ports"
            ],
            "properties": {
              "connection_ports": {
                "$ref": "#/components/schemas/ConnectionPorts"
              },
              "instance_configuration": {
                "$ref": "#/components/schemas/InstanceConfiguration"
              },
              "links": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        ]
      },
      "OccupancyResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ApiResolution"
          },
          {
            "type": "object",
            "required": [
              "insertion_base_local",
              "equipment_occupancy_frame",
              "rectangle"
            ],
            "properties": {
              "insertion_base_local": {
                "$ref": "#/components/schemas/Vector3"
              },
              "equipment_occupancy_frame": {
                "$ref": "#/components/schemas/EquipmentOccupancyFrame"
              },
              "rectangle": {
                "type": "object",
                "additionalProperties": true
              },
              "links": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        ]
      },
      "BlockPlacement": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ApiResolution"
          },
          {
            "type": "object",
            "required": [
              "schema",
              "transform",
              "occupancy",
              "ports"
            ],
            "properties": {
              "schema": {
                "type": "string",
                "const": "cad-aspen-block-placement/v1"
              },
              "block_role": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "instance_configuration": {
                "$ref": "#/components/schemas/InstanceConfiguration"
              },
              "transform": {
                "type": "object",
                "required": [
                  "insertion_world",
                  "insertion_base_local",
                  "scale",
                  "rotation_deg",
                  "point_formula"
                ],
                "properties": {
                  "insertion_world": {
                    "$ref": "#/components/schemas/Vector3"
                  },
                  "insertion_base_local": {
                    "$ref": "#/components/schemas/Vector3"
                  },
                  "scale": {
                    "$ref": "#/components/schemas/Vector3"
                  },
                  "rotation_deg": {
                    "type": "number"
                  },
                  "point_formula": {
                    "type": "string"
                  }
                }
              },
              "occupancy": {
                "type": "object",
                "required": [
                  "available"
                ],
                "additionalProperties": true
              },
              "ports": {
                "type": "object",
                "required": [
                  "connectable",
                  "review_required",
                  "count",
                  "inlet_count",
                  "outlet_count",
                  "items"
                ],
                "properties": {
                  "schema": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "status": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "connectable": {
                    "type": "boolean"
                  },
                  "review_required": {
                    "type": "boolean"
                  },
                  "count": {
                    "type": "integer"
                  },
                  "inlet_count": {
                    "type": "integer"
                  },
                  "outlet_count": {
                    "type": "integer"
                  },
                  "items": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/ConnectionPort"
                    }
                  }
                }
              },
              "links": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        ]
      }
    }
  }
}