{"openapi":"3.0.3","info":{"title":"Jornada Control API \u2014 REP-P","description":"API RESTful do sistema de Registro Eletr\u00f4nico de Ponto por Programa (REP-P), conforme Portaria MTP n\u00b0 671\/2021. Suporta m\u00faltiplos ciclos de assinatura, carimbo de tempo ICP-Brasil (Serpro), reconhecimento facial, conformidade LGPD e relat\u00f3rios de auditoria completos.\n\n## Autentica\u00e7\u00e3o\nUtilize **Bearer JWT** no header `Authorization: Bearer <token>`. Obtenha o token via `POST \/api\/auth\/login`.\n\n## N\u00edveis de acesso\n- **employee** (roleLevel 0): registros pr\u00f3prios, assinatura, perfil, LGPD\n- **manager** (roleLevel 50): acesso de leitura a registros de equipe, dashboard\n- **admin** (roleLevel 100): acesso total exceto opera\u00e7\u00f5es de sistema\n- **system_owner**: acesso irrestrito (Wtime)\n\n## Erros padronizados\nTodas as respostas de erro retornam `{ message, error }` onde `error` \u00e9 um c\u00f3digo de m\u00e1quina.","version":"2.2.0","contact":{"name":"Jornada Control","email":"suporte@jornadacontrol.com.br"},"license":{"name":"Propriet\u00e1rio","url":"https:\/\/jornadacontrol.com.br\/termos"}},"servers":[{"url":"https:\/\/api.controle.lpatech.com.br\/api"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Token JWT obtido via POST \/api\/auth\/login"}},"schemas":{"Error":{"type":"object","properties":{"message":{"type":"string","example":"Sem permiss\u00e3o para esta a\u00e7\u00e3o."},"error":{"type":"string","example":"forbidden"}}},"Pagination":{"type":"object","properties":{"current_page":{"type":"integer"},"per_page":{"type":"integer"},"total":{"type":"integer"},"last_page":{"type":"integer"}}},"User":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"email":{"type":"string","format":"email"},"cpf":{"type":"string","example":"123.456.789-00"},"role":{"type":"string","enum":["admin","manager","employee"]},"department":{"type":"string","nullable":true},"position":{"type":"string","nullable":true},"status":{"type":"string","enum":["active","inactive"]},"company_id":{"type":"integer"},"is_owner":{"type":"boolean"},"is_system_owner":{"type":"boolean"},"is_contractor":{"type":"boolean","description":"Indica se o funcion\u00e1rio \u00e9 prestador de servi\u00e7os (terceirizado). Prestadores t\u00eam role=employee mas registram atividades em \/contractor-activities.","example":false}}},"Record":{"type":"object","properties":{"id":{"type":"integer"},"user_id":{"type":"integer"},"date":{"type":"string","format":"date"},"time":{"type":"string","example":"08:00:00"},"type":{"type":"string","enum":["entry","lunch_out","lunch_in","exit"]},"nsr":{"type":"integer","description":"N\u00famero Sequencial de Registro"},"processing_status":{"type":"string","enum":["pending","approved","rejected"]},"is_manual":{"type":"boolean"},"is_manual_adjustment":{"type":"boolean"},"facial_validated":{"type":"boolean"},"location_validated":{"type":"boolean"},"receipt_hash":{"type":"string","nullable":true},"timestamp_serial":{"type":"string","nullable":true,"description":"Serial do carimbo Serpro ICP-Brasil"},"latitude":{"type":"number","format":"float","nullable":true},"longitude":{"type":"number","format":"float","nullable":true}}},"TimesheetSignature":{"type":"object","properties":{"id":{"type":"integer"},"user_id":{"type":"integer"},"cycle_id":{"type":"integer","nullable":true},"cycle_name":{"type":"string","nullable":true},"cycle_type":{"type":"string","nullable":true},"month":{"type":"integer"},"year":{"type":"integer"},"status":{"type":"string","enum":["pending","signed","refused","expired"]},"ref_start":{"type":"string","format":"date"},"ref_end":{"type":"string","format":"date"},"available_from":{"type":"string","format":"date-time","nullable":true},"deadline":{"type":"string","format":"date-time","nullable":true,"description":"null = sem prazo definido (nunca expira)"},"signed_at":{"type":"string","format":"date-time","nullable":true},"signed_ip":{"type":"string","nullable":true},"signed_phone":{"type":"string","nullable":true,"description":"Celular que recebeu o SMS (armazenado para trilha de auditoria)"},"document_hash":{"type":"string","nullable":true,"description":"SHA-256 do espelho + celular"},"serpro_serial":{"type":"string","nullable":true}}},"SignatureCycle":{"type":"object","properties":{"id":{"type":"integer"},"company_id":{"type":"integer","nullable":true},"name":{"type":"string"},"description":{"type":"string","nullable":true},"cycle_type":{"type":"string","enum":["monthly","weekly","biweekly","daily"]},"rule_filter":{"type":"string","enum":["all","journey_rule"]},"journey_rule_ids":{"type":"array","items":{"type":"integer"},"nullable":true},"deadline_days":{"type":"integer","nullable":true,"description":"0 ou null = sem prazo"},"status":{"type":"string","enum":["active","inactive"]},"period_start_day":{"type":"integer","nullable":true},"period_end_day":{"type":"integer","nullable":true},"available_from_day":{"type":"integer","nullable":true},"available_from_hour":{"type":"integer","nullable":true},"period_length_days":{"type":"integer","nullable":true},"available_after_period_end_hours":{"type":"integer","nullable":true}}},"JourneyRule":{"type":"object","properties":{"id":{"type":"integer"},"company_id":{"type":"integer"},"name":{"type":"string"},"is_clt":{"type":"boolean"},"weekdays":{"type":"object","description":"Configura\u00e7\u00e3o por dia da semana (0=dom..6=sab)"},"entry_tolerance":{"type":"integer","description":"Toler\u00e2ncia entrada em minutos"},"exit_tolerance":{"type":"integer","description":"Toler\u00e2ncia sa\u00edda em minutos"},"require_location":{"type":"boolean"},"require_facial_recognition":{"type":"boolean"},"status":{"type":"string","enum":["active","inactive"]}}},"Leave":{"type":"object","properties":{"id":{"type":"integer"},"user_id":{"type":"integer"},"type":{"type":"string","enum":["vacation","sick","personal","other"]},"start_date":{"type":"string","format":"date"},"end_date":{"type":"string","format":"date"},"status":{"type":"string","enum":["pending","approved","rejected","cancelled"]},"reason":{"type":"string","nullable":true}}},"Location":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"address":{"type":"string"},"latitude":{"type":"number"},"longitude":{"type":"number"},"radius":{"type":"integer"},"status":{"type":"string"}}},"Schedule":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"start_date":{"type":"string","format":"date"},"end_date":{"type":"string","format":"date"},"max_employees":{"type":"integer"},"status":{"type":"string"},"journey_rule_id":{"type":"integer"}}},"CompanyDocument":{"type":"object","description":"Lote de documentos enviados pelo admin\/RH para funcion\u00e1rios.","properties":{"id":{"type":"integer"},"company_id":{"type":"integer"},"uploaded_by":{"type":"integer","description":"ID do usu\u00e1rio que fez o upload"},"title":{"type":"string","example":"Contracheques Abril 2026"},"description":{"type":"string","nullable":true},"category":{"type":"string","enum":["holerite","contrato","aviso","atestado","outros"],"nullable":true},"created_at":{"type":"string","format":"date-time"}}},"EmployeeDocument":{"type":"object","description":"Documento individual vinculado a um funcion\u00e1rio espec\u00edfico via CPF no nome do arquivo.","properties":{"id":{"type":"integer"},"company_document_id":{"type":"integer"},"user_id":{"type":"integer"},"original_filename":{"type":"string","example":"holerite_12345678901.pdf"},"file_size":{"type":"integer","description":"Tamanho em bytes"},"mime_type":{"type":"string","example":"application\/pdf"},"acknowledged":{"type":"boolean","description":"Funcion\u00e1rio confirmou leitura"},"acknowledged_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"},"company_document":{"$ref":"#\/components\/schemas\/CompanyDocument","nullable":true}}},"ContractorActivity":{"type":"object","description":"Registro de atividade de prestador de servi\u00e7os (funcion\u00e1rio com is_contractor=true).","properties":{"id":{"type":"integer"},"company_id":{"type":"integer"},"user_id":{"type":"integer","description":"ID do prestador (funcion\u00e1rio com is_contractor=true)"},"client_company_id":{"type":"integer","nullable":true,"description":"Cliente para o qual a atividade foi realizada"},"activity_date":{"type":"string","format":"date","example":"2026-05-07"},"description":{"type":"string","example":"Desenvolvimento de m\u00f3dulo de relat\u00f3rios","maxLength":1000},"hours":{"type":"number","format":"float","example":8,"minimum":0.25,"maximum":24},"status":{"type":"string","enum":["pending","approved","rejected"],"description":"pending = aguardando aprova\u00e7\u00e3o, approved = aprovado, rejected = rejeitado"},"approved_by":{"type":"integer","nullable":true,"description":"ID do admin\/manager que aprovou ou rejeitou"},"approved_at":{"type":"string","format":"date-time","nullable":true},"notes":{"type":"string","nullable":true,"description":"Observa\u00e7\u00f5es do revisor ao rejeitar"},"user":{"$ref":"#\/components\/schemas\/User","nullable":true}}}},"responses":{"Unauthorized":{"description":"Token inv\u00e1lido ou expirado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"},"example":{"message":"Unauthenticated.","error":"unauthenticated"}}}},"Forbidden":{"description":"Sem permiss\u00e3o","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"},"example":{"message":"Sem permiss\u00e3o para esta a\u00e7\u00e3o.","error":"forbidden"}}}},"NotFound":{"description":"Recurso n\u00e3o encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"},"example":{"message":"Recurso n\u00e3o encontrado.","error":"not_found"}}}},"ValidationError":{"description":"Erro de valida\u00e7\u00e3o","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"errors":{"type":"object"}}}}}}}},"tags":[{"name":"Autentica\u00e7\u00e3o","description":"Login, logout, refresh e altera\u00e7\u00e3o de senha"},{"name":"Perfil","description":"Dados do usu\u00e1rio autenticado"},{"name":"Notifica\u00e7\u00f5es","description":"Notifica\u00e7\u00f5es in-app"},{"name":"Registros de Ponto","description":"Registro eletr\u00f4nico de ponto (REP-P) \u2014 entrada, sa\u00edda, almo\u00e7o"},{"name":"Registros Manuais","description":"Solicita\u00e7\u00e3o e aprova\u00e7\u00e3o de registros manuais"},{"name":"Assinatura de Folha","description":"Ciclos e assinaturas digitais de espelho de ponto (ICP-Brasil)"},{"name":"Espelho de Ponto","description":"Visualiza\u00e7\u00e3o do espelho de ponto mensal"},{"name":"Funcion\u00e1rios","description":"Gest\u00e3o de funcion\u00e1rios (admin\/manager)"},{"name":"Dashboard","description":"Indicadores do dia e alertas (admin\/manager)"},{"name":"KPIs","description":"Indicadores de desempenho operacional"},{"name":"Relat\u00f3rios","description":"Relat\u00f3rios de pontualidade, horas extras e presen\u00e7a"},{"name":"Regras de Jornada","description":"Configura\u00e7\u00e3o de jornadas CLT\/flex\u00edveis (admin)"},{"name":"Feriados","description":"Calend\u00e1rio de feriados da empresa"},{"name":"Escalas","description":"Escalas de trabalho"},{"name":"F\u00e9rias e Licen\u00e7as","description":"Gest\u00e3o de f\u00e9rias, licen\u00e7as e afastamentos"},{"name":"Justificativas","description":"Justificativas de aus\u00eancia"},{"name":"Conformidade REP-P","description":"Exporta\u00e7\u00e3o AFD\/AEP, comprovantes e trilha de auditoria (Portaria 671)"},{"name":"LGPD","description":"Consentimentos e portabilidade de dados (Lei 13.709\/2018)"},{"name":"Configura\u00e7\u00f5es","description":"Configura\u00e7\u00f5es da empresa e notifica\u00e7\u00f5es"},{"name":"Integra\u00e7\u00f5es","description":"eSocial, folha de pagamento e ERP"},{"name":"Webhooks","description":"Webhooks para integra\u00e7\u00e3o com sistemas externos"},{"name":"Cargos e Permiss\u00f5es","description":"Gest\u00e3o de cargos com permiss\u00f5es granulares"},{"name":"Tokens API","description":"Tokens de acesso para integra\u00e7\u00f5es"},{"name":"Check-in Compartilhado","description":"Modo tablet\/quiosque com reconhecimento facial"},{"name":"Locais de Trabalho"},{"name":"V\u00ednculos de Cliente","description":"Associa\u00e7\u00e3o entre funcion\u00e1rios e empresas-cliente da Wtime. Permite filtrar espelho de ponto e relat\u00f3rios por cliente."},{"name":"Documentos","description":"Envio em lote de documentos para funcion\u00e1rios (holerites, contratos, avisos). Cada arquivo \u00e9 vinculado ao funcion\u00e1rio pelo CPF contido no nome do arquivo."},{"name":"Prestadores","description":"Registro e aprova\u00e7\u00e3o de atividades de prestadores de servi\u00e7os. Prestadores s\u00e3o funcion\u00e1rios com is_contractor=true e registram horas via este m\u00f3dulo."},{"name":"Empresas Clientes","description":"CRUD de empresas clientes vinculadas \u00e0 empresa (admin\/manager). Suporta importa\u00e7\u00e3o em lote via planilha."},{"name":"Registros Pendentes","description":"Listagem e corre\u00e7\u00e3o de dias \u00fateis sem registro de entrada\/sa\u00edda. Inclui preenchimento autom\u00e1tico individual, em lote e baseado na regra de jornada."},{"name":"Convites de Funcion\u00e1rios","description":"Fluxo de auto-cadastro: admin\/manager gera link \u2192 colaborador preenche dados \u2192 gestor aprova e conta \u00e9 criada."},{"name":"Treinamento","description":"Controle de progresso de treinamento in-app por m\u00f3dulo (chave textual). M\u00f3dulos gerenciados pelo front-end."},{"name":"Deploy","description":"Endpoints internos para CI\/CD. Protegidos por Bearer token est\u00e1tico (DEPLOY_TOKEN), independente de JWT de usu\u00e1rio."},{"name":"Painel do Sistema","description":"Monitoramento de recursos e gestao de filas. Acesso exclusivo do dono do sistema (is_system_owner=true)."}],"paths":{"\/absences":{"get":{"tags":["Justificativas"],"summary":"Todas as justificativas (admin\/manager)","responses":{"200":{"description":"Lista de justificativas"}}},"post":{"tags":["Justificativas"],"summary":"Enviar justificativa","requestBody":{"required":true,"content":{"multipart\/form-data":{"schema":{"type":"object","required":["date","reason"],"properties":{"date":{"type":"string","format":"date"},"reason":{"type":"string"},"attachment":{"type":"string","format":"binary"}}}}}},"responses":{"201":{"description":"Justificativa enviada"}}}},"\/absences\/absent-days":{"get":{"tags":["Justificativas"],"summary":"Datas com aus\u00eancias justificadas","description":"Retorna lista de datas em que h\u00e1 justificativas de aus\u00eancia para o usu\u00e1rio\/funcion\u00e1rio indicado.","parameters":[{"name":"month","in":"query","schema":{"type":"integer","minimum":1,"maximum":12}},{"name":"year","in":"query","schema":{"type":"integer"}},{"name":"employee_id","in":"query","schema":{"type":"integer"},"description":"Admin\/manager pode consultar outro funcion\u00e1rio"}],"responses":{"200":{"description":"Datas com aus\u00eancias","content":{"application\/json":{"schema":{"type":"object","properties":{"absent_days":{"type":"array","items":{"type":"string","format":"date"}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"}}}},"\/absences\/my":{"get":{"tags":["Justificativas"],"summary":"Minhas justificativas","responses":{"200":{"description":"Justificativas do usu\u00e1rio"}}}},"\/absences\/{id}":{"get":{"tags":["Justificativas"],"summary":"Ver justificativa","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Detalhes da justificativa"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}},"delete":{"tags":["Justificativas"],"summary":"Excluir justificativa (admin\/manager)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Justificativa exclu\u00edda"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/absences\/{id}\/approve":{"post":{"tags":["Justificativas"],"summary":"Aprovar justificativa (admin\/manager)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Aprovada"}}}},"\/absences\/{id}\/attachment":{"get":{"tags":["Justificativas"],"summary":"Download do anexo de uma justificativa","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da justificativa"}],"responses":{"200":{"description":"Arquivo (PDF, imagem, etc.) retornado como download"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/absences\/{id}\/reject":{"post":{"tags":["Justificativas"],"summary":"Rejeitar justificativa (admin\/manager)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Rejeitada"}}}},"\/activity-logs":{"get":{"tags":["Configura\u00e7\u00f5es"],"summary":"Logs de atividade","description":"Lista logs de atividade da empresa com antes\/depois de cada altera\u00e7\u00e3o. Para a\u00e7\u00f5es `created:*`, `updated:*` e `deleted:*` (geradas pelo sistema de auditoria), o campo `properties` cont\u00e9m `before` (valores anteriores), `after` (novos valores) e `changed_fields` (lista de campos alterados). Funcion\u00e1rios v\u00eaem apenas os pr\u00f3prios logs. Admin v\u00ea tudo.","parameters":[{"name":"date_from","in":"query","schema":{"type":"string","format":"date"}},{"name":"date_to","in":"query","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Lista de logs"}}}},"\/activity-logs\/summary":{"get":{"tags":["Conformidade REP-P"],"summary":"Resumo de logs de atividade","description":"Agrega logs por a\u00e7\u00e3o e logins por dia nos \u00faltimos N dias.","parameters":[{"name":"days","in":"query","schema":{"type":"integer","default":7},"description":"Per\u00edodo em dias"}],"responses":{"200":{"description":"Resumo de atividade","content":{"application\/json":{"schema":{"type":"object","properties":{"actions_summary":{"type":"object"},"logins_by_day":{"type":"object"},"period_days":{"type":"integer"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/auth\/change-password":{"put":{"tags":["Autentica\u00e7\u00e3o"],"summary":"Alterar senha","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["current_password","password","password_confirmation"],"properties":{"current_password":{"type":"string"},"password":{"type":"string"},"password_confirmation":{"type":"string"}}}}}},"responses":{"200":{"description":"Senha alterada"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/auth\/forgot-password":{"post":{"tags":["Autentica\u00e7\u00e3o"],"summary":"Solicitar redefini\u00e7\u00e3o de senha","security":[],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"}}}}}},"responses":{"200":{"description":"E-mail enviado"}}}},"\/auth\/login":{"post":{"tags":["Autentica\u00e7\u00e3o"],"summary":"Login","description":"Autentica usu\u00e1rio e retorna token JWT. Aceita e-mail ou CPF.","security":[],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","description":"E-mail ou CPF (apenas d\u00edgitos)","example":"joao@empresa.com"},"password":{"type":"string","format":"password","example":"senha123"}}}}}},"responses":{"200":{"description":"Login bem-sucedido","content":{"application\/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string"},"token_type":{"type":"string","example":"bearer"},"expires_in":{"type":"integer","example":3600},"user":{"$ref":"#\/components\/schemas\/User"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"}}}},"\/auth\/logout":{"post":{"tags":["Autentica\u00e7\u00e3o"],"summary":"Logout","description":"Invalida o token atual.","responses":{"200":{"description":"Logout realizado","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string","example":"Logout realizado com sucesso."}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"}}}},"\/auth\/me":{"get":{"tags":["Autentica\u00e7\u00e3o"],"summary":"Dados do usu\u00e1rio autenticado","responses":{"200":{"description":"Dados do usu\u00e1rio","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/User"}}}}}}},"\/auth\/otp\/request":{"post":{"tags":["Autentica\u00e7\u00e3o"],"summary":"Solicitar c\u00f3digo OTP por e-mail","description":"Envia um c\u00f3digo de 6 d\u00edgitos para o e-mail informado. V\u00e1lido por 24 horas. Throttle: 5 req\/min.","security":[],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email","example":"usuario@empresa.com"}}}}}},"responses":{"200":{"description":"C\u00f3digo enviado (resposta id\u00eantica mesmo se e-mail n\u00e3o existir)"}}}},"\/auth\/otp\/verify":{"post":{"tags":["Autentica\u00e7\u00e3o"],"summary":"Verificar c\u00f3digo OTP e obter JWT","description":"Valida o c\u00f3digo recebido por e-mail e retorna um token JWT para autentica\u00e7\u00e3o.","security":[],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["email","code"],"properties":{"email":{"type":"string","format":"email"},"code":{"type":"string","example":"123456","description":"C\u00f3digo de 6 d\u00edgitos recebido por e-mail"}}}}}},"responses":{"200":{"description":"Login realizado \u2014 retorna access_token e dados do usu\u00e1rio","content":{"application\/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string"},"token_type":{"type":"string","example":"bearer"},"expires_in":{"type":"integer"},"user":{"$ref":"#\/components\/schemas\/User"}}}}}},"422":{"description":"C\u00f3digo inv\u00e1lido ou expirado","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"error":{"type":"string","enum":["invalid_otp","otp_expired"]}}}}}}}}},"\/auth\/refresh":{"post":{"tags":["Autentica\u00e7\u00e3o"],"summary":"Refresh do token","description":"Gera um novo token JWT a partir do token atual.","responses":{"200":{"description":"Novo token gerado","content":{"application\/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string"},"token_type":{"type":"string"},"expires_in":{"type":"integer"}}}}}}}}},"\/auth\/reset-password":{"post":{"tags":["Autentica\u00e7\u00e3o"],"summary":"Redefinir senha","security":[],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["email","token","password","password_confirmation"],"properties":{"email":{"type":"string","format":"email"},"token":{"type":"string"},"password":{"type":"string","format":"password"},"password_confirmation":{"type":"string","format":"password"}}}}}},"responses":{"200":{"description":"Senha alterada com sucesso"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/chat":{"post":{"tags":["Chat de Suporte"],"summary":"Enviar mensagem (primeira cria conversa automaticamente)","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":"message, topic_id (opcional), employee_id (opcional)"}}}},"responses":{"201":{"description":"Mensagem enviada + conversation_token","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/chat-conversations":{"get":{"tags":["Chat de Suporte"],"summary":"Listar conversas da empresa por status (requer settings:write)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Lista de conversas","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/chat-conversations\/{id}":{"get":{"tags":["Chat de Suporte"],"summary":"Detalhe da conversa com mensagens","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/chat-conversations\/{id}\/close":{"post":{"tags":["Chat de Suporte"],"summary":"Admin encerra conversa (envia transcript)","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/chat-conversations\/{id}\/reply":{"post":{"tags":["Chat de Suporte"],"summary":"Agente responde a conversa (broadcast via Pusher)","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":"message"}}}},"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/chat-settings":{"get":{"tags":["Chat de Suporte"],"summary":"Configuracoes de chat da empresa (email padrao, ativo)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"put":{"tags":["Chat de Suporte"],"summary":"Atualizar configuracoes de chat","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":"default_email, is_active"}}}},"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/chat-settings\/topics":{"post":{"tags":["Chat de Suporte"],"summary":"Criar topico de chat","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":"name, email"}}}},"responses":{"201":{"description":"Criado","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/chat-settings\/topics\/{id}":{"put":{"tags":["Chat de Suporte"],"summary":"Atualizar topico","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":""}}}},"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"delete":{"tags":["Chat de Suporte"],"summary":"Remover topico","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/chat\/topics":{"get":{"tags":["Chat de Suporte"],"summary":"Listar topicos de chat da empresa (usuario autenticado)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Lista de topicos","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/chat\/{token}":{"get":{"tags":["Chat de Suporte"],"summary":"Historico da conversa por token UUID","security":[{"bearerAuth":[]}],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Mensagens da conversa","content":{"application\/json":{"schema":{"type":"object"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/chat\/{token}\/close":{"post":{"tags":["Chat de Suporte"],"summary":"Encerrar conversa (envia transcript por e-mail)","security":[{"bearerAuth":[]}],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Conversa encerrada","content":{"application\/json":{"schema":{"type":"object"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/check-in\/biometric\/begin":{"post":{"tags":["WebAuthn - Biometria Digital"],"summary":"Iniciar check-in biometrico (challenge assertion)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Challenge para navigator.credentials.get()","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/check-in\/biometric\/finish":{"post":{"tags":["WebAuthn - Biometria Digital"],"summary":"Concluir check-in biometrico (assertion + optional face_image)","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":"assertion credential + face_image (opcional para dual-factor)"}}}},"responses":{"200":{"description":"Record criado","content":{"application\/json":{"schema":{"type":"object"}}}},"201":{"description":"Record enfileirado (GPS)","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/check-in\/config":{"get":{"tags":["Check-in Compartilhado"],"summary":"Configura\u00e7\u00e3o do check-in","responses":{"200":{"description":"Configura\u00e7\u00f5es de check-in"}}}},"\/client-companies":{"get":{"tags":["Empresas Clientes"],"summary":"Listar empresas clientes (admin\/manager)","description":"Retorna lista paginada de empresas clientes vinculadas \u00e0 empresa do usu\u00e1rio.","parameters":[{"name":"search","in":"query","schema":{"type":"string"},"description":"Busca por nome, CNPJ, contato ou cidade"},{"name":"status","in":"query","schema":{"type":"string","enum":["active","inactive","all"],"default":"active"}},{"name":"per_page","in":"query","schema":{"type":"integer","default":15}},{"name":"page","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Lista paginada de empresas clientes"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}},"post":{"tags":["Empresas Clientes"],"summary":"Criar empresa cliente (admin\/manager)","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":255},"cnpj":{"type":"string","maxLength":18,"example":"12.345.678\/0001-99"},"email":{"type":"string","format":"email"},"phone":{"type":"string","maxLength":20},"address":{"type":"string"},"city":{"type":"string","maxLength":100},"state":{"type":"string","minLength":2,"maxLength":2,"example":"SP"},"zip_code":{"type":"string","maxLength":10},"latitude":{"type":"number","format":"float"},"longitude":{"type":"number","format":"float"},"contact_name":{"type":"string","maxLength":255},"notes":{"type":"string"},"status":{"type":"string","enum":["active","inactive"]}}}}}},"responses":{"201":{"description":"Empresa cliente criada"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/client-companies\/import":{"post":{"tags":["Empresas Clientes"],"summary":"Importar empresas clientes por planilha (admin\/manager)","requestBody":{"required":true,"content":{"multipart\/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"Planilha XLSX\/XLS\/CSV (m\u00e1x 5MB)"}}}}}},"responses":{"200":{"description":"Resultado da importa\u00e7\u00e3o (created, updated, failed)"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/client-companies\/template":{"get":{"tags":["Empresas Clientes"],"summary":"Baixar template de importa\u00e7\u00e3o (admin\/manager)","description":"Retorna planilha XLSX modelo para importa\u00e7\u00e3o de empresas clientes.","responses":{"200":{"description":"Arquivo XLSX para download","content":{"application\/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"schema":{"type":"string","format":"binary"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/client-companies\/{id}":{"get":{"tags":["Empresas Clientes"],"summary":"Ver empresa cliente (admin\/manager)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Detalhes da empresa cliente"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}},"put":{"tags":["Empresas Clientes"],"summary":"Atualizar empresa cliente (admin\/manager)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application\/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":255},"cnpj":{"type":"string","maxLength":18},"email":{"type":"string","format":"email"},"phone":{"type":"string","maxLength":20},"address":{"type":"string"},"city":{"type":"string","maxLength":100},"state":{"type":"string","minLength":2,"maxLength":2},"zip_code":{"type":"string","maxLength":10},"latitude":{"type":"number","format":"float"},"longitude":{"type":"number","format":"float"},"contact_name":{"type":"string","maxLength":255},"notes":{"type":"string"},"status":{"type":"string","enum":["active","inactive"]}}}}}},"responses":{"200":{"description":"Empresa cliente atualizada"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}},"delete":{"tags":["Empresas Clientes"],"summary":"Excluir empresa cliente (admin\/manager)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Empresa cliente exclu\u00edda"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/collective-agreements":{"get":{"tags":["Convencoes Coletivas"],"summary":"Listar CCTs","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"post":{"tags":["Convencoes Coletivas"],"summary":"Criar CCT","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":"Dados da CCT"}}}},"responses":{"201":{"description":"Criado","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/collective-agreements\/{id}":{"get":{"tags":["Convencoes Coletivas"],"summary":"Detalhe da CCT","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"put":{"tags":["Convencoes Coletivas"],"summary":"Atualizar CCT","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":""}}}},"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"delete":{"tags":["Convencoes Coletivas"],"summary":"Excluir CCT","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/collective-agreements\/{id}\/link-journey\/{journeyId}":{"post":{"tags":["Convencoes Coletivas"],"summary":"Vincular CCT a jornada","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""},{"name":"journeyId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/collective-agreements\/{id}\/unlink-journey\/{journeyId}":{"delete":{"tags":["Convencoes Coletivas"],"summary":"Desvincular CCT da jornada","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""},{"name":"journeyId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/company\/settings":{"get":{"tags":["Configura\u00e7\u00f5es"],"summary":"Configura\u00e7\u00f5es da empresa (admin)","responses":{"200":{"description":"Configura\u00e7\u00f5es atuais"}}},"put":{"tags":["Configura\u00e7\u00f5es"],"summary":"Atualizar configura\u00e7\u00f5es da empresa (admin)","requestBody":{"content":{"application\/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Configura\u00e7\u00f5es atualizadas"}}}},"\/compliance\/aep":{"get":{"tags":["Conformidade REP-P"],"summary":"Exportar AEP (admin)","description":"Gera o Arquivo de Espelho de Ponto (AEP).","parameters":[{"name":"date_from","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"date_to","in":"query","required":true,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Arquivo AEP","content":{"text\/plain":{"schema":{"type":"string"}}}}}}},"\/compliance\/afd":{"get":{"tags":["Conformidade REP-P"],"summary":"Exportar AFD (admin)","description":"Gera o Arquivo de Fonte de Dados (AFD) conforme Portaria 671\/2021.","parameters":[{"name":"date_from","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"date_to","in":"query","required":true,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Arquivo AFD","content":{"text\/plain":{"schema":{"type":"string"}}}}}}},"\/compliance\/audit-trail":{"get":{"tags":["Conformidade REP-P"],"summary":"Trilha de auditoria completa (admin)","description":"Gera HTML imprim\u00edvel com trilha de auditoria completa: registros de ponto (NSR, data\/hora, tipo, biometria, GPS, carimbo Serpro, ajustes), **assinaturas digitais do per\u00edodo** (ciclo, datas, status, celular mascarado LGPD, IP, GPS, hash, Serpro), resumo e nota legal. Carimbo de tempo ICP-Brasil aplicado ao documento inteiro. N\u00famero do celular parcialmente mascarado conforme LGPD (primeiros 2 + \u00faltimos 4 d\u00edgitos vis\u00edveis).","parameters":[{"name":"employee_id","in":"query","required":true,"schema":{"type":"integer"}},{"name":"date_from","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"date_to","in":"query","required":true,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"HTML da trilha de auditoria","content":{"text\/html":{"schema":{"type":"string"}}}},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/compliance\/download":{"get":{"tags":["Conformidade REP-P"],"summary":"Download de exporta\u00e7\u00e3o de conformidade","description":"Faz download de um arquivo de exporta\u00e7\u00e3o (AEP, AFD, etc.) gerado previamente.","parameters":[{"name":"id","in":"query","schema":{"type":"integer"},"description":"ID da exporta\u00e7\u00e3o"}],"responses":{"200":{"description":"Arquivo de exporta\u00e7\u00e3o (octet-stream)"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/compliance\/exports":{"get":{"tags":["Conformidade REP-P"],"summary":"Hist\u00f3rico de exporta\u00e7\u00f5es (admin)","responses":{"200":{"description":"Lista paginada de exporta\u00e7\u00f5es"}}}},"\/compliance\/receipt\/{recordId}":{"get":{"tags":["Conformidade REP-P"],"summary":"Comprovante de registro (HTML)","description":"Retorna HTML com comprovante do registro de ponto com hash SHA-256 e dados Serpro. Funcion\u00e1rio v\u00ea apenas o pr\u00f3prio; admin\/manager v\u00ea todos.","parameters":[{"name":"recordId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"HTML do comprovante","content":{"text\/html":{"schema":{"type":"string"}}}},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/compliance\/receipt\/{recordId}\/zpl":{"get":{"tags":["Conformidade REP-P"],"summary":"Comprovante ZPL para impressora Zebra","parameters":[{"name":"recordId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"ZPL do comprovante","content":{"application\/x-zpl":{"schema":{"type":"string"}}}}}}},"\/contractor-activities":{"get":{"tags":["Prestadores"],"summary":"Listar atividades de prestadores","description":"Prestadores (is_contractor=true) veem somente suas pr\u00f3prias atividades. Admin\/manager veem todas da empresa e podem filtrar por user_id, client_company_id, status e per\u00edodo.","parameters":[{"name":"user_id","in":"query","description":"Filtrar por prestador (admin\/manager)","schema":{"type":"integer"}},{"name":"client_company_id","in":"query","description":"Filtrar por empresa-cliente","schema":{"type":"integer"}},{"name":"status","in":"query","schema":{"type":"string","enum":["pending","approved","rejected"]}},{"name":"date_from","in":"query","schema":{"type":"string","format":"date","example":"2026-05-01"}},{"name":"date_to","in":"query","schema":{"type":"string","format":"date","example":"2026-05-31"}},{"name":"per_page","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Lista paginada de atividades","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/ContractorActivity"}},"current_page":{"type":"integer"},"total":{"type":"integer"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"}}},"post":{"tags":["Prestadores"],"summary":"Registrar atividade de prestador","description":"Prestador registra suas pr\u00f3prias atividades (status=pending). Admin\/manager pode informar user_id para criar no nome do prestador.","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["activity_date","description"],"properties":{"activity_date":{"type":"string","format":"date","example":"2026-05-07"},"description":{"type":"string","example":"Desenvolvimento de m\u00f3dulo de relat\u00f3rios","maxLength":1000},"hours":{"type":"number","format":"float","example":8,"minimum":0.25,"maximum":24,"description":"Horas trabalhadas"},"client_company_id":{"type":"integer","nullable":true,"description":"ID da empresa-cliente atendida"},"user_id":{"type":"integer","nullable":true,"description":"ID do prestador (somente admin\/manager)"}}}}}},"responses":{"201":{"description":"Atividade registrada","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string","example":"Atividade registrada."},"data":{"$ref":"#\/components\/schemas\/ContractorActivity"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/contractor-activities\/export":{"get":{"tags":["Prestadores"],"summary":"Exportar atividades de prestadores (CSV\/XLSX)","description":"Exporta as atividades de prestadores no per\u00edodo em formato CSV ou Excel.","parameters":[{"name":"start_date","in":"query","schema":{"type":"string","format":"date"}},{"name":"end_date","in":"query","schema":{"type":"string","format":"date"}},{"name":"employee_id","in":"query","schema":{"type":"integer"}},{"name":"client_company_id","in":"query","schema":{"type":"integer"}},{"name":"format","in":"query","schema":{"type":"string","enum":["csv","xlsx"],"default":"csv"}}],"responses":{"200":{"description":"Arquivo de exporta\u00e7\u00e3o","content":{"text\/csv":{"schema":{"type":"string"}},"application\/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"schema":{"type":"string","format":"binary"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/contractor-activities\/report":{"get":{"tags":["Prestadores"],"summary":"Relat\u00f3rio resumo de atividades (admin\/manager)","description":"Retorna total de horas agrupado por prestador e lista detalhada de atividades. Filtr\u00e1vel por per\u00edodo, cliente e prestador. Exclui atividades rejeitadas.","parameters":[{"name":"date_from","in":"query","schema":{"type":"string","format":"date","example":"2026-05-01"}},{"name":"date_to","in":"query","schema":{"type":"string","format":"date","example":"2026-05-31"}},{"name":"client_company_id","in":"query","schema":{"type":"integer"}},{"name":"user_id","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Relat\u00f3rio de atividades","content":{"application\/json":{"schema":{"type":"object","properties":{"total_hours":{"type":"number","description":"Total de horas aprovadas\/pendentes no per\u00edodo","example":120.5},"summary":{"type":"array","description":"Resumo agrupado por prestador","items":{"type":"object","properties":{"employee":{"$ref":"#\/components\/schemas\/User"},"total_hours":{"type":"number"},"activity_count":{"type":"integer"},"activities":{"type":"array","items":{"$ref":"#\/components\/schemas\/ContractorActivity"}}}}},"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/ContractorActivity"}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/contractor-activities\/{id}":{"put":{"tags":["Prestadores"],"summary":"Editar atividade de prestador","description":"Prestador pode editar apenas suas pr\u00f3prias atividades com status=pending. Admin\/manager pode editar qualquer atividade da empresa.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application\/json":{"schema":{"type":"object","properties":{"activity_date":{"type":"string","format":"date"},"description":{"type":"string","maxLength":1000},"hours":{"type":"number","format":"float","minimum":0.25,"maximum":24},"client_company_id":{"type":"integer","nullable":true}}}}}},"responses":{"200":{"description":"Atividade atualizada"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}},"delete":{"tags":["Prestadores"],"summary":"Excluir atividade de prestador","description":"Prestador pode excluir apenas suas pr\u00f3prias atividades. Admin\/manager pode excluir qualquer atividade da empresa.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Atividade exclu\u00edda"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}},"get":{"tags":["Prestadores"],"summary":"Buscar atividade por ID","description":"Retorna detalhes de uma atividade de prestador. Admin\/manager acessa qualquer; prestador acessa apenas as pr\u00f3prias.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da atividade."}],"responses":{"200":{"description":"Dados da atividade.","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"integer"},"contractor_id":{"type":"integer"},"client_company_id":{"type":"integer"},"description":{"type":"string"},"date":{"type":"string","format":"date"},"hours":{"type":"number"},"status":{"type":"string","enum":["pending","approved","rejected"]},"notes":{"type":"string","nullable":true},"approved_by":{"type":"integer","nullable":true},"approved_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}}},"403":{"description":"Sem permiss\u00e3o para acessar esta atividade."},"404":{"description":"Atividade n\u00e3o encontrada."}}}},"\/contractor-activities\/{id}\/approve":{"post":{"tags":["Prestadores"],"summary":"Aprovar atividade (admin\/manager)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Atividade aprovada"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/contractor-activities\/{id}\/reject":{"post":{"tags":["Prestadores"],"summary":"Rejeitar atividade com observa\u00e7\u00e3o (admin\/manager)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application\/json":{"schema":{"type":"object","properties":{"notes":{"type":"string","description":"Motivo da rejei\u00e7\u00e3o","example":"Atividade sem evid\u00eancia comprobat\u00f3ria.","maxLength":500}}}}}},"responses":{"200":{"description":"Atividade rejeitada"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/dashboard\/alerts":{"get":{"tags":["Dashboard"],"summary":"Alertas ativos (admin\/manager)","responses":{"200":{"description":"Lista de alertas"}}}},"\/dashboard\/pending-counts":{"get":{"tags":["Dashboard"],"summary":"Contagem de itens pendentes (admin\/manager)","responses":{"200":{"description":"Contagens por categoria"}}}},"\/dashboard\/stats":{"get":{"tags":["Dashboard"],"summary":"Estat\u00edsticas do dia (admin\/manager)","responses":{"200":{"description":"Estat\u00edsticas consolidadas","content":{"application\/json":{"schema":{"type":"object","properties":{"total_employees":{"type":"integer"},"present_today":{"type":"integer"},"late_today":{"type":"integer"},"absent_today":{"type":"integer"}}}}}}}}},"\/dashboard\/today-records":{"get":{"tags":["Dashboard"],"summary":"Registros de hoje (admin\/manager)","responses":{"200":{"description":"Registros do dia"}}}},"\/deploy\/log":{"get":{"tags":["Deploy"],"summary":"Ver log de deploy (protegido por Bearer token na env)","description":"Retorna as \u00faltimas 200 linhas do log de deploy. N\u00e3o requer JWT de usu\u00e1rio \u2014 protegido pela vari\u00e1vel de ambiente `DEPLOY_TOKEN` passada como Bearer.","security":[],"responses":{"200":{"description":"Conte\u00fado do log","content":{"application\/json":{"schema":{"type":"object","properties":{"log":{"type":"string"}}}}}},"401":{"description":"Token de deploy inv\u00e1lido"}}}},"\/deploy\/webhook":{"post":{"tags":["Deploy"],"summary":"Disparar deploy via webhook CI\/CD (protegido por Bearer token na env)","description":"Inicia o processo de deploy em background (git pull, migrate, cache). Protegido pela vari\u00e1vel de ambiente `DEPLOY_TOKEN`. Retorna imediatamente com status 202.","security":[],"responses":{"202":{"description":"Deploy iniciado","content":{"application\/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"deploying"},"log":{"type":"string","example":"\/api\/deploy\/log"}}}}}},"401":{"description":"Token de deploy inv\u00e1lido"}}}},"\/device-token":{"post":{"tags":["Notifica\u00e7\u00f5es"],"summary":"Registrar token FCM para push notifications","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"type":"string"},"platform":{"type":"string","enum":["android","ios","web"]}}}}}},"responses":{"200":{"description":"Token registrado"}}},"delete":{"tags":["Notifica\u00e7\u00f5es"],"summary":"Remover token FCM","responses":{"200":{"description":"Token removido"}}}},"\/documents":{"get":{"tags":["Documentos"],"summary":"Listar documentos da empresa (admin\/manager)","description":"Retorna todos os lotes de documentos enviados, com contagem de confirma\u00e7\u00f5es por lote.","parameters":[{"name":"search","in":"query","description":"Buscar por t\u00edtulo do lote","schema":{"type":"string"}},{"name":"category","in":"query","schema":{"type":"string","enum":["holerite","contrato","aviso","atestado","outros"]}},{"name":"per_page","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Lista paginada de documentos","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/CompanyDocument"}},"current_page":{"type":"integer"},"total":{"type":"integer"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/documents\/batch-upload":{"post":{"tags":["Documentos"],"summary":"Enviar documentos em lote (admin\/manager)","description":"Envia m\u00faltiplos arquivos e vincula cada um ao funcion\u00e1rio cujo CPF est\u00e1 contido no nome do arquivo. Formato aceito: `holerite_12345678901.pdf` ou `documento-123.456.789-01.pdf`. Arquivos sem CPF v\u00e1lido no nome s\u00e3o listados em `results.unmatched`.","requestBody":{"required":true,"content":{"multipart\/form-data":{"schema":{"type":"object","required":["title","files"],"properties":{"title":{"type":"string","example":"Contracheques Abril 2026","description":"T\u00edtulo do lote de documentos"},"category":{"type":"string","enum":["holerite","contrato","aviso","atestado","outros"]},"description":{"type":"string","description":"Descri\u00e7\u00e3o opcional do lote"},"files":{"type":"array","items":{"type":"string","format":"binary"},"description":"Formatos: PDF, Word, Excel, imagens, ZIP. M\u00e1x. 50 arquivos, 50 MB cada. Para ZIPs: m\u00e1ximo 200 arquivos internos e 100 MB descompactado (prote\u00e7\u00e3o contra ZIP bomb). Os arquivos internos do ZIP s\u00e3o extra\u00eddos e processados individualmente."}}}}}},"responses":{"201":{"description":"Lote enviado","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string","example":"3 arquivo(s) vinculado(s) com sucesso."},"document_id":{"type":"integer"},"results":{"type":"object","properties":{"matched":{"type":"array","items":{"type":"object","properties":{"employee":{"type":"string"},"file":{"type":"string"}}}},"unmatched":{"type":"array","items":{"type":"string"},"description":"Arquivos sem CPF v\u00e1lido no nome"},"errors":{"type":"array","items":{"type":"string"},"description":"Erros de armazenamento"}}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/documents\/my":{"get":{"tags":["Documentos"],"summary":"Meus documentos (funcion\u00e1rio)","description":"Lista apenas os documentos vinculados ao funcion\u00e1rio autenticado. Cada item cont\u00e9m status de confirma\u00e7\u00e3o e dados do lote pai.","parameters":[{"name":"per_page","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Documentos do funcion\u00e1rio","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/EmployeeDocument"}},"current_page":{"type":"integer"},"total":{"type":"integer"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"}}}},"\/documents\/{id}":{"delete":{"tags":["Documentos"],"summary":"Excluir lote de documentos (admin\/manager)","description":"Exclui o lote e todos os arquivos individuais vinculados (S3 + banco).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":"ID do lote (CompanyDocument)"}],"responses":{"200":{"description":"Documento exclu\u00eddo"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/employee-documents\/{id}\/acknowledge":{"post":{"tags":["Documentos"],"summary":"Confirmar leitura de documento (funcion\u00e1rio)","description":"Registra que o funcion\u00e1rio leu e confirmou o documento. Opera\u00e7\u00e3o irrevers\u00edvel.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":"ID do EmployeeDocument"}],"responses":{"200":{"description":"Documento confirmado"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"description":"Documento j\u00e1 confirmado anteriormente","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/employee-documents\/{id}\/download":{"get":{"tags":["Documentos"],"summary":"Obter URL tempor\u00e1ria de download","description":"Gera URL pr\u00e9-assinada do S3 v\u00e1lida por 5 minutos. Funcion\u00e1rio s\u00f3 acessa seus pr\u00f3prios documentos. Admin\/manager acessa qualquer documento da empresa.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":"ID do EmployeeDocument"}],"responses":{"200":{"description":"URL de download gerada","content":{"application\/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"URL pr\u00e9-assinada, v\u00e1lida por 5 minutos"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/employee-invitations":{"get":{"tags":["Convites de Funcion\u00e1rios"],"summary":"Listar convites (admin\/manager)","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["pending","registered","approved","rejected","expired"]}},{"name":"per_page","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Lista paginada de convites"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}},"post":{"tags":["Convites de Funcion\u00e1rios"],"summary":"Criar convite (admin\/manager)","description":"Gera um token de convite. Se `email` for fornecido, envia e-mail automaticamente. O link \u00e9 v\u00e1lido por 24 horas.","requestBody":{"content":{"application\/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Nome pr\u00e9-preenchido (opcional)"},"email":{"type":"string","format":"email"},"role":{"type":"string","enum":["employee","manager"],"default":"employee"},"branch_id":{"type":"integer"},"template_id":{"type":"integer","description":"ID do template de cadastro"}}}}}},"responses":{"201":{"description":"Convite criado","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"token":{"type":"string"},"link":{"type":"string","format":"uri"},"expires_at":{"type":"string","format":"date-time"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/employee-invitations\/{id}":{"delete":{"tags":["Convites de Funcion\u00e1rios"],"summary":"Excluir convite (admin\/manager)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Convite removido"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/employee-invitations\/{id}\/approve":{"post":{"tags":["Convites de Funcion\u00e1rios"],"summary":"Aprovar convite e criar funcion\u00e1rio (admin\/manager)","description":"Aprova um cadastro enviado pelo colaborador, criando a conta de usu\u00e1rio na empresa.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Funcion\u00e1rio aprovado e conta criada","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"user_id":{"type":"integer"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/employee-invitations\/{id}\/reject":{"post":{"tags":["Convites de Funcion\u00e1rios"],"summary":"Rejeitar cadastro de convite (admin\/manager)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application\/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","description":"Motivo da rejei\u00e7\u00e3o (enviado por e-mail ao colaborador)"}}}}}},"responses":{"200":{"description":"Cadastro recusado"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/employee-invitations\/{id}\/resend":{"post":{"tags":["Convites de Funcion\u00e1rios"],"summary":"Reenviar convite (admin\/manager)","description":"Gera novo token e reenvia o e-mail de convite. Preserva dados anteriores do colaborador para que possa revis\u00e1-los.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application\/json":{"schema":{"type":"object","properties":{"note":{"type":"string","description":"Observa\u00e7\u00e3o do RH exibida no e-mail"}}}}}},"responses":{"200":{"description":"Convite reenviado","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"token":{"type":"string"},"link":{"type":"string","format":"uri"},"expires_at":{"type":"string","format":"date-time"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"description":"Convite j\u00e1 aprovado ou em estado inv\u00e1lido"}}}},"\/employee-invitations\/{token}\/register":{"post":{"tags":["Convites de Funcion\u00e1rios"],"summary":"Auto-cadastro pelo convite (p\u00fablico)","description":"Endpoint p\u00fablico (sem autentica\u00e7\u00e3o). O colaborador preenche seus dados usando o link de convite. Ap\u00f3s o envio, aguarda aprova\u00e7\u00e3o do gestor.","security":[],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["name","email","cpf","password","password_confirmation","lgpd_accepted","terms_accepted"],"properties":{"name":{"type":"string"},"email":{"type":"string","format":"email"},"cpf":{"type":"string","minLength":11,"maxLength":11},"password":{"type":"string","format":"password","minLength":8},"password_confirmation":{"type":"string","format":"password"},"lgpd_accepted":{"type":"boolean"},"terms_accepted":{"type":"boolean"},"phone":{"type":"string"},"rg":{"type":"string"},"birth_date":{"type":"string","format":"date"},"gender":{"type":"string"},"zip_code":{"type":"string"},"address":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"position":{"type":"string"},"department":{"type":"string"},"admission_date":{"type":"string","format":"date"},"pis":{"type":"string"}}}}}},"responses":{"200":{"description":"Cadastro enviado \u2014 aguardando aprova\u00e7\u00e3o"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/employee-invitations\/{token}\/validate":{"get":{"tags":["Convites de Funcion\u00e1rios"],"summary":"Validar token de convite (p\u00fablico)","description":"Endpoint p\u00fablico (sem autentica\u00e7\u00e3o). Verifica se o token \u00e9 v\u00e1lido, n\u00e3o expirado e n\u00e3o utilizado. Retorna dados pr\u00e9-preenchidos do convite.","security":[],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Token v\u00e1lido","content":{"application\/json":{"schema":{"type":"object","properties":{"valid":{"type":"boolean"},"name":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"role":{"type":"string"},"branch":{"type":"string","nullable":true},"expires_at":{"type":"string","format":"date-time"},"company":{"type":"string"},"template_fields":{"type":"array","nullable":true,"items":{"type":"string"}},"prefill":{"type":"object","nullable":true}}}}}},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"description":"Token expirado ou j\u00e1 utilizado"}}}},"\/employees":{"get":{"tags":["Funcion\u00e1rios"],"summary":"Listar funcion\u00e1rios (admin\/manager)","parameters":[{"name":"search","in":"query","schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"string","enum":["active","inactive"]}},{"name":"department","in":"query","schema":{"type":"string"}},{"name":"per_page","in":"query","schema":{"type":"integer","default":20}},{"name":"client_id","in":"query","description":"Filtrar funcion\u00e1rios vinculados a este cliente (ID da empresa-cliente)","schema":{"type":"integer"}},{"name":"is_contractor","in":"query","description":"Filtrar prestadores (1) ou funcion\u00e1rios regulares (0)","schema":{"type":"integer","enum":[0,1]}}],"responses":{"200":{"description":"Lista paginada de funcion\u00e1rios"}}},"post":{"tags":["Funcion\u00e1rios"],"summary":"Criar funcion\u00e1rio (admin\/manager)","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["name","email","cpf"],"properties":{"name":{"type":"string"},"email":{"type":"string","format":"email"},"cpf":{"type":"string"},"phone":{"type":"string"},"department":{"type":"string"},"position":{"type":"string"},"role":{"type":"string","enum":["admin","manager","employee"]},"admission_date":{"type":"string","format":"date"}}}}}},"responses":{"201":{"description":"Funcion\u00e1rio criado"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/employees\/bulk-clients":{"post":{"tags":["Funcionarios"],"summary":"Vincular filiais a multiplos funcionarios (bulk)","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":"employee_ids[], client_ids[]"}}}},"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/employees\/bulk-manager":{"post":{"tags":["Funcionarios"],"summary":"Atribuir gestor a multiplos funcionarios (bulk)","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":"employee_ids[], manager_id"}}}},"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/employees\/export":{"get":{"tags":["Funcion\u00e1rios"],"summary":"Exportar lista de funcion\u00e1rios (Excel)","parameters":[{"name":"status","in":"query","schema":{"type":"string"},"description":"Filtrar por status (active\/inactive)"}],"responses":{"200":{"description":"Arquivo Excel (.xlsx) com todos os funcion\u00e1rios"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/employees\/import":{"post":{"tags":["Funcion\u00e1rios"],"summary":"Importar funcion\u00e1rios via planilha","requestBody":{"required":true,"content":{"multipart\/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"Planilha .xlsx, .xls ou .csv"}}}}}},"responses":{"200":{"description":"Resultado da importa\u00e7\u00e3o","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"created":{"type":"integer"},"failed":{"type":"integer"},"rows":{"type":"array","items":{"type":"object"}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/employees\/import-template":{"get":{"tags":["Funcion\u00e1rios"],"summary":"Baixar planilha modelo para importa\u00e7\u00e3o","responses":{"200":{"description":"Arquivo Excel modelo com cabe\u00e7alhos, exemplo e instru\u00e7\u00f5es"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/employees\/import-templates":{"get":{"tags":["Funcionarios"],"summary":"Listar templates de importacao salvos","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"post":{"tags":["Funcionarios"],"summary":"Criar template de importacao","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":""}}}},"responses":{"201":{"description":"Criado","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/employees\/import-templates\/{id}":{"put":{"tags":["Funcionarios"],"summary":"Atualizar template de importacao","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":""}}}},"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"delete":{"tags":["Funcionarios"],"summary":"Excluir template de importacao","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/employees\/search":{"get":{"tags":["Funcion\u00e1rios"],"summary":"Buscar funcion\u00e1rios","parameters":[{"name":"q","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Resultados da busca"}}}},"\/employees\/{id}":{"get":{"tags":["Funcion\u00e1rios"],"summary":"Ver funcion\u00e1rio","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Dados do funcion\u00e1rio"}}},"put":{"tags":["Funcion\u00e1rios"],"summary":"Atualizar funcion\u00e1rio","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/User"}}}},"responses":{"200":{"description":"Funcion\u00e1rio atualizado"}}},"delete":{"tags":["Funcion\u00e1rios"],"summary":"Desativar funcion\u00e1rio","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Funcion\u00e1rio desativado"}}}},"\/employees\/{id}\/activate":{"post":{"tags":["Funcion\u00e1rios"],"summary":"Reativar funcion\u00e1rio","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Funcion\u00e1rio reativado.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/employees\/{id}\/clients":{"get":{"tags":["V\u00ednculos de Cliente"],"summary":"Listar clientes do funcion\u00e1rio","description":"Retorna as empresas-cliente vinculadas ao funcion\u00e1rio. Requer admin ou manager.","parameters":[{"name":"id","in":"path","required":true,"description":"ID do funcion\u00e1rio","schema":{"type":"integer"}}],"responses":{"200":{"description":"Lista de clientes","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"pivot":{"type":"object","properties":{"assigned_at":{"type":"string","format":"date-time"}}}}}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}},"post":{"tags":["V\u00ednculos de Cliente"],"summary":"Sincronizar clientes do funcion\u00e1rio","description":"Substitui todos os clientes vinculados pelo array informado. Para remover todos, envie client_ids=[]. Opera\u00e7\u00e3o idempotente.","parameters":[{"name":"id","in":"path","required":true,"description":"ID do funcion\u00e1rio","schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"client_ids":{"type":"array","items":{"type":"integer"},"description":"IDs das empresas-cliente. Array vazio remove todos.","example":[3,7,12]}}}}}},"responses":{"200":{"description":"Clientes sincronizados com sucesso"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/employees\/{id}\/clients\/{clientId}":{"delete":{"tags":["V\u00ednculos de Cliente"],"summary":"Remover um cliente do funcion\u00e1rio","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":"ID do funcion\u00e1rio"},{"name":"clientId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da empresa-cliente a desvincular"}],"responses":{"200":{"description":"V\u00ednculo removido"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/employees\/{id}\/deactivate":{"post":{"tags":["Funcion\u00e1rios"],"summary":"Desativar funcion\u00e1rio","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Funcion\u00e1rio desativado.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/employees\/{id}\/face-photo":{"post":{"tags":["Funcion\u00e1rios"],"summary":"Enviar foto facial do funcion\u00e1rio","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"multipart\/form-data":{"schema":{"type":"object","required":["face_photo"],"properties":{"face_photo":{"type":"string","format":"binary","description":"Imagem JPEG\/PNG do rosto"}}}}}},"responses":{"200":{"description":"Foto facial salva com sucesso.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}},"delete":{"tags":["Funcion\u00e1rios"],"summary":"Remover foto facial do funcion\u00e1rio","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Foto facial removida.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/employees\/{id}\/impersonate":{"post":{"tags":["Funcion\u00e1rios"],"summary":"Impersonar funcion\u00e1rio (somente admin)","description":"Gera um token JWT tempor\u00e1rio autenticado como o funcion\u00e1rio, para suporte e depura\u00e7\u00e3o.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Token gerado","content":{"application\/json":{"schema":{"type":"object","properties":{"token":{"type":"string"},"user":{"$ref":"#\/components\/schemas\/User"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/employees\/{id}\/webauthn-credentials":{"get":{"tags":["Funcionarios"],"summary":"Listar digitais cadastradas do funcionario (admin)","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":"ID do funcionario"}],"responses":{"200":{"description":"Lista de credenciais do funcionario","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/employees\/{id}\/webauthn-credentials\/{credId}":{"delete":{"tags":["Funcionarios"],"summary":"Revogar digital do funcionario (admin)","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":"ID do funcionario"},{"name":"credId","in":"path","required":true,"schema":{"type":"string"},"description":"ID da credencial (base64url)"}],"responses":{"200":{"description":"Credencial revogada","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/holidays":{"get":{"tags":["Feriados"],"summary":"Listar feriados","parameters":[{"name":"year","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Lista de feriados"}}},"post":{"tags":["Feriados"],"summary":"Criar feriado (admin)","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["name","date"],"properties":{"name":{"type":"string"},"date":{"type":"string","format":"date"},"type":{"type":"string","enum":["national","state","municipal","company"]},"recurrent":{"type":"boolean"}}}}}},"responses":{"201":{"description":"Feriado criado"}}}},"\/holidays\/import-national":{"post":{"tags":["Feriados"],"summary":"Importar feriados nacionais (admin)","requestBody":{"content":{"application\/json":{"schema":{"type":"object","properties":{"year":{"type":"integer"}}}}}},"responses":{"200":{"description":"Feriados importados"}}}},"\/holidays\/{id}":{"put":{"tags":["Feriados"],"summary":"Atualizar feriado (admin)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application\/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Feriado atualizado"}}},"delete":{"tags":["Feriados"],"summary":"Excluir feriado (admin)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Feriado exclu\u00eddo"}}}},"\/integrations\/bank-hours":{"get":{"tags":["Integra\u00e7\u00f5es"],"summary":"Banco de horas (admin)","responses":{"200":{"description":"Dados do banco de horas"}}}},"\/integrations\/bank-hours\/status":{"get":{"tags":["Integracoes"],"summary":"Status do banco de horas (ok \/ warning >80% \/ critical >100%)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Status do banco de horas","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/integrations\/esocial":{"get":{"tags":["Integra\u00e7\u00f5es"],"summary":"Dados para eSocial (admin)","responses":{"200":{"description":"Payload eSocial"}}}},"\/integrations\/formats":{"get":{"tags":["Integra\u00e7\u00f5es"],"summary":"Formatos de exporta\u00e7\u00e3o dispon\u00edveis","responses":{"200":{"description":"Formatos suportados"}}}},"\/integrations\/payroll":{"get":{"tags":["Integra\u00e7\u00f5es"],"summary":"Dados para folha de pagamento (admin)","responses":{"200":{"description":"Dados de folha"}}}},"\/job-roles":{"get":{"tags":["Cargos"],"summary":"Listar cargos","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"post":{"tags":["Cargos"],"summary":"Criar cargo","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":"name, employment_type, pay_frequency, base_salary"}}}},"responses":{"201":{"description":"Criado","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/job-roles\/import":{"post":{"tags":["Cargos"],"summary":"Importar cargos via CSV","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"multipart\/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/job-roles\/import\/template":{"get":{"tags":["Cargos"],"summary":"Template CSV para importacao de cargos","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}}}}},"\/job-roles\/{id}":{"get":{"tags":["Cargos"],"summary":"Detalhe do cargo","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"put":{"tags":["Cargos"],"summary":"Atualizar cargo","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":""}}}},"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"delete":{"tags":["Cargos"],"summary":"Excluir cargo","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/job-roles\/{id}\/activate":{"post":{"tags":["Cargos"],"summary":"Ativar cargo","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/job-roles\/{id}\/deactivate":{"post":{"tags":["Cargos"],"summary":"Desativar cargo","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/journey-rules":{"get":{"tags":["Regras de Jornada"],"summary":"Listar regras de jornada (admin)","responses":{"200":{"description":"Lista de regras"}}},"post":{"tags":["Regras de Jornada"],"summary":"Criar regra de jornada (admin)","requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/JourneyRule"}}}},"responses":{"201":{"description":"Regra criada"}}}},"\/journey-rules\/{id}":{"get":{"tags":["Regras de Jornada"],"summary":"Ver regra de jornada","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Detalhes da regra"}}},"put":{"tags":["Regras de Jornada"],"summary":"Atualizar regra de jornada","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/JourneyRule"}}}},"responses":{"200":{"description":"Regra atualizada"}}},"delete":{"tags":["Regras de Jornada"],"summary":"Excluir regra de jornada","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Regra exclu\u00edda"}}}},"\/journey-rules\/{id}\/activate":{"post":{"tags":["Regras de Jornada"],"summary":"Ativar regra de jornada","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Regra ativada.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/journey-rules\/{id}\/assign":{"post":{"tags":["Regras de Jornada"],"summary":"Atribuir regra a funcion\u00e1rios (admin)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["employee_ids"],"properties":{"employee_ids":{"type":"array","items":{"type":"integer"}}}}}}},"responses":{"200":{"description":"Regra atribu\u00edda"}}}},"\/journey-rules\/{id}\/deactivate":{"post":{"tags":["Regras de Jornada"],"summary":"Desativar regra de jornada","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Regra desativada.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/journey-rules\/{id}\/employees":{"get":{"tags":["Regras de Jornada"],"summary":"Listar funcion\u00e1rios de uma regra","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"filter","in":"query","schema":{"type":"string","enum":["all","in_rule","available","other_rules"]}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"per_page","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Funcion\u00e1rios","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/User"}},"total":{"type":"integer"},"in_rule_count":{"type":"integer"},"rule_name":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/journey-rules\/{id}\/employees\/{employeeId}":{"delete":{"tags":["Regras de Jornada"],"summary":"Remover funcion\u00e1rio de uma regra","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"employeeId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Funcion\u00e1rio removido da regra.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/kpis\/attendance":{"get":{"tags":["KPIs"],"summary":"KPI de assiduidade","responses":{"200":{"description":"Dados de assiduidade"}}}},"\/kpis\/daily-presence":{"get":{"tags":["KPIs"],"summary":"Presen\u00e7a di\u00e1ria","responses":{"200":{"description":"Dados de presen\u00e7a di\u00e1ria"}}}},"\/kpis\/overtime":{"get":{"tags":["KPIs"],"summary":"KPI de horas extras","responses":{"200":{"description":"Dados de horas extras"}}}},"\/kpis\/overview":{"get":{"tags":["KPIs"],"summary":"Vis\u00e3o geral dos KPIs","parameters":[{"name":"date_from","in":"query","schema":{"type":"string","format":"date"}},{"name":"date_to","in":"query","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"KPIs consolidados"}}}},"\/kpis\/punctuality":{"get":{"tags":["KPIs"],"summary":"KPI de pontualidade","responses":{"200":{"description":"Dados de pontualidade"}}}},"\/leaves":{"get":{"tags":["F\u00e9rias e Licen\u00e7as"],"summary":"Listar afastamentos","description":"Funcion\u00e1rios veem apenas os pr\u00f3prios. Admin\/manager veem todos.","parameters":[{"name":"employee_id","in":"query","schema":{"type":"integer"}},{"name":"status","in":"query","schema":{"type":"string"}},{"name":"type","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Lista de afastamentos"}}},"post":{"tags":["F\u00e9rias e Licen\u00e7as"],"summary":"Criar afastamento (admin\/manager)","requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Leave"}}}},"responses":{"201":{"description":"Afastamento criado"}}}},"\/leaves\/my":{"get":{"tags":["F\u00e9rias e Licen\u00e7as"],"summary":"Meus afastamentos","responses":{"200":{"description":"Afastamentos do usu\u00e1rio autenticado"}}}},"\/leaves\/request":{"post":{"tags":["F\u00e9rias e Licen\u00e7as"],"summary":"Solicitar afastamento","requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Leave"}}}},"responses":{"201":{"description":"Solicita\u00e7\u00e3o criada"}}}},"\/leaves\/types":{"get":{"tags":["F\u00e9rias e Licen\u00e7as"],"summary":"Listar tipos de afastamento dispon\u00edveis","description":"Retorna todos os tipos suportados (23 tipos) e quais exigem justificativa obrigat\u00f3ria.","responses":{"200":{"description":"Tipos de afastamento","content":{"application\/json":{"schema":{"type":"object","properties":{"types":{"type":"object","description":"Mapa key \u2192 label (pt-BR)","example":{"vacation":"F\u00e9rias","sick_leave":"Licen\u00e7a M\u00e9dica"}},"require_reason":{"type":"array","items":{"type":"string"},"description":"Tipos que exigem campo reason preenchido"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"}}}},"\/leaves\/{id}":{"get":{"tags":["F\u00e9rias e Licen\u00e7as"],"summary":"Ver afastamento","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Detalhes do afastamento"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}},"put":{"tags":["F\u00e9rias e Licen\u00e7as"],"summary":"Atualizar afastamento (admin\/manager)","description":"Edita campos de um afastamento existente. Campos omitidos n\u00e3o s\u00e3o alterados.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"multipart\/form-data":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["vacation","sick_leave","maternity_leave","paternity_leave","adoption","abono","afastamento","work_accident","bereavement","marriage","blood_donation","military","jury_duty","election","union_meeting","notice_period","doctor_appointment","training","compensatory","unpaid","suspension","personal","other"]},"start_date":{"type":"string","format":"date"},"end_date":{"type":"string","format":"date"},"reason":{"type":"string","maxLength":2000},"status":{"type":"string","enum":["pending","approved","rejected","cancelled"]},"is_abonado":{"type":"boolean"},"abono_hours":{"type":"number"},"attachment":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Afastamento atualizado"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}},"delete":{"tags":["F\u00e9rias e Licen\u00e7as"],"summary":"Excluir afastamento (admin\/manager)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Afastamento exclu\u00eddo"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/leaves\/{id}\/approve":{"post":{"tags":["F\u00e9rias e Licen\u00e7as"],"summary":"Aprovar afastamento (admin\/manager)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Aprovado"}}}},"\/leaves\/{id}\/cancel":{"post":{"tags":["F\u00e9rias e Licen\u00e7as"],"summary":"Cancelar afastamento","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Cancelado"}}}},"\/leaves\/{id}\/reject":{"post":{"tags":["F\u00e9rias e Licen\u00e7as"],"summary":"Rejeitar afastamento (admin\/manager)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Rejeitado"}}}},"\/lgpd\/access-logs":{"get":{"tags":["LGPD"],"summary":"Logs de acesso a dados pessoais","parameters":[{"name":"user_id","in":"query","schema":{"type":"integer"}},{"name":"resource_type","in":"query","schema":{"type":"string"}},{"name":"date_from","in":"query","schema":{"type":"string","format":"date"}},{"name":"date_to","in":"query","schema":{"type":"string","format":"date"}},{"name":"per_page","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Logs de acesso","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"user_id":{"type":"integer"},"resource_type":{"type":"string"},"action":{"type":"string"},"created_at":{"type":"string","format":"date-time"}}}},"current_page":{"type":"integer"},"last_page":{"type":"integer"},"total":{"type":"integer"},"per_page":{"type":"integer"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/lgpd\/consents":{"get":{"tags":["LGPD"],"summary":"Meus consentimentos","description":"Tipos obrigat\u00f3rios para registrar ponto: `terms`, `data_processing`, `third_party`. Tipo `biometric` obrigat\u00f3rio para assinar espelho.","responses":{"200":{"description":"Lista de consentimentos"}}},"post":{"tags":["LGPD"],"summary":"Registrar consentimento","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["consent_type","version","accepted"],"properties":{"consent_type":{"type":"string","enum":["terms","data_processing","third_party","biometric","location"]},"version":{"type":"string","example":"1.0"},"accepted":{"type":"boolean"}}}}}},"responses":{"201":{"description":"Consentimento registrado"}}}},"\/lgpd\/consents\/pending":{"get":{"tags":["LGPD"],"summary":"Consentimentos pendentes do usu\u00e1rio","description":"Retorna tipos de consentimento que o usu\u00e1rio ainda n\u00e3o aceitou, considerando as regras de jornada ativas.","responses":{"200":{"description":"Consentimentos pendentes","content":{"application\/json":{"schema":{"type":"object","properties":{"pending":{"type":"array","items":{"type":"object"}},"total_pending":{"type":"integer"},"next":{"type":"object","nullable":true},"all_granted":{"type":"boolean"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"}}}},"\/lgpd\/consents\/{type}\/revoke":{"post":{"tags":["LGPD"],"summary":"Revogar consentimento","description":"Revoga um consentimento espec\u00edfico. Consentimentos obrigat\u00f3rios (terms, data_processing) n\u00e3o podem ser revogados.","parameters":[{"name":"type","in":"path","required":true,"schema":{"type":"string"},"description":"Tipo de consentimento (biometric, location, third_party)"}],"responses":{"200":{"description":"Consentimento revogado","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"revoked":{"type":"boolean"},"logout":{"type":"boolean","description":"Se true, o usu\u00e1rio deve ser deslogado"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/lgpd\/deletion-request":{"post":{"tags":["LGPD"],"summary":"Solicitar exclus\u00e3o de dados","requestBody":{"content":{"application\/json":{"schema":{"type":"object","properties":{"reason":{"type":"string"}}}}}},"responses":{"201":{"description":"Solicita\u00e7\u00e3o registrada"}}}},"\/lgpd\/deletion-requests":{"get":{"tags":["LGPD"],"summary":"Listar solicita\u00e7\u00f5es de exclus\u00e3o (admin)","responses":{"200":{"description":"Lista de solicita\u00e7\u00f5es"}}}},"\/lgpd\/deletion-requests\/{id}\/approve":{"post":{"tags":["LGPD"],"summary":"Aprovar solicita\u00e7\u00e3o de exclus\u00e3o (DPO)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Solicita\u00e7\u00e3o aprovada.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/lgpd\/deletion-requests\/{id}\/reject":{"post":{"tags":["LGPD"],"summary":"Rejeitar solicita\u00e7\u00e3o de exclus\u00e3o (DPO)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"notes":{"type":"string","description":"Motivo da rejei\u00e7\u00e3o"}}}}}},"responses":{"200":{"description":"Solicita\u00e7\u00e3o rejeitada.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/lgpd\/my-data":{"get":{"tags":["LGPD"],"summary":"Meus dados pessoais (portabilidade LGPD)","responses":{"200":{"description":"Dados pessoais completos"}}}},"\/lgpd\/retention-policy":{"get":{"tags":["LGPD"],"summary":"Consultar pol\u00edtica de reten\u00e7\u00e3o de dados","responses":{"200":{"description":"Pol\u00edtica de reten\u00e7\u00e3o","content":{"application\/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}},"put":{"tags":["LGPD"],"summary":"Atualizar pol\u00edtica de reten\u00e7\u00e3o de dados","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"retention_days":{"type":"integer"}}}}}},"responses":{"200":{"description":"Pol\u00edtica atualizada.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/locations":{"get":{"tags":["Regras de Jornada"],"summary":"Listar locais de trabalho","parameters":[{"name":"status","in":"query","schema":{"type":"string","default":"active"}},{"name":"per_page","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Locais paginados","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"address":{"type":"string"},"latitude":{"type":"number"},"longitude":{"type":"number"},"radius":{"type":"integer","description":"Raio em metros"},"description":{"type":"string"},"status":{"type":"string","enum":["active","inactive"]}}}},"current_page":{"type":"integer"},"last_page":{"type":"integer"},"total":{"type":"integer"},"per_page":{"type":"integer"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}},"post":{"tags":["Regras de Jornada"],"summary":"Criar local de trabalho","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"address":{"type":"string"},"latitude":{"type":"number"},"longitude":{"type":"number"},"radius":{"type":"integer","description":"Raio em metros"},"description":{"type":"string"}},"required":["name","latitude","longitude","radius"]}}}},"responses":{"201":{"description":"Local criado","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"address":{"type":"string"},"latitude":{"type":"number"},"longitude":{"type":"number"},"radius":{"type":"integer","description":"Raio em metros"},"description":{"type":"string"},"status":{"type":"string","enum":["active","inactive"]}}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/locations\/geocode":{"post":{"tags":["Regras de Jornada"],"summary":"Geocodificar endere\u00e7o","description":"Converte um endere\u00e7o textual em coordenadas GPS via Nominatim (OpenStreetMap).","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"address":{"type":"string","example":"Av. Paulista, 1000, S\u00e3o Paulo"}},"required":["address"]}}}},"responses":{"200":{"description":"Coordenadas","content":{"application\/json":{"schema":{"type":"object","properties":{"latitude":{"type":"number"},"longitude":{"type":"number"},"display_name":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/locations\/{id}":{"get":{"tags":["Regras de Jornada"],"summary":"Detalhes de um local","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Local","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"address":{"type":"string"},"latitude":{"type":"number"},"longitude":{"type":"number"},"radius":{"type":"integer","description":"Raio em metros"},"description":{"type":"string"},"status":{"type":"string","enum":["active","inactive"]}}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"404":{"$ref":"#\/components\/responses\/NotFound"}}},"put":{"tags":["Regras de Jornada"],"summary":"Atualizar local de trabalho","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"address":{"type":"string"},"latitude":{"type":"number"},"longitude":{"type":"number"},"radius":{"type":"integer","description":"Raio em metros"},"description":{"type":"string"}}}}}},"responses":{"200":{"description":"Local atualizado","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"address":{"type":"string"},"latitude":{"type":"number"},"longitude":{"type":"number"},"radius":{"type":"integer","description":"Raio em metros"},"description":{"type":"string"},"status":{"type":"string","enum":["active","inactive"]}}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}},"delete":{"tags":["Regras de Jornada"],"summary":"Remover local de trabalho","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Local removido.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/locations\/{id}\/activate":{"post":{"tags":["Regras de Jornada"],"summary":"Reativar local de trabalho","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Local reativado.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/locations\/{id}\/deactivate":{"post":{"tags":["Regras de Jornada"],"summary":"Desativar local de trabalho","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Local desativado.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/my-plan":{"get":{"tags":["Configura\u00e7\u00f5es"],"summary":"Ver plano atual","responses":{"200":{"description":"Informa\u00e7\u00f5es do plano e assinatura"}}}},"\/notification-settings":{"get":{"tags":["Configura\u00e7\u00f5es"],"summary":"Configura\u00e7\u00f5es de notifica\u00e7\u00e3o (admin)","responses":{"200":{"description":"Configura\u00e7\u00f5es de notifica\u00e7\u00e3o"}}},"put":{"tags":["Configura\u00e7\u00f5es"],"summary":"Atualizar configura\u00e7\u00f5es de notifica\u00e7\u00e3o (admin)","requestBody":{"content":{"application\/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Atualizado"}}}},"\/notifications":{"get":{"tags":["Notifica\u00e7\u00f5es"],"summary":"Listar notifica\u00e7\u00f5es","parameters":[{"name":"per_page","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Lista paginada de notifica\u00e7\u00f5es"}}}},"\/notifications\/read-all":{"post":{"tags":["Notifica\u00e7\u00f5es"],"summary":"Marcar todas como lidas","responses":{"200":{"description":"Todas marcadas como lidas"}}}},"\/notifications\/unread-count":{"get":{"tags":["Notifica\u00e7\u00f5es"],"summary":"Contagem de notifica\u00e7\u00f5es n\u00e3o lidas","responses":{"200":{"description":"Contagem","content":{"application\/json":{"schema":{"type":"object","properties":{"count":{"type":"integer"}}}}}}}}},"\/notifications\/{id}\/read":{"patch":{"tags":["Notifica\u00e7\u00f5es"],"summary":"Marcar notifica\u00e7\u00e3o como lida","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Marcada como lida"}}}},"\/payroll":{"get":{"tags":["Payroll"],"summary":"Listar holerites","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/payroll\/generate":{"post":{"tags":["Payroll"],"summary":"Gerar holerites do periodo","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":"month, year"}}}},"responses":{"201":{"description":"Criado","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/payroll\/notify-admin":{"post":{"tags":["Payroll"],"summary":"Notificar admin sobre holerites pendentes","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/payroll\/{id}":{"get":{"tags":["Payroll"],"summary":"Detalhe do holerite","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/payroll\/{id}\/approve":{"post":{"tags":["Payroll"],"summary":"Aprovar holerites do periodo","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/payroll\/{id}\/employees\/{peId}\/pdf":{"get":{"tags":["Payroll"],"summary":"Download PDF do holerite","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""},{"name":"peId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/payroll\/{id}\/employees\/{peId}\/send":{"post":{"tags":["Payroll"],"summary":"Enviar holerite de um funcionario","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""},{"name":"peId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/payroll\/{id}\/send":{"post":{"tags":["Payroll"],"summary":"Enviar holerites por e-mail (todos os funcionarios)","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/pending-records":{"get":{"tags":["Registros Pendentes"],"summary":"Listar dias com registros faltando (admin\/manager)","description":"Retorna dias \u00fateis em que funcion\u00e1rios n\u00e3o t\u00eam registro de entrada e\/ou sa\u00edda. Gestores veem apenas sua equipe; admins veem todos.","parameters":[{"name":"month","in":"query","schema":{"type":"integer","minimum":1,"maximum":12}},{"name":"year","in":"query","schema":{"type":"integer","example":2026}},{"name":"employee_id","in":"query","schema":{"type":"integer"}},{"name":"manager_id","in":"query","schema":{"type":"integer"}},{"name":"rule_id","in":"query","schema":{"type":"integer"}},{"name":"branch_id","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Lista de dias pendentes","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"employee_id":{"type":"integer"},"employee_name":{"type":"string"},"date":{"type":"string","format":"date"},"missing_entry":{"type":"boolean"},"missing_exit":{"type":"boolean"},"existing_records":{"type":"array","items":{"type":"object"}}}}},"total":{"type":"integer"},"summary":{"type":"object","properties":{"total_missing":{"type":"integer"},"employees_with_pending":{"type":"integer"},"period_from":{"type":"string","format":"date"},"period_to":{"type":"string","format":"date"}}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/pending-records\/adjust-day":{"post":{"tags":["Registros Pendentes"],"summary":"Ajustar registros de um dia (admin\/manager)","description":"Cria ou atualiza registros de ponto para um funcion\u00e1rio em uma data espec\u00edfica. Suporta anexo como comprovante.","requestBody":{"required":true,"content":{"multipart\/form-data":{"schema":{"type":"object","required":["employee_id","date","records","justification"],"properties":{"employee_id":{"type":"integer"},"date":{"type":"string","format":"date"},"records":{"type":"array","items":{"type":"object","required":["type","time"],"properties":{"type":{"type":"string","enum":["entry","lunch_out","lunch_in","exit"]},"time":{"type":"string","pattern":"^\\d{2}:\\d{2}","example":"08:00"}}}},"justification":{"type":"string","minLength":5,"maxLength":1000},"attachment":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Registros ajustados"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/pending-records\/auto-fill":{"post":{"tags":["Registros Pendentes"],"summary":"Preencher automaticamente registros em lote (admin\/manager)","description":"Cria registros de ponto com hor\u00e1rios fixos para funcion\u00e1rios em um per\u00edodo. \u00datil para corrigir dias sem registro de forma massiva.","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["entry_time","exit_time","justification"],"properties":{"employee_ids":{"type":"array","items":{"type":"integer"}},"fill_all":{"type":"boolean","description":"Preencher todos os funcion\u00e1rios ativos (ignora employee_ids)"},"branch_id":{"type":"integer"},"month":{"type":"integer","minimum":1,"maximum":12},"year":{"type":"integer"},"date_from":{"type":"string","format":"date"},"date_to":{"type":"string","format":"date"},"entry_time":{"type":"string","pattern":"^\\d{2}:\\d{2}$","example":"08:00"},"exit_time":{"type":"string","pattern":"^\\d{2}:\\d{2}$","example":"17:00"},"lunch_out":{"type":"string","pattern":"^\\d{2}:\\d{2}$","example":"12:00"},"lunch_in":{"type":"string","pattern":"^\\d{2}:\\d{2}$","example":"13:00"},"justification":{"type":"string","minLength":5,"maxLength":1000},"only_missing":{"type":"boolean","default":true,"description":"true = pula dias j\u00e1 com registros"},"override_existing":{"type":"boolean","default":false}}}}}},"responses":{"200":{"description":"Resultado do preenchimento autom\u00e1tico","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"created":{"type":"integer"},"updated":{"type":"integer"},"skipped":{"type":"integer"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/pending-records\/auto-fill-from-rule":{"post":{"tags":["Registros Pendentes"],"summary":"Preencher registros com base na regra de jornada (admin\/manager)","description":"Preenche automaticamente os registros de cada funcion\u00e1rio usando os hor\u00e1rios configurados em sua regra de jornada ativa (weekdays config). Mais preciso que auto-fill pois respeita a grade hor\u00e1ria individual.","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["justification"],"properties":{"employee_id":{"type":"integer"},"employee_ids":{"type":"array","items":{"type":"integer"}},"client_id":{"type":"integer","description":"Filtrar por empresa cliente"},"fill_all":{"type":"boolean"},"date":{"type":"string","format":"date","description":"Data \u00fanica (alternativa a date_from\/date_to)"},"date_from":{"type":"string","format":"date"},"date_to":{"type":"string","format":"date"},"only_missing":{"type":"boolean","default":true},"justification":{"type":"string","minLength":5,"maxLength":1000}}}}}},"responses":{"200":{"description":"Resultado do preenchimento por regra","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"created":{"type":"integer"},"updated":{"type":"integer"},"skipped":{"type":"integer"},"no_rule":{"type":"integer","description":"Funcion\u00e1rios sem regra de jornada configurada"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/pending-records\/reasons":{"get":{"tags":["Registros Pendentes"],"summary":"Listar motivos de ajuste predefinidos (admin\/manager)","description":"Retorna array de strings com os motivos mais comuns para justificar ajustes de ponto.","responses":{"200":{"description":"Array de motivos","content":{"application\/json":{"schema":{"type":"object","properties":{"reasons":{"type":"array","items":{"type":"string"}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/profile":{"get":{"tags":["Perfil"],"summary":"Ver perfil","responses":{"200":{"description":"Dados do perfil","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/User"}}}}}},"put":{"tags":["Perfil"],"summary":"Atualizar perfil","requestBody":{"content":{"application\/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"phone":{"type":"string"}}}}}},"responses":{"200":{"description":"Perfil atualizado"}}}},"\/profile\/photo":{"post":{"tags":["Perfil"],"summary":"Atualizar foto de perfil","requestBody":{"content":{"multipart\/form-data":{"schema":{"type":"object","required":["photo"],"properties":{"photo":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Foto atualizada"}}}},"\/rdo\/dashboard":{"get":{"tags":["RDO - Controle de Obras"],"summary":"Dashboard gerencial de todas as obras","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras":{"get":{"tags":["RDO - Controle de Obras"],"summary":"Listar obras","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"post":{"tags":["RDO - Controle de Obras"],"summary":"Criar obra","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":"name, code, client, address, status, start_date"}}}},"responses":{"201":{"description":"Criado","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras\/{id}":{"get":{"tags":["RDO - Controle de Obras"],"summary":"Detalhe da obra","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"put":{"tags":["RDO - Controle de Obras"],"summary":"Atualizar obra","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":""}}}},"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"delete":{"tags":["RDO - Controle de Obras"],"summary":"Excluir obra","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras\/{id}\/dashboard":{"get":{"tags":["RDO - Controle de Obras"],"summary":"Painel financeiro da obra (orcamento x realizado)","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras\/{id}\/users":{"post":{"tags":["RDO - Controle de Obras"],"summary":"Adicionar usuario a obra","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":"user_id"}}}},"responses":{"201":{"description":"Criado","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras\/{id}\/users\/{userId}":{"delete":{"tags":["RDO - Controle de Obras"],"summary":"Remover usuario da obra","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""},{"name":"userId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras\/{obraId}\/budgets":{"get":{"tags":["RDO - Controle de Obras"],"summary":"Listar orcamentos da obra","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"post":{"tags":["RDO - Controle de Obras"],"summary":"Criar orcamento","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":"category, description, amount"}}}},"responses":{"201":{"description":"Criado","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras\/{obraId}\/budgets\/{id}":{"put":{"tags":["RDO - Controle de Obras"],"summary":"Atualizar orcamento","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"},{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":""}}}},"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"delete":{"tags":["RDO - Controle de Obras"],"summary":"Excluir orcamento","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"},{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras\/{obraId}\/contracts":{"get":{"tags":["RDO - Controle de Obras"],"summary":"Listar contratos da obra","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"post":{"tags":["RDO - Controle de Obras"],"summary":"Criar contrato","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":"supplier, description, value, start_date, end_date"}}}},"responses":{"201":{"description":"Criado","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras\/{obraId}\/contracts\/{id}":{"get":{"tags":["RDO - Controle de Obras"],"summary":"Detalhe do contrato","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"},{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"put":{"tags":["RDO - Controle de Obras"],"summary":"Atualizar contrato","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"},{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":""}}}},"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"delete":{"tags":["RDO - Controle de Obras"],"summary":"Excluir contrato","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"},{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras\/{obraId}\/contracts\/{id}\/cancel":{"post":{"tags":["RDO - Controle de Obras"],"summary":"Cancelar contrato","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"},{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras\/{obraId}\/costs":{"get":{"tags":["RDO - Controle de Obras"],"summary":"Listar custos reais da obra","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"post":{"tags":["RDO - Controle de Obras"],"summary":"Registrar custo real","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":"category, description, amount, date"}}}},"responses":{"201":{"description":"Criado","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras\/{obraId}\/costs\/{id}":{"put":{"tags":["RDO - Controle de Obras"],"summary":"Atualizar custo","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"},{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":""}}}},"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"delete":{"tags":["RDO - Controle de Obras"],"summary":"Excluir custo","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"},{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras\/{obraId}\/measurements":{"get":{"tags":["RDO - Controle de Obras"],"summary":"Listar medicoes da obra","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"post":{"tags":["RDO - Controle de Obras"],"summary":"Criar medicao","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":"period, items[]"}}}},"responses":{"201":{"description":"Criado","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras\/{obraId}\/measurements\/{id}":{"get":{"tags":["RDO - Controle de Obras"],"summary":"Detalhe da medicao","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"},{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"put":{"tags":["RDO - Controle de Obras"],"summary":"Atualizar medicao","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"},{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":""}}}},"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"delete":{"tags":["RDO - Controle de Obras"],"summary":"Excluir medicao","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"},{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras\/{obraId}\/measurements\/{id}\/approve":{"post":{"tags":["RDO - Controle de Obras"],"summary":"Aprovar medicao","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"},{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras\/{obraId}\/measurements\/{id}\/retract":{"post":{"tags":["RDO - Controle de Obras"],"summary":"Retratar medicao aprovada","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"},{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras\/{obraId}\/measurements\/{id}\/submit":{"post":{"tags":["RDO - Controle de Obras"],"summary":"Submeter medicao para aprovacao","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"},{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras\/{obraId}\/reports":{"get":{"tags":["RDO - Controle de Obras"],"summary":"Listar RDOs da obra","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"post":{"tags":["RDO - Controle de Obras"],"summary":"Criar RDO diario","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":"date, teams[], activities[], materials[], equipment[]"}}}},"responses":{"201":{"description":"Criado","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras\/{obraId}\/reports\/export":{"get":{"tags":["RDO - Controle de Obras"],"summary":"Exportar RDOs da obra (CSV)","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras\/{obraId}\/reports\/export-pdf":{"get":{"tags":["RDO - Controle de Obras"],"summary":"Exportar RDO em PDF (DomPDF)","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras\/{obraId}\/reports\/{id}":{"get":{"tags":["RDO - Controle de Obras"],"summary":"Detalhe do RDO","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"},{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"put":{"tags":["RDO - Controle de Obras"],"summary":"Atualizar RDO","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"},{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":""}}}},"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"delete":{"tags":["RDO - Controle de Obras"],"summary":"Excluir RDO","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"},{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras\/{obraId}\/reports\/{id}\/approve":{"post":{"tags":["RDO - Controle de Obras"],"summary":"Aprovar RDO","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"},{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras\/{obraId}\/reports\/{id}\/retract":{"post":{"tags":["RDO - Controle de Obras"],"summary":"Retratar RDO aprovado","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"},{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/obras\/{obraId}\/reports\/{id}\/submit":{"post":{"tags":["RDO - Controle de Obras"],"summary":"Submeter RDO para aprovacao","security":[{"bearerAuth":[]}],"parameters":[{"name":"obraId","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da obra"},{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/users":{"get":{"tags":["RDO - Controle de Obras"],"summary":"Listar usuarios RDO","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"post":{"tags":["RDO - Controle de Obras"],"summary":"Criar usuario RDO (admin_rdo ou prestador_rdo)","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":"name, email, role_id, cpf|cnpj"}}}},"responses":{"201":{"description":"Criado","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/rdo\/users\/{id}":{"put":{"tags":["RDO - Controle de Obras"],"summary":"Atualizar usuario RDO","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":""}}}},"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"delete":{"tags":["RDO - Controle de Obras"],"summary":"Excluir usuario RDO","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":""}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/records":{"post":{"tags":["Registros de Ponto"],"summary":"Registrar ponto","description":"Cria um novo registro de ponto (entrada, sa\u00edda, almo\u00e7o). Requer consentimentos LGPD (terms, data_processing, third_party). Aplica Serpro ICP-Brasil e NSR sequencial.","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["entry","lunch_out","lunch_in","exit"]},"latitude":{"type":"number"},"longitude":{"type":"number"},"face_image":{"type":"string","description":"Base64 da foto facial (se reconhecimento facial ativo)"}}}}}},"responses":{"202":{"description":"Registro enfileirado para processamento","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"record_id":{"type":"integer"},"status_url":{"type":"string"}}}}}},"403":{"description":"Consentimento LGPD pendente (`error: consent_required`)"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}},"get":{"tags":["Registros de Ponto"],"summary":"Listar registros (admin\/manager)","description":"Lista registros de ponto de todos os funcion\u00e1rios. Suporta filtros por data, funcion\u00e1rio e status.","parameters":[{"name":"date_from","in":"query","schema":{"type":"string","format":"date"}},{"name":"date_to","in":"query","schema":{"type":"string","format":"date"}},{"name":"employee_id","in":"query","schema":{"type":"integer"}},{"name":"type","in":"query","schema":{"type":"string","enum":["entry","lunch_out","lunch_in","exit"]}},{"name":"per_page","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Lista paginada de registros"}}}},"\/records\/adjustments\/export":{"get":{"tags":["Records"],"summary":"Exportar relatorio CSV de ajustes e ciencias (gestor\/admin)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"CSV exportado","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/records\/adjustments\/my-pending":{"get":{"tags":["Records"],"summary":"Listar ajustes pendentes de ciencia (funcionario)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Lista de ajustes pendentes","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/records\/adjustments\/{id}\/acknowledge":{"post":{"tags":["Records"],"summary":"Confirmar ciencia de ajuste (CLT art.74 \u00a73)","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":"ID do ajuste"}],"responses":{"200":{"description":"Ciencia registrada","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/records\/day\/{date}":{"get":{"tags":["Registros de Ponto"],"summary":"Registros do dia","parameters":[{"name":"date","in":"path","required":true,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Registros do dia solicitado"}}}},"\/records\/manual":{"post":{"tags":["Registros Manuais"],"summary":"Solicitar registro manual","description":"Funcion\u00e1rio solicita registro para data passada. Bloqueado se a data pertencer a per\u00edodo j\u00e1 assinado. Datas futuras s\u00e3o rejeitadas. O tipo \u00e9 `records:manual` \u00e9 necess\u00e1rio na permiss\u00e3o do cargo.","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["type","timestamp","reason"],"properties":{"type":{"type":"string","enum":["entry","lunch_out","lunch_in","exit"]},"timestamp":{"type":"string","format":"date-time","example":"2026-04-10 08:30:00","description":"Qualquer data passada (n\u00e3o futura) e n\u00e3o em per\u00edodo assinado"},"reason":{"type":"string","maxLength":1000}}}}}},"responses":{"201":{"description":"Solicita\u00e7\u00e3o enviada para aprova\u00e7\u00e3o"},"403":{"description":"Per\u00edodo assinado (`error: period_signed`) ou sem permiss\u00e3o (`error: feature_disabled`)"},"422":{"description":"Data futura ou duplicata"}}}},"\/records\/manual\/pending":{"get":{"tags":["Registros Manuais"],"summary":"Registros manuais pendentes (admin\/manager)","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["pending","approved","rejected"]}},{"name":"employee_id","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Lista de registros manuais"}}}},"\/records\/manual\/{id}\/approve":{"post":{"tags":["Registros Manuais"],"summary":"Aprovar registro manual (admin\/manager)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Aprovado"}}}},"\/records\/manual\/{id}\/reject":{"post":{"tags":["Registros Manuais"],"summary":"Rejeitar registro manual (admin\/manager)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application\/json":{"schema":{"type":"object","properties":{"reason":{"type":"string"}}}}}},"responses":{"200":{"description":"Rejeitado"}}}},"\/records\/my":{"get":{"tags":["Registros de Ponto"],"summary":"Meus registros","parameters":[{"name":"date_from","in":"query","schema":{"type":"string","format":"date"}},{"name":"date_to","in":"query","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Registros do usu\u00e1rio autenticado"}}}},"\/records\/stats":{"get":{"tags":["Registros de Ponto"],"summary":"Estat\u00edsticas de registros (admin\/manager)","parameters":[{"name":"date_from","in":"query","schema":{"type":"string","format":"date"}},{"name":"date_to","in":"query","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Estat\u00edsticas agregadas"}}}},"\/records\/status\/{id}":{"get":{"tags":["Registros de Ponto"],"summary":"Status de processamento do registro","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Status do processamento","content":{"application\/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["pending","approved","rejected"]},"receipt_hash":{"type":"string","nullable":true}}}}}}}}},"\/records\/today-status":{"get":{"tags":["Registros de Ponto"],"summary":"Status do dia atual (feriado \/ licen\u00e7a)","description":"Retorna se hoje \u00e9 feriado e\/ou se o colaborador est\u00e1 em licen\u00e7a\/f\u00e9rias aprovada. Usado pelo frontend para exibir tarja informativa.","responses":{"200":{"description":"Status do dia","content":{"application\/json":{"schema":{"type":"object","properties":{"is_holiday":{"type":"boolean"},"holiday_name":{"type":"string","nullable":true},"is_on_leave":{"type":"boolean"},"leave_type":{"type":"string","nullable":true,"example":"F\u00e9rias"},"leave_end":{"type":"string","nullable":true,"example":"30\/05\/2026"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"}}}},"\/records\/{id}\/adjust":{"put":{"tags":["Registros de Ponto"],"summary":"Ajustar hor\u00e1rio de registro (admin\/manager)","description":"Preserva o registro original e cria registro de ajuste. Bloqueado se per\u00edodo estiver assinado.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["time","reason"],"properties":{"time":{"type":"string","example":"09:15:00"},"reason":{"type":"string"}}}}}},"responses":{"200":{"description":"Ajuste realizado"},"403":{"description":"Per\u00edodo assinado (`error: period_signed`)"}}}},"\/records\/{id}\/adjustments":{"get":{"tags":["Registros de Ponto"],"summary":"Hist\u00f3rico de ajustes do registro","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Lista de ajustes"}}}},"\/records\/{id}\/approve":{"put":{"tags":["Registros de Ponto"],"summary":"Aprovar registro de ponto (admin\/manager)","description":"Aprova um registro manual ou pendente de revis\u00e3o.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":"ID do registro"}],"requestBody":{"content":{"application\/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Registro aprovado"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/records\/{id}\/detail":{"get":{"tags":["Registros de Ponto"],"summary":"Detalhes de um registro (admin\/manager)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Detalhes completos do registro"}}}},"\/records\/{id}\/reject":{"put":{"tags":["Registros de Ponto"],"summary":"Reprovar registro (gestor\/admin)","description":"Reprova um registro aprovado ou pendente. Requer justificativa. Bloqueado em per\u00edodos j\u00e1 assinados digitalmente.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":"ID do registro"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","maxLength":500,"example":"Registro duplicado por engano."}},"required":["reason"]}}}},"responses":{"200":{"description":"Registro reprovado com sucesso.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"description":"Per\u00edodo assinado ou status inv\u00e1lido","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"error":{"type":"string","enum":["record_in_signed_period"]}}}}}}}}},"\/reports\/absenteeism":{"get":{"tags":["Relatorios"],"summary":"Relatorio de absenteismo (faltas, atrasos, saidas antecipadas)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/reports\/attendance":{"get":{"tags":["Relat\u00f3rios"],"summary":"Relat\u00f3rio de assiduidade (admin\/manager)","responses":{"200":{"description":"Relat\u00f3rio de assiduidade"}}}},"\/reports\/bank-hours-forecast":{"get":{"tags":["Relatorios"],"summary":"Previsao de banco de horas \u2014 acumulo projetado","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/reports\/cost-estimate":{"get":{"tags":["Relatorios"],"summary":"Estimativa de custo de horas trabalhadas + banco de horas (por salario\/cargo)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/reports\/fraud-audit":{"get":{"tags":["Relatorios"],"summary":"Auditoria de fraudes (localizacao suspeita, digital nao reconhecida, tentativas multiplas)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/reports\/inconsistencies":{"get":{"tags":["Relatorios"],"summary":"Relatorio de inconsistencias de ponto (batidas faltantes, hora extra excessiva)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/reports\/overtime":{"get":{"tags":["Relat\u00f3rios"],"summary":"Relat\u00f3rio de horas extras (admin\/manager)","responses":{"200":{"description":"Relat\u00f3rio de horas extras"}}}},"\/reports\/punctuality":{"get":{"tags":["Relat\u00f3rios"],"summary":"Relat\u00f3rio de pontualidade (admin\/manager)","parameters":[{"name":"date_from","in":"query","schema":{"type":"string","format":"date"}},{"name":"date_to","in":"query","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Relat\u00f3rio de pontualidade"}}}},"\/reports\/timesheet-allocation":{"get":{"tags":["Relatorios"],"summary":"Alocacao de horas por filial \/ cargo \/ departamento","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Sucesso","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/roles":{"get":{"tags":["Cargos e Permiss\u00f5es"],"summary":"Listar cargos (admin)","responses":{"200":{"description":"Lista de cargos"}}},"post":{"tags":["Cargos e Permiss\u00f5es"],"summary":"Criar cargo (admin)","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["name","slug","level","permissions"],"properties":{"name":{"type":"string"},"slug":{"type":"string"},"level":{"type":"integer","minimum":0,"maximum":100},"permissions":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"201":{"description":"Cargo criado"}}}},"\/roles\/permissions":{"get":{"tags":["Cargos e Permiss\u00f5es"],"summary":"Listar permiss\u00f5es dispon\u00edveis (admin)","description":"Retorna todas as permiss\u00f5es granulares dispon\u00edveis para configurar em cargos, como `records:manual`, `signatures:open`, `employees:write`, etc.","responses":{"200":{"description":"Lista de permiss\u00f5es agrupadas por m\u00f3dulo"}}}},"\/roles\/{id}":{"put":{"tags":["Cargos e Permiss\u00f5es"],"summary":"Atualizar cargo \/ permiss\u00f5es","description":"Atualiza nome, n\u00edvel e permiss\u00f5es de um cargo. Se o cargo for global (Wtime), cria uma c\u00f3pia para a empresa.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"level":{"type":"integer","description":"N\u00edvel hier\u00e1rquico (0\u2013100)"},"permissions":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Cargo atualizado.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}},"delete":{"tags":["Cargos e Permiss\u00f5es"],"summary":"Excluir cargo","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Cargo removido.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/schedules":{"get":{"tags":["Escalas"],"summary":"Listar escalas (admin\/manager)","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["draft","active","closed"]}},{"name":"per_page","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Escalas","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"start_date":{"type":"string","format":"date"},"end_date":{"type":"string","format":"date"},"max_employees":{"type":"integer"},"status":{"type":"string","enum":["draft","active","closed"]},"journey_rule_id":{"type":"integer"}}}},"current_page":{"type":"integer"},"last_page":{"type":"integer"},"total":{"type":"integer"},"per_page":{"type":"integer"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}},"post":{"tags":["Escalas"],"summary":"Criar escala","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"start_date":{"type":"string","format":"date"},"end_date":{"type":"string","format":"date"},"max_employees":{"type":"integer"},"journey_rule_id":{"type":"integer"}},"required":["name","start_date","end_date","journey_rule_id"]}}}},"responses":{"201":{"description":"Escala criada","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"start_date":{"type":"string","format":"date"},"end_date":{"type":"string","format":"date"},"max_employees":{"type":"integer"},"status":{"type":"string","enum":["draft","active","closed"]},"journey_rule_id":{"type":"integer"}}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/schedules\/calendar":{"get":{"tags":["Escalas"],"summary":"Calend\u00e1rio de escalas","parameters":[{"name":"month","in":"query","schema":{"type":"integer"}},{"name":"year","in":"query","schema":{"type":"integer"}},{"name":"journey_rule_id","in":"query","schema":{"type":"integer"}},{"name":"status","in":"query","schema":{"type":"string"}},{"name":"employee_id","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Calend\u00e1rio","content":{"application\/json":{"schema":{"type":"object","properties":{"schedules":{"type":"array"},"rules":{"type":"array"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/schedules\/full":{"post":{"tags":["Escalas"],"summary":"Criar escala + regra + funcion\u00e1rios em um request","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"schedule":{"type":"object","description":"Dados da escala"},"rule":{"type":"object","description":"Dados da regra de jornada (se criar nova)"},"employees":{"type":"array","items":{"type":"integer"},"description":"IDs dos funcion\u00e1rios"}}}}}},"responses":{"201":{"description":"Escala criada.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/schedules\/my":{"get":{"tags":["Escalas"],"summary":"Minhas escalas (funcion\u00e1rio)","description":"Retorna escalas ativas \u00e0s quais o funcion\u00e1rio autenticado est\u00e1 vinculado.","responses":{"200":{"description":"Minhas escalas","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"start_date":{"type":"string","format":"date"},"end_date":{"type":"string","format":"date"},"max_employees":{"type":"integer"},"status":{"type":"string","enum":["draft","active","closed"]},"journey_rule_id":{"type":"integer"}}}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"}}}},"\/schedules\/{id}":{"get":{"tags":["Escalas"],"summary":"Detalhes de uma escala","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Escala","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"start_date":{"type":"string","format":"date"},"end_date":{"type":"string","format":"date"},"max_employees":{"type":"integer"},"status":{"type":"string","enum":["draft","active","closed"]},"journey_rule_id":{"type":"integer"}}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}},"put":{"tags":["Escalas"],"summary":"Atualizar escala","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"start_date":{"type":"string","format":"date"},"end_date":{"type":"string","format":"date"},"max_employees":{"type":"integer"},"journey_rule_id":{"type":"integer"}}}}}},"responses":{"200":{"description":"Escala atualizada","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"start_date":{"type":"string","format":"date"},"end_date":{"type":"string","format":"date"},"max_employees":{"type":"integer"},"status":{"type":"string","enum":["draft","active","closed"]},"journey_rule_id":{"type":"integer"}}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}},"delete":{"tags":["Escalas"],"summary":"Excluir escala","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Escala exclu\u00edda.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/schedules\/{id}\/cancel":{"post":{"tags":["Escalas"],"summary":"Cancelar escala (admin\/manager)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Escala cancelada"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/schedules\/{id}\/confirm":{"post":{"tags":["Escalas"],"summary":"Confirmar participa\u00e7\u00e3o em escala (funcion\u00e1rio)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Participa\u00e7\u00e3o confirmada.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/schedules\/{id}\/details":{"get":{"tags":["Escalas"],"summary":"Detalhes completos de uma escala (com funcion\u00e1rios)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"search","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Escala com detalhes.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/schedules\/{id}\/employees":{"get":{"tags":["Escalas"],"summary":"Listar funcion\u00e1rios de uma escala","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Funcion\u00e1rios da escala","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"confirmed":{"type":"boolean"}}}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}},"post":{"tags":["Escalas"],"summary":"Adicionar funcion\u00e1rios \u00e0 escala","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"employee_ids":{"type":"array","items":{"type":"integer"}}},"required":["employee_ids"]}}}},"responses":{"200":{"description":"Resultado","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"added":{"type":"integer"},"errors":{"type":"array"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/schedules\/{id}\/employees\/{employeeId}":{"delete":{"tags":["Escalas"],"summary":"Remover funcion\u00e1rio de uma escala","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"employeeId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Funcion\u00e1rio removido.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/schedules\/{id}\/full":{"put":{"tags":["Escalas"],"summary":"Atualizar escala + regra + funcion\u00e1rios em um request","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"schedule":{"type":"object"},"rule":{"type":"object"},"employees":{"type":"array","items":{"type":"integer"}}}}}}},"responses":{"200":{"description":"Escala atualizada.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/schedules\/{id}\/reject":{"post":{"tags":["Escalas"],"summary":"Recusar participa\u00e7\u00e3o em escala (funcion\u00e1rio)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"reason":{"type":"string"}}}}}},"responses":{"200":{"description":"Participa\u00e7\u00e3o recusada.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/shared-checkin":{"post":{"tags":["Check-in Compartilhado"],"summary":"Registrar ponto em modo compartilhado (tablet\/quiosque)","description":"Permite registros de ponto em dispositivos compartilhados com identifica\u00e7\u00e3o pr\u00e9via por facial. Requer permiss\u00e3o `shared-checkin:use`.","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["employee_id","type"],"properties":{"employee_id":{"type":"integer"},"type":{"type":"string","enum":["entry","lunch_out","lunch_in","exit"]}}}}}},"responses":{"202":{"description":"Registro processado"}}}},"\/shared-checkin\/biometric\/begin":{"post":{"tags":["Check-in Compartilhado"],"summary":"Iniciar check-in biom\u00e9trico (modo compartilhado)","description":"Gera challenge WebAuthn para um funcion\u00e1rio espec\u00edfico. Usado por tablet\/quiosque para iniciar verifica\u00e7\u00e3o de digital.","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["employee_id"],"properties":{"employee_id":{"type":"integer","description":"ID do funcion\u00e1rio a autenticar"}}}}}},"responses":{"200":{"description":"Challenge WebAuthn gerado","content":{"application\/json":{"schema":{"type":"object","properties":{"challenge":{"type":"string"},"rpId":{"type":"string"},"allowCredentials":{"type":"array","items":{"type":"object"}}}}}}},"422":{"description":"Funcion\u00e1rio sem digital cadastrada (no_credentials) ou dados inv\u00e1lidos"},"404":{"description":"Funcion\u00e1rio n\u00e3o encontrado (cross-company bloqueado)"}},"security":[{"bearerAuth":[]}]}},"\/shared-checkin\/biometric\/finish":{"post":{"tags":["Check-in Compartilhado"],"summary":"Finalizar check-in biom\u00e9trico (modo compartilhado)","description":"Verifica a asser\u00e7\u00e3o WebAuthn do funcion\u00e1rio e cria o registro de ponto. Aceita  opcional para modo dual-factor (facial + digital simult\u00e2neos).","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["employee_id","id","rawId","type","response","check_in_type","check_in_timestamp"],"properties":{"employee_id":{"type":"integer","description":"ID do funcion\u00e1rio"},"id":{"type":"string","description":"Credential ID (base64url)"},"rawId":{"type":"string","description":"Raw credential ID (base64url)"},"type":{"type":"string","enum":["public-key"]},"response":{"type":"object","description":"Asser\u00e7\u00e3o WebAuthn"},"check_in_type":{"type":"string","enum":["entry","lunch_out","lunch_in","exit"]},"check_in_timestamp":{"type":"string","format":"date-time"},"face_image":{"type":"string","description":"Selfie base64 opcional \u2014 ativa dual-factor (facial + digital)"},"latitude":{"type":"number"},"longitude":{"type":"number"},"accuracy":{"type":"number"}}}}}},"responses":{"201":{"description":"Ponto registrado com sucesso","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"integer"},"type":{"type":"string"},"date":{"type":"string","format":"date"},"time":{"type":"string"}}}}}}}},"422":{"description":"Falha na verifica\u00e7\u00e3o biom\u00e9trica (webauthn_auth_failed) ou regra violada"},"404":{"description":"Funcion\u00e1rio n\u00e3o encontrado"}},"security":[{"bearerAuth":[]}]}},"\/shared-checkin\/config":{"get":{"tags":["Check-in Compartilhado"],"summary":"Configura\u00e7\u00e3o do modo compartilhado","description":"Retorna nome e ID da empresa para exibi\u00e7\u00e3o na tela de check-in compartilhado.","responses":{"200":{"description":"Configura\u00e7\u00e3o","content":{"application\/json":{"schema":{"type":"object","properties":{"company_name":{"type":"string"},"company_id":{"type":"integer"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"}}}},"\/shared-checkin\/employees":{"get":{"tags":["Check-in Compartilhado"],"summary":"Buscar funcion\u00e1rios no modo compartilhado","parameters":[{"name":"rule_id","in":"query","schema":{"type":"integer"},"description":"ID da regra de jornada"},{"name":"search","in":"query","schema":{"type":"string"},"description":"Nome ou CPF (parcial)"}],"responses":{"200":{"description":"Funcion\u00e1rios","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"initials":{"type":"string"},"cpf_masked":{"type":"string"},"has_face":{"type":"boolean"}}}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"}}}},"\/shared-checkin\/identify":{"post":{"tags":["Check-in Compartilhado"],"summary":"Identificar funcion\u00e1rio por face","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["selfie"],"properties":{"selfie":{"type":"string","description":"Base64 da selfie"}}}}}},"responses":{"200":{"description":"Identifica\u00e7\u00e3o iniciada"}}}},"\/shared-checkin\/identify\/{id}\/status":{"get":{"tags":["Check-in Compartilhado"],"summary":"Status da identifica\u00e7\u00e3o facial em modo compartilhado","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":"ID do pending check-in"}],"responses":{"200":{"description":"Status da identifica\u00e7\u00e3o","content":{"application\/json":{"schema":{"type":"object","properties":{"pending_id":{"type":"integer"},"status":{"type":"string","enum":["pending","completed","failed"]},"identified":{"type":"boolean"},"employee_name":{"type":"string"},"employee_initials":{"type":"string"},"similarity":{"type":"number"},"rule_name":{"type":"string"},"record_type":{"type":"string"},"time":{"type":"string"},"record_id":{"type":"integer"},"error":{"type":"string"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/shared-checkin\/rules":{"get":{"tags":["Check-in Compartilhado"],"summary":"Regras dispon\u00edveis no modo compartilhado","responses":{"200":{"description":"Regras","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"require_location":{"type":"boolean"},"require_facial_recognition":{"type":"boolean"}}}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"}}}},"\/signature-cycles":{"get":{"tags":["Assinatura de Folha"],"summary":"Listar ciclos de assinatura (admin\/manager)","responses":{"200":{"description":"Lista de ciclos","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/SignatureCycle"}}}}}}}}},"post":{"tags":["Assinatura de Folha"],"summary":"Criar ciclo de assinatura (admin\/manager)","requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/SignatureCycle"}}}},"responses":{"201":{"description":"Ciclo criado"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/signature-cycles\/{id}":{"get":{"tags":["Assinatura de Folha"],"summary":"Detalhes do ciclo","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Detalhes do ciclo"}}},"put":{"tags":["Assinatura de Folha"],"summary":"Atualizar ciclo (admin\/manager)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/SignatureCycle"}}}},"responses":{"200":{"description":"Ciclo atualizado"}}},"delete":{"tags":["Assinatura de Folha"],"summary":"Excluir ciclo (admin\/manager)","description":"Bloqueado se houver assinaturas pendentes.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Ciclo exclu\u00eddo"},"422":{"description":"Ciclo possui assinaturas pendentes"}}}},"\/signature-cycles\/{id}\/preview":{"get":{"tags":["Assinatura de Folha"],"summary":"Preview do pr\u00f3ximo per\u00edodo do ciclo","description":"Calcula os campos ref_start, ref_end, available_from e deadline para o pr\u00f3ximo per\u00edodo.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"month","in":"query","schema":{"type":"integer"}},{"name":"year","in":"query","schema":{"type":"integer"}},{"name":"period_start","in":"query","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Preview do per\u00edodo","content":{"application\/json":{"schema":{"type":"object","properties":{"ref_start":{"type":"string","format":"date"},"ref_end":{"type":"string","format":"date"},"available_from":{"type":"string","format":"date-time"},"deadline":{"type":"string","format":"date-time","nullable":true}}}}}}}}},"\/system\/queue\/failed":{"get":{"tags":["Painel do Sistema"],"summary":"Jobs com falha (paginado)","description":"Lista todos os jobs que falharam, com payload e exce\u00e7\u00e3o. Paginado.","security":[{"bearerAuth":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","example":1}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Lista paginada de jobs com falha.","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"uuid":{"type":"string"},"job_class":{"type":"string"},"queue":{"type":"string"},"failed_at":{"type":"string","format":"date-time"},"exception":{"type":"string"}}}},"current_page":{"type":"integer"},"last_page":{"type":"integer"},"per_page":{"type":"integer"},"total":{"type":"integer"}}}}}},"403":{"description":"Acesso restrito ao dono do sistema."}}}},"\/system\/queue\/failed\/{id}":{"delete":{"tags":["Painel do Sistema"],"summary":"Remover job com falha","description":"Remove permanentemente um job da fila de falhas. A\u00e7\u00e3o irrevers\u00edvel.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Job removido.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"404":{"description":"Job n\u00e3o encontrado."},"403":{"description":"Acesso restrito ao dono do sistema."}}}},"\/system\/queue\/flush":{"delete":{"tags":["Painel do Sistema"],"summary":"Limpar todos os jobs com falha","description":"Remove permanentemente todos os jobs da fila de falhas. A\u00e7\u00e3o irrevers\u00edvel e n\u00e3o pode ser desfeita.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Fila limpa.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"count":{"type":"integer","example":5}}}}}},"403":{"description":"Acesso restrito ao dono do sistema."}}}},"\/system\/queue\/retry-all":{"post":{"tags":["Painel do Sistema"],"summary":"Retentar todos os jobs com falha","description":"Reenfileira todos os jobs com falha de uma vez para reprocessamento.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Todos os jobs reenfileirados.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"403":{"description":"Acesso restrito ao dono do sistema."}}}},"\/system\/queue\/retry\/{id}":{"post":{"tags":["Painel do Sistema"],"summary":"Retentar job com falha","description":"Reenfileira um job espec\u00edfico para nova tentativa de execu\u00e7\u00e3o.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Job reenfileirado.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string","example":"Job reenfileirado."}}}}}},"404":{"description":"Job n\u00e3o encontrado."},"403":{"description":"Acesso restrito ao dono do sistema."}}}},"\/system\/queue\/stats":{"get":{"tags":["Painel do Sistema"],"summary":"Estat\u00edsticas da fila de processamento","description":"Retorna contagem de jobs pendentes, falhos e o driver em uso.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Estat\u00edsticas da fila.","content":{"application\/json":{"schema":{"type":"object","properties":{"pending_jobs":{"type":"integer","example":3},"failed_jobs":{"type":"integer","example":0},"queue_driver":{"type":"string","example":"database"},"checked_at":{"type":"string","format":"date-time"}}}}}},"403":{"description":"Acesso restrito ao dono do sistema."}}}},"\/system\/server\/metrics":{"get":{"tags":["Painel do Sistema"],"summary":"M\u00e9tricas do servidor","description":"Retorna CPU%, RAM, disco, uptime e top processos. Exclusivo para is_system_owner=true. Retorna 403 para qualquer outro usu\u00e1rio.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"M\u00e9tricas coletadas com sucesso.","content":{"application\/json":{"schema":{"type":"object","properties":{"cpu_percent":{"type":"number","example":12.5},"memory":{"type":"object","properties":{"percent":{"type":"number"},"used_mb":{"type":"number"},"total_mb":{"type":"number"}}},"disk":{"type":"object","properties":{"percent":{"type":"number"},"used_gb":{"type":"number"},"total_gb":{"type":"number"}}},"uptime":{"type":"string","example":"5 days, 3:14:22"},"queue_workers":{"type":"array","items":{"type":"object"}},"top_processes":{"type":"array","items":{"type":"object","properties":{"pid":{"type":"integer"},"user":{"type":"string"},"cpu":{"type":"number"},"mem":{"type":"number"},"command":{"type":"string"}}}}}}}}},"403":{"description":"Acesso restrito ao dono do sistema."}}}},"\/terminal-tokens":{"get":{"tags":["Terminais"],"summary":"Listar terminais de ponto (admin)","description":"Retorna todos os tokens de terminal cadastrados para a empresa. Requer role admin.","responses":{"200":{"description":"Lista de terminais","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"ip_address":{"type":"string","nullable":true},"is_active":{"type":"boolean"},"last_used_at":{"type":"string","format":"date-time","nullable":true},"last_ip":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"}}}}}}}}}}},"post":{"tags":["Terminais"],"summary":"Criar terminal de ponto (admin)","description":"Cria um novo terminal. O token raw de 64 caracteres \u00e9 retornado apenas uma vez nesta resposta \u2014 guarde-o imediatamente.","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","example":"Ponto Recep\u00e7\u00e3o"},"ip_address":{"type":"string","nullable":true,"example":"192.168.1.10","description":"IP esperado do terminal (opcional). Se preenchido e require_terminal_ip=true, valida o IP na batida."}}}}}},"responses":{"201":{"description":"Terminal criado \u2014 token retornado apenas nesta resposta","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"token":{"type":"string","description":"Token de 64 caracteres \u2014 mostrado apenas uma vez"}}}}}}}}}}},"\/terminal-tokens\/{id}":{"put":{"tags":["Terminais"],"summary":"Atualizar terminal (admin)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"ip_address":{"type":"string","nullable":true}}}}}},"responses":{"200":{"description":"Terminal atualizado"}}},"delete":{"tags":["Terminais"],"summary":"Excluir terminal (admin)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Terminal exclu\u00eddo"}}}},"\/terminal-tokens\/{id}\/activate":{"post":{"tags":["Terminais"],"summary":"Ativar terminal (admin)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Terminal ativado"}}}},"\/terminal-tokens\/{id}\/revoke":{"post":{"tags":["Terminais"],"summary":"Revogar terminal (admin)","description":"Desativa o terminal sem exclu\u00ed-lo. Batidas com este token ser\u00e3o rejeitadas.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Terminal revogado"}}}},"\/timesheet":{"get":{"tags":["Espelho de Ponto"],"summary":"Espelho de ponto da empresa (admin\/manager)","parameters":[{"name":"month","in":"query","schema":{"type":"integer"}},{"name":"year","in":"query","schema":{"type":"integer"}},{"name":"employee_id","in":"query","schema":{"type":"integer"}},{"name":"start_date","in":"query","description":"Data inicial do per\u00edodo (YYYY-MM-DD). Use em conjunto com end_date. Quando ambos informados, ignora month\/year.","schema":{"type":"string","format":"date","example":"2026-05-01"}},{"name":"end_date","in":"query","description":"Data final do per\u00edodo (YYYY-MM-DD). Use em conjunto com start_date.","schema":{"type":"string","format":"date","example":"2026-05-31"}},{"name":"client_id","in":"query","description":"Filtrar espelho de ponto apenas de funcion\u00e1rios vinculados a este cliente.","schema":{"type":"integer"}}],"responses":{"200":{"description":"Espelhos de ponto"}},"description":"Retorna o espelho de ponto da empresa. Aceita intervalo livre (start_date + end_date) ou m\u00eas\/ano (month + year). Quando start_date e end_date s\u00e3o informados, o par\u00e2metro month\/year \u00e9 ignorado. Use client_id para filtrar somente funcion\u00e1rios vinculados a um cliente espec\u00edfico."}},"\/timesheet-signatures":{"get":{"tags":["Assinatura de Folha"],"summary":"Listar assinaturas (admin\/manager)","description":"Lista status de assinaturas da empresa. Filtros por ciclo, per\u00edodo ou m\u00eas\/ano.","parameters":[{"name":"cycle_id","in":"query","schema":{"type":"integer"}},{"name":"ref_start","in":"query","schema":{"type":"string","format":"date"}},{"name":"month","in":"query","schema":{"type":"integer"}},{"name":"year","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Lista de assinaturas + estat\u00edsticas + funcion\u00e1rios pendentes","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/TimesheetSignature"}},"missing":{"type":"array","description":"Funcion\u00e1rios que ainda n\u00e3o t\u00eam assinatura no per\u00edodo"},"stats":{"type":"object","properties":{"total":{"type":"integer"},"signed":{"type":"integer"},"pending":{"type":"integer"},"refused":{"type":"integer"},"expired":{"type":"integer"}}}}}}}}}}},"\/timesheet-signatures\/my":{"get":{"tags":["Assinatura de Folha"],"summary":"Minhas assinaturas pendentes","description":"Lista ciclos finalizados (ref_end < hoje) que ainda n\u00e3o foram assinados. Ciclos em andamento e j\u00e1 assinados n\u00e3o aparecem.","responses":{"200":{"description":"Lista de assinaturas pendentes","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/TimesheetSignature"}},"pending_available":{"type":"integer","description":"Pendentes dispon\u00edveis para assinar agora"},"pending_waiting":{"type":"integer","description":"Pendentes que ainda aguardam available_from"},"pending":{"type":"integer","description":"Total pendentes"}}}}}}}}},"\/timesheet-signatures\/open":{"post":{"tags":["Assinatura de Folha"],"summary":"Abrir per\u00edodo de assinatura (admin\/manager)","description":"Cria assinaturas pendentes para todos os funcion\u00e1rios do ciclo. Para ciclos mensais, informe `month` e `year`. Para semanais\/quinzenais\/di\u00e1rios, informe `period_start`.","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["cycle_id"],"properties":{"cycle_id":{"type":"integer"},"month":{"type":"integer","minimum":1,"maximum":12,"description":"Obrigat\u00f3rio para ciclos mensais"},"year":{"type":"integer","description":"Obrigat\u00f3rio para ciclos mensais"},"period_start":{"type":"string","format":"date","description":"Obrigat\u00f3rio para ciclos semanais\/di\u00e1rios"}}}}}},"responses":{"200":{"description":"Assinaturas criadas","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"created":{"type":"integer"},"skipped":{"type":"integer"},"period_start":{"type":"string","format":"date"},"period_end":{"type":"string","format":"date"},"available_from":{"type":"string"},"deadline":{"type":"string","nullable":true},"warning":{"type":"string","nullable":true}}}}}},"422":{"description":"Nenhum funcion\u00e1rio encontrado para o ciclo (`error: no_employees_found`)"}}}},"\/timesheet-signatures\/settings":{"get":{"tags":["Assinatura de Folha"],"summary":"Ver configura\u00e7\u00f5es de assinatura (admin\/manager)","responses":{"200":{"description":"Configura\u00e7\u00f5es atuais","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"mode":{"type":"string","enum":["auto","manual"]},"deadline_days":{"type":"integer","nullable":true,"description":"null = sem prazo definido"},"max_serpro_stamps_month":{"type":"integer"}}}}}}}}}},"put":{"tags":["Assinatura de Folha"],"summary":"Atualizar configura\u00e7\u00f5es de assinatura (admin\/manager)","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"mode":{"type":"string","enum":["auto","manual"]},"deadline_days":{"type":"integer","minimum":1,"maximum":30,"nullable":true,"description":"null ou 0 = sem prazo"}}}}}},"responses":{"200":{"description":"Configura\u00e7\u00f5es atualizadas"}}}},"\/timesheet-signatures\/{id}\/receipt":{"get":{"tags":["Assinatura de Folha"],"summary":"Comprovante de assinatura (HTML)","description":"Retorna HTML imprim\u00edvel do comprovante de assinatura digital com carimbo Serpro ICP-Brasil. Inclui celular mascarado (LGPD).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"HTML do comprovante","content":{"text\/html":{"schema":{"type":"string"}}}},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/timesheet-signatures\/{id}\/refuse":{"post":{"tags":["Assinatura de Folha"],"summary":"Recusar assinatura","description":"Funcion\u00e1rio recusa assinar o espelho de ponto e notifica o gestor.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application\/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","maxLength":2000}}}}}},"responses":{"200":{"description":"Recusa registrada"}}}},"\/timesheet-signatures\/{id}\/reopen":{"post":{"tags":["Assinatura de Folha"],"summary":"Reabrir assinatura recusada\/expirada (admin\/manager)","description":"Reabre assinatura com status `refused` ou `expired`. N\u00e3o pode reabrir assinaturas j\u00e1 `signed`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Assinatura reaberta"},"422":{"description":"Assinatura j\u00e1 assinada (`error: already_signed`)"}}}},"\/timesheet-signatures\/{id}\/request-otp":{"post":{"tags":["Assinatura de Folha"],"summary":"Solicitar c\u00f3digo OTP para assinatura","description":"Envia um c\u00f3digo OTP de 6 d\u00edgitos para o e-mail cadastrado do funcion\u00e1rio. O c\u00f3digo \u00e9 necess\u00e1rio para assinar o espelho de ponto. Limitado a 5 tentativas\/minuto por e-mail e 10\/minuto por IP.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da assinatura de folha."}],"responses":{"200":{"description":"C\u00f3digo enviado com sucesso.","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string","example":"C\u00f3digo enviado para o seu e-mail."}}}}}},"404":{"description":"Assinatura n\u00e3o encontrada."},"429":{"description":"Muitas tentativas. Aguarde antes de solicitar novamente."},"403":{"description":"Sem permiss\u00e3o para esta a\u00e7\u00e3o."}}}},"\/timesheet-signatures\/{id}\/sign":{"post":{"tags":["Assinatura de Folha"],"summary":"Assinar espelho de ponto","description":"Assina digitalmente o espelho de ponto. Requer: CPF confirmado + consentimento biom\u00e9trico LGPD + reconhecimento facial (se foto cadastrada) + celular que recebeu SMS. O hash SHA-256 inclui todos os registros do per\u00edodo **e** o n\u00famero do celular (apenas d\u00edgitos). Carimbo de tempo ICP-Brasil via Serpro. Bloqueado se houver jornadas incompletas (entrada sem sa\u00edda), exceto: (a) \u00faltimo ponto \u00e9 lunch_out, (b) turno noturno com sa\u00edda no dia seguinte ao ref_end.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["cpf_confirm","selfie","phone"],"properties":{"cpf_confirm":{"type":"string","description":"CPF do funcion\u00e1rio (apenas 11 d\u00edgitos, sem formata\u00e7\u00e3o)","example":"12345678901","minLength":11,"maxLength":11},"selfie":{"type":"string","description":"Base64 da selfie capturada (usada para reconhecimento facial se foto de refer\u00eancia cadastrada)"},"phone":{"type":"string","description":"Celular que recebeu o SMS de verifica\u00e7\u00e3o (inclu\u00eddo no hash para vincular ao signat\u00e1rio)","example":"(11) 98765-4321","maxLength":30},"latitude":{"type":"number","nullable":true},"longitude":{"type":"number","nullable":true}}}}}},"responses":{"200":{"description":"Assinatura realizada com sucesso","content":{"application\/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"cycle_name":{"type":"string"},"ref_start":{"type":"string","format":"date"},"ref_end":{"type":"string","format":"date"},"signed_at":{"type":"string","format":"date-time"},"serpro_serial":{"type":"string"},"document_hash":{"type":"string"}}}}}},"422":{"description":"Erro de valida\u00e7\u00e3o, CPF inv\u00e1lido, prazo expirado, jornada incompleta ou j\u00e1 assinado","content":{"application\/json":{"schema":{"allOf":[{"$ref":"#\/components\/schemas\/Error"},{"type":"object","properties":{"dates":{"type":"array","items":{"type":"string","format":"date"},"description":"Datas com jornadas incompletas (presente quando error=incomplete_shifts)"}}}]}}}},"403":{"description":"Consentimento biom\u00e9trico pendente (`error: consent_required`)"}}}},"\/timesheet\/bulk-pdf":{"post":{"tags":["Espelho de Ponto"],"summary":"Gerar PDF em lote para m\u00faltiplos funcion\u00e1rios (admin\/manager)","description":"Retorna um arquivo PDF consolidado com os espelhos de ponto de todos os funcion\u00e1rios selecionados no per\u00edodo indicado.","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["start_date","end_date"],"properties":{"employee_ids":{"type":"array","items":{"type":"integer"},"description":"IDs dos funcion\u00e1rios (omitir para todos)"},"start_date":{"type":"string","format":"date","example":"2026-05-01"},"end_date":{"type":"string","format":"date","example":"2026-05-31"}}}}}},"responses":{"200":{"description":"PDF bin\u00e1rio","content":{"application\/pdf":{"schema":{"type":"string","format":"binary"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/timesheet\/excel":{"get":{"tags":["Espelho de Ponto"],"summary":"Exportar espelho de ponto em Excel (admin\/manager)","parameters":[{"name":"month","in":"query","schema":{"type":"integer"}},{"name":"year","in":"query","schema":{"type":"integer"}},{"name":"employee_id","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Arquivo Excel (.xlsx) com o espelho de ponto"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/timesheet\/my":{"get":{"tags":["Espelho de Ponto"],"summary":"Meu espelho de ponto","parameters":[{"name":"month","in":"query","schema":{"type":"integer"}},{"name":"year","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Espelho de ponto do m\u00eas"}}}},"\/timesheet\/my\/excel":{"get":{"tags":["Espelho de Ponto"],"summary":"Meu espelho de ponto em Excel","responses":{"200":{"description":"Excel do espelho"}}}},"\/timesheet\/my\/pdf":{"get":{"tags":["Espelho de Ponto"],"summary":"Meu espelho de ponto em PDF","responses":{"200":{"description":"PDF do espelho"}}}},"\/timesheet\/{employeeId}":{"get":{"tags":["Espelho de Ponto"],"summary":"Espelho de ponto de funcion\u00e1rio espec\u00edfico (admin\/manager)","parameters":[{"name":"employeeId","in":"path","required":true,"schema":{"type":"integer"}},{"name":"month","in":"query","schema":{"type":"integer"}},{"name":"year","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Espelho do funcion\u00e1rio"}}}},"\/tokens":{"get":{"tags":["Tokens API"],"summary":"Listar tokens de API (admin)","responses":{"200":{"description":"Lista de tokens"}}},"post":{"tags":["Tokens API"],"summary":"Criar token de API (admin)","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"permissions":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"201":{"description":"Token criado \u2014 salve-o agora, n\u00e3o ser\u00e1 exibido novamente"}}}},"\/tokens\/{id}":{"delete":{"tags":["Tokens API"],"summary":"Revogar token de API (admin)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Token revogado"}}}},"\/training\/complete":{"post":{"tags":["Treinamento"],"summary":"Marcar m\u00f3dulo de treinamento como conclu\u00eddo","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["module_key"],"properties":{"module_key":{"type":"string","pattern":"^[a-z0-9\\-_]+$","maxLength":100,"example":"intro"}}}}}},"responses":{"200":{"description":"M\u00f3dulo marcado como conclu\u00eddo"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/training\/complete\/{key}":{"delete":{"tags":["Treinamento"],"summary":"Desmarcar um m\u00f3dulo de treinamento","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"},"description":"Chave do m\u00f3dulo"}],"responses":{"200":{"description":"M\u00f3dulo desmarcado"},"401":{"$ref":"#\/components\/responses\/Unauthorized"}}}},"\/training\/progress":{"get":{"tags":["Treinamento"],"summary":"Meu progresso de treinamento","description":"Retorna os m\u00f3dulos de treinamento j\u00e1 conclu\u00eddos pelo usu\u00e1rio autenticado.","responses":{"200":{"description":"M\u00f3dulos conclu\u00eddos","content":{"application\/json":{"schema":{"type":"object","properties":{"completed":{"type":"array","items":{"type":"string"},"example":["intro","checkin-overview"]}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"}}}},"\/training\/reset":{"delete":{"tags":["Treinamento"],"summary":"Resetar todo o progresso de treinamento do usu\u00e1rio atual","responses":{"200":{"description":"Progresso resetado"},"401":{"$ref":"#\/components\/responses\/Unauthorized"}}}},"\/training\/stats":{"get":{"tags":["Treinamento"],"summary":"Estat\u00edsticas de treinamento da empresa (admin\/manager)","description":"Retorna o progresso de treinamento de todos os funcion\u00e1rios da empresa.","responses":{"200":{"description":"Progresso por usu\u00e1rio","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"user":{"$ref":"#\/components\/schemas\/User"},"completed":{"type":"array","items":{"type":"string"}},"count":{"type":"integer"}}}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/users\/online":{"get":{"tags":["Dashboard"],"summary":"Usu\u00e1rios online agora (admin\/manager)","responses":{"200":{"description":"Lista de usu\u00e1rios online"}}}},"\/users\/online\/count":{"get":{"tags":["Dashboard"],"summary":"Contagem de usu\u00e1rios online","responses":{"200":{"description":"Contagem","content":{"application\/json":{"schema":{"type":"object","properties":{"count":{"type":"integer"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/webauthn\/credentials":{"get":{"tags":["WebAuthn - Biometria Digital"],"summary":"Listar digitais cadastradas do usuario logado","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Lista de credenciais","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/webauthn\/credentials\/{id}":{"delete":{"tags":["WebAuthn - Biometria Digital"],"summary":"Revogar digital cadastrada","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":"ID da credencial"}],"responses":{"200":{"description":"Credencial removida","content":{"application\/json":{"schema":{"type":"object"}}}},"404":{"description":"Nao encontrado","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/webauthn\/register\/begin":{"post":{"tags":["WebAuthn - Biometria Digital"],"summary":"Iniciar registro de digital (challenge)","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":"device_name"}}}},"responses":{"200":{"description":"Challenge para navigator.credentials.create()","content":{"application\/json":{"schema":{"type":"object"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/webauthn\/register\/finish":{"post":{"tags":["WebAuthn - Biometria Digital"],"summary":"Concluir registro de digital (attestation)","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","description":"attestation credential do navigator.credentials.create()"}}}},"responses":{"201":{"description":"Credencial registrada","content":{"application\/json":{"schema":{"type":"object"}}}},"422":{"description":"Validacao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"403":{"description":"Sem permissao","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/webhooks":{"get":{"tags":["Webhooks"],"summary":"Listar webhooks (admin)","responses":{"200":{"description":"Lista de webhooks"}}},"post":{"tags":["Webhooks"],"summary":"Criar webhook (admin)","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["url","events"],"properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string"},"example":["record.created","timesheet.signed"]},"secret":{"type":"string"},"active":{"type":"boolean"}}}}}},"responses":{"201":{"description":"Webhook criado"}}}},"\/webhooks\/{id}":{"get":{"tags":["Webhooks"],"summary":"Ver webhook (admin)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Detalhes do webhook"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}},"put":{"tags":["Webhooks"],"summary":"Atualizar webhook (admin)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application\/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Webhook atualizado"}}},"delete":{"tags":["Webhooks"],"summary":"Excluir webhook (admin)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Exclu\u00eddo"}}}},"\/webhooks\/{id}\/test":{"post":{"tags":["Webhooks"],"summary":"Testar webhook (admin)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Ping enviado"}}}}}}