{
  "openapi": "3.1.0",
  "info": {
    "title": "onto·fincas Catalogación API (GPT)",
    "version": "1.0.0",
    "description": "Clasifica una incidencia textual en la taxonomía onto·fincas y devuelve una respuesta compacta para GPT Actions."
  },
  "servers": [
    {
      "url": "https://api.aaff.pro"
    }
  ],
  "paths": {
    "/api/v1/catalogar-incidencia": {
      "post": {
        "operationId": "catalogarIncidencia",
        "summary": "Catalogar incidencia",
        "description": "Devuelve categoría más probable, confianza, revisión humana, evaluación operativa v1 (o null), actuaciones derivadas y alternativas.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "text"
                ],
                "properties": {
                  "text": {
                    "type": "string",
                    "description": "Texto libre de la incidencia.",
                    "minLength": 3,
                    "maxLength": 2000
                  },
                  "minConfidence": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1,
                    "default": 0.55
                  },
                  "maxAlternatives": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 5,
                    "default": 3
                  }
                },
                "example": {
                  "text": "cae agua en el patio",
                  "minConfidence": 0.55,
                  "maxAlternatives": 3
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Clasificación realizada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatalogacionSuccess"
                },
                "example": {
                  "ok": true,
                  "input": "cae agua en el patio",
                  "bestNodeId": "01.02.01.04.01",
                  "bestNodeName": "Fuga en tramo claramente común (patio, garaje, cuarto)",
                  "ruta": "Incidencias técnicas y de mantenimiento > Instalaciones de agua > Agua fría sanitaria (AFS) > Fugas y humedades AFS > Fuga en tramo claramente común (patio, garaje, cuarto)",
                  "confidence": 0.5108,
                  "appliedMinConfidence": 0.55,
                  "reviewRequired": true,
                  "coherenceAdjustments": [],
                  "coherenceRules": "v1",
                  "evaluacionOperativa": {
                    "version": "v1",
                    "riesgoOperativo": "Medio",
                    "impactoServicio": "Medio",
                    "criticidadActivo": "Alta",
                    "tipoActuacion": "Correctiva y preventiva",
                    "prioridadSugerida": "Alta",
                    "resumenCriterio": "v1: urgencia=media, fm_type=hard, maxRiesgoCatálogo=3, riesgos=2"
                  },
                  "actuacionesDerivadas": [
                    {
                      "id": "A.03",
                      "nombre": "Avisar técnico urgente (<2h)",
                      "descripcion": "Contratar técnico especialista de forma urgente"
                    }
                  ],
                  "alternatives": [
                    {
                      "nodeId": "01.02.01.04.01",
                      "nodeName": "Fuga en tramo claramente común (patio, garaje, cuarto)",
                      "confidence": 0.5108
                    },
                    {
                      "nodeId": "10.06.02",
                      "nodeName": "Calidad del agua deficiente",
                      "confidence": 0.35
                    }
                  ],
                  "fmStandardRefs": {
                    "iso41001": {
                      "section": "8.3",
                      "type": "hard_fm"
                    },
                    "gefma100": {
                      "code": "310",
                      "domain": "Instandhalten"
                    },
                    "din_en13306": {
                      "failure": "potential",
                      "intervention": "deferred"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Solicitud inválida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "BAD_REQUEST",
                    "message": "El campo `text` es obligatorio."
                  }
                }
              }
            }
          },
          "401": {
            "description": "No autorizado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "No autorizado."
                  }
                }
              }
            }
          },
          "429": {
            "description": "Demasiadas peticiones",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Demasiadas peticiones. Intenta de nuevo en unos segundos."
                  }
                }
              }
            }
          },
          "500": {
            "description": "Error interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Error interno."
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "CoherenceAdjustment": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ruleId",
          "fromNodeId",
          "toNodeId",
          "reason"
        ],
        "properties": {
          "ruleId": {
            "type": "string"
          },
          "fromNodeId": {
            "type": "string"
          },
          "toNodeId": {
            "type": "string"
          },
          "reason": {
            "type": "string"
          }
        }
      },
      "EvaluacionOperativaV1": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "version",
          "riesgoOperativo",
          "impactoServicio",
          "criticidadActivo",
          "tipoActuacion",
          "prioridadSugerida",
          "resumenCriterio"
        ],
        "properties": {
          "version": {
            "type": "string",
            "enum": [
              "v1"
            ]
          },
          "riesgoOperativo": {
            "type": "string",
            "enum": [
              "Bajo",
              "Medio",
              "Alto"
            ]
          },
          "impactoServicio": {
            "type": "string",
            "enum": [
              "Bajo",
              "Medio",
              "Alto"
            ]
          },
          "criticidadActivo": {
            "type": "string",
            "enum": [
              "Baja",
              "Media",
              "Alta"
            ]
          },
          "tipoActuacion": {
            "type": "string",
            "enum": [
              "Correctiva",
              "Preventiva",
              "Correctiva y preventiva"
            ]
          },
          "prioridadSugerida": {
            "type": "string",
            "enum": [
              "Baja",
              "Media",
              "Alta"
            ]
          },
          "resumenCriterio": {
            "type": "string"
          }
        }
      },
      "CatalogacionSuccess": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ok",
          "input",
          "bestNodeId",
          "bestNodeName",
          "ruta",
          "confidence",
          "appliedMinConfidence",
          "reviewRequired",
          "evaluacionOperativa",
          "coherenceAdjustments",
          "coherenceRules",
          "actuacionesDerivadas",
          "alternatives"
        ],
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "input": {
            "type": "string"
          },
          "bestNodeId": {
            "type": [
              "string",
              "null"
            ]
          },
          "bestNodeName": {
            "type": [
              "string",
              "null"
            ]
          },
          "ruta": {
            "type": [
              "string",
              "null"
            ]
          },
          "confidence": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          },
          "appliedMinConfidence": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          },
          "reviewRequired": {
            "type": "boolean"
          },
          "evaluacionOperativa": {
            "description": "Triaje operativo v1. Null si no hay nodo clasificado.",
            "anyOf": [
              {
                "$ref": "#/components/schemas/EvaluacionOperativaV1"
              },
              {
                "type": "null"
              }
            ]
          },
          "coherenceAdjustments": {
            "type": "array",
            "description": "Reordenaciones entre hojas hermanas tras reglas de coherencia jerárquica (p. ej. 1.4.2.x). Vacío si no hubo ajuste.",
            "items": {
              "$ref": "#/components/schemas/CoherenceAdjustment"
            }
          },
          "coherenceRules": {
            "description": "Versión del fichero de reglas aplicado (p. ej. v1).",
            "type": [
              "string",
              "null"
            ]
          },
          "actuacionesDerivadas": {
            "type": "array",
            "minItems": 0,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "id",
                "nombre",
                "descripcion"
              ],
              "properties": {
                "id": {
                  "type": "string"
                },
                "nombre": {
                  "type": "string"
                },
                "descripcion": {
                  "type": "string"
                }
              }
            }
          },
          "alternatives": {
            "type": "array",
            "minItems": 0,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "nodeId",
                "nodeName",
                "confidence"
              ],
              "properties": {
                "nodeId": {
                  "type": "string"
                },
                "nodeName": {
                  "type": "string"
                },
                "confidence": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1
                }
              }
            }
          },
          "fmStandardRefs": {
            "description": "Alineación con estándares FM internacionales (ISO 41001, GEFMA 100, DIN EN 13306). Null si el nodo no está clasificado. din_en13306 solo para nodos hard/mixto en familias técnicas.",
            "anyOf": [
              {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "iso41001": {
                    "type": "object",
                    "properties": {
                      "section": {
                        "type": "string"
                      },
                      "type": {
                        "type": "string"
                      }
                    }
                  },
                  "gefma100": {
                    "type": "object",
                    "properties": {
                      "code": {
                        "type": "string"
                      },
                      "domain": {
                        "type": "string"
                      }
                    }
                  },
                  "din_en13306": {
                    "type": "object",
                    "properties": {
                      "failure": {
                        "type": "string",
                        "enum": [
                          "functional",
                          "potential"
                        ]
                      },
                      "intervention": {
                        "type": "string",
                        "enum": [
                          "immediate",
                          "urgent",
                          "deferred",
                          "planned"
                        ]
                      }
                    }
                  }
                }
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ok",
          "error"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "error": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "BAD_REQUEST",
                  "UNAUTHORIZED",
                  "RATE_LIMITED",
                  "INTERNAL_ERROR"
                ]
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      }
    },
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key"
      }
    }
  }
}
