{
  "openapi": "3.0.3",
  "info": {
    "title": "SSTSegura API",
    "description": "API REST pública da plataforma SSTSegura. Permite leitura e escrita de recursos SST (workers, GHE, PCMSO, ASO, eSocial) e validação pública de documentos via QR.\n\n**Autenticação:** Bearer token (JWT) emitido pelo Supabase Auth. Para integrações server-to-server, use uma chave de serviço escopada gerada em /configuracoes/api-keys.\n\n**Rate limit:** 600 req/min por token. Headers `X-RateLimit-Limit`, `X-RateLimit-Remaining` retornados em cada resposta.\n\n**Tenant isolation:** todas as queries são filtradas por company_id derivado do JWT — não é possível acessar dados de outra empresa.\n\nDocumentação detalhada por recurso em https://sstsegura.com.br/api-docs.\n",
    "version": "1.0.0",
    "contact": {
      "name": "Suporte SSTSegura",
      "email": "contato@sstsegura.com.br",
      "url": "https://sstsegura.com.br"
    },
    "license": {
      "name": "Proprietária — uso conforme contrato",
      "url": "https://sstsegura.com.br/termos"
    }
  },
  "servers": [
    {
      "url": "https://zjoamffclopvsswqofjr.supabase.co/rest/v1",
      "description": "Produção (PostgREST)"
    },
    {
      "url": "https://zjoamffclopvsswqofjr.supabase.co/functions/v1",
      "description": "Produção (Edge Functions)"
    }
  ],
  "tags": [
    { "name": "Workers", "description": "Cadastro de trabalhadores, vínculos, cargos, CBO." },
    { "name": "GHE", "description": "Grupo Homogêneo de Exposição — postos de trabalho e agentes." },
    { "name": "PGR", "description": "Programa de Gerenciamento de Riscos (NR-01)." },
    { "name": "PCMSO", "description": "Programa de Controle Médico de Saúde Ocupacional (NR-07) e ASOs." },
    { "name": "eSocial", "description": "Eventos eSocial SST (S-2210, S-2220, S-2240)." },
    { "name": "PPP", "description": "Perfil Profissiográfico Previdenciário." },
    { "name": "LTCAT", "description": "Laudo Técnico das Condições Ambientais do Trabalho." },
    { "name": "Pública", "description": "Endpoints sem autenticação para validação de documentos." }
  ],
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Token JWT do Supabase Auth (header `Authorization: Bearer <token>`). Expira em 1h. Use refresh token para renovar."
      },
      "ApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "apikey",
        "description": "Chave anônima do projeto Supabase. Obrigatória em conjunto com Authorization."
      }
    },
    "schemas": {
      "Worker": {
        "type": "object",
        "required": ["name", "cpf"],
        "properties": {
          "id":             { "type": "string", "format": "uuid", "readOnly": true },
          "company_id":     { "type": "string", "format": "uuid", "description": "Derivado do JWT, não setar manualmente." },
          "name":           { "type": "string", "example": "João da Silva" },
          "cpf":            { "type": "string", "example": "12345678900", "description": "CPF apenas dígitos." },
          "matricula":      { "type": "string", "nullable": true },
          "cargo":          { "type": "string", "nullable": true, "example": "Operador de máquinas" },
          "cbo":            { "type": "string", "nullable": true, "example": "7826-10", "description": "Classificação Brasileira de Ocupações (7 dígitos)." },
          "filial":         { "type": "string", "nullable": true },
          "admission_date": { "type": "string", "format": "date", "example": "2024-03-15" },
          "active":         { "type": "boolean", "default": true },
          "created_at":     { "type": "string", "format": "date-time", "readOnly": true }
        }
      },
      "GHE": {
        "type": "object",
        "required": ["name"],
        "properties": {
          "id":          { "type": "string", "format": "uuid", "readOnly": true },
          "company_id":  { "type": "string", "format": "uuid", "readOnly": true },
          "name":        { "type": "string", "example": "Galpão de Embalagem A" },
          "setor":       { "type": "string", "nullable": true },
          "funcao":      { "type": "string", "nullable": true },
          "descricao":   { "type": "string", "nullable": true }
        }
      },
      "RiskPGR": {
        "type": "object",
        "required": ["category", "name", "intensity"],
        "properties": {
          "id":            { "type": "string", "format": "uuid", "readOnly": true },
          "ghe_id":        { "type": "string", "format": "uuid", "nullable": true },
          "category":      { "type": "string", "enum": ["fisico", "quimico", "biologico", "ergonomico", "psicossocial"] },
          "name":          { "type": "string", "example": "Ruído contínuo" },
          "intensity":     { "type": "string", "enum": ["baixo", "medio", "alto"] },
          "medicao":       { "type": "number", "nullable": true, "example": 88.5 },
          "unidade":       { "type": "string", "nullable": true, "example": "dB(A)" },
          "limite_tolerancia": { "type": "number", "nullable": true, "example": 85 }
        }
      },
      "EsocialEvent": {
        "type": "object",
        "properties": {
          "id":            { "type": "string", "format": "uuid", "readOnly": true },
          "worker_id":     { "type": "string", "format": "uuid" },
          "event_type":    { "type": "string", "enum": ["S-2210", "S-2220", "S-2240"] },
          "status":        { "type": "string", "enum": ["pendente", "enviado", "processado", "rejeitado", "erro"] },
          "ambiente":      { "type": "string", "enum": ["producao", "homologacao"] },
          "xml_payload":   { "type": "string", "description": "XML do evento, gerado conforme leiaute eSocial vigente." },
          "protocolo":     { "type": "string", "nullable": true, "description": "Protocolo retornado pelo governo." },
          "data_envio":    { "type": "string", "format": "date-time", "nullable": true }
        }
      },
      "PPPRecord": {
        "type": "object",
        "properties": {
          "id":                 { "type": "string", "format": "uuid", "readOnly": true },
          "worker_id":          { "type": "string", "format": "uuid" },
          "status":             { "type": "string", "enum": ["rascunho", "emitido", "cancelado"] },
          "agentes_nocivos":    { "type": "array", "items": { "type": "object" }, "description": "Estrutura JSON dos agentes nocivos com período, EPC e EPI." },
          "medico_responsavel_nome": { "type": "string", "nullable": true },
          "medico_responsavel_crm":  { "type": "string", "nullable": true }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error":   { "type": "string", "example": "permission denied for table workers" },
          "code":    { "type": "string", "nullable": true },
          "details": { "type": "string", "nullable": true }
        }
      }
    },
    "parameters": {
      "PreferRepresentation": {
        "name": "Prefer",
        "in": "header",
        "schema": { "type": "string", "default": "return=representation" },
        "description": "Use 'return=representation' para receber o registro completo na resposta de POST/PATCH."
      },
      "SelectColumns": {
        "name": "select",
        "in": "query",
        "schema": { "type": "string" },
        "example": "id,name,cpf,cargo",
        "description": "Lista de colunas a retornar, separadas por vírgula."
      }
    }
  },
  "security": [
    { "BearerAuth": [], "ApiKey": [] }
  ],
  "paths": {
    "/workers": {
      "get": {
        "tags": ["Workers"],
        "summary": "Listar trabalhadores",
        "description": "Retorna trabalhadores da empresa do JWT. Suporta filtros via query string padrão PostgREST (eq., gt., like.). Ex: `?cargo=eq.Operador`.",
        "parameters": [
          { "$ref": "#/components/parameters/SelectColumns" }
        ],
        "responses": {
          "200": {
            "description": "Lista de trabalhadores",
            "content": {
              "application/json": {
                "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Worker" } }
              }
            }
          },
          "401": { "description": "Token inválido ou expirado", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      },
      "post": {
        "tags": ["Workers"],
        "summary": "Criar trabalhador",
        "parameters": [
          { "$ref": "#/components/parameters/PreferRepresentation" }
        ],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Worker" } } }
        },
        "responses": {
          "201": { "description": "Trabalhador criado", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Worker" } } } },
          "409": { "description": "CPF já cadastrado para a empresa", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/ghe": {
      "get": {
        "tags": ["GHE"],
        "summary": "Listar Grupos Homogêneos de Exposição",
        "responses": {
          "200": {
            "description": "Lista de GHEs",
            "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/GHE" } } } }
          }
        }
      }
    },
    "/risks_pgr": {
      "get": {
        "tags": ["PGR"],
        "summary": "Listar riscos do PGR (NR-01)",
        "description": "Inclui riscos psicossociais conforme atualização da NR-01. Filtre por GHE com `?ghe_id=eq.<uuid>` ou por categoria com `?category=eq.psicossocial`.",
        "responses": {
          "200": {
            "description": "Lista de riscos",
            "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/RiskPGR" } } } }
          }
        }
      }
    },
    "/esocial_events": {
      "get": {
        "tags": ["eSocial"],
        "summary": "Listar eventos eSocial SST",
        "description": "Eventos S-2210 (CAT), S-2220 (Monitoramento) e S-2240 (Exposição a riscos). Cada evento inclui o XML gerado e status de envio.",
        "responses": {
          "200": {
            "description": "Lista de eventos",
            "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/EsocialEvent" } } } }
          }
        }
      }
    },
    "/ppp_records": {
      "get": {
        "tags": ["PPP"],
        "summary": "Listar PPPs emitidos",
        "responses": {
          "200": {
            "description": "Lista de PPPs",
            "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PPPRecord" } } } }
          }
        }
      }
    },
    "/proposal-action": {
      "get": {
        "tags": ["Pública"],
        "summary": "Consultar proposta comercial pelo token",
        "description": "Endpoint público (sem autenticação) usado pela página /proposta/:token. Marca proposta como 'visualizada' na primeira leitura.",
        "security": [],
        "parameters": [
          { "name": "token", "in": "query", "required": true, "schema": { "type": "string", "minLength": 16 } }
        ],
        "responses": {
          "200": { "description": "Dados da proposta" },
          "404": { "description": "Proposta não encontrada" },
          "410": { "description": "Link de versão antiga ou proposta expirada/cancelada" }
        }
      }
    },
    "/v/aso/{hash}": {
      "get": {
        "tags": ["Pública"],
        "summary": "Validar ASO publicamente via hash",
        "description": "Endpoint público para auditores e fiscalização verificarem autenticidade de um ASO emitido. Retorna metadados (CRM do médico, validade, hash) sem expor PII completa.",
        "security": [],
        "parameters": [
          { "name": "hash", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "ASO válido com metadados públicos" },
          "404": { "description": "ASO não encontrado ou hash inválido" }
        }
      }
    }
  }
}
