{
  "openapi": "3.0.3",
  "info": {
    "title": "Trento Core API — Endpoints requeridos por FTL Trace",
    "version": "1.0.0-draft",
    "description": "Documento de referencia · 2026-05-14 · v1.0.\n\nEste Swagger acompaña al **documento técnico** (Docx) entregado por separado. Las rutas, parámetros y schemas son **propuestas**: Trento puede ajustar nombres y estructura siempre que la cobertura de campos se preserve.\n\nPara el detalle narrativo —contexto, autenticación, paginación, manejo de errores, rate limits, caching, versionado y roadmap— ver el Docx adjunto.\n\n---\n\n**Ejemplos anclados en data real** — partida `24-06432` de la OP `6297` (id `6297`), cliente WORLD TEXTILE SOURCING INC / Peter Millar, estilo del piloto. Extraído del schema `trento.*` el 2026-05-14. Campos PII de individuos redactados a `null`. **El API no ejecuta** — el Try-it-out está deshabilitado porque el contrato aún no está implementado.",
    "contact": {
      "name": "FintechLab S.A.C. — FTL Trace",
      "email": "info@fintechlab.la"
    },
    "license": {
      "name": "Documento confidencial interno",
      "url": "https://fintechlab.la"
    }
  },
  "servers": [
    {
      "url": "https://api-sandbox.trento.example/v1",
      "description": "Sandbox (snapshot de OPs piloto)"
    },
    {
      "url": "https://api.trento.example/v1",
      "description": "Producción"
    }
  ],
  "tags": [
    {
      "name": "Maestros",
      "description": "Categoría 1 (v1.5 sec 3.1). Productos, estilos, colores, proveedores, clientes, tallas, composición."
    },
    {
      "name": "Órdenes de Producción",
      "description": "Categoría 2. OP master + planificación de corte. `op_id` es la llave universal."
    },
    {
      "name": "Recepciones",
      "description": "Categoría 3. Entrada de tela y lookup GS1 por partida."
    },
    {
      "name": "Avíos",
      "description": "Anexa P2. CP8."
    },
    {
      "name": "Lavado",
      "description": "Anexa P2. CP3 (integración Qlever)."
    },
    {
      "name": "Packing y Despacho",
      "description": "Anexa P2. CP8 / CP9."
    },
    {
      "name": "Costura e Inspección",
      "description": "Anexa P2. CP6 / CP7 (con gap aceptado)."
    },
    {
      "name": "_meta",
      "description": "Endpoints de salud y metadata del API."
    }
  ],
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKey": []
    }
  ],
  "paths": {
    "/health": {
      "get": {
        "summary": "Estado del API y lag de replicación",
        "description": "Endpoint de salud. FTL lo consulta para detectar lag del replicador SQL Server → API.",
        "tags": [
          "_meta"
        ],
        "operationId": "health",
        "parameters": [],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "ok",
                        "degraded",
                        "down"
                      ],
                      "example": "ok"
                    },
                    "replication_lag_seconds": {
                      "type": "integer",
                      "example": 12
                    },
                    "version": {
                      "type": "string",
                      "example": "1.0.4"
                    },
                    "build": {
                      "type": "string",
                      "format": "date-time",
                      "example": "2026-05-12T18:00:00Z"
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/products/{product_id}": {
      "get": {
        "summary": "M-1 · Producto por id",
        "description": "Devuelve descripción, código y tipo de tela. Hoy: parte de Q_CP1 sobre `trento.\"TblProductos\"`.",
        "tags": [
          "Maestros"
        ],
        "operationId": "getProductById",
        "parameters": [
          {
            "name": "product_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 12345
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:masters"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Producto encontrado.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "id",
                    "code"
                  ],
                  "properties": {
                    "id": {
                      "type": "integer",
                      "example": 12345,
                      "description": "trento.TblProductos.IdProducto"
                    },
                    "code": {
                      "type": "string",
                      "example": "TELA-PIMA-185"
                    },
                    "productive_description": {
                      "type": "string",
                      "example": "Jersey Pima 185g 93% Algodón Pima 7% Spandex"
                    },
                    "commercial_description": {
                      "type": "string",
                      "example": "Pima 100% premium"
                    },
                    "supplier_id": {
                      "type": "integer",
                      "nullable": true,
                      "example": 9087
                    },
                    "fabric_type": {
                      "type": "string",
                      "example": "JERSEY"
                    }
                  }
                },
                "example": {
                  "id": 41821,
                  "code": "27881",
                  "productive_description": "JERSEY LISTADO FULL LYCRA 93% PIMA COTTON ORGANICO 7% SPANDEX - RYLES STRIPE MS26K51",
                  "commercial_description": "JERSEY LISTADO FULL LYCRA 93% PIMA COTTON ORGANICO 7% SPANDEX",
                  "supplier_id": 726,
                  "fabric_type": "JERSEY LISTADO FULL LYCRA 93% PIMA COTTON ORGANICO 7% SPANDEX"
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/products": {
      "get": {
        "summary": "M-2 · Producto por código",
        "description": "Lookup alternativo por `code` cuando el QR/SSCC trae el código humano.",
        "tags": [
          "Maestros"
        ],
        "operationId": "getProductByCode",
        "parameters": [
          {
            "name": "code",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "TELA-PIMA-185"
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:masters"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Producto encontrado.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "id",
                    "code"
                  ],
                  "properties": {
                    "id": {
                      "type": "integer",
                      "example": 12345,
                      "description": "trento.TblProductos.IdProducto"
                    },
                    "code": {
                      "type": "string",
                      "example": "TELA-PIMA-185"
                    },
                    "productive_description": {
                      "type": "string",
                      "example": "Jersey Pima 185g 93% Algodón Pima 7% Spandex"
                    },
                    "commercial_description": {
                      "type": "string",
                      "example": "Pima 100% premium"
                    },
                    "supplier_id": {
                      "type": "integer",
                      "nullable": true,
                      "example": 9087
                    },
                    "fabric_type": {
                      "type": "string",
                      "example": "JERSEY"
                    }
                  }
                },
                "example": {
                  "id": 41821,
                  "code": "27881",
                  "productive_description": "JERSEY LISTADO FULL LYCRA 93% PIMA COTTON ORGANICO 7% SPANDEX - RYLES STRIPE MS26K51",
                  "commercial_description": "JERSEY LISTADO FULL LYCRA 93% PIMA COTTON ORGANICO 7% SPANDEX",
                  "supplier_id": 726,
                  "fabric_type": "JERSEY LISTADO FULL LYCRA 93% PIMA COTTON ORGANICO 7% SPANDEX"
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/styles/{style_id}": {
      "get": {
        "summary": "M-3 · Estilo por id (o code)",
        "description": "Maestro de estilos `trento.\"UdpEstilo\"`. Necesario para CP4 y CP8.",
        "tags": [
          "Maestros"
        ],
        "operationId": "getStyleById",
        "parameters": [
          {
            "name": "style_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "4421",
            "description": "Acepta id numérico o `code` precedido por `code:`."
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:masters"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Estilo encontrado.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "id",
                    "code"
                  ],
                  "properties": {
                    "id": {
                      "type": "integer",
                      "example": 4421
                    },
                    "code": {
                      "type": "string",
                      "example": "P-12345"
                    },
                    "description": {
                      "type": "string",
                      "example": "Polo manga corta Pima"
                    },
                    "default_color_id": {
                      "type": "integer",
                      "nullable": true,
                      "example": 88
                    }
                  }
                },
                "example": {
                  "id": 34191,
                  "code": "MS26K51",
                  "description": "Polo Peter Millar línea MS26K51",
                  "default_color_id": null
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/colors/{color_id}": {
      "get": {
        "summary": "M-4 · Color por id",
        "description": "Maestro de colores `trento.\"UdpColor\"` (y `TblDMaestro` para colores universales).",
        "tags": [
          "Maestros"
        ],
        "operationId": "getColorById",
        "parameters": [
          {
            "name": "color_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 88
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:masters"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Color encontrado.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "id",
                    "code"
                  ],
                  "properties": {
                    "id": {
                      "type": "integer",
                      "example": 88
                    },
                    "code": {
                      "type": "string",
                      "example": "BLANCO"
                    },
                    "description": {
                      "type": "string",
                      "example": "Blanco óptico"
                    },
                    "pantone": {
                      "type": "string",
                      "nullable": true,
                      "example": "11-0601 TPX"
                    }
                  }
                },
                "example": {
                  "id": null,
                  "code": "WHT",
                  "description": "Blanco óptico",
                  "pantone": null
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/suppliers/{supplier_id}": {
      "get": {
        "summary": "M-5 · Proveedor por id (P0)",
        "description": "Datos de `trento.\"Persona\"` (proveedor textil para CP1; proveedor de lavandería para CP3).",
        "tags": [
          "Maestros"
        ],
        "operationId": "getSupplierById",
        "parameters": [
          {
            "name": "supplier_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 9087
          },
          {
            "name": "ruc",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Lookup alterno por RUC."
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:masters"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Proveedor encontrado.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "id",
                    "ruc",
                    "legal_name"
                  ],
                  "properties": {
                    "id": {
                      "type": "integer",
                      "example": 9087,
                      "description": "trento.Persona.IdPersona"
                    },
                    "ruc": {
                      "type": "string",
                      "example": "20512345678",
                      "description": "trento.Persona.CodPersona"
                    },
                    "legal_name": {
                      "type": "string",
                      "example": "Hilanderías del Sur S.A.C."
                    },
                    "address": {
                      "type": "string",
                      "nullable": true,
                      "example": "Av. Industrial 123, Lima, Perú"
                    },
                    "country_code": {
                      "type": "string",
                      "nullable": true,
                      "example": "PE",
                      "minLength": 2,
                      "maxLength": 2
                    },
                    "tier": {
                      "type": "string",
                      "nullable": true,
                      "enum": [
                        "fabric_supplier",
                        "laundry_supplier",
                        "fiber_supplier",
                        "accessories_supplier",
                        null
                      ],
                      "example": "fabric_supplier"
                    }
                  }
                },
                "example": {
                  "id": 726,
                  "ruc": "20102261551",
                  "legal_name": "TEXTIL SAN RAMON S A",
                  "address": null,
                  "country_code": "PE",
                  "tier": "fabric_supplier"
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/clients/by-op/{op_id}": {
      "get": {
        "summary": "M-6 · Cliente por OP (P0)",
        "description": "Resuelve `trento.\"ComCentroGestion\"` encapsulando la concatenación `'OP-' + CodigoOP`.",
        "tags": [
          "Maestros"
        ],
        "operationId": "getClientByOp",
        "parameters": [
          {
            "name": "op_id",
            "in": "path",
            "required": true,
            "description": "trento.UdpOrdenProduccion.IdOrdenProduccion (entero, PK).",
            "schema": {
              "type": "integer"
            },
            "example": 6223
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:masters"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Cliente resuelto.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "op_id",
                    "client_name"
                  ],
                  "properties": {
                    "op_id": {
                      "type": "integer",
                      "example": 6223
                    },
                    "client_name": {
                      "type": "string",
                      "example": "Brand X Apparel Ltd."
                    },
                    "client_brand": {
                      "type": "string",
                      "nullable": true,
                      "example": "BX-Athleisure"
                    },
                    "style_code": {
                      "type": "string",
                      "nullable": true,
                      "example": "P-12345"
                    }
                  }
                },
                "example": {
                  "op_id": 6297,
                  "client_name": "WORLD TEXTILE SOURCING INC",
                  "client_brand": "PETER MILLAR",
                  "style_code": "MS26K51"
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/production-orders/{op_id}/size-distribution": {
      "get": {
        "summary": "M-7 · Distribución de tallas asignada a la OP (P0)",
        "description": "Reemplaza el adaptador `get_distribucion_tallas(op_id)`.",
        "tags": [
          "Maestros"
        ],
        "operationId": "getSizeDistributionByOp",
        "parameters": [
          {
            "name": "op_id",
            "in": "path",
            "required": true,
            "description": "trento.UdpOrdenProduccion.IdOrdenProduccion (entero, PK).",
            "schema": {
              "type": "integer"
            },
            "example": 6223
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:masters"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Distribución de tallas.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "op_id",
                    "distribution",
                    "total"
                  ],
                  "properties": {
                    "op_id": {
                      "type": "integer",
                      "example": 6223
                    },
                    "production_order_code": {
                      "type": "string",
                      "example": "6223"
                    },
                    "distribution": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "size_code",
                          "quantity"
                        ],
                        "properties": {
                          "size_code": {
                            "type": "string",
                            "example": "M"
                          },
                          "quantity": {
                            "type": "integer",
                            "minimum": 0,
                            "example": 240
                          }
                        }
                      }
                    },
                    "total": {
                      "type": "integer",
                      "minimum": 0,
                      "example": 640
                    }
                  }
                },
                "example": {
                  "op_id": 6297,
                  "production_order_code": "6297",
                  "distribution": [],
                  "total": 0
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/production-orders/{op_id}/material-composition": {
      "get": {
        "summary": "M-8 · Composición de fibra parseada (P0)",
        "description": "Composición ya estructurada (no string libre). Pilar del cálculo PEF LCS1.",
        "tags": [
          "Maestros"
        ],
        "operationId": "getMaterialCompositionByOp",
        "parameters": [
          {
            "name": "op_id",
            "in": "path",
            "required": true,
            "description": "trento.UdpOrdenProduccion.IdOrdenProduccion (entero, PK).",
            "schema": {
              "type": "integer"
            },
            "example": 6223
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:masters"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Composición parseada.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "op_id",
                    "composition"
                  ],
                  "properties": {
                    "op_id": {
                      "type": "integer",
                      "example": 6223
                    },
                    "composition": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "material",
                          "percentage"
                        ],
                        "properties": {
                          "material": {
                            "type": "string",
                            "example": "cotton"
                          },
                          "percentage": {
                            "type": "number",
                            "minimum": 0,
                            "maximum": 100,
                            "example": 93
                          },
                          "organic": {
                            "type": "boolean",
                            "example": true
                          },
                          "iso_2076_code": {
                            "type": "string",
                            "example": "CO",
                            "description": "ISO 2076 fibre code"
                          }
                        }
                      }
                    },
                    "total_percentage": {
                      "type": "number",
                      "example": 100
                    },
                    "raw_source_string": {
                      "type": "string",
                      "nullable": true,
                      "example": "93% PIMA COTTON ORGANICO 7% SPANDEX"
                    }
                  }
                },
                "example": {
                  "op_id": 6297,
                  "composition": [],
                  "total_percentage": null,
                  "raw_source_string": "(27881) JERSEY LISTADO FULL LYCRA 93% PIMA COTTON ORGANICO 7% SPANDEX - RYLES STRIPE MS26K51"
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/production-orders/{op_id}": {
      "get": {
        "summary": "OP-1 · OP master + detalle + ficha técnica (P0)",
        "description": "Primer call del flujo CP1. Reemplaza el adaptador `get_op_metadata(op_id)`.",
        "tags": [
          "Órdenes de Producción"
        ],
        "operationId": "getProductionOrderById",
        "parameters": [
          {
            "name": "op_id",
            "in": "path",
            "required": true,
            "description": "trento.UdpOrdenProduccion.IdOrdenProduccion (entero, PK).",
            "schema": {
              "type": "integer"
            },
            "example": 6223
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:production-orders"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OP encontrada.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "id",
                    "code"
                  ],
                  "properties": {
                    "id": {
                      "type": "integer",
                      "example": 6223,
                      "description": "trento.UdpOrdenProduccion.IdOrdenProduccion"
                    },
                    "code": {
                      "type": "string",
                      "example": "6223"
                    },
                    "purchase_order": {
                      "type": "object",
                      "required": [
                        "id",
                        "code"
                      ],
                      "properties": {
                        "id": {
                          "type": "integer",
                          "example": 87123
                        },
                        "code": {
                          "type": "string",
                          "example": "PO-2026-0042"
                        },
                        "planned_shipment_date": {
                          "type": "string",
                          "format": "date",
                          "nullable": true,
                          "example": "2026-07-15"
                        },
                        "tolerance_pct": {
                          "type": "number",
                          "nullable": true,
                          "example": 5
                        },
                        "destination_country_code": {
                          "type": "string",
                          "nullable": true,
                          "example": "DE"
                        },
                        "destination_id": {
                          "type": "integer",
                          "nullable": true,
                          "example": 412
                        },
                        "transport_mode_id": {
                          "type": "integer",
                          "nullable": true,
                          "example": 2
                        }
                      }
                    },
                    "style": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer",
                          "example": 4421
                        },
                        "code": {
                          "type": "string",
                          "example": "P-12345"
                        },
                        "description": {
                          "type": "string",
                          "example": "Polo manga corta Pima"
                        },
                        "technical_sheet_id": {
                          "type": "integer",
                          "nullable": true,
                          "example": 1572
                        }
                      }
                    },
                    "fabric_product_id": {
                      "type": "integer",
                      "nullable": true,
                      "example": 12345
                    },
                    "client": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer",
                          "example": 33
                        },
                        "name": {
                          "type": "string",
                          "example": "Brand X Apparel Ltd."
                        },
                        "brand": {
                          "type": "string",
                          "nullable": true,
                          "example": "BX-Athleisure"
                        }
                      }
                    },
                    "season": {
                      "type": "string",
                      "nullable": true,
                      "example": "SS-2026"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time",
                      "example": "2026-03-12T10:14:00-05:00"
                    },
                    "lines": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "color_id",
                          "size_code",
                          "quantity"
                        ],
                        "properties": {
                          "color_id": {
                            "type": "integer",
                            "example": 88
                          },
                          "size_code": {
                            "type": "string",
                            "example": "M"
                          },
                          "quantity": {
                            "type": "integer",
                            "minimum": 0,
                            "example": 60
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "id": 6297,
                  "code": "6297",
                  "purchase_order": {
                    "id": 2226,
                    "code": "43713",
                    "planned_shipment_date": "2026-01-16",
                    "tolerance_pct": 5.0,
                    "destination_country_code": null,
                    "destination_id": 0,
                    "transport_mode_id": 627
                  },
                  "style": {
                    "id": 34191,
                    "code": "MS26K51",
                    "description": null,
                    "technical_sheet_id": null
                  },
                  "fabric_product_id": 41821,
                  "client": {
                    "id": null,
                    "name": "WORLD TEXTILE SOURCING INC",
                    "brand": "PETER MILLAR"
                  },
                  "season": null,
                  "created_at": null,
                  "lines": []
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/production-orders": {
      "get": {
        "summary": "OP-2 · Listado paginado de OPs (P2)",
        "description": "Para dashboard astro a futuro. No bloquea piloto.",
        "tags": [
          "Órdenes de Producción"
        ],
        "operationId": "listProductionOrders",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "client_id",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "closed",
                "despatched"
              ]
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:production-orders"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Listado paginado.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "type": "object",
                      "required": [
                        "page",
                        "limit",
                        "has_more"
                      ],
                      "properties": {
                        "page": {
                          "type": "integer",
                          "minimum": 1,
                          "example": 2
                        },
                        "limit": {
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 200,
                          "example": 50
                        },
                        "total": {
                          "type": "integer",
                          "nullable": true,
                          "example": 312
                        },
                        "has_more": {
                          "type": "boolean",
                          "example": true
                        }
                      }
                    },
                    {
                      "type": "object",
                      "required": [
                        "items"
                      ],
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "required": [
                              "id",
                              "code"
                            ],
                            "properties": {
                              "id": {
                                "type": "integer",
                                "example": 6223
                              },
                              "code": {
                                "type": "string",
                                "example": "6223"
                              },
                              "client_id": {
                                "type": "integer",
                                "nullable": true,
                                "example": 33
                              },
                              "client_name": {
                                "type": "string",
                                "nullable": true,
                                "example": "Brand X Apparel Ltd."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "active",
                                  "closed",
                                  "despatched"
                                ],
                                "example": "active"
                              },
                              "created_at": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/production-orders/{op_id}/cutting-orders": {
      "get": {
        "summary": "OP-3 · Hojas de corte por OP (P0)",
        "description": "CP2/CP4 precargado. `sizes` debe entregarse parseado de `ProdOrdenCorte.CampoTallas`.",
        "tags": [
          "Órdenes de Producción"
        ],
        "operationId": "getCuttingOrdersByOp",
        "parameters": [
          {
            "name": "op_id",
            "in": "path",
            "required": true,
            "description": "trento.UdpOrdenProduccion.IdOrdenProduccion (entero, PK).",
            "schema": {
              "type": "integer"
            },
            "example": 6223
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:production-orders"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Hojas de corte.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "op_id",
                    "cutting_orders"
                  ],
                  "properties": {
                    "op_id": {
                      "type": "integer",
                      "example": 6223
                    },
                    "cutting_orders": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "code"
                        ],
                        "properties": {
                          "id": {
                            "type": "integer",
                            "example": 901
                          },
                          "code": {
                            "type": "string",
                            "example": "HC-6223-01"
                          },
                          "cutting_program_id": {
                            "type": "integer",
                            "nullable": true,
                            "example": 514
                          },
                          "cutting_date": {
                            "type": "string",
                            "format": "date",
                            "nullable": true,
                            "example": "2026-04-12"
                          },
                          "total_units_cut": {
                            "type": "integer",
                            "nullable": true,
                            "example": 320
                          },
                          "sizes": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "required": [
                                "size_code",
                                "quantity"
                              ],
                              "properties": {
                                "size_code": {
                                  "type": "string",
                                  "example": "M"
                                },
                                "quantity": {
                                  "type": "integer",
                                  "minimum": 0,
                                  "example": 240
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "op_id": 6297,
                  "cutting_orders": [
                    {
                      "id": 6711084,
                      "code": "O - 0010090",
                      "cutting_program_id": 7231,
                      "cutting_date": "2025-12-19",
                      "total_units_cut": 840.0,
                      "sizes": []
                    },
                    {
                      "id": 6711084,
                      "code": "O - 0010090",
                      "cutting_program_id": 7230,
                      "cutting_date": "2025-12-19",
                      "total_units_cut": 840.0,
                      "sizes": []
                    },
                    {
                      "id": 6711084,
                      "code": "O - 0010090",
                      "cutting_program_id": 7347,
                      "cutting_date": "2025-12-29",
                      "total_units_cut": 840.0,
                      "sizes": []
                    },
                    {
                      "id": 6711085,
                      "code": "O - 0010091",
                      "cutting_program_id": 7231,
                      "cutting_date": "2025-12-19",
                      "total_units_cut": 840.0,
                      "sizes": []
                    },
                    {
                      "id": 6711085,
                      "code": "O - 0010091",
                      "cutting_program_id": 7230,
                      "cutting_date": "2025-12-19",
                      "total_units_cut": 840.0,
                      "sizes": []
                    },
                    {
                      "id": 6711085,
                      "code": "O - 0010091",
                      "cutting_program_id": 7347,
                      "cutting_date": "2025-12-29",
                      "total_units_cut": 840.0,
                      "sizes": []
                    },
                    {
                      "id": 6711220,
                      "code": "O - 0010226",
                      "cutting_program_id": 7230,
                      "cutting_date": "2025-12-19",
                      "total_units_cut": 844.0,
                      "sizes": []
                    },
                    {
                      "id": 6711220,
                      "code": "O - 0010226",
                      "cutting_program_id": 7347,
                      "cutting_date": "2025-12-29",
                      "total_units_cut": 844.0,
                      "sizes": []
                    },
                    {
                      "id": 6711220,
                      "code": "O - 0010226",
                      "cutting_program_id": 7231,
                      "cutting_date": "2025-12-19",
                      "total_units_cut": 844.0,
                      "sizes": []
                    }
                  ]
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/cutting-orders/{cutting_id}": {
      "get": {
        "summary": "OP-4 · Hoja de corte por id (P1)",
        "description": "Drill-down individual.",
        "tags": [
          "Órdenes de Producción"
        ],
        "operationId": "getCuttingOrderById",
        "parameters": [
          {
            "name": "cutting_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 901
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:production-orders"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Hoja de corte.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "id",
                    "code"
                  ],
                  "properties": {
                    "id": {
                      "type": "integer",
                      "example": 901
                    },
                    "code": {
                      "type": "string",
                      "example": "HC-6223-01"
                    },
                    "cutting_program_id": {
                      "type": "integer",
                      "nullable": true,
                      "example": 514
                    },
                    "cutting_date": {
                      "type": "string",
                      "format": "date",
                      "nullable": true,
                      "example": "2026-04-12"
                    },
                    "total_units_cut": {
                      "type": "integer",
                      "nullable": true,
                      "example": 320
                    },
                    "sizes": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "size_code",
                          "quantity"
                        ],
                        "properties": {
                          "size_code": {
                            "type": "string",
                            "example": "M"
                          },
                          "quantity": {
                            "type": "integer",
                            "minimum": 0,
                            "example": 240
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "id": 6711084,
                  "code": "O - 0010090",
                  "cutting_program_id": 7231,
                  "cutting_date": "2025-12-19",
                  "total_units_cut": 840.0,
                  "sizes": []
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/production-orders/{op_id}/size-analysis": {
      "get": {
        "summary": "OP-5 · Análisis programado vs pedido por talla y color (P1)",
        "description": "CP4 (corte de piezas + GTIN).",
        "tags": [
          "Órdenes de Producción"
        ],
        "operationId": "getSizeAnalysisByOp",
        "parameters": [
          {
            "name": "op_id",
            "in": "path",
            "required": true,
            "description": "trento.UdpOrdenProduccion.IdOrdenProduccion (entero, PK).",
            "schema": {
              "type": "integer"
            },
            "example": 6223
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:production-orders"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Análisis.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "op_id",
                    "analysis"
                  ],
                  "properties": {
                    "op_id": {
                      "type": "integer",
                      "example": 6223
                    },
                    "analysis": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "color_id": {
                            "type": "integer",
                            "example": 88
                          },
                          "total_planned": {
                            "type": "integer",
                            "example": 320
                          },
                          "total_original_order": {
                            "type": "integer",
                            "example": 320
                          },
                          "by_size": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "size_code": {
                                  "type": "string",
                                  "example": "S"
                                },
                                "planned": {
                                  "type": "integer",
                                  "example": 60
                                },
                                "original": {
                                  "type": "integer",
                                  "example": 60
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "op_id": 6297,
                  "analysis": [
                    {
                      "color_id": 829,
                      "total_planned": 840.0,
                      "total_original_order": 800.0,
                      "by_size": []
                    },
                    {
                      "color_id": 832,
                      "total_planned": 840.0,
                      "total_original_order": 800.0,
                      "by_size": []
                    },
                    {
                      "color_id": 5489,
                      "total_planned": 843.0,
                      "total_original_order": 800.0,
                      "by_size": []
                    }
                  ]
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/production-orders/{op_id}/cutting-closure": {
      "get": {
        "summary": "OP-6 · Cierre QA del corte (P1)",
        "description": "CP5: fecha de habilitado + tipos de consumo presentes.",
        "tags": [
          "Órdenes de Producción"
        ],
        "operationId": "getCuttingClosureByOp",
        "parameters": [
          {
            "name": "op_id",
            "in": "path",
            "required": true,
            "description": "trento.UdpOrdenProduccion.IdOrdenProduccion (entero, PK).",
            "schema": {
              "type": "integer"
            },
            "example": 6223
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:production-orders"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Cierre QA.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "op_id": {
                      "type": "integer",
                      "example": 6223
                    },
                    "enabled_date": {
                      "type": "string",
                      "format": "date",
                      "nullable": true,
                      "example": "2026-04-20"
                    },
                    "consumption_types_present": {
                      "type": "array",
                      "items": {
                        "type": "integer"
                      },
                      "example": [
                        1,
                        2,
                        3
                      ]
                    }
                  }
                },
                "example": {
                  "op_id": 6297,
                  "enabled_date": "2025-12-29",
                  "consumption_types_present": [
                    1,
                    5
                  ]
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/production-orders/{op_id}/consumption-sheet": {
      "get": {
        "summary": "OP-7 · Hoja de consumo por talla y color (P1)",
        "description": "Filtrable por `consumption_type` (1=tela, otros=avíos/embalaje).",
        "tags": [
          "Órdenes de Producción"
        ],
        "operationId": "getConsumptionSheetByOp",
        "parameters": [
          {
            "name": "op_id",
            "in": "path",
            "required": true,
            "description": "trento.UdpOrdenProduccion.IdOrdenProduccion (entero, PK).",
            "schema": {
              "type": "integer"
            },
            "example": 6223
          },
          {
            "name": "consumption_type",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "1 = tela; otros = avíos/embalaje."
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:production-orders"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Hoja de consumo.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "op_id",
                    "sheets"
                  ],
                  "properties": {
                    "op_id": {
                      "type": "integer",
                      "example": 6223
                    },
                    "sheets": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "consumption_type": {
                            "type": "integer",
                            "example": 1
                          },
                          "label": {
                            "type": "string",
                            "enum": [
                              "fabric",
                              "accessories",
                              "packaging",
                              "other"
                            ],
                            "example": "fabric"
                          },
                          "consumption_per_unit": {
                            "type": "number",
                            "nullable": true,
                            "example": 0.45
                          },
                          "unit": {
                            "type": "string",
                            "nullable": true,
                            "example": "kg/garment"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "op_id": 6297,
                  "sheets": [
                    {
                      "consumption_type": 1,
                      "label": "fabric",
                      "consumption_per_unit": 0.329,
                      "unit": "kg/garment"
                    },
                    {
                      "consumption_type": 5,
                      "label": "other",
                      "consumption_per_unit": null,
                      "unit": null
                    }
                  ]
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/production-orders/{op_id}/fabric-receipts": {
      "get": {
        "summary": "RC-1 · Recepciones de tela por OP (P0)",
        "description": "Cuello de botella del piloto. Sin esto CP1 mobile no opera.",
        "tags": [
          "Recepciones"
        ],
        "operationId": "getFabricReceiptsByOp",
        "parameters": [
          {
            "name": "op_id",
            "in": "path",
            "required": true,
            "description": "trento.UdpOrdenProduccion.IdOrdenProduccion (entero, PK).",
            "schema": {
              "type": "integer"
            },
            "example": 6223
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:fabric-receipts"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Recepciones de tela.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "op_id",
                    "receipts"
                  ],
                  "properties": {
                    "op_id": {
                      "type": "integer",
                      "example": 6223
                    },
                    "production_order_code": {
                      "type": "string",
                      "example": "6223"
                    },
                    "fabric_purchase_order": {
                      "type": "object",
                      "required": [
                        "id",
                        "code"
                      ],
                      "properties": {
                        "id": {
                          "type": "integer",
                          "example": 87123
                        },
                        "code": {
                          "type": "string",
                          "example": "PO-2026-0042"
                        },
                        "planned_shipment_date": {
                          "type": "string",
                          "format": "date",
                          "nullable": true,
                          "example": "2026-07-15"
                        },
                        "tolerance_pct": {
                          "type": "number",
                          "nullable": true,
                          "example": 5
                        },
                        "destination_country_code": {
                          "type": "string",
                          "nullable": true,
                          "example": "DE"
                        },
                        "destination_id": {
                          "type": "integer",
                          "nullable": true,
                          "example": 412
                        },
                        "transport_mode_id": {
                          "type": "integer",
                          "nullable": true,
                          "example": 2
                        }
                      }
                    },
                    "supplier": {
                      "type": "object",
                      "required": [
                        "id",
                        "ruc",
                        "legal_name"
                      ],
                      "properties": {
                        "id": {
                          "type": "integer",
                          "example": 9087,
                          "description": "trento.Persona.IdPersona"
                        },
                        "ruc": {
                          "type": "string",
                          "example": "20512345678",
                          "description": "trento.Persona.CodPersona"
                        },
                        "legal_name": {
                          "type": "string",
                          "example": "Hilanderías del Sur S.A.C."
                        },
                        "address": {
                          "type": "string",
                          "nullable": true,
                          "example": "Av. Industrial 123, Lima, Perú"
                        },
                        "country_code": {
                          "type": "string",
                          "nullable": true,
                          "example": "PE",
                          "minLength": 2,
                          "maxLength": 2
                        },
                        "tier": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "fabric_supplier",
                            "laundry_supplier",
                            "fiber_supplier",
                            "accessories_supplier",
                            null
                          ],
                          "example": "fabric_supplier"
                        }
                      }
                    },
                    "fabric": {
                      "type": "object",
                      "required": [
                        "id",
                        "code"
                      ],
                      "properties": {
                        "id": {
                          "type": "integer",
                          "example": 12345,
                          "description": "trento.TblProductos.IdProducto"
                        },
                        "code": {
                          "type": "string",
                          "example": "TELA-PIMA-185"
                        },
                        "productive_description": {
                          "type": "string",
                          "example": "Jersey Pima 185g 93% Algodón Pima 7% Spandex"
                        },
                        "commercial_description": {
                          "type": "string",
                          "example": "Pima 100% premium"
                        },
                        "supplier_id": {
                          "type": "integer",
                          "nullable": true,
                          "example": 9087
                        },
                        "fabric_type": {
                          "type": "string",
                          "example": "JERSEY"
                        }
                      }
                    },
                    "receipts": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "receipt_id": {
                            "type": "integer",
                            "example": 50211
                          },
                          "lot_number_header": {
                            "type": "string",
                            "example": "P-2026-3344"
                          },
                          "reception_date": {
                            "type": "string",
                            "format": "date",
                            "example": "2026-04-05"
                          },
                          "reception_time": {
                            "type": "string",
                            "example": "10:23:00"
                          },
                          "total_weight_kg": {
                            "type": "number",
                            "nullable": true,
                            "example": 845.6
                          },
                          "fabric_width_cm": {
                            "type": "number",
                            "nullable": true,
                            "example": 152.4
                          },
                          "fabric_density_gsm": {
                            "type": "number",
                            "nullable": true,
                            "example": 185
                          },
                          "shrinkage_width_pct": {
                            "type": "number",
                            "nullable": true,
                            "example": -3.2
                          },
                          "shrinkage_length_pct": {
                            "type": "number",
                            "nullable": true,
                            "example": -4.1
                          },
                          "lots": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "lot_detail_number": {
                                  "type": "string",
                                  "example": "P-2026-3344-A"
                                },
                                "weight_kg": {
                                  "type": "number",
                                  "example": 422.8
                                }
                              }
                            }
                          }
                        }
                      }
                    },
                    "consumption_per_unit_kg": {
                      "type": "number",
                      "nullable": true,
                      "example": 0.45
                    },
                    "material_composition_raw": {
                      "type": "string",
                      "nullable": true,
                      "example": "93% PIMA COTTON ORGANICO 7% SPANDEX"
                    }
                  }
                },
                "example": {
                  "op_id": 6297,
                  "production_order_code": "6297",
                  "fabric_purchase_order": {
                    "id": 2226,
                    "code": "43713"
                  },
                  "supplier": {
                    "id": 726,
                    "ruc": "20102261551",
                    "legal_name": "TEXTIL SAN RAMON S A",
                    "address": null,
                    "country_code": "PE",
                    "tier": "fabric_supplier"
                  },
                  "fabric": {
                    "id": 41821,
                    "code": "27881",
                    "productive_description": "JERSEY LISTADO FULL LYCRA 93% PIMA COTTON ORGANICO 7% SPANDEX - RYLES STRIPE MS26K51",
                    "commercial_description": "JERSEY LISTADO FULL LYCRA 93% PIMA COTTON ORGANICO 7% SPANDEX",
                    "supplier_id": 726,
                    "fabric_type": "JERSEY LISTADO FULL LYCRA 93% PIMA COTTON ORGANICO 7% SPANDEX"
                  },
                  "receipts": [
                    {
                      "receipt_id": 4181,
                      "lot_number_header": "24-08038,24-06432",
                      "reception_date": "2024-10-29",
                      "reception_time": "07:44:45",
                      "total_weight_kg": 535.6,
                      "fabric_width_cm": 1.95,
                      "fabric_density_gsm": 0.162,
                      "shrinkage_width_pct": 10.0,
                      "shrinkage_length_pct": 13.0,
                      "lots": [
                        {
                          "lot_detail_number": "24-06432",
                          "weight_kg": 9.05
                        },
                        {
                          "lot_detail_number": "24-06432",
                          "weight_kg": 9.05
                        },
                        {
                          "lot_detail_number": "24-06432",
                          "weight_kg": 11.3
                        },
                        {
                          "lot_detail_number": "24-06432",
                          "weight_kg": 429.7
                        },
                        {
                          "lot_detail_number": "24-06432",
                          "weight_kg": 25.5
                        },
                        {
                          "lot_detail_number": "24-08038",
                          "weight_kg": 35.0
                        },
                        {
                          "lot_detail_number": "24-08038",
                          "weight_kg": 16.0
                        }
                      ]
                    }
                  ],
                  "consumption_per_unit_kg": 0.329,
                  "material_composition_raw": "(27881) JERSEY LISTADO FULL LYCRA 93% PIMA COTTON ORGANICO 7% SPANDEX - RYLES STRIPE MS26K51"
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/fabric-receipts/{receipt_id}": {
      "get": {
        "summary": "RC-2 · Drill-down de recepción individual (P1)",
        "description": "",
        "tags": [
          "Recepciones"
        ],
        "operationId": "getFabricReceiptById",
        "parameters": [
          {
            "name": "receipt_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 50211
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:fabric-receipts"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Recepción.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "type": "object",
                      "properties": {
                        "receipt_id": {
                          "type": "integer",
                          "example": 50211
                        },
                        "lot_number_header": {
                          "type": "string",
                          "example": "P-2026-3344"
                        },
                        "reception_date": {
                          "type": "string",
                          "format": "date",
                          "example": "2026-04-05"
                        },
                        "reception_time": {
                          "type": "string",
                          "example": "10:23:00"
                        },
                        "total_weight_kg": {
                          "type": "number",
                          "nullable": true,
                          "example": 845.6
                        },
                        "fabric_width_cm": {
                          "type": "number",
                          "nullable": true,
                          "example": 152.4
                        },
                        "fabric_density_gsm": {
                          "type": "number",
                          "nullable": true,
                          "example": 185
                        },
                        "shrinkage_width_pct": {
                          "type": "number",
                          "nullable": true,
                          "example": -3.2
                        },
                        "shrinkage_length_pct": {
                          "type": "number",
                          "nullable": true,
                          "example": -4.1
                        },
                        "lots": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "lot_detail_number": {
                                "type": "string",
                                "example": "P-2026-3344-A"
                              },
                              "weight_kg": {
                                "type": "number",
                                "example": 422.8
                              }
                            }
                          }
                        }
                      }
                    },
                    {
                      "type": "object",
                      "properties": {
                        "op_id": {
                          "type": "integer",
                          "example": 6223
                        },
                        "supplier_id": {
                          "type": "integer",
                          "example": 9087
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "receipt_id": 4181,
                  "lot_number_header": "24-08038,24-06432",
                  "reception_date": "2024-10-29",
                  "reception_time": "07:44:45",
                  "total_weight_kg": 535.6,
                  "fabric_width_cm": 1.95,
                  "fabric_density_gsm": 0.162,
                  "shrinkage_width_pct": 10.0,
                  "shrinkage_length_pct": 13.0,
                  "lots": [
                    {
                      "lot_detail_number": "24-06432",
                      "weight_kg": 9.05
                    },
                    {
                      "lot_detail_number": "24-06432",
                      "weight_kg": 9.05
                    },
                    {
                      "lot_detail_number": "24-06432",
                      "weight_kg": 11.3
                    },
                    {
                      "lot_detail_number": "24-06432",
                      "weight_kg": 429.7
                    },
                    {
                      "lot_detail_number": "24-06432",
                      "weight_kg": 25.5
                    },
                    {
                      "lot_detail_number": "24-08038",
                      "weight_kg": 35.0
                    },
                    {
                      "lot_detail_number": "24-08038",
                      "weight_kg": 16.0
                    }
                  ],
                  "op_id": 6297,
                  "supplier_id": 726
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/fabric-receipts": {
      "get": {
        "summary": "RC-3 · Lookup por partida (GS1 AI 240) (P0)",
        "description": "Mobile escanea GS1-128 → resuelve `op_id` por número de partida. Debe ser indexado.",
        "tags": [
          "Recepciones"
        ],
        "operationId": "lookupFabricReceiptByPartida",
        "parameters": [
          {
            "name": "partida",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "P-2026-3344-A"
          },
          {
            "name": "supplier_ruc",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Desambiguación si la partida está duplicada."
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:fabric-receipts"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Partida resuelta.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "partida",
                    "op_id"
                  ],
                  "properties": {
                    "partida": {
                      "type": "string",
                      "example": "P-2026-3344-A"
                    },
                    "op_id": {
                      "type": "integer",
                      "example": 6223
                    },
                    "production_order_code": {
                      "type": "string",
                      "example": "6223"
                    },
                    "receipt_id": {
                      "type": "integer",
                      "example": 50211
                    },
                    "lot_detail_number": {
                      "type": "string",
                      "example": "P-2026-3344-A"
                    },
                    "weight_kg": {
                      "type": "number",
                      "nullable": true,
                      "example": 422.8
                    },
                    "supplier_ruc": {
                      "type": "string",
                      "example": "20512345678"
                    }
                  }
                },
                "example": {
                  "partida": "24-06432",
                  "op_id": 6297,
                  "production_order_code": "6297",
                  "receipt_id": 4181,
                  "lot_detail_number": "24-06432",
                  "weight_kg": 9.05,
                  "supplier_ruc": "20102261551"
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/production-orders/{op_id}/fabric-lots-summary": {
      "get": {
        "summary": "RC-4 · Resumen de lotes por OP (P1)",
        "description": "CP2 muestra lote origen como referencia.",
        "tags": [
          "Recepciones"
        ],
        "operationId": "getFabricLotsSummaryByOp",
        "parameters": [
          {
            "name": "op_id",
            "in": "path",
            "required": true,
            "description": "trento.UdpOrdenProduccion.IdOrdenProduccion (entero, PK).",
            "schema": {
              "type": "integer"
            },
            "example": 6223
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:fabric-receipts"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Resumen.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "op_id": {
                      "type": "integer",
                      "example": 6223
                    },
                    "lots": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "lot_number": {
                            "type": "string",
                            "example": "P-2026-3344"
                          },
                          "weight_kg": {
                            "type": "number",
                            "example": 845.6
                          },
                          "lot_details_count": {
                            "type": "integer",
                            "example": 2
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "op_id": 6297,
                  "lots": [
                    {
                      "lot_number": "24-08038,24-06432",
                      "weight_kg": 535.5999999999999,
                      "lot_details_count": 7
                    }
                  ]
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/accessories": {
      "get": {
        "summary": "AV-1 · Avíos por estilo + color (P2)",
        "description": "Cacheable 1h. Avío `115` debe entregarse splitted en `115-A` (bolsa) y `115-B` (etiqueta).",
        "tags": [
          "Avíos"
        ],
        "operationId": "getAccessoriesByStyleColor",
        "parameters": [
          {
            "name": "style",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "P-12345"
          },
          {
            "name": "color",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "BLANCO"
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:accessories"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Avíos por (estilo, color).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "style": {
                      "type": "string",
                      "example": "P-12345"
                    },
                    "color": {
                      "type": "string",
                      "example": "BLANCO"
                    },
                    "accessories": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string",
                            "example": "115-A",
                            "description": "Códigos como `115` pueden venir splitted en `115-A`/`115-B`."
                          },
                          "description": {
                            "type": "string",
                            "example": "Bolsa de polietileno"
                          },
                          "quantity_per_garment": {
                            "type": "number",
                            "example": 1
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/production-orders/{op_id}/laundry-movements": {
      "get": {
        "summary": "LV-1 · Movimientos de lavado por OP (P2)",
        "description": "Tipos S=salida, I=ingreso. El API debe encapsular `IdCore = IdTraCorte`.",
        "tags": [
          "Lavado"
        ],
        "operationId": "getLaundryMovementsByOp",
        "parameters": [
          {
            "name": "op_id",
            "in": "path",
            "required": true,
            "description": "trento.UdpOrdenProduccion.IdOrdenProduccion (entero, PK).",
            "schema": {
              "type": "integer"
            },
            "example": 6223
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:laundry"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Movimientos.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "op_id": {
                      "type": "integer",
                      "example": 6223
                    },
                    "movements": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "movement_id": {
                            "type": "integer",
                            "example": 7711
                          },
                          "transfer_code": {
                            "type": "string",
                            "nullable": true,
                            "example": "TC-6223-001"
                          },
                          "laundry_supplier_code": {
                            "type": "string",
                            "nullable": true,
                            "example": "LAV-NORTE"
                          },
                          "laundry_supplier_name": {
                            "type": "string",
                            "nullable": true,
                            "example": "Lavandería del Norte S.A.C."
                          },
                          "warehouse_origin": {
                            "type": "string",
                            "nullable": true,
                            "example": "PLANTA-01"
                          },
                          "warehouse_destination": {
                            "type": "string",
                            "nullable": true,
                            "example": "LAV-NORTE-01"
                          },
                          "movement_date": {
                            "type": "string",
                            "format": "date",
                            "example": "2026-04-22"
                          },
                          "movement_type": {
                            "type": "string",
                            "enum": [
                              "S",
                              "I"
                            ],
                            "example": "S"
                          },
                          "guide_number": {
                            "type": "string",
                            "nullable": true,
                            "example": "G-2026-0421"
                          },
                          "service_description": {
                            "type": "string",
                            "nullable": true,
                            "example": "Lavado enzimático + suavizado"
                          },
                          "items": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "item_name": {
                                  "type": "string",
                                  "example": "Panos Pima 185g"
                                },
                                "quantity": {
                                  "type": "number",
                                  "example": 320
                                },
                                "lot_number": {
                                  "type": "string",
                                  "nullable": true,
                                  "example": "P-2026-3344-A"
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "op_id": 6297,
                  "movements": [
                    {
                      "movement_id": 18204,
                      "transfer_code": "T-COR - 0010376",
                      "laundry_supplier_code": null,
                      "warehouse_origin": 24.0,
                      "warehouse_destination": 0.0,
                      "movement_date": "02-01-2026",
                      "movement_type": "I",
                      "guide_number": 86,
                      "service_description": null,
                      "laundry_supplier_name": null,
                      "items": [
                        {
                          "item_name": "(MS26K51) CROWN FLEX COTTON SS POLO - RYLES STRIPE, WHT, S - PP",
                          "quantity": 30.0,
                          "lot_number": null
                        },
                        {
                          "item_name": "(MS26K51) CROWN FLEX COTTON SS POLO - RYLES STRIPE, WHT, M - PP",
                          "quantity": 239.0,
                          "lot_number": null
                        },
                        {
                          "item_name": "(MS26K51) CROWN FLEX COTTON SS POLO - RYLES STRIPE, WHT, L - PP",
                          "quantity": 334.0,
                          "lot_number": null
                        },
                        {
                          "item_name": "(MS26K51) CROWN FLEX COTTON SS POLO - RYLES STRIPE, WHT, XL - PP",
                          "quantity": 197.0,
                          "lot_number": null
                        },
                        {
                          "item_name": "(MS26K51) CROWN FLEX COTTON SS POLO - RYLES STRIPE, WHT, XXL - PP",
                          "quantity": 42.0,
                          "lot_number": null
                        }
                      ]
                    },
                    {
                      "movement_id": 18203,
                      "transfer_code": "T-COR - 0010376",
                      "laundry_supplier_code": null,
                      "warehouse_origin": 23.0,
                      "warehouse_destination": 0.0,
                      "movement_date": "02-01-2026",
                      "movement_type": "S",
                      "guide_number": 85,
                      "service_description": null,
                      "laundry_supplier_name": null,
                      "items": [
                        {
                          "item_name": "(27881) JERSEY LISTADO FULL LYCRA 93% PIMA COTTON ORGANICO 7% SPANDEX - RYLES STRIPE MS26K51",
                          "quantity": 60.77,
                          "lot_number": "25-10343"
                        },
                        {
                          "item_name": "(27881) JERSEY LISTADO FULL LYCRA 93% PIMA COTTON ORGANICO 7% SPANDEX - RYLES STRIPE MS26K51",
                          "quantity": 60.13,
                          "lot_number": "25-10344"
                        }
                      ]
                    },
                    {
                      "movement_id": 18263,
                      "transfer_code": "T-COR - 0010419",
                      "laundry_supplier_code": null,
                      "warehouse_origin": 24.0,
                      "warehouse_destination": 0.0,
                      "movement_date": "12-01-2026",
                      "movement_type": "I",
                      "guide_number": 758,
                      "service_description": null,
                      "laundry_supplier_name": null,
                      "items": [
                        {
                          "item_name": "(MS26K51) CROWN FLEX COTTON SS POLO - RYLES STRIPE, CLDYB, S - PP",
                          "quantity": 36.0,
                          "lot_number": null
                        },
                        {
                          "item_name": "(MS26K51) CROWN FLEX COTTON SS POLO - RYLES STRIPE, CLDYB, M - PP",
                          "quantity": 233.0,
                          "lot_number": null
                        },
                        {
                          "item_name": "(MS26K51) CROWN FLEX COTTON SS POLO - RYLES STRIPE, CLDYB, L - PP",
                          "quantity": 323.0,
                          "lot_number": null
                        },
                        {
                          "item_name": "(MS26K51) CROWN FLEX COTTON SS POLO - RYLES STRIPE, CLDYB, XL - PP",
                          "quantity": 199.0,
                          "lot_number": null
                        },
                        {
                          "item_name": "(MS26K51) CROWN FLEX COTTON SS POLO - RYLES STRIPE, CLDYB, XXL - PP",
                          "quantity": 53.0,
                          "lot_number": null
                        }
                      ]
                    },
                    {
                      "movement_id": 18262,
                      "transfer_code": "T-COR - 0010419",
                      "laundry_supplier_code": null,
                      "warehouse_origin": 23.0,
                      "warehouse_destination": 0.0,
                      "movement_date": "12-01-2026",
                      "movement_type": "S",
                      "guide_number": 730,
                      "service_description": null,
                      "laundry_supplier_name": null,
                      "items": [
                        {
                          "item_name": "(27881) JERSEY LISTADO FULL LYCRA 93% PIMA COTTON ORGANICO 7% SPANDEX - RYLES STRIPE MS26K51",
                          "quantity": 108.59,
                          "lot_number": "25-10339"
                        },
                        {
                          "item_name": "(27881) JERSEY LISTADO FULL LYCRA 93% PIMA COTTON ORGANICO 7% SPANDEX - RYLES STRIPE MS26K51",
                          "quantity": 104.41,
                          "lot_number": "25-10340"
                        }
                      ]
                    },
                    {
                      "movement_id": 18141,
                      "transfer_code": "T-COR - 0010281",
                      "laundry_supplier_code": null,
                      "warehouse_origin": 24.0,
                      "warehouse_destination": 0.0,
                      "movement_date": "27-12-2025",
                      "movement_type": "I",
                      "guide_number": 27052,
                      "service_description": null,
                      "laundry_supplier_name": null,
                      "items": [
                        {
                          "item_name": "(MS26K51) CROWN FLEX COTTON SS POLO - RYLES STRIPE, NAV, S - PP",
                          "quantity": 30.0,
                          "lot_number": null
                        },
                        {
                          "item_name": "(MS26K51) CROWN FLEX COTTON SS POLO - RYLES STRIPE, NAV, M - PP",
                          "quantity": 226.0,
                          "lot_number": null
                        },
                        {
                          "item_name": "(MS26K51) CROWN FLEX COTTON SS POLO - RYLES STRIPE, NAV, L - PP",
                          "quantity": 321.0,
                          "lot_number": null
                        },
                        {
                          "item_name": "(MS26K51) CROWN FLEX COTTON SS POLO - RYLES STRIPE, NAV, XL - PP",
                          "quantity": 205.0,
                          "lot_number": null
                        },
                        {
                          "item_name": "(MS26K51) CROWN FLEX COTTON SS POLO - RYLES STRIPE, NAV, XXL - PP",
                          "quantity": 58.0,
                          "lot_number": null
                        }
                      ]
                    },
                    {
                      "movement_id": 18140,
                      "transfer_code": "T-COR - 0010281",
                      "laundry_supplier_code": null,
                      "warehouse_origin": 23.0,
                      "warehouse_destination": 0.0,
                      "movement_date": "27-12-2025",
                      "movement_type": "S",
                      "guide_number": 24779,
                      "service_description": null,
                      "laundry_supplier_name": null,
                      "items": [
                        {
                          "item_name": "(27881) JERSEY LISTADO FULL LYCRA 93% PIMA COTTON ORGANICO 7% SPANDEX - RYLES STRIPE MS26K51",
                          "quantity": 60.8,
                          "lot_number": "25-10341"
                        },
                        {
                          "item_name": "(27881) JERSEY LISTADO FULL LYCRA 93% PIMA COTTON ORGANICO 7% SPANDEX - RYLES STRIPE MS26K51",
                          "quantity": 61.4,
                          "lot_number": "25-10342"
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/laundry-movements/{movement_id}": {
      "get": {
        "summary": "LV-2 · Movimiento de lavado por id (P2)",
        "description": "",
        "tags": [
          "Lavado"
        ],
        "operationId": "getLaundryMovementById",
        "parameters": [
          {
            "name": "movement_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 7711
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:laundry"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Movimiento.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "movement_id": {
                      "type": "integer",
                      "example": 7711
                    },
                    "transfer_code": {
                      "type": "string",
                      "nullable": true,
                      "example": "TC-6223-001"
                    },
                    "laundry_supplier_code": {
                      "type": "string",
                      "nullable": true,
                      "example": "LAV-NORTE"
                    },
                    "laundry_supplier_name": {
                      "type": "string",
                      "nullable": true,
                      "example": "Lavandería del Norte S.A.C."
                    },
                    "warehouse_origin": {
                      "type": "string",
                      "nullable": true,
                      "example": "PLANTA-01"
                    },
                    "warehouse_destination": {
                      "type": "string",
                      "nullable": true,
                      "example": "LAV-NORTE-01"
                    },
                    "movement_date": {
                      "type": "string",
                      "format": "date",
                      "example": "2026-04-22"
                    },
                    "movement_type": {
                      "type": "string",
                      "enum": [
                        "S",
                        "I"
                      ],
                      "example": "S"
                    },
                    "guide_number": {
                      "type": "string",
                      "nullable": true,
                      "example": "G-2026-0421"
                    },
                    "service_description": {
                      "type": "string",
                      "nullable": true,
                      "example": "Lavado enzimático + suavizado"
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "item_name": {
                            "type": "string",
                            "example": "Panos Pima 185g"
                          },
                          "quantity": {
                            "type": "number",
                            "example": 320
                          },
                          "lot_number": {
                            "type": "string",
                            "nullable": true,
                            "example": "P-2026-3344-A"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "movement_id": 18204,
                  "transfer_code": "T-COR - 0010376",
                  "laundry_supplier_code": null,
                  "warehouse_origin": 24.0,
                  "warehouse_destination": 0.0,
                  "movement_date": "02-01-2026",
                  "movement_type": "I",
                  "guide_number": 86,
                  "service_description": null,
                  "laundry_supplier_name": null,
                  "items": [
                    {
                      "item_name": "(MS26K51) CROWN FLEX COTTON SS POLO - RYLES STRIPE, WHT, S - PP",
                      "quantity": 30.0,
                      "lot_number": null
                    },
                    {
                      "item_name": "(MS26K51) CROWN FLEX COTTON SS POLO - RYLES STRIPE, WHT, M - PP",
                      "quantity": 239.0,
                      "lot_number": null
                    },
                    {
                      "item_name": "(MS26K51) CROWN FLEX COTTON SS POLO - RYLES STRIPE, WHT, L - PP",
                      "quantity": 334.0,
                      "lot_number": null
                    },
                    {
                      "item_name": "(MS26K51) CROWN FLEX COTTON SS POLO - RYLES STRIPE, WHT, XL - PP",
                      "quantity": 197.0,
                      "lot_number": null
                    },
                    {
                      "item_name": "(MS26K51) CROWN FLEX COTTON SS POLO - RYLES STRIPE, WHT, XXL - PP",
                      "quantity": 42.0,
                      "lot_number": null
                    }
                  ]
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/production-orders/{op_id}/boxes": {
      "get": {
        "summary": "PK-1 · Cajas/bultos por OP (P2)",
        "description": "`gross_weight_kg` puede venir 0 en piloto; consultar `gross_weight_from_scale`.",
        "tags": [
          "Packing y Despacho"
        ],
        "operationId": "getBoxesByOp",
        "parameters": [
          {
            "name": "op_id",
            "in": "path",
            "required": true,
            "description": "trento.UdpOrdenProduccion.IdOrdenProduccion (entero, PK).",
            "schema": {
              "type": "integer"
            },
            "example": 6223
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:packing"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Cajas.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "op_id": {
                      "type": "integer",
                      "example": 6223
                    },
                    "boxes": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "box_number": {
                            "type": "integer",
                            "example": 1
                          },
                          "total_finished_garments": {
                            "type": "integer",
                            "example": 24
                          },
                          "gross_weight_kg": {
                            "type": "number",
                            "nullable": true,
                            "example": 0,
                            "description": "En piloto suele venir 0; ver `gross_weight_from_scale` flag."
                          },
                          "gross_weight_from_scale": {
                            "type": "boolean",
                            "example": false
                          },
                          "net_weight_kg": {
                            "type": "number",
                            "nullable": true,
                            "example": 5.2
                          },
                          "box_tare_kg": {
                            "type": "number",
                            "nullable": true,
                            "example": 0.3
                          },
                          "dimensions_cm": {
                            "type": "object",
                            "properties": {
                              "height": {
                                "type": "number",
                                "example": 35
                              },
                              "width": {
                                "type": "number",
                                "example": 45
                              },
                              "length": {
                                "type": "number",
                                "example": 60
                              }
                            }
                          },
                          "carton_label": {
                            "type": "string",
                            "nullable": true,
                            "example": "C-001"
                          },
                          "sizes": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "required": [
                                "size_code",
                                "quantity"
                              ],
                              "properties": {
                                "size_code": {
                                  "type": "string",
                                  "example": "M"
                                },
                                "quantity": {
                                  "type": "integer",
                                  "minimum": 0,
                                  "example": 240
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "op_id": 6297,
                  "boxes": [
                    {
                      "box_number": 1,
                      "total_finished_garments": 34.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 2,
                      "total_finished_garments": 60.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 3,
                      "total_finished_garments": 60.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 4,
                      "total_finished_garments": 60.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 5,
                      "total_finished_garments": 46.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 6,
                      "total_finished_garments": 54.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 7,
                      "total_finished_garments": 54.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 8,
                      "total_finished_garments": 54.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 9,
                      "total_finished_garments": 54.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 10,
                      "total_finished_garments": 54.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 11,
                      "total_finished_garments": 45.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 12,
                      "total_finished_garments": 51.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 13,
                      "total_finished_garments": 51.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 14,
                      "total_finished_garments": 51.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 15,
                      "total_finished_garments": 43.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 16,
                      "total_finished_garments": 50.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 17,
                      "total_finished_garments": 30.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 18,
                      "total_finished_garments": 60.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 19,
                      "total_finished_garments": 60.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 20,
                      "total_finished_garments": 60.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 21,
                      "total_finished_garments": 46.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 22,
                      "total_finished_garments": 54.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 23,
                      "total_finished_garments": 54.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 24,
                      "total_finished_garments": 54.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 25,
                      "total_finished_garments": 54.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 26,
                      "total_finished_garments": 54.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 27,
                      "total_finished_garments": 43.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 28,
                      "total_finished_garments": 51.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 29,
                      "total_finished_garments": 51.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 30,
                      "total_finished_garments": 51.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 31,
                      "total_finished_garments": 51.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 32,
                      "total_finished_garments": 48.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 33,
                      "total_finished_garments": 10.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 34,
                      "total_finished_garments": 29.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 35,
                      "total_finished_garments": 60.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 36,
                      "total_finished_garments": 60.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 37,
                      "total_finished_garments": 60.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 38,
                      "total_finished_garments": 55.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 39,
                      "total_finished_garments": 54.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 40,
                      "total_finished_garments": 54.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 41,
                      "total_finished_garments": 54.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 42,
                      "total_finished_garments": 54.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 43,
                      "total_finished_garments": 54.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 44,
                      "total_finished_garments": 56.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 45,
                      "total_finished_garments": 51.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 46,
                      "total_finished_garments": 51.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 47,
                      "total_finished_garments": 51.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 48,
                      "total_finished_garments": 34.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    },
                    {
                      "box_number": 49,
                      "total_finished_garments": 42.0,
                      "gross_weight_kg": 0.0,
                      "gross_weight_from_scale": false,
                      "net_weight_kg": -1.4,
                      "box_tare_kg": 1.4,
                      "dimensions_cm": {
                        "height": 26.0,
                        "width": 40.0,
                        "length": 88.0
                      },
                      "carton_label": 1,
                      "sizes": []
                    }
                  ]
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/production-orders/{op_id}/packing-list": {
      "get": {
        "summary": "PK-2 · Packing list por OP (P2)",
        "description": "",
        "tags": [
          "Packing y Despacho"
        ],
        "operationId": "getPackingListByOp",
        "parameters": [
          {
            "name": "op_id",
            "in": "path",
            "required": true,
            "description": "trento.UdpOrdenProduccion.IdOrdenProduccion (entero, PK).",
            "schema": {
              "type": "integer"
            },
            "example": 6223
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:packing"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Packing list.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "op_id": {
                      "type": "integer",
                      "example": 6223
                    },
                    "packing_list": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "PL-2026-0042"
                        },
                        "shipment_date": {
                          "type": "string",
                          "format": "date",
                          "nullable": true,
                          "example": "2026-06-10"
                        },
                        "total_boxes": {
                          "type": "integer",
                          "example": 22
                        },
                        "consolidated_transfer_id": {
                          "type": "integer",
                          "nullable": true,
                          "example": 8812
                        }
                      }
                    }
                  }
                },
                "example": {
                  "op_id": 6297,
                  "packing_list": {
                    "code": "PALIST - 0001716",
                    "shipment_date": "2026-01-16",
                    "consolidated_transfer_id": 2722,
                    "total_boxes": 49
                  }
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/production-orders/{op_id}/shipment-program": {
      "get": {
        "summary": "PK-3 · Programa de embarque (P2)",
        "description": "`actual_dispatched` puede venir 0; `destination_id = 0` se trata como ausencia.",
        "tags": [
          "Packing y Despacho"
        ],
        "operationId": "getShipmentProgramByOp",
        "parameters": [
          {
            "name": "op_id",
            "in": "path",
            "required": true,
            "description": "trento.UdpOrdenProduccion.IdOrdenProduccion (entero, PK).",
            "schema": {
              "type": "integer"
            },
            "example": 6223
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:packing"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Programa.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "op_id": {
                      "type": "integer",
                      "example": 6223
                    },
                    "planned_shipment_date": {
                      "type": "string",
                      "format": "date",
                      "nullable": true,
                      "example": "2026-07-15"
                    },
                    "actual_shipment_date": {
                      "type": "string",
                      "format": "date",
                      "nullable": true,
                      "example": "2026-07-12"
                    },
                    "destination_country_code": {
                      "type": "string",
                      "nullable": true,
                      "example": "DE"
                    },
                    "destination_id": {
                      "type": "integer",
                      "nullable": true,
                      "example": 412,
                      "description": "0 se trata como ausencia."
                    },
                    "transport_mode_id": {
                      "type": "integer",
                      "nullable": true,
                      "example": 2
                    },
                    "tolerance_pct": {
                      "type": "number",
                      "nullable": true,
                      "example": 5
                    },
                    "quantity_planned": {
                      "type": "integer",
                      "nullable": true,
                      "example": 640
                    },
                    "quantity_dispatched": {
                      "type": "integer",
                      "nullable": true,
                      "example": 638
                    },
                    "actual_dispatched": {
                      "type": "integer",
                      "nullable": true,
                      "example": 0,
                      "description": "En piloto suele venir 0."
                    },
                    "qlever_po_number": {
                      "type": "string",
                      "nullable": true,
                      "example": "OC-Q-2026-0042"
                    }
                  }
                },
                "example": {
                  "op_id": 6297,
                  "planned_shipment_date": "2026-01-16",
                  "actual_shipment_date": "2026-01-16",
                  "destination_country_code": null,
                  "destination_id": 0,
                  "transport_mode_id": 627,
                  "tolerance_pct": 5.0,
                  "quantity_planned": 800.0,
                  "quantity_dispatched": 800.0,
                  "actual_dispatched": 0.0,
                  "qlever_po_number": null
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/production-orders/{op_id}/sewing-dispatches": {
      "get": {
        "summary": "IN-1 · Despachos a costura por OP (P2)",
        "description": "CP6.",
        "tags": [
          "Costura e Inspección"
        ],
        "operationId": "getSewingDispatchesByOp",
        "parameters": [
          {
            "name": "op_id",
            "in": "path",
            "required": true,
            "description": "trento.UdpOrdenProduccion.IdOrdenProduccion (entero, PK).",
            "schema": {
              "type": "integer"
            },
            "example": 6223
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:inspection"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Despachos.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "op_id": {
                      "type": "integer",
                      "example": 6223
                    },
                    "dispatches": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "destination_id": {
                            "type": "integer",
                            "nullable": true,
                            "example": 33
                          },
                          "destination_name": {
                            "type": "string",
                            "nullable": true,
                            "example": "Taller Costura San Juan"
                          },
                          "total_garments_sewn": {
                            "type": "integer",
                            "nullable": true,
                            "example": 638
                          },
                          "sewing_date": {
                            "type": "string",
                            "format": "date",
                            "nullable": true,
                            "example": "2026-05-05"
                          },
                          "total_boxes": {
                            "type": "integer",
                            "nullable": true,
                            "example": 22
                          },
                          "total_bundles": {
                            "type": "integer",
                            "nullable": true,
                            "example": 110
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "op_id": 6297,
                  "dispatches": [
                    {
                      "destination_id": 1299,
                      "total_garments_sewn": 840.0,
                      "sewing_date": "2025-12-23",
                      "total_boxes": 0.0,
                      "total_bundles": 0.0,
                      "destination_name": null
                    },
                    {
                      "destination_id": 1299,
                      "total_garments_sewn": 842.0,
                      "sewing_date": "2025-12-26",
                      "total_boxes": 0.0,
                      "total_bundles": 0.0,
                      "destination_name": null
                    },
                    {
                      "destination_id": 1299,
                      "total_garments_sewn": 844.0,
                      "sewing_date": "2025-12-29",
                      "total_boxes": 0.0,
                      "total_bundles": 0.0,
                      "destination_name": null
                    },
                    {
                      "destination_id": 1299,
                      "total_garments_sewn": 840.0,
                      "sewing_date": "2025-12-23",
                      "total_boxes": 0.0,
                      "total_bundles": 0.0,
                      "destination_name": null
                    },
                    {
                      "destination_id": 1299,
                      "total_garments_sewn": 842.0,
                      "sewing_date": "2025-12-26",
                      "total_boxes": 0.0,
                      "total_bundles": 0.0,
                      "destination_name": null
                    },
                    {
                      "destination_id": 1299,
                      "total_garments_sewn": 844.0,
                      "sewing_date": "2025-12-29",
                      "total_boxes": 0.0,
                      "total_bundles": 0.0,
                      "destination_name": null
                    },
                    {
                      "destination_id": 1299,
                      "total_garments_sewn": 840.0,
                      "sewing_date": "2025-12-23",
                      "total_boxes": 0.0,
                      "total_bundles": 0.0,
                      "destination_name": null
                    },
                    {
                      "destination_id": 1299,
                      "total_garments_sewn": 842.0,
                      "sewing_date": "2025-12-26",
                      "total_boxes": 0.0,
                      "total_bundles": 0.0,
                      "destination_name": null
                    },
                    {
                      "destination_id": 1299,
                      "total_garments_sewn": 844.0,
                      "sewing_date": "2025-12-29",
                      "total_boxes": 0.0,
                      "total_bundles": 0.0,
                      "destination_name": null
                    }
                  ]
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/production-orders/{op_id}/finished-garments": {
      "get": {
        "summary": "IN-2 · Prendas terminadas / inspecciones por OP (P2, con gap)",
        "description": "Para OPs piloto 6223–6230 devolver array vacío sin error.",
        "tags": [
          "Costura e Inspección"
        ],
        "operationId": "getFinishedGarmentsByOp",
        "parameters": [
          {
            "name": "op_id",
            "in": "path",
            "required": true,
            "description": "trento.UdpOrdenProduccion.IdOrdenProduccion (entero, PK).",
            "schema": {
              "type": "integer"
            },
            "example": 6223
          }
        ],
        "security": [
          {
            "bearerAuth": [
              "read:inspection"
            ]
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Inspecciones.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "op_id": {
                      "type": "integer",
                      "example": 6223
                    },
                    "finished_garments": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "finished_garment_id": {
                            "type": "integer",
                            "example": 121345
                          },
                          "inspection_date": {
                            "type": "string",
                            "format": "date",
                            "nullable": true,
                            "example": "2026-05-20"
                          }
                        }
                      },
                      "description": "Para OPs piloto 6223–6230 puede devolver array vacío (gap aceptado)."
                    }
                  }
                },
                "example": {
                  "op_id": 6297,
                  "finished_garments": []
                }
              }
            }
          },
          "4XX": {
            "description": "Errores del cliente — agrupados.\n\n- **400** parámetros inválidos (formato, tipo, requeridos).\n- **401** token ausente o inválido. El cliente refresca y reintenta una vez.\n- **403** token válido pero scope insuficiente.\n- **404** recurso no encontrado. Tratar como ausencia, no como error.\n- **409** conflicto (ej. `partida` duplicada sin `supplier_ruc`).\n- **429** rate limit superado. Respeta `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solo en 429."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "5XX": {
            "description": "Errores del servidor — agrupados.\n\n- **500** error interno. Cliente reintenta con backoff (máx. 3).\n- **503** indisponible o `replication_lag_seconds > 600` (10 min). Respeta `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "production_order_not_found"
                        },
                        "message": {
                          "type": "string",
                          "example": "OP 9999 no existe en Trento Core."
                        },
                        "details": {
                          "type": "object",
                          "additionalProperties": true
                        },
                        "request_id": {
                          "type": "string",
                          "example": "req_abc123"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "example": "production_order_not_found"
              },
              "message": {
                "type": "string",
                "example": "OP 9999 no existe en Trento Core."
              },
              "details": {
                "type": "object",
                "additionalProperties": true
              },
              "request_id": {
                "type": "string",
                "example": "req_abc123"
              }
            }
          }
        }
      },
      "PaginationMeta": {
        "type": "object",
        "required": [
          "page",
          "limit",
          "has_more"
        ],
        "properties": {
          "page": {
            "type": "integer",
            "minimum": 1,
            "example": 2
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 200,
            "example": 50
          },
          "total": {
            "type": "integer",
            "nullable": true,
            "example": 312
          },
          "has_more": {
            "type": "boolean",
            "example": true
          }
        }
      },
      "Product": {
        "type": "object",
        "required": [
          "id",
          "code"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "example": 12345,
            "description": "trento.TblProductos.IdProducto"
          },
          "code": {
            "type": "string",
            "example": "TELA-PIMA-185"
          },
          "productive_description": {
            "type": "string",
            "example": "Jersey Pima 185g 93% Algodón Pima 7% Spandex"
          },
          "commercial_description": {
            "type": "string",
            "example": "Pima 100% premium"
          },
          "supplier_id": {
            "type": "integer",
            "nullable": true,
            "example": 9087
          },
          "fabric_type": {
            "type": "string",
            "example": "JERSEY"
          }
        }
      },
      "Style": {
        "type": "object",
        "required": [
          "id",
          "code"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "example": 4421
          },
          "code": {
            "type": "string",
            "example": "P-12345"
          },
          "description": {
            "type": "string",
            "example": "Polo manga corta Pima"
          },
          "default_color_id": {
            "type": "integer",
            "nullable": true,
            "example": 88
          }
        }
      },
      "Color": {
        "type": "object",
        "required": [
          "id",
          "code"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "example": 88
          },
          "code": {
            "type": "string",
            "example": "BLANCO"
          },
          "description": {
            "type": "string",
            "example": "Blanco óptico"
          },
          "pantone": {
            "type": "string",
            "nullable": true,
            "example": "11-0601 TPX"
          }
        }
      },
      "Supplier": {
        "type": "object",
        "required": [
          "id",
          "ruc",
          "legal_name"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "example": 9087,
            "description": "trento.Persona.IdPersona"
          },
          "ruc": {
            "type": "string",
            "example": "20512345678",
            "description": "trento.Persona.CodPersona"
          },
          "legal_name": {
            "type": "string",
            "example": "Hilanderías del Sur S.A.C."
          },
          "address": {
            "type": "string",
            "nullable": true,
            "example": "Av. Industrial 123, Lima, Perú"
          },
          "country_code": {
            "type": "string",
            "nullable": true,
            "example": "PE",
            "minLength": 2,
            "maxLength": 2
          },
          "tier": {
            "type": "string",
            "nullable": true,
            "enum": [
              "fabric_supplier",
              "laundry_supplier",
              "fiber_supplier",
              "accessories_supplier",
              null
            ],
            "example": "fabric_supplier"
          }
        }
      },
      "ClientByOp": {
        "type": "object",
        "required": [
          "op_id",
          "client_name"
        ],
        "properties": {
          "op_id": {
            "type": "integer",
            "example": 6223
          },
          "client_name": {
            "type": "string",
            "example": "Brand X Apparel Ltd."
          },
          "client_brand": {
            "type": "string",
            "nullable": true,
            "example": "BX-Athleisure"
          },
          "style_code": {
            "type": "string",
            "nullable": true,
            "example": "P-12345"
          }
        }
      },
      "SizeDistributionEntry": {
        "type": "object",
        "required": [
          "size_code",
          "quantity"
        ],
        "properties": {
          "size_code": {
            "type": "string",
            "example": "M"
          },
          "quantity": {
            "type": "integer",
            "minimum": 0,
            "example": 240
          }
        }
      },
      "SizeDistribution": {
        "type": "object",
        "required": [
          "op_id",
          "distribution",
          "total"
        ],
        "properties": {
          "op_id": {
            "type": "integer",
            "example": 6223
          },
          "production_order_code": {
            "type": "string",
            "example": "6223"
          },
          "distribution": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SizeDistributionEntry"
            }
          },
          "total": {
            "type": "integer",
            "minimum": 0,
            "example": 640
          }
        }
      },
      "MaterialEntry": {
        "type": "object",
        "required": [
          "material",
          "percentage"
        ],
        "properties": {
          "material": {
            "type": "string",
            "example": "cotton"
          },
          "percentage": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "example": 93
          },
          "organic": {
            "type": "boolean",
            "example": true
          },
          "iso_2076_code": {
            "type": "string",
            "example": "CO",
            "description": "ISO 2076 fibre code"
          }
        }
      },
      "MaterialComposition": {
        "type": "object",
        "required": [
          "op_id",
          "composition"
        ],
        "properties": {
          "op_id": {
            "type": "integer",
            "example": 6223
          },
          "composition": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MaterialEntry"
            }
          },
          "total_percentage": {
            "type": "number",
            "example": 100
          },
          "raw_source_string": {
            "type": "string",
            "nullable": true,
            "example": "93% PIMA COTTON ORGANICO 7% SPANDEX"
          }
        }
      },
      "PurchaseOrder": {
        "type": "object",
        "required": [
          "id",
          "code"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "example": 87123
          },
          "code": {
            "type": "string",
            "example": "PO-2026-0042"
          },
          "planned_shipment_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "example": "2026-07-15"
          },
          "tolerance_pct": {
            "type": "number",
            "nullable": true,
            "example": 5
          },
          "destination_country_code": {
            "type": "string",
            "nullable": true,
            "example": "DE"
          },
          "destination_id": {
            "type": "integer",
            "nullable": true,
            "example": 412
          },
          "transport_mode_id": {
            "type": "integer",
            "nullable": true,
            "example": 2
          }
        }
      },
      "OpLine": {
        "type": "object",
        "required": [
          "color_id",
          "size_code",
          "quantity"
        ],
        "properties": {
          "color_id": {
            "type": "integer",
            "example": 88
          },
          "size_code": {
            "type": "string",
            "example": "M"
          },
          "quantity": {
            "type": "integer",
            "minimum": 0,
            "example": 60
          }
        }
      },
      "ProductionOrder": {
        "type": "object",
        "required": [
          "id",
          "code"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "example": 6223,
            "description": "trento.UdpOrdenProduccion.IdOrdenProduccion"
          },
          "code": {
            "type": "string",
            "example": "6223"
          },
          "purchase_order": {
            "$ref": "#/components/schemas/PurchaseOrder"
          },
          "style": {
            "type": "object",
            "properties": {
              "id": {
                "type": "integer",
                "example": 4421
              },
              "code": {
                "type": "string",
                "example": "P-12345"
              },
              "description": {
                "type": "string",
                "example": "Polo manga corta Pima"
              },
              "technical_sheet_id": {
                "type": "integer",
                "nullable": true,
                "example": 1572
              }
            }
          },
          "fabric_product_id": {
            "type": "integer",
            "nullable": true,
            "example": 12345
          },
          "client": {
            "type": "object",
            "properties": {
              "id": {
                "type": "integer",
                "example": 33
              },
              "name": {
                "type": "string",
                "example": "Brand X Apparel Ltd."
              },
              "brand": {
                "type": "string",
                "nullable": true,
                "example": "BX-Athleisure"
              }
            }
          },
          "season": {
            "type": "string",
            "nullable": true,
            "example": "SS-2026"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-03-12T10:14:00-05:00"
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OpLine"
            }
          }
        }
      },
      "ProductionOrderSummary": {
        "type": "object",
        "required": [
          "id",
          "code"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "example": 6223
          },
          "code": {
            "type": "string",
            "example": "6223"
          },
          "client_id": {
            "type": "integer",
            "nullable": true,
            "example": 33
          },
          "client_name": {
            "type": "string",
            "nullable": true,
            "example": "Brand X Apparel Ltd."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "closed",
              "despatched"
            ],
            "example": "active"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ProductionOrdersList": {
        "allOf": [
          {
            "$ref": "#/components/schemas/PaginationMeta"
          },
          {
            "type": "object",
            "required": [
              "items"
            ],
            "properties": {
              "items": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ProductionOrderSummary"
                }
              }
            }
          }
        ]
      },
      "CuttingOrder": {
        "type": "object",
        "required": [
          "id",
          "code"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "example": 901
          },
          "code": {
            "type": "string",
            "example": "HC-6223-01"
          },
          "cutting_program_id": {
            "type": "integer",
            "nullable": true,
            "example": 514
          },
          "cutting_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "example": "2026-04-12"
          },
          "total_units_cut": {
            "type": "integer",
            "nullable": true,
            "example": 320
          },
          "sizes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SizeDistributionEntry"
            }
          }
        }
      },
      "CuttingOrdersResponse": {
        "type": "object",
        "required": [
          "op_id",
          "cutting_orders"
        ],
        "properties": {
          "op_id": {
            "type": "integer",
            "example": 6223
          },
          "cutting_orders": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CuttingOrder"
            }
          }
        }
      },
      "SizeAnalysisEntry": {
        "type": "object",
        "properties": {
          "color_id": {
            "type": "integer",
            "example": 88
          },
          "total_planned": {
            "type": "integer",
            "example": 320
          },
          "total_original_order": {
            "type": "integer",
            "example": 320
          },
          "by_size": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "size_code": {
                  "type": "string",
                  "example": "S"
                },
                "planned": {
                  "type": "integer",
                  "example": 60
                },
                "original": {
                  "type": "integer",
                  "example": 60
                }
              }
            }
          }
        }
      },
      "SizeAnalysis": {
        "type": "object",
        "required": [
          "op_id",
          "analysis"
        ],
        "properties": {
          "op_id": {
            "type": "integer",
            "example": 6223
          },
          "analysis": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SizeAnalysisEntry"
            }
          }
        }
      },
      "CuttingClosure": {
        "type": "object",
        "properties": {
          "op_id": {
            "type": "integer",
            "example": 6223
          },
          "enabled_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "example": "2026-04-20"
          },
          "consumption_types_present": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "example": [
              1,
              2,
              3
            ]
          }
        }
      },
      "ConsumptionSheetItem": {
        "type": "object",
        "properties": {
          "consumption_type": {
            "type": "integer",
            "example": 1
          },
          "label": {
            "type": "string",
            "enum": [
              "fabric",
              "accessories",
              "packaging",
              "other"
            ],
            "example": "fabric"
          },
          "consumption_per_unit": {
            "type": "number",
            "nullable": true,
            "example": 0.45
          },
          "unit": {
            "type": "string",
            "nullable": true,
            "example": "kg/garment"
          }
        }
      },
      "ConsumptionSheet": {
        "type": "object",
        "required": [
          "op_id",
          "sheets"
        ],
        "properties": {
          "op_id": {
            "type": "integer",
            "example": 6223
          },
          "sheets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConsumptionSheetItem"
            }
          }
        }
      },
      "FabricLotDetail": {
        "type": "object",
        "properties": {
          "lot_detail_number": {
            "type": "string",
            "example": "P-2026-3344-A"
          },
          "weight_kg": {
            "type": "number",
            "example": 422.8
          }
        }
      },
      "FabricReceiptHeader": {
        "type": "object",
        "properties": {
          "receipt_id": {
            "type": "integer",
            "example": 50211
          },
          "lot_number_header": {
            "type": "string",
            "example": "P-2026-3344"
          },
          "reception_date": {
            "type": "string",
            "format": "date",
            "example": "2026-04-05"
          },
          "reception_time": {
            "type": "string",
            "example": "10:23:00"
          },
          "total_weight_kg": {
            "type": "number",
            "nullable": true,
            "example": 845.6
          },
          "fabric_width_cm": {
            "type": "number",
            "nullable": true,
            "example": 152.4
          },
          "fabric_density_gsm": {
            "type": "number",
            "nullable": true,
            "example": 185
          },
          "shrinkage_width_pct": {
            "type": "number",
            "nullable": true,
            "example": -3.2
          },
          "shrinkage_length_pct": {
            "type": "number",
            "nullable": true,
            "example": -4.1
          },
          "lots": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FabricLotDetail"
            }
          }
        }
      },
      "FabricReceiptsByOp": {
        "type": "object",
        "required": [
          "op_id",
          "receipts"
        ],
        "properties": {
          "op_id": {
            "type": "integer",
            "example": 6223
          },
          "production_order_code": {
            "type": "string",
            "example": "6223"
          },
          "fabric_purchase_order": {
            "$ref": "#/components/schemas/PurchaseOrder"
          },
          "supplier": {
            "$ref": "#/components/schemas/Supplier"
          },
          "fabric": {
            "$ref": "#/components/schemas/Product"
          },
          "receipts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FabricReceiptHeader"
            }
          },
          "consumption_per_unit_kg": {
            "type": "number",
            "nullable": true,
            "example": 0.45
          },
          "material_composition_raw": {
            "type": "string",
            "nullable": true,
            "example": "93% PIMA COTTON ORGANICO 7% SPANDEX"
          }
        }
      },
      "FabricReceiptDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/FabricReceiptHeader"
          },
          {
            "type": "object",
            "properties": {
              "op_id": {
                "type": "integer",
                "example": 6223
              },
              "supplier_id": {
                "type": "integer",
                "example": 9087
              }
            }
          }
        ]
      },
      "PartidaLookup": {
        "type": "object",
        "required": [
          "partida",
          "op_id"
        ],
        "properties": {
          "partida": {
            "type": "string",
            "example": "P-2026-3344-A"
          },
          "op_id": {
            "type": "integer",
            "example": 6223
          },
          "production_order_code": {
            "type": "string",
            "example": "6223"
          },
          "receipt_id": {
            "type": "integer",
            "example": 50211
          },
          "lot_detail_number": {
            "type": "string",
            "example": "P-2026-3344-A"
          },
          "weight_kg": {
            "type": "number",
            "nullable": true,
            "example": 422.8
          },
          "supplier_ruc": {
            "type": "string",
            "example": "20512345678"
          }
        }
      },
      "FabricLotSummaryItem": {
        "type": "object",
        "properties": {
          "lot_number": {
            "type": "string",
            "example": "P-2026-3344"
          },
          "weight_kg": {
            "type": "number",
            "example": 845.6
          },
          "lot_details_count": {
            "type": "integer",
            "example": 2
          }
        }
      },
      "FabricLotsSummary": {
        "type": "object",
        "properties": {
          "op_id": {
            "type": "integer",
            "example": 6223
          },
          "lots": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FabricLotSummaryItem"
            }
          }
        }
      },
      "Accessory": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "example": "115-A",
            "description": "Códigos como `115` pueden venir splitted en `115-A`/`115-B`."
          },
          "description": {
            "type": "string",
            "example": "Bolsa de polietileno"
          },
          "quantity_per_garment": {
            "type": "number",
            "example": 1
          }
        }
      },
      "Accessories": {
        "type": "object",
        "properties": {
          "style": {
            "type": "string",
            "example": "P-12345"
          },
          "color": {
            "type": "string",
            "example": "BLANCO"
          },
          "accessories": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Accessory"
            }
          }
        }
      },
      "LaundryMovementItem": {
        "type": "object",
        "properties": {
          "item_name": {
            "type": "string",
            "example": "Panos Pima 185g"
          },
          "quantity": {
            "type": "number",
            "example": 320
          },
          "lot_number": {
            "type": "string",
            "nullable": true,
            "example": "P-2026-3344-A"
          }
        }
      },
      "LaundryMovement": {
        "type": "object",
        "properties": {
          "movement_id": {
            "type": "integer",
            "example": 7711
          },
          "transfer_code": {
            "type": "string",
            "nullable": true,
            "example": "TC-6223-001"
          },
          "laundry_supplier_code": {
            "type": "string",
            "nullable": true,
            "example": "LAV-NORTE"
          },
          "laundry_supplier_name": {
            "type": "string",
            "nullable": true,
            "example": "Lavandería del Norte S.A.C."
          },
          "warehouse_origin": {
            "type": "string",
            "nullable": true,
            "example": "PLANTA-01"
          },
          "warehouse_destination": {
            "type": "string",
            "nullable": true,
            "example": "LAV-NORTE-01"
          },
          "movement_date": {
            "type": "string",
            "format": "date",
            "example": "2026-04-22"
          },
          "movement_type": {
            "type": "string",
            "enum": [
              "S",
              "I"
            ],
            "example": "S"
          },
          "guide_number": {
            "type": "string",
            "nullable": true,
            "example": "G-2026-0421"
          },
          "service_description": {
            "type": "string",
            "nullable": true,
            "example": "Lavado enzimático + suavizado"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LaundryMovementItem"
            }
          }
        }
      },
      "LaundryMovementsByOp": {
        "type": "object",
        "properties": {
          "op_id": {
            "type": "integer",
            "example": 6223
          },
          "movements": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LaundryMovement"
            }
          }
        }
      },
      "Box": {
        "type": "object",
        "properties": {
          "box_number": {
            "type": "integer",
            "example": 1
          },
          "total_finished_garments": {
            "type": "integer",
            "example": 24
          },
          "gross_weight_kg": {
            "type": "number",
            "nullable": true,
            "example": 0,
            "description": "En piloto suele venir 0; ver `gross_weight_from_scale` flag."
          },
          "gross_weight_from_scale": {
            "type": "boolean",
            "example": false
          },
          "net_weight_kg": {
            "type": "number",
            "nullable": true,
            "example": 5.2
          },
          "box_tare_kg": {
            "type": "number",
            "nullable": true,
            "example": 0.3
          },
          "dimensions_cm": {
            "type": "object",
            "properties": {
              "height": {
                "type": "number",
                "example": 35
              },
              "width": {
                "type": "number",
                "example": 45
              },
              "length": {
                "type": "number",
                "example": 60
              }
            }
          },
          "carton_label": {
            "type": "string",
            "nullable": true,
            "example": "C-001"
          },
          "sizes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SizeDistributionEntry"
            }
          }
        }
      },
      "BoxesByOp": {
        "type": "object",
        "properties": {
          "op_id": {
            "type": "integer",
            "example": 6223
          },
          "boxes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Box"
            }
          }
        }
      },
      "PackingList": {
        "type": "object",
        "properties": {
          "op_id": {
            "type": "integer",
            "example": 6223
          },
          "packing_list": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "example": "PL-2026-0042"
              },
              "shipment_date": {
                "type": "string",
                "format": "date",
                "nullable": true,
                "example": "2026-06-10"
              },
              "total_boxes": {
                "type": "integer",
                "example": 22
              },
              "consolidated_transfer_id": {
                "type": "integer",
                "nullable": true,
                "example": 8812
              }
            }
          }
        }
      },
      "ShipmentProgram": {
        "type": "object",
        "properties": {
          "op_id": {
            "type": "integer",
            "example": 6223
          },
          "planned_shipment_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "example": "2026-07-15"
          },
          "actual_shipment_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "example": "2026-07-12"
          },
          "destination_country_code": {
            "type": "string",
            "nullable": true,
            "example": "DE"
          },
          "destination_id": {
            "type": "integer",
            "nullable": true,
            "example": 412,
            "description": "0 se trata como ausencia."
          },
          "transport_mode_id": {
            "type": "integer",
            "nullable": true,
            "example": 2
          },
          "tolerance_pct": {
            "type": "number",
            "nullable": true,
            "example": 5
          },
          "quantity_planned": {
            "type": "integer",
            "nullable": true,
            "example": 640
          },
          "quantity_dispatched": {
            "type": "integer",
            "nullable": true,
            "example": 638
          },
          "actual_dispatched": {
            "type": "integer",
            "nullable": true,
            "example": 0,
            "description": "En piloto suele venir 0."
          },
          "qlever_po_number": {
            "type": "string",
            "nullable": true,
            "example": "OC-Q-2026-0042"
          }
        }
      },
      "SewingDispatch": {
        "type": "object",
        "properties": {
          "destination_id": {
            "type": "integer",
            "nullable": true,
            "example": 33
          },
          "destination_name": {
            "type": "string",
            "nullable": true,
            "example": "Taller Costura San Juan"
          },
          "total_garments_sewn": {
            "type": "integer",
            "nullable": true,
            "example": 638
          },
          "sewing_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "example": "2026-05-05"
          },
          "total_boxes": {
            "type": "integer",
            "nullable": true,
            "example": 22
          },
          "total_bundles": {
            "type": "integer",
            "nullable": true,
            "example": 110
          }
        }
      },
      "SewingDispatchesByOp": {
        "type": "object",
        "properties": {
          "op_id": {
            "type": "integer",
            "example": 6223
          },
          "dispatches": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SewingDispatch"
            }
          }
        }
      },
      "FinishedGarment": {
        "type": "object",
        "properties": {
          "finished_garment_id": {
            "type": "integer",
            "example": 121345
          },
          "inspection_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "example": "2026-05-20"
          }
        }
      },
      "FinishedGarmentsByOp": {
        "type": "object",
        "properties": {
          "op_id": {
            "type": "integer",
            "example": 6223
          },
          "finished_garments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FinishedGarment"
            },
            "description": "Para OPs piloto 6223–6230 puede devolver array vacío (gap aceptado)."
          }
        }
      },
      "HealthStatus": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "ok",
              "degraded",
              "down"
            ],
            "example": "ok"
          },
          "replication_lag_seconds": {
            "type": "integer",
            "example": 12
          },
          "version": {
            "type": "string",
            "example": "1.0.4"
          },
          "build": {
            "type": "string",
            "format": "date-time",
            "example": "2026-05-12T18:00:00Z"
          }
        }
      }
    },
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "OAuth 2.0 client credentials grant. Scopes: read:masters, read:production-orders, read:fabric-receipts, read:laundry, read:packing, read:inspection, read:accessories."
      },
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Alternativa para v1 si no se implementa OAuth."
      }
    }
  }
}