{
  "openapi": "3.1.0",
  "info": {
    "title": "Calculadora de Tubos — API",
    "version": "2.1.0",
    "description": "Catálogo, receitas e produção compartilhados pela empresa. Use Bearer em integrações servidor a servidor. JSON com números decimais usando ponto. Valores monetários calculados são strings em BRL. Sem endpoints de exclusão de histórico, webhooks, OAuth ou chaves de idempotência."
  },
  "servers": [
    {
      "url": "https://calculadora-tubos.krato.ai/api/v1"
    }
  ],
  "paths": {
    "/health/live": {
      "get": {
        "summary": "Estado do serviço",
        "tags": [
          "health"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Estado do serviço",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/health/ready": {
      "get": {
        "summary": "Estado do serviço",
        "tags": [
          "health"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Estado do serviço",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/auth/session": {
      "post": {
        "summary": "Iniciar sessão de navegador",
        "tags": [
          "auth"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Iniciar sessão de navegador",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Session"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Login"
              }
            }
          }
        },
        "description": "Exige Origin igual ao domínio do sistema. Não aceita Authorization. Retorna cookie HttpOnly, SameSite=Lax, Secure sob HTTPS, validade de 12 horas."
      },
      "get": {
        "summary": "Consultar sessão",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "Consultar sessão",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Session"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Encerrar sessão",
        "tags": [
          "auth"
        ],
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "204": {
            "description": "Concluído sem corpo"
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/users": {
      "get": {
        "summary": "Listar usuários",
        "tags": [
          "Administração"
        ],
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "Listar usuários",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Users"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000000,
              "default": 1
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "description": "Exige sessão de administrador. Não aceita Bearer. Mutações exigem Origin igual ao domínio do sistema."
      },
      "post": {
        "summary": "Cadastrar usuário",
        "tags": [
          "Administração"
        ],
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "201": {
            "description": "Cadastrar usuário",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserCreate"
              }
            }
          }
        },
        "description": "Exige sessão de administrador. Não aceita Bearer. Mutações exigem Origin igual ao domínio do sistema."
      }
    },
    "/users/{id}": {
      "patch": {
        "summary": "Alterar usuário",
        "tags": [
          "Administração"
        ],
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "Alterar usuário",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserUpdate"
              }
            }
          }
        },
        "description": "Exige sessão de administrador. Não aceita Bearer. Mutações exigem Origin igual ao domínio do sistema."
      }
    },
    "/users/{id}/password": {
      "post": {
        "summary": "Redefinir senha e revogar acessos",
        "tags": [
          "Administração"
        ],
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "Redefinir senha e revogar acessos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PasswordReset"
              }
            }
          }
        },
        "description": "Exige sessão de administrador. Não aceita Bearer. Mutações exigem Origin igual ao domínio do sistema."
      }
    },
    "/tokens": {
      "get": {
        "summary": "Listar tokens sem segredo",
        "tags": [
          "Administração"
        ],
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "Listar tokens sem segredo",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Tokens"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000000,
              "default": 1
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "description": "Exige sessão de administrador. Não aceita Bearer. Mutações exigem Origin igual ao domínio do sistema."
      },
      "post": {
        "summary": "Emitir token (segredo exibido uma vez)",
        "tags": [
          "Administração"
        ],
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "201": {
            "description": "Emitir token (segredo exibido uma vez)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenIssued"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TokenCreate"
              }
            }
          }
        },
        "description": "Exige sessão de administrador. Não aceita Bearer. Mutações exigem Origin igual ao domínio do sistema."
      }
    },
    "/tokens/{id}": {
      "delete": {
        "summary": "Revogar token",
        "tags": [
          "Administração"
        ],
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "204": {
            "description": "Concluído sem corpo"
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "description": "Exige sessão de administrador. Não aceita Bearer. Mutações exigem Origin igual ao domínio do sistema."
      }
    },
    "/papers": {
      "get": {
        "summary": "Listar papéis",
        "tags": [
          "papers"
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "Listar papéis",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Papers"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000000,
              "default": 1
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "inactive",
                "all"
              ]
            }
          }
        ],
        "description": "Aceita token read ou write."
      },
      "post": {
        "summary": "Cadastrar papel",
        "tags": [
          "papers"
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "201": {
            "description": "Cadastrar papel",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paper"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PaperCreate"
              }
            }
          }
        },
        "description": "Exige token write ou sessão de usuário. Sessões exigem Origin nas mutações."
      }
    },
    "/papers/{id}": {
      "get": {
        "summary": "Consultar papel",
        "tags": [
          "papers"
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "Consultar papel",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paper"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "description": "Aceita token read ou write."
      },
      "patch": {
        "summary": "Atualizar papel",
        "tags": [
          "papers"
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "Atualizar papel",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paper"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PaperUpdate"
              }
            }
          }
        },
        "description": "Exige token write ou sessão de usuário. Sessões exigem Origin nas mutações."
      }
    },
    "/papers/{id}/prices": {
      "get": {
        "summary": "Histórico de preços",
        "tags": [
          "papers"
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "Histórico de preços",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Prices"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000000,
              "default": 1
            }
          }
        ],
        "description": "Aceita token read ou write."
      },
      "post": {
        "summary": "Registrar preço por kg",
        "tags": [
          "papers"
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "201": {
            "description": "Registrar preço por kg",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Paper"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PriceCreate"
              }
            }
          }
        },
        "description": "Exige token write ou sessão de usuário. Sessões exigem Origin nas mutações."
      }
    },
    "/compositions": {
      "get": {
        "summary": "Listar perfis",
        "tags": [
          "compositions"
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "Listar perfis",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Profiles"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000000,
              "default": 1
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "archived",
                "all"
              ]
            }
          }
        ],
        "description": "Aceita token read ou write."
      },
      "post": {
        "summary": "Criar perfil e primeira revisão",
        "tags": [
          "compositions"
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "201": {
            "description": "Criar perfil e primeira revisão",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevisionSaved"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProfileCreate"
              }
            }
          }
        },
        "description": "Exige token write ou sessão de usuário. Sessões exigem Origin nas mutações."
      }
    },
    "/compositions/{id}": {
      "get": {
        "summary": "Consultar revisão atual do perfil",
        "tags": [
          "compositions"
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "Consultar revisão atual do perfil",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Revision"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "description": "Aceita token read ou write."
      },
      "patch": {
        "summary": "Arquivar ou reativar perfil",
        "tags": [
          "compositions"
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "Arquivar ou reativar perfil",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Revision"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Archive"
              }
            }
          }
        },
        "description": "Exige token write ou sessão de usuário. Sessões exigem Origin nas mutações."
      }
    },
    "/compositions/{id}/revisions": {
      "get": {
        "summary": "Listar revisões",
        "tags": [
          "compositions"
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "Listar revisões",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Revisions"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000000,
              "default": 1
            }
          }
        ],
        "description": "Aceita token read ou write."
      },
      "post": {
        "summary": "Salvar nova revisão",
        "tags": [
          "compositions"
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "201": {
            "description": "Salvar nova revisão",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevisionSaved"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RevisionCreate"
              }
            }
          }
        },
        "description": "Exige token write ou sessão de usuário. Sessões exigem Origin nas mutações."
      }
    },
    "/compositions/{id}/revisions/{revisionId}": {
      "get": {
        "summary": "Consultar revisão histórica",
        "tags": [
          "compositions"
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "Consultar revisão histórica",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Revision"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "revisionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "description": "Aceita token read ou write."
      }
    },
    "/compositions/{id}/duplicate": {
      "post": {
        "summary": "Duplicar perfil",
        "tags": [
          "compositions"
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "201": {
            "description": "Duplicar perfil",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevisionSaved"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Duplicate"
              }
            }
          }
        },
        "description": "Exige token write ou sessão de usuário. Sessões exigem Origin nas mutações."
      }
    },
    "/calculations/preview": {
      "post": {
        "summary": "Calcular sem salvar",
        "tags": [
          "calculations"
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "Calcular sem salvar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CalculationResult"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Preview"
              }
            }
          }
        },
        "description": "Aceita token read ou write."
      }
    },
    "/revisions/{revisionId}/calculations": {
      "get": {
        "summary": "Listar produções da revisão",
        "tags": [
          "revisions"
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "Listar produções da revisão",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Calculations"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "revisionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000000,
              "default": 1
            }
          }
        ],
        "description": "Aceita token read ou write."
      },
      "post": {
        "summary": "Calcular e salvar produção",
        "tags": [
          "revisions"
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "201": {
            "description": "Calcular e salvar produção",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Calculation"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "revisionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Production"
              }
            }
          }
        },
        "description": "Exige token write ou sessão de usuário. Sessões exigem Origin nas mutações."
      }
    },
    "/calculations/{id}": {
      "get": {
        "summary": "Consultar produção salva",
        "tags": [
          "calculations"
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "Consultar produção salva",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Calculation"
                }
              }
            }
          },
          "400": {
            "description": "JSON inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Autenticação inválida/expirada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permissão, escopo ou origem insuficiente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Registro não encontrado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Código duplicado ou alteração concorrente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo acima de 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validação dos dados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de login",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Erro interno",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "description": "Aceita token read ou write."
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Token tube_... emitido por administrador em Usuários e API."
      },
      "sessionCookie": {
        "type": "apiKey",
        "in": "cookie",
        "name": "tube_session"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "fields": {
            "type": "object"
          }
        },
        "required": [
          "code",
          "message"
        ]
      },
      "Session": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "login": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "role": {
            "enum": [
              "admin",
              "operator"
            ]
          }
        },
        "required": [
          "id",
          "login",
          "role"
        ]
      },
      "Login": {
        "type": "object",
        "properties": {
          "login": {
            "type": "string"
          },
          "password": {
            "type": "string",
            "writeOnly": true
          }
        },
        "required": [
          "login",
          "password"
        ]
      },
      "User": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "login": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "role": {
            "enum": [
              "admin",
              "operator"
            ]
          },
          "active": {
            "type": "boolean"
          },
          "version": {
            "type": "integer",
            "minimum": 1
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "UserCreate": {
        "type": "object",
        "properties": {
          "login": {
            "type": "string",
            "maxLength": 120
          },
          "name": {
            "type": "string",
            "maxLength": 160
          },
          "role": {
            "enum": [
              "admin",
              "operator"
            ],
            "default": "operator"
          },
          "password": {
            "type": "string",
            "minLength": 12,
            "maxLength": 256,
            "writeOnly": true
          }
        },
        "required": [
          "login",
          "name",
          "password"
        ]
      },
      "UserUpdate": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 160
          },
          "role": {
            "enum": [
              "admin",
              "operator"
            ]
          },
          "active": {
            "type": "boolean"
          },
          "expectedVersion": {
            "type": "integer",
            "minimum": 1
          }
        },
        "required": [
          "expectedVersion"
        ]
      },
      "PasswordReset": {
        "type": "object",
        "properties": {
          "password": {
            "type": "string",
            "minLength": 12,
            "maxLength": 256,
            "writeOnly": true
          },
          "expectedVersion": {
            "type": "integer",
            "minimum": 1
          }
        },
        "required": [
          "password",
          "expectedVersion"
        ]
      },
      "Token": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "userId": {
            "type": "string",
            "format": "uuid"
          },
          "login": {
            "type": "string"
          },
          "userActive": {
            "type": "boolean"
          },
          "name": {
            "type": "string"
          },
          "prefix": {
            "type": "string"
          },
          "scope": {
            "enum": [
              "read",
              "write"
            ]
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "revokedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "lastUsedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TokenCreate": {
        "type": "object",
        "properties": {
          "userId": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "maxLength": 160
          },
          "scope": {
            "enum": [
              "read",
              "write"
            ],
            "default": "read"
          },
          "expiresInDays": {
            "type": "integer",
            "minimum": 1,
            "maximum": 365,
            "default": 90
          }
        },
        "required": [
          "userId",
          "name"
        ]
      },
      "TokenIssued": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Token"
          },
          {
            "type": "object",
            "properties": {
              "token": {
                "type": "string",
                "description": "Segredo completo, retornado somente nesta resposta."
              }
            },
            "required": [
              "token"
            ]
          }
        ]
      },
      "Paper": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "maxLength": 80
          },
          "name": {
            "type": "string",
            "maxLength": 160
          },
          "type": {
            "type": "string"
          },
          "supplier": {
            "type": "string"
          },
          "notes": {
            "type": "string"
          },
          "grammage": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000,
            "exclusiveMinimum": 0
          },
          "tp": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000,
            "exclusiveMinimum": 0
          },
          "widthMm": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000,
            "exclusiveMinimum": 0
          },
          "wastePct": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000
          },
          "active": {
            "type": "boolean"
          },
          "pricePerKg": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1000000000
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "version": {
            "type": "integer",
            "minimum": 1
          },
          "priceId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "PaperCreate": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "maxLength": 80
          },
          "name": {
            "type": "string",
            "maxLength": 160
          },
          "type": {
            "type": "string"
          },
          "supplier": {
            "type": "string"
          },
          "notes": {
            "type": "string"
          },
          "grammage": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000,
            "exclusiveMinimum": 0
          },
          "tp": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000,
            "exclusiveMinimum": 0
          },
          "widthMm": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000,
            "exclusiveMinimum": 0
          },
          "wastePct": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000
          },
          "active": {
            "type": "boolean"
          },
          "pricePerKg": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1000000000
          }
        },
        "required": [
          "code",
          "name",
          "grammage",
          "tp",
          "widthMm",
          "wastePct"
        ]
      },
      "PaperUpdate": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "maxLength": 80
          },
          "name": {
            "type": "string",
            "maxLength": 160
          },
          "type": {
            "type": "string"
          },
          "supplier": {
            "type": "string"
          },
          "notes": {
            "type": "string"
          },
          "grammage": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000,
            "exclusiveMinimum": 0
          },
          "tp": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000,
            "exclusiveMinimum": 0
          },
          "widthMm": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000,
            "exclusiveMinimum": 0
          },
          "wastePct": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000
          },
          "active": {
            "type": "boolean"
          },
          "pricePerKg": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1000000000
          },
          "expectedVersion": {
            "type": "integer",
            "minimum": 1
          }
        },
        "required": [
          "expectedVersion"
        ]
      },
      "Price": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "pricePerKg": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1000000000
          },
          "effectiveAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdBy": {
            "type": "string",
            "format": "uuid"
          }
        }
      },
      "PriceCreate": {
        "type": "object",
        "properties": {
          "pricePerKg": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1000000000
          },
          "expectedVersion": {
            "type": "integer",
            "minimum": 1
          }
        },
        "required": [
          "pricePerKg",
          "expectedVersion"
        ]
      },
      "ProfileItem": {
        "type": "object",
        "properties": {
          "paperId": {
            "type": "string",
            "format": "uuid"
          },
          "expectedPaperVersion": {
            "type": "integer",
            "minimum": 1
          },
          "expectedPriceId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "sourceItemId": {
            "type": "string",
            "format": "uuid"
          },
          "count": {
            "type": "integer",
            "minimum": 1,
            "maximum": 5000
          },
          "widthMm": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000,
            "exclusiveMinimum": 0
          },
          "wastePct": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000
          },
          "label": {
            "type": "string"
          }
        },
        "required": [
          "paperId",
          "count",
          "widthMm",
          "wastePct"
        ],
        "description": "Material atual: expectedPaperVersion e expectedPriceId obrigatórios. Material histórico: sourceItemId obrigatório junto com sourceRevisionId no corpo do perfil."
      },
      "Production": {
        "type": "object",
        "properties": {
          "lengthMm": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000,
            "exclusiveMinimum": 0
          },
          "quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000
          }
        },
        "required": [
          "lengthMm",
          "quantity"
        ]
      },
      "ProfileCreate": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "maxLength": 80
          },
          "name": {
            "type": "string",
            "maxLength": 160
          },
          "diMm": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000,
            "exclusiveMinimum": 0
          },
          "targetWallMm": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000,
            "exclusiveMinimum": 0
          },
          "notes": {
            "type": "string"
          },
          "sourceRevisionId": {
            "type": "string",
            "format": "uuid"
          },
          "items": {
            "type": "array",
            "minItems": 1,
            "maxItems": 5000,
            "items": {
              "$ref": "#/components/schemas/ProfileItem"
            }
          },
          "filler": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "paperId": {
                "type": "string",
                "format": "uuid"
              },
              "position": {
                "type": "integer",
                "minimum": 0
              }
            },
            "required": [
              "paperId",
              "position"
            ]
          },
          "production": {
            "$ref": "#/components/schemas/Production"
          }
        },
        "required": [
          "code",
          "name",
          "diMm",
          "targetWallMm",
          "items"
        ]
      },
      "RevisionCreate": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "maxLength": 80
          },
          "name": {
            "type": "string",
            "maxLength": 160
          },
          "diMm": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000,
            "exclusiveMinimum": 0
          },
          "targetWallMm": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000,
            "exclusiveMinimum": 0
          },
          "notes": {
            "type": "string"
          },
          "sourceRevisionId": {
            "type": "string",
            "format": "uuid"
          },
          "items": {
            "type": "array",
            "minItems": 1,
            "maxItems": 5000,
            "items": {
              "$ref": "#/components/schemas/ProfileItem"
            }
          },
          "filler": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "paperId": {
                "type": "string",
                "format": "uuid"
              },
              "position": {
                "type": "integer",
                "minimum": 0
              }
            },
            "required": [
              "paperId",
              "position"
            ]
          },
          "production": {
            "$ref": "#/components/schemas/Production"
          },
          "expectedRevision": {
            "type": "integer",
            "minimum": 1
          }
        },
        "required": [
          "name",
          "diMm",
          "targetWallMm",
          "items",
          "expectedRevision"
        ]
      },
      "Preview": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "maxLength": 80
          },
          "name": {
            "type": "string",
            "maxLength": 160
          },
          "diMm": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000,
            "exclusiveMinimum": 0
          },
          "targetWallMm": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000,
            "exclusiveMinimum": 0
          },
          "notes": {
            "type": "string"
          },
          "sourceRevisionId": {
            "type": "string",
            "format": "uuid"
          },
          "items": {
            "type": "array",
            "minItems": 1,
            "maxItems": 5000,
            "items": {
              "$ref": "#/components/schemas/ProfileItem"
            }
          },
          "filler": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "paperId": {
                "type": "string",
                "format": "uuid"
              },
              "position": {
                "type": "integer",
                "minimum": 0
              }
            },
            "required": [
              "paperId",
              "position"
            ]
          },
          "production": {
            "$ref": "#/components/schemas/Production"
          }
        },
        "required": [
          "diMm",
          "targetWallMm",
          "items"
        ]
      },
      "Duplicate": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "maxLength": 80
          },
          "name": {
            "type": "string",
            "maxLength": 160
          },
          "sourceRevisionId": {
            "type": "string",
            "format": "uuid"
          },
          "production": {
            "$ref": "#/components/schemas/Production"
          }
        },
        "required": [
          "code",
          "name"
        ]
      },
      "ProfileSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "archived": {
            "type": "boolean"
          },
          "currentRevision": {
            "type": "integer",
            "minimum": 1
          },
          "diMm": {
            "type": [
              "number",
              "string"
            ]
          },
          "targetWallMm": {
            "type": [
              "number",
              "string"
            ]
          }
        }
      },
      "RevisionSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "number": {
            "type": "integer",
            "minimum": 1
          },
          "name": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Revision": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "compositionId": {
            "type": "string",
            "format": "uuid"
          },
          "number": {
            "type": "integer",
            "minimum": 1
          },
          "currentRevision": {
            "type": "integer",
            "minimum": 1
          },
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "archived": {
            "type": "boolean"
          },
          "diMm": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000,
            "exclusiveMinimum": 0
          },
          "targetWallMm": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000,
            "exclusiveMinimum": 0
          },
          "notes": {
            "type": "string"
          },
          "filler": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "paperId": {
                "type": "string",
                "format": "uuid"
              },
              "position": {
                "type": "integer",
                "minimum": 0
              }
            },
            "required": [
              "paperId",
              "position"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "paperId": {
                  "type": "string",
                  "format": "uuid"
                },
                "expectedPaperVersion": {
                  "type": "integer",
                  "minimum": 1
                },
                "expectedPriceId": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "uuid"
                },
                "sourceItemId": {
                  "type": "string",
                  "format": "uuid"
                },
                "count": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 5000
                },
                "widthMm": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1000000000,
                  "exclusiveMinimum": 0
                },
                "wastePct": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1000000000
                },
                "label": {
                  "type": "string"
                },
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "code": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "type": {
                  "type": "string"
                },
                "grammage": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1000000000,
                  "exclusiveMinimum": 0
                },
                "tp": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1000000000,
                  "exclusiveMinimum": 0
                },
                "pricePerKg": {
                  "type": [
                    "number",
                    "null"
                  ],
                  "minimum": 0,
                  "maximum": 1000000000
                },
                "priceId": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "uuid"
                },
                "paperVersion": {
                  "type": "integer",
                  "minimum": 1
                },
                "paperActive": {
                  "type": "boolean"
                }
              }
            }
          }
        }
      },
      "Usage": {
        "type": "object",
        "properties": {
          "areaM2": {
            "type": "number",
            "minimum": 0
          },
          "meters": {
            "type": "number",
            "minimum": 0
          },
          "weightKg": {
            "type": "number",
            "minimum": 0
          },
          "areaWithWasteM2": {
            "type": "number",
            "minimum": 0
          },
          "metersWithWaste": {
            "type": "number",
            "minimum": 0
          },
          "weightWithWasteKg": {
            "type": "number",
            "minimum": 0
          },
          "cost": {
            "type": [
              "string",
              "null"
            ],
            "description": "Valor em reais com duas casas; null quando há preço pendente."
          },
          "knownCost": {
            "type": "string"
          },
          "costComplete": {
            "type": "boolean"
          },
          "missingPrices": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "CalculationResult": {
        "type": "object",
        "properties": {
          "engineVersion": {
            "type": "string"
          },
          "layerCount": {
            "type": "integer",
            "minimum": 1
          },
          "wallMm": {
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000
          },
          "validWinding": {
            "type": "boolean"
          },
          "layers": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "groups": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "materials": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "perTube": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Usage"
              },
              {
                "type": "null"
              }
            ]
          },
          "batch": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Usage"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "Calculation": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "revisionId": {
            "type": "string",
            "format": "uuid"
          },
          "lengthMm": {
            "type": [
              "number",
              "string"
            ]
          },
          "quantity": {
            "type": "integer",
            "minimum": 1
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "results": {
            "$ref": "#/components/schemas/CalculationResult"
          }
        }
      },
      "CalculationSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "lengthMm": {
            "type": [
              "number",
              "string"
            ]
          },
          "quantity": {
            "type": "integer",
            "minimum": 1
          },
          "engineVersion": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "RevisionSaved": {
        "type": "object",
        "properties": {
          "revision": {
            "$ref": "#/components/schemas/Revision"
          },
          "calculation": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Calculation"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "revision",
          "calculation"
        ]
      },
      "Health": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string"
          }
        },
        "required": [
          "status"
        ]
      },
      "Users": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/User"
            }
          },
          "page": {
            "type": "integer",
            "minimum": 1
          },
          "limit": {
            "type": "integer",
            "const": 25
          },
          "total": {
            "type": "integer",
            "minimum": 0
          }
        },
        "required": [
          "items",
          "page",
          "limit"
        ]
      },
      "Tokens": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Token"
            }
          },
          "page": {
            "type": "integer",
            "minimum": 1
          },
          "limit": {
            "type": "integer",
            "const": 25
          },
          "total": {
            "type": "integer",
            "minimum": 0
          }
        },
        "required": [
          "items",
          "page",
          "limit"
        ]
      },
      "Papers": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Paper"
            }
          },
          "page": {
            "type": "integer",
            "minimum": 1
          },
          "limit": {
            "type": "integer",
            "const": 25
          },
          "total": {
            "type": "integer",
            "minimum": 0
          }
        },
        "required": [
          "items",
          "page",
          "limit"
        ]
      },
      "Prices": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Price"
            }
          },
          "page": {
            "type": "integer",
            "minimum": 1
          },
          "limit": {
            "type": "integer",
            "const": 25
          }
        },
        "required": [
          "items",
          "page",
          "limit"
        ]
      },
      "Profiles": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProfileSummary"
            }
          },
          "page": {
            "type": "integer",
            "minimum": 1
          },
          "limit": {
            "type": "integer",
            "const": 25
          },
          "total": {
            "type": "integer",
            "minimum": 0
          }
        },
        "required": [
          "items",
          "page",
          "limit"
        ]
      },
      "Revisions": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RevisionSummary"
            }
          },
          "page": {
            "type": "integer",
            "minimum": 1
          },
          "limit": {
            "type": "integer",
            "const": 25
          }
        },
        "required": [
          "items",
          "page",
          "limit"
        ]
      },
      "Calculations": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CalculationSummary"
            }
          },
          "page": {
            "type": "integer",
            "minimum": 1
          },
          "limit": {
            "type": "integer",
            "const": 25
          }
        },
        "required": [
          "items",
          "page",
          "limit"
        ]
      },
      "Archive": {
        "type": "object",
        "properties": {
          "archived": {
            "type": "boolean"
          }
        },
        "required": [
          "archived"
        ]
      }
    }
  }
}
