{
  "openapi": "3.1.0",
  "info": {
    "title": "API de provisionamento PsicoGes",
    "version": "2026-10-19",
    "description": "Provisiona usuários do painel por empresa. Não importa folha nem expõe questionários ou denúncias. Quatro operações no mesmo endpoint POST, selecionadas por action."
  },
  "servers": [
    {
      "url": "https://fizgujocdsnnvmwbrvgq.supabase.co/functions/v1"
    }
  ],
  "security": [
    {
      "ProvisioningKey": []
    }
  ],
  "paths": {
    "/api": {
      "post": {
        "operationId": "provisionarUsuarios",
        "summary": "Executar uma operação de usuários e permissões",
        "parameters": [
          {
            "in": "query",
            "name": "route",
            "required": true,
            "schema": {
              "type": "string",
              "const": "integracao"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/usuario-upsert"
                  },
                  {
                    "$ref": "#/components/schemas/usuarios-list"
                  },
                  {
                    "$ref": "#/components/schemas/usuario-revogar"
                  },
                  {
                    "$ref": "#/components/schemas/usuario-reconvidar"
                  }
                ],
                "discriminator": {
                  "propertyName": "action",
                  "mapping": {
                    "usuario-upsert": "#/components/schemas/usuario-upsert",
                    "usuarios-list": "#/components/schemas/usuarios-list",
                    "usuario-revogar": "#/components/schemas/usuario-revogar",
                    "usuario-reconvidar": "#/components/schemas/usuario-reconvidar"
                  }
                }
              },
              "examples": {
                "usuario-upsert": {
                  "value": {
                    "action": "usuario-upsert",
                    "externalId": "RH-12345",
                    "email": "pessoa@example.com",
                    "nome": "Pessoa da equipe",
                    "permissions": {
                      "avaliacoes": "leitura",
                      "riscos": "nenhum",
                      "epi": "nenhum"
                    }
                  }
                },
                "usuarios-list": {
                  "value": {
                    "action": "usuarios-list",
                    "limit": 100,
                    "offset": 0
                  }
                },
                "usuario-revogar": {
                  "value": {
                    "action": "usuario-revogar",
                    "externalId": "RH-12345"
                  }
                },
                "usuario-reconvidar": {
                  "value": {
                    "action": "usuario-reconvidar",
                    "externalId": "RH-12345",
                    "idempotencyKey": "evento-rh-20261019-12345"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Listagem, atualização, revogação ou reconvite",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/UpsertResult"
                    },
                    {
                      "$ref": "#/components/schemas/ListResult"
                    },
                    {
                      "$ref": "#/components/schemas/RevokeResult"
                    },
                    {
                      "$ref": "#/components/schemas/ReinviteResult"
                    }
                  ]
                },
                "examples": {
                  "usuario-upsert": {
                    "value": {
                      "usuario": {
                        "id": "11111111-1111-4111-8111-111111111111",
                        "empresa_id": "22222222-2222-4222-8222-222222222222",
                        "usuario_id": null,
                        "email": "pessoa@example.com",
                        "nome": "Pessoa da equipe",
                        "status": "pendente",
                        "permissions": {
                          "avaliacoes": "leitura",
                          "riscos": "nenhum",
                          "epi": "nenhum"
                        },
                        "external_id": "RH-12345"
                      },
                      "emailSent": true
                    }
                  },
                  "usuarios-list": {
                    "value": {
                      "usuarios": [
                        {
                          "id": "11111111-1111-4111-8111-111111111111",
                          "empresa_id": "22222222-2222-4222-8222-222222222222",
                          "usuario_id": null,
                          "email": "pessoa@example.com",
                          "nome": "Pessoa da equipe",
                          "status": "pendente",
                          "permissions": {
                            "avaliacoes": "leitura",
                            "riscos": "nenhum",
                            "epi": "nenhum"
                          },
                          "external_id": "RH-12345",
                          "created_at": "2026-10-19T12:00:00Z",
                          "updated_at": "2026-10-19T12:00:00Z"
                        }
                      ],
                      "limit": 100,
                      "offset": 0
                    }
                  },
                  "usuario-revogar": {
                    "value": {
                      "ok": true
                    }
                  },
                  "usuario-reconvidar": {
                    "value": {
                      "usuario": {
                        "id": "11111111-1111-4111-8111-111111111111",
                        "empresa_id": "22222222-2222-4222-8222-222222222222",
                        "usuario_id": null,
                        "email": "pessoa@example.com",
                        "nome": "Pessoa da equipe",
                        "status": "pendente",
                        "permissions": {
                          "avaliacoes": "leitura",
                          "riscos": "nenhum",
                          "epi": "nenhum"
                        },
                        "external_id": "RH-12345"
                      },
                      "emailSent": true,
                      "replayed": false
                    }
                  }
                }
              }
            }
          },
          "201": {
            "description": "Novo vínculo pendente criado; convite tentado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpsertResult"
                },
                "example": {
                  "usuario": {
                    "id": "11111111-1111-4111-8111-111111111111",
                    "empresa_id": "22222222-2222-4222-8222-222222222222",
                    "usuario_id": null,
                    "email": "pessoa@example.com",
                    "nome": "Pessoa da equipe",
                    "status": "pendente",
                    "permissions": {
                      "avaliacoes": "leitura",
                      "riscos": "nenhum",
                      "epi": "nenhum"
                    },
                    "external_id": "RH-12345"
                  },
                  "emailSent": true
                }
              }
            }
          },
          "400": {
            "description": "Entrada inválida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Chave ausente, inválida ou revogada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Assinatura inativa",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Vínculo inexistente no reconvite",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflito de vínculo ou evento",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limite de requisições",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Falha interna",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Corpo da requisição maior que 1 MiB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Content-Type deve ser application/json",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Autenticação ou serviço temporariamente indisponível",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ProvisioningKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Chave administrativa gerada pelo proprietário em Equipe e integrações. Usar somente no servidor."
      }
    },
    "schemas": {
      "Permissions": {
        "type": "object",
        "properties": {
          "avaliacoes": {
            "type": "string",
            "enum": [
              "nenhum",
              "leitura",
              "escrita"
            ]
          },
          "riscos": {
            "type": "string",
            "enum": [
              "nenhum",
              "leitura",
              "escrita"
            ]
          },
          "epi": {
            "type": "string",
            "enum": [
              "nenhum",
              "leitura",
              "escrita"
            ]
          }
        },
        "additionalProperties": false,
        "description": "Ao informar permissions, módulos omitidos recebem nenhum. Na atualização, omitir o objeto preserva as permissões."
      },
      "Usuario": {
        "type": "object",
        "required": [
          "id",
          "empresa_id",
          "usuario_id",
          "email",
          "nome",
          "status",
          "permissions",
          "external_id"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "empresa_id": {
            "type": "string"
          },
          "usuario_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "email": {
            "type": "string"
          },
          "nome": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pendente",
              "ativo",
              "revogado"
            ]
          },
          "permissions": {
            "$ref": "#/components/schemas/Permissions"
          },
          "external_id": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "UsuarioListado": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Usuario"
          },
          {
            "type": "object",
            "required": [
              "created_at",
              "updated_at"
            ],
            "properties": {
              "created_at": {
                "type": "string",
                "format": "date-time"
              },
              "updated_at": {
                "type": "string",
                "format": "date-time"
              }
            }
          }
        ]
      },
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          }
        }
      },
      "usuario-upsert": {
        "type": "object",
        "properties": {
          "action": {
            "type": "string",
            "const": "usuario-upsert"
          },
          "externalId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "description": "Identificador estável e único por empresa. Nunca reutilize para outra pessoa."
          },
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 254
          },
          "nome": {
            "type": "string",
            "minLength": 1,
            "maxLength": 160
          },
          "permissions": {
            "$ref": "#/components/schemas/Permissions"
          }
        },
        "required": [
          "action",
          "externalId"
        ],
        "example": {
          "action": "usuario-upsert",
          "externalId": "RH-12345",
          "email": "pessoa@example.com",
          "nome": "Pessoa da equipe",
          "permissions": {
            "avaliacoes": "leitura",
            "riscos": "nenhum",
            "epi": "nenhum"
          }
        },
        "description": "Novos vínculos exigem email, nome e permissions; para atualizar, esses campos são opcionais. Email existente é imutável."
      },
      "usuarios-list": {
        "type": "object",
        "properties": {
          "action": {
            "type": "string",
            "const": "usuarios-list"
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000,
            "default": 100
          },
          "offset": {
            "type": "integer",
            "minimum": 0,
            "default": 0
          }
        },
        "required": [
          "action"
        ],
        "example": {
          "action": "usuarios-list",
          "limit": 100,
          "offset": 0
        },
        "description": ""
      },
      "usuario-revogar": {
        "type": "object",
        "properties": {
          "action": {
            "type": "string",
            "const": "usuario-revogar"
          },
          "externalId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "description": "Identificador estável e único por empresa. Nunca reutilize para outra pessoa."
          }
        },
        "required": [
          "action",
          "externalId"
        ],
        "example": {
          "action": "usuario-revogar",
          "externalId": "RH-12345"
        },
        "description": ""
      },
      "usuario-reconvidar": {
        "type": "object",
        "properties": {
          "action": {
            "type": "string",
            "const": "usuario-reconvidar"
          },
          "externalId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "description": "Identificador estável e único por empresa. Nunca reutilize para outra pessoa."
          },
          "idempotencyKey": {
            "type": "string",
            "minLength": 16,
            "maxLength": 128,
            "pattern": "^[A-Za-z0-9_-]{16,128}$"
          }
        },
        "required": [
          "action",
          "externalId",
          "idempotencyKey"
        ],
        "example": {
          "action": "usuario-reconvidar",
          "externalId": "RH-12345",
          "idempotencyKey": "evento-rh-20261019-12345"
        },
        "description": ""
      },
      "UpsertResult": {
        "type": "object",
        "required": [
          "usuario"
        ],
        "properties": {
          "usuario": {
            "$ref": "#/components/schemas/Usuario"
          },
          "emailSent": {
            "type": "boolean"
          },
          "created": {
            "type": "boolean",
            "const": false
          }
        }
      },
      "ListResult": {
        "type": "object",
        "required": [
          "usuarios",
          "limit",
          "offset"
        ],
        "properties": {
          "usuarios": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UsuarioListado"
            }
          },
          "limit": {
            "type": "integer"
          },
          "offset": {
            "type": "integer"
          }
        }
      },
      "RevokeResult": {
        "type": "object",
        "required": [
          "ok"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          }
        }
      },
      "ReinviteResult": {
        "type": "object",
        "required": [
          "usuario",
          "replayed"
        ],
        "properties": {
          "usuario": {
            "$ref": "#/components/schemas/Usuario"
          },
          "emailSent": {
            "type": "boolean",
            "description": "Omitido no replay."
          },
          "replayed": {
            "type": "boolean"
          }
        }
      }
    }
  }
}
