{
  "openapi": "3.1.0",
  "info": {
    "title": "GEAEF Public API",
    "version": "1.0.0",
    "description": "API REST publica do Grupo Educacional e Assistencial Espirita Fraternidade (GEAEF), sediado em Brasilia - DF. Permite a agentes de IA e desenvolvedores consultar atividades, palestras publicas, grupos de estudos doutrinarios (ESDE, EADE, GER, etc.), evangelizacao infantojuvenil e dados de contato e acolhimento.",
    "contact": {
      "name": "GEAEF",
      "email": "geaef@geaef.org.br",
      "url": "https://geaef.org.br"
    },
    "license": {
      "name": "CC-BY-4.0",
      "url": "https://creativecommons.org/licenses/by/4.0/"
    },
    "x-versioning-policy": {
      "strategy": "URL path versioning (/v1/) and X-API-Version header parameter",
      "current_version": "1.0.0",
      "major_version": "v1",
      "supported_versions": [
        "v1"
      ],
      "deprecation_policy": "Deprecations are communicated at least 180 days in advance via RFC 8594 Sunset and Deprecation headers. Breaking changes result in a new major version path.",
      "sunset_header": "Sunset",
      "deprecation_header": "Deprecation",
      "documentation": "https://geaef.org.br/docs#versioning"
    }
  },
  "servers": [
    {
      "url": "https://geaef.org.br/v1",
      "description": "Versao 1 da API oficial (URL Path Versioning)"
    },
    {
      "url": "https://geaef.org.br/api/v1",
      "description": "Versao 1 com prefixo de API"
    },
    {
      "url": "https://geaef.org.br/api",
      "description": "Endpoints legados de producao"
    }
  ],
  "paths": {
    "/v1/activities": {
      "get": {
        "operationId": "v1_getActivities",
        "summary": "Listar atividades da casa",
        "description": "Retorna a lista completa de atividades publicas, doutrinarias e assistenciais do GEAEF, com filtros opcionais por categoria ou dia.",
        "parameters": [
          {
            "name": "category",
            "in": "query",
            "required": false,
            "description": "Filtrar por categoria (ex: estudo, palestras, atendimento-fraterno, infancia-juventude, bazar, trabalho)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "day",
            "in": "query",
            "required": false,
            "description": "Filtrar por dia da semana (ex: Quarta-feira, Sabado, Domingo)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Numero maximo de itens por pagina para paginacao",
            "schema": {
              "type": "integer",
              "default": 20
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Deslocamento de registros para paginacao baseada em offset",
            "schema": {
              "type": "integer",
              "default": 0
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Cursor sequencial para paginacao baseada em cursor",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lista de atividades retornada com sucesso.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Activity"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Parametros invalidos na requisicao.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/info": {
      "get": {
        "operationId": "v1_getInstitutionInfo",
        "summary": "Obter informacoes institucionais do GEAEF",
        "description": "Retorna endereco oficial em Brasilia, telefones de contato, e-mail institucional, CNPJ, canais de comunicacao e instrucoes para doacoes PIX.",
        "responses": {
          "200": {
            "description": "Dados institucionais retornados com sucesso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InstitutionInfo"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "section",
            "in": "query",
            "required": false,
            "description": "Secao especifica das informacoes (geral, endereco, departamentos, doacoes)",
            "schema": {
              "type": "string",
              "enum": [
                "geral",
                "endereco",
                "departamentos",
                "doacoes"
              ]
            }
          }
        ]
      }
    },
    "/v1/studies": {
      "get": {
        "operationId": "v1_getStudyGroups",
        "summary": "Listar grupos de estudos doutrinarios",
        "description": "Retorna todos os grupos de estudo da Doutrina Espirita em andamento no GEAEF (ESDE, EADE, GER, EOCE, ELAL, MEP), contendo livros de referencia, horarios e salas.",
        "responses": {
          "200": {
            "description": "Lista de grupos de estudo retornada com sucesso.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/StudyGroup"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Numero maximo de itens por pagina para paginacao",
            "schema": {
              "type": "integer",
              "default": 20
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Deslocamento de registros para paginacao baseada em offset",
            "schema": {
              "type": "integer",
              "default": 0
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Cursor sequencial para paginacao baseada em cursor",
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/v1/events": {
      "get": {
        "operationId": "v1_getRecentEvents",
        "summary": "Listar ultimos eventos e palestras",
        "description": "Retorna a relacao de eventos especiais, seminarios e ultimas palestras gravadas no canal do YouTube.",
        "responses": {
          "200": {
            "description": "Lista de eventos retornada com sucesso.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Event"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Numero maximo de itens por pagina para paginacao",
            "schema": {
              "type": "integer",
              "default": 20
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Deslocamento de registros para paginacao baseada em offset",
            "schema": {
              "type": "integer",
              "default": 0
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Cursor sequencial para paginacao baseada em cursor",
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/v1/sandbox": {
      "get": {
        "operationId": "v1_getSandboxEnvironment",
        "summary": "Obter informacoes do ambiente sandbox",
        "description": "Fornece um ambiente seguro e controlado para que agentes de IA exercitem integracoes, realizem testes de schemas e validem chamadas sem alterar dados reais.",
        "responses": {
          "200": {
            "description": "Status e instrucoes do ambiente de testes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "sandbox": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string",
                      "example": "Ambiente sandbox ativo para testes de agentes."
                    },
                    "availableEndpoints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/ApiVersion"
          }
        ]
      },
      "post": {
        "operationId": "v1_executeSandboxMutation",
        "summary": "Executar operacao de teste no ambiente sandbox",
        "description": "Executa mutacao idempotente no ambiente sandbox para simulacao de agentes.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/ApiVersion"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "action": {
                    "type": "string",
                    "example": "simulate_booking"
                  },
                  "payload": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Mutacao simulada com sucesso.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "success"
                    },
                    "idempotent": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string",
                      "example": "Operacao de sandbox executada com sucesso."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/ask": {
      "post": {
        "operationId": "v1_askQuestionNLWeb",
        "summary": "Responder pergunta em linguagem natural (Protocolo NLWeb v0.55)",
        "description": "Recebe uma pergunta em linguagem natural sobre o GEAEF e retorna respostas diretas e fundamentadas em informacoes institucionais, suportando streaming SSE.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "query"
                ],
                "properties": {
                  "query": {
                    "type": "object",
                    "required": [
                      "text"
                    ],
                    "properties": {
                      "text": {
                        "type": "string",
                        "description": "Pergunta em linguagem natural"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resposta formulada com sucesso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NLWebResponse"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/ApiVersion"
          }
        ]
      }
    },
    "/api/activities": {
      "get": {
        "operationId": "getActivities",
        "summary": "Listar atividades da casa",
        "description": "Retorna a lista completa de atividades publicas, doutrinarias e assistenciais do GEAEF, com filtros opcionais por categoria ou dia.",
        "parameters": [
          {
            "name": "category",
            "in": "query",
            "required": false,
            "description": "Filtrar por categoria (ex: estudo, palestras, atendimento-fraterno, infancia-juventude, bazar, trabalho)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "day",
            "in": "query",
            "required": false,
            "description": "Filtrar por dia da semana (ex: Quarta-feira, Sabado, Domingo)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Numero maximo de itens por pagina para paginacao",
            "schema": {
              "type": "integer",
              "default": 20
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Deslocamento de registros para paginacao baseada em offset",
            "schema": {
              "type": "integer",
              "default": 0
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Cursor sequencial para paginacao baseada em cursor",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lista de atividades retornada com sucesso.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Activity"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Parametros invalidos na requisicao.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/info": {
      "get": {
        "operationId": "getInstitutionInfo",
        "summary": "Obter informacoes institucionais do GEAEF",
        "description": "Retorna endereco oficial em Brasilia, telefones de contato, e-mail institucional, CNPJ, canais de comunicacao e instrucoes para doacoes PIX.",
        "responses": {
          "200": {
            "description": "Dados institucionais retornados com sucesso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InstitutionInfo"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "section",
            "in": "query",
            "required": false,
            "description": "Secao especifica das informacoes (geral, endereco, departamentos, doacoes)",
            "schema": {
              "type": "string",
              "enum": [
                "geral",
                "endereco",
                "departamentos",
                "doacoes"
              ]
            }
          }
        ]
      }
    },
    "/api/studies": {
      "get": {
        "operationId": "getStudyGroups",
        "summary": "Listar grupos de estudos doutrinarios",
        "description": "Retorna todos os grupos de estudo da Doutrina Espirita em andamento no GEAEF (ESDE, EADE, GER, EOCE, ELAL, MEP), contendo livros de referencia, horarios e salas.",
        "responses": {
          "200": {
            "description": "Lista de grupos de estudo retornada com sucesso.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/StudyGroup"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Numero maximo de itens por pagina para paginacao",
            "schema": {
              "type": "integer",
              "default": 20
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Deslocamento de registros para paginacao baseada em offset",
            "schema": {
              "type": "integer",
              "default": 0
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Cursor sequencial para paginacao baseada em cursor",
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/api/events": {
      "get": {
        "operationId": "getRecentEvents",
        "summary": "Listar ultimos eventos e palestras",
        "description": "Retorna a relacao de eventos especiais, seminarios e ultimas palestras gravadas no canal do YouTube.",
        "responses": {
          "200": {
            "description": "Lista de eventos retornada com sucesso.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Event"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Numero maximo de itens por pagina para paginacao",
            "schema": {
              "type": "integer",
              "default": 20
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Deslocamento de registros para paginacao baseada em offset",
            "schema": {
              "type": "integer",
              "default": 0
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Cursor sequencial para paginacao baseada em cursor",
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/api/sandbox": {
      "get": {
        "operationId": "getSandboxEnvironment",
        "summary": "Obter informacoes do ambiente sandbox",
        "description": "Fornece um ambiente seguro e controlado para que agentes de IA exercitem integracoes, realizem testes de schemas e validem chamadas sem alterar dados reais.",
        "responses": {
          "200": {
            "description": "Status e instrucoes do ambiente de testes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "sandbox": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string",
                      "example": "Ambiente sandbox ativo para testes de agentes."
                    },
                    "availableEndpoints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/ApiVersion"
          }
        ]
      },
      "post": {
        "operationId": "executeSandboxMutation",
        "summary": "Executar operacao de teste no ambiente sandbox",
        "description": "Executa mutacao idempotente no ambiente sandbox para simulacao de agentes.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/ApiVersion"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "action": {
                    "type": "string",
                    "example": "simulate_booking"
                  },
                  "payload": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Mutacao simulada com sucesso.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "success"
                    },
                    "idempotent": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string",
                      "example": "Operacao de sandbox executada com sucesso."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/ask": {
      "post": {
        "operationId": "askQuestionNLWeb",
        "summary": "Responder pergunta em linguagem natural (Protocolo NLWeb v0.55)",
        "description": "Recebe uma pergunta em linguagem natural sobre o GEAEF e retorna respostas diretas e fundamentadas em informacoes institucionais, suportando streaming SSE.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "query"
                ],
                "properties": {
                  "query": {
                    "type": "object",
                    "required": [
                      "text"
                    ],
                    "properties": {
                      "text": {
                        "type": "string",
                        "description": "Pergunta em linguagem natural"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resposta formulada com sucesso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NLWebResponse"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/ApiVersion"
          }
        ]
      }
    },
    "/v1/jobs": {
      "post": {
        "operationId": "v1_createAsyncJob",
        "summary": "Iniciar processamento assincrono (Async-job pattern)",
        "description": "Inicia uma tarefa assincrona retornando status 202 com cabecalho Location para acompanhamento.",
        "responses": {
          "202": {
            "description": "Trabalho aceito para processamento.",
            "headers": {
              "Location": {
                "description": "URL para verificar status do trabalho",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobStatus"
                }
              }
            }
          }
        }
      }
    },
    "/v1/jobs/{id}": {
      "get": {
        "operationId": "v1_getAsyncJobStatus",
        "summary": "Consultar status de trabalho assincrono",
        "description": "Retorna o progresso e resultado de uma operacao assincrona.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Identificador do trabalho assincrono",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Status do trabalho recuperado com sucesso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobStatus"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/jobs": {
      "post": {
        "operationId": "api_v1_createAsyncJob",
        "summary": "Iniciar processamento assincrono (Async-job pattern)",
        "description": "Inicia uma tarefa assincrona retornando status 202 com cabecalho Location para acompanhamento.",
        "responses": {
          "202": {
            "description": "Trabalho aceito para processamento.",
            "headers": {
              "Location": {
                "description": "URL para verificar status do trabalho",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobStatus"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/jobs/{id}": {
      "get": {
        "operationId": "api_v1_getAsyncJobStatus",
        "summary": "Consultar status de trabalho assincrono",
        "description": "Retorna o progresso e resultado de uma operacao assincrona.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Identificador do trabalho assincrono",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Status do trabalho recuperado com sucesso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobStatus"
                }
              }
            }
          }
        }
      }
    },
    "/v1/batch": {
      "post": {
        "summary": "Executar operacoes em lote (Batch/bulk endpoint)",
        "description": "Executa multiplas operacoes de leitura ou mutacao em uma unica requisicao HTTP.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Lote processado com sucesso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchResponse"
                }
              }
            }
          }
        },
        "operationId": "v1_executeBatch"
      }
    },
    "/api/v1/batch": {
      "post": {
        "summary": "Executar operacoes em lote (Batch/bulk endpoint)",
        "description": "Executa multiplas operacoes de leitura ou mutacao em uma unica requisicao HTTP.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Lote processado com sucesso.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchResponse"
                }
              }
            }
          }
        },
        "operationId": "api_v1_executeBatch"
      }
    }
  },
  "components": {
    "schemas": {
      "Activity": {
        "type": "object",
        "required": [
          "id",
          "name",
          "category",
          "schedule"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "esde-segunda"
          },
          "name": {
            "type": "string",
            "example": "Estudo Sistematizado da Doutrina Espirita (ESDE)"
          },
          "category": {
            "type": "string",
            "example": "estudo"
          },
          "schedule": {
            "type": "string",
            "example": "Segundas-feiras, as 20h00"
          },
          "location": {
            "type": "string",
            "example": "Sala 3 - Sede do GEAEF"
          },
          "audience": {
            "type": "string",
            "example": "Publico em geral"
          },
          "observations": {
            "type": "string",
            "example": "Inscricoes abertas no inicio de cada semestre."
          },
          "url": {
            "type": "string",
            "example": "https://geaef.org.br/estudos-doutrinarios"
          }
        }
      },
      "InstitutionInfo": {
        "type": "object",
        "required": [
          "name",
          "address",
          "phone",
          "email",
          "cnpj"
        ],
        "properties": {
          "name": {
            "type": "string",
            "example": "Grupo Educacional e Assistencial Espirita Fraternidade - GEAEF"
          },
          "address": {
            "type": "string",
            "example": "SGAS 910/909 Sul - Asa Sul, Brasilia DF, CEP 70390-100"
          },
          "phone": {
            "type": "string",
            "example": "+55 (61) 99845-6487"
          },
          "email": {
            "type": "string",
            "example": "geaef@geaef.org.br"
          },
          "cnpj": {
            "type": "string",
            "example": "00.640.292/0001-27"
          },
          "website": {
            "type": "string",
            "example": "https://geaef.org.br"
          },
          "donation": {
            "type": "object",
            "properties": {
              "pixKey": {
                "type": "string",
                "example": "00.640.292/0001-27"
              },
              "bank": {
                "type": "string",
                "example": "Banco do Brasil"
              },
              "materialDonations": {
                "type": "string",
                "example": "Doações de roupas e bens antigos em bom estado aceitas presencialmente durante o horário de funcionamento."
              }
            }
          },
          "casasLares": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "example": "Casas Lares Humberto de Campos (CLHC)"
              },
              "description": {
                "type": "string",
                "example": "Projeto social do GEAEF de contraturno escolar para crianças em vulnerabilidade social."
              }
            }
          },
          "operatingHours": {
            "type": "object",
            "description": "Horários de funcionamento do GEAEF para atendimento e recebimento de doações materiais."
          }
        }
      },
      "StudyGroup": {
        "type": "object",
        "required": [
          "acronym",
          "name",
          "books"
        ],
        "properties": {
          "acronym": {
            "type": "string",
            "example": "ESDE"
          },
          "name": {
            "type": "string",
            "example": "Estudo Sistematizado da Doutrina Espirita"
          },
          "books": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "O Livro dos Espiritos",
              "O Evangelho segundo o Espiritismo"
            ]
          },
          "schedule": {
            "type": "string",
            "example": "Sabados, 15h30"
          }
        }
      },
      "Event": {
        "type": "object",
        "required": [
          "title",
          "date"
        ],
        "properties": {
          "title": {
            "type": "string",
            "example": "O Acolhimento na Casa Espirita"
          },
          "date": {
            "type": "string",
            "example": "2026-10"
          },
          "description": {
            "type": "string",
            "example": "Palestra publica e reflexao sobre o acolhimento fraterno."
          },
          "youtubeUrl": {
            "type": "string",
            "example": "https://youtube.com/@geaef"
          }
        }
      },
      "NLWebResponse": {
        "type": "object",
        "required": [
          "_meta",
          "results"
        ],
        "properties": {
          "_meta": {
            "type": "object",
            "properties": {
              "response_type": {
                "type": "string",
                "example": "answer"
              },
              "version": {
                "type": "string",
                "example": "0.55"
              }
            }
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "title": {
                  "type": "string"
                },
                "text": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "example": "INVALID_QUERY_PARAMETER"
              },
              "message": {
                "type": "string",
                "example": "A categoria informada nao foi reconhecida."
              },
              "resolution": {
                "type": "string",
                "example": "Consulte as categorias validas em /api/activities."
              }
            }
          }
        }
      },
      "Pagination": {
        "type": "object",
        "description": "Metadados de paginacao da resposta baseada em cursor e offset",
        "properties": {
          "total": {
            "type": "integer",
            "description": "Total de itens disponiveis"
          },
          "limit": {
            "type": "integer",
            "description": "Limite de itens por pagina"
          },
          "offset": {
            "type": "integer",
            "description": "Deslocamento atual de registros"
          },
          "cursor": {
            "type": "string",
            "description": "Cursor atual para paginacao sequencial"
          },
          "next_cursor": {
            "type": "string",
            "nullable": true,
            "description": "Cursor da proxima pagina"
          },
          "has_more": {
            "type": "boolean",
            "description": "Indica se existem mais registros"
          }
        }
      },
      "JobStatus": {
        "type": "object",
        "description": "Status de execucao de um trabalho assincrono (Async-job pattern)",
        "properties": {
          "id": {
            "type": "string",
            "description": "Identificador unico do trabalho"
          },
          "job_id": {
            "type": "string",
            "description": "Identificador do trabalho"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "completed",
              "failed"
            ],
            "description": "Estado atual do trabalho"
          },
          "progress": {
            "type": "integer",
            "description": "Progresso percentual (0 a 100)"
          },
          "poll_url": {
            "type": "string",
            "description": "URL para polling do status"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "result": {
            "type": "object",
            "description": "Resultado da operacao concluida"
          }
        },
        "required": [
          "id",
          "status",
          "poll_url"
        ]
      },
      "BatchRequest": {
        "type": "object",
        "description": "Requisicao de operacoes em lote (Batch/bulk endpoint)",
        "properties": {
          "operations": {
            "type": "array",
            "description": "Lista de operacoes a executar em lote",
            "items": {
              "type": "object",
              "properties": {
                "method": {
                  "type": "string",
                  "enum": [
                    "GET",
                    "POST"
                  ],
                  "description": "Metodo HTTP da operacao"
                },
                "path": {
                  "type": "string",
                  "description": "Caminho do endpoint"
                },
                "body": {
                  "type": "object",
                  "description": "Corpo da requisicao quando aplicavel"
                }
              },
              "required": [
                "method",
                "path"
              ]
            }
          }
        },
        "required": [
          "operations"
        ]
      },
      "BatchResponse": {
        "type": "object",
        "description": "Resposta de execucao em lote",
        "properties": {
          "status": {
            "type": "string",
            "example": "success"
          },
          "totalOperations": {
            "type": "integer"
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "index": {
                  "type": "integer"
                },
                "status": {
                  "type": "integer"
                },
                "success": {
                  "type": "boolean"
                },
                "result": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "description": "Chave de idempotencia para prevenir operacoes duplicadas em retentativas de rede (UUID v4 recomendado).",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "ApiVersion": {
        "name": "X-API-Version",
        "in": "header",
        "required": false,
        "description": "Versao da API solicitada (padrao: 1.0.0).",
        "schema": {
          "type": "string",
          "default": "1.0.0"
        }
      }
    }
  }
}