{"openapi":"3.0.0","paths":{"/me":{"get":{"description":"Valida o token da Zoppy, o papel (MASTER ou ADMIN) e se o Zoppy Connect está liberado para a loja; diz se o usuário já aceitou os termos atuais.","operationId":"MeController_me","parameters":[],"responses":{"200":{"description":"Loja e usuário do token","content":{"application/json":{"schema":{"type":"object","properties":{"company":{"description":"Loja do token","type":"object","properties":{"id":{"description":"Id da loja na Zoppy","type":"string","format":"uuid"},"name":{"description":"Nome da loja","type":"string"}},"required":["id","name"]},"user":{"description":"Usuário do token","type":"object","properties":{"id":{"description":"Id do usuário na Zoppy","type":"string"},"name":{"type":"string"},"email":{"type":"string"},"role":{"type":"string","enum":["MASTER","ADMIN"]}},"required":["id","name","email","role"]},"featureEnabled":{"description":"O Zoppy Connect está liberado para a loja","type":"boolean"},"termsAcceptedAt":{"description":"Quando um MASTER da loja aceitou os termos atuais do Zoppy Connect; null antes do aceite","type":"string","format":"date-time","nullable":true},"termsAcceptedBy":{"description":"Id na Zoppy do MASTER que aceitou os termos atuais pela loja; null antes do aceite","type":"string","nullable":true}},"required":["company","user","featureEnabled","termsAcceptedAt","termsAcceptedBy"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Token restrito, sem loja, papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Quem está usando","tags":["identity"]}},"/connect/terms":{"post":{"description":"Registra que um MASTER aceitou a versão atual dos termos do Zoppy Connect pela loja (quem, loja, versão e quando). Repetir não muda nada e devolve o primeiro aceite. Antes do aceite, as outras rotas do Connect respondem 403 connect.terms_not_accepted.","operationId":"ConnectTermsController_accept","parameters":[],"responses":{"200":{"description":"Aceite registrado","content":{"application/json":{"schema":{"type":"object","properties":{"version":{"description":"Versão dos termos aceita","type":"string"},"termsAcceptedAt":{"description":"Quando a loja aceitou essa versão; repetir o aceite devolve o primeiro instante","type":"string","format":"date-time"},"termsAcceptedBy":{"description":"Id na Zoppy do MASTER que aceitou essa versão pela loja","type":"string"}},"required":["version","termsAcceptedAt","termsAcceptedBy"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Token restrito, sem loja, papel sem acesso, usuário que não é MASTER ou Connect não liberado (connect.forbidden_role, connect.terms_master_only, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Aceitar os termos","tags":["identity"]}},"/connectors":{"get":{"description":"Lista os conectores da loja, do mais novo ao mais antigo, com o estado de cada um.","operationId":"ConnectorsController_list","parameters":[],"responses":{"200":{"description":"Conectores","content":{"application/json":{"schema":{"description":"Conectores da loja, do mais novo ao mais antigo","type":"array","items":{"type":"object","properties":{"id":{"description":"Id do conector","type":"string","format":"uuid"},"name":{"description":"Nome que a loja deu ao conector","type":"string"},"description":{"description":"O que o conector faz","type":"string","nullable":true},"systemId":{"description":"Sistema do catálogo de onde ele partiu","type":"string","format":"uuid","nullable":true},"status":{"description":"draft, enabled ou paused","type":"string","enum":["draft","enabled","paused"],"x-enumNames":["draft","enabled","paused"]},"pausedReason":{"description":"Por que está pausado: manual, failures, emergency ou zoppy_token_revoked","type":"string","enum":["manual","failures","emergency","zoppy_token_revoked"],"x-enumNames":["manual","failures","emergency","zoppyTokenRevoked"],"nullable":true},"pausedAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"headSeq":{"description":"Versão mais nova, publicada ou não; null antes da primeira","type":"integer","nullable":true},"publishedSeq":{"description":"Versão que roda de verdade","type":"integer","nullable":true},"scheduleEveryMinutes":{"description":"Intervalo do cron da versão publicada","type":"integer","nullable":true},"nextRunAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"approvedHosts":{"description":"Hosts que uma pessoa aprovou para os ensaios","type":"array","items":{"type":"string"}},"pendingHosts":{"description":"Hosts da versão mais nova ainda esperando aprovação","type":"array","items":{"type":"string"}},"createdAt":{"description":"Quando foi criado","type":"string","format":"date-time"},"updatedAt":{"description":"Última alteração","type":"string","format":"date-time"},"direction":{"description":"De onde vêm e para onde vão os dados, pelo sistema do catálogo e pelo manifesto; null enquanto não está claro","type":"object","properties":{"source":{"description":"Slug do sistema do catálogo de onde vêm os dados (zoppy para a Zoppy)","type":"string"},"target":{"description":"Slug do sistema do catálogo para onde vão os dados (zoppy para a Zoppy)","type":"string"}},"required":["source","target"],"nullable":true},"lastRun":{"description":"A execução mais recente, ensaios inclusos; null antes da primeira","type":"object","properties":{"id":{"description":"Id da execução","type":"string","format":"uuid"},"status":{"description":"running, succeeded, partial, failed ou timed_out","type":"string","enum":["running","succeeded","partial","failed","timed_out"]},"mode":{"description":"live escreve de verdade; dry_run é um ensaio","type":"string","enum":["live","dry_run"],"x-enumNames":["live","dryRun"]},"startedAt":{"description":"Quando começou","type":"string","format":"date-time"},"finishedAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"counters":{"description":"Contagens do ctx.count, por objeto e tipo (read, created, updated, skipped, failed)","type":"object","additionalProperties":{"type":"object","additionalProperties":{"type":"integer"}}},"quarantined":{"description":"Registros que a execução mandou para a quarentena","type":"integer"}},"required":["id","status","mode","startedAt","finishedAt","counters","quarantined"],"nullable":true},"heldWritesCount":{"description":"Escritas em outros sistemas guardadas ou confirmadas, esperando para sair","type":"integer","minimum":0,"exclusiveMinimum":false},"agentId":{"description":"Primeiro agente local do manifesto (da versão publicada ou, antes de publicar, da mais nova)","type":"string","nullable":true}},"required":["id","name","description","systemId","status","pausedReason","pausedAt","headSeq","publishedSeq","scheduleEveryMinutes","nextRunAt","approvedHosts","pendingHosts","createdAt","updatedAt","direction","lastRun","heldWritesCount","agentId"]}}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Conectores da loja","tags":["connectors"]},"post":{"description":"Cria um conector em rascunho. Na primeira vez da loja, gera o acesso do Connect à Zoppy (ExternalToken) com o token de quem chamou.","operationId":"ConnectorsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"description":"Nome do conector","type":"string","minLength":1,"maxLength":120},"description":{"description":"O que ele deve fazer","type":"string","maxLength":1000,"nullable":true,"default":null},"systemId":{"description":"Sistema do catálogo de onde ele parte","type":"string","format":"uuid","nullable":true,"default":null}},"required":["name"]}}}},"responses":{"201":{"description":"Conector criado","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"description":"Id do conector","type":"string","format":"uuid"},"name":{"description":"Nome que a loja deu ao conector","type":"string"},"description":{"description":"O que o conector faz","type":"string","nullable":true},"systemId":{"description":"Sistema do catálogo de onde ele partiu","type":"string","format":"uuid","nullable":true},"status":{"description":"draft, enabled ou paused","type":"string","enum":["draft","enabled","paused"],"x-enumNames":["draft","enabled","paused"]},"pausedReason":{"description":"Por que está pausado: manual, failures, emergency ou zoppy_token_revoked","type":"string","enum":["manual","failures","emergency","zoppy_token_revoked"],"x-enumNames":["manual","failures","emergency","zoppyTokenRevoked"],"nullable":true},"pausedAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"headSeq":{"description":"Versão mais nova, publicada ou não; null antes da primeira","type":"integer","nullable":true},"publishedSeq":{"description":"Versão que roda de verdade","type":"integer","nullable":true},"scheduleEveryMinutes":{"description":"Intervalo do cron da versão publicada","type":"integer","nullable":true},"nextRunAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"approvedHosts":{"description":"Hosts que uma pessoa aprovou para os ensaios","type":"array","items":{"type":"string"}},"pendingHosts":{"description":"Hosts da versão mais nova ainda esperando aprovação","type":"array","items":{"type":"string"}},"createdAt":{"description":"Quando foi criado","type":"string","format":"date-time"},"updatedAt":{"description":"Última alteração","type":"string","format":"date-time"},"direction":{"description":"De onde vêm e para onde vão os dados, pelo sistema do catálogo e pelo manifesto; null enquanto não está claro","type":"object","properties":{"source":{"description":"Slug do sistema do catálogo de onde vêm os dados (zoppy para a Zoppy)","type":"string"},"target":{"description":"Slug do sistema do catálogo para onde vão os dados (zoppy para a Zoppy)","type":"string"}},"required":["source","target"],"nullable":true},"lastRun":{"description":"A execução mais recente, ensaios inclusos; null antes da primeira","type":"object","properties":{"id":{"description":"Id da execução","type":"string","format":"uuid"},"status":{"description":"running, succeeded, partial, failed ou timed_out","type":"string","enum":["running","succeeded","partial","failed","timed_out"]},"mode":{"description":"live escreve de verdade; dry_run é um ensaio","type":"string","enum":["live","dry_run"],"x-enumNames":["live","dryRun"]},"startedAt":{"description":"Quando começou","type":"string","format":"date-time"},"finishedAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"counters":{"description":"Contagens do ctx.count, por objeto e tipo (read, created, updated, skipped, failed)","type":"object","additionalProperties":{"type":"object","additionalProperties":{"type":"integer"}}},"quarantined":{"description":"Registros que a execução mandou para a quarentena","type":"integer"}},"required":["id","status","mode","startedAt","finishedAt","counters","quarantined"],"nullable":true},"heldWritesCount":{"description":"Escritas em outros sistemas guardadas ou confirmadas, esperando para sair","type":"integer","minimum":0,"exclusiveMinimum":false},"agentId":{"description":"Primeiro agente local do manifesto (da versão publicada ou, antes de publicar, da mais nova)","type":"string","nullable":true}},"required":["id","name","description","systemId","status","pausedReason","pausedAt","headSeq","publishedSeq","scheduleEveryMinutes","nextRunAt","approvedHosts","pendingHosts","createdAt","updatedAt","direction","lastRun","heldWritesCount","agentId"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Loja no plano gratuito da Zoppy (connect.zoppy_free_tier)\n\nPapel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"503":{"description":"Zoppy indisponível para gerar o acesso (connect.zoppy_token_unavailable)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Criar conector","tags":["connectors"]}},"/connectors/{connectorId}":{"get":{"description":"Estado do conector, hosts aprovados e hosts que esperam aprovação.","operationId":"ConnectorsController_get","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"responses":{"200":{"description":"Conector","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"description":"Id do conector","type":"string","format":"uuid"},"name":{"description":"Nome que a loja deu ao conector","type":"string"},"description":{"description":"O que o conector faz","type":"string","nullable":true},"systemId":{"description":"Sistema do catálogo de onde ele partiu","type":"string","format":"uuid","nullable":true},"status":{"description":"draft, enabled ou paused","type":"string","enum":["draft","enabled","paused"],"x-enumNames":["draft","enabled","paused"]},"pausedReason":{"description":"Por que está pausado: manual, failures, emergency ou zoppy_token_revoked","type":"string","enum":["manual","failures","emergency","zoppy_token_revoked"],"x-enumNames":["manual","failures","emergency","zoppyTokenRevoked"],"nullable":true},"pausedAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"headSeq":{"description":"Versão mais nova, publicada ou não; null antes da primeira","type":"integer","nullable":true},"publishedSeq":{"description":"Versão que roda de verdade","type":"integer","nullable":true},"scheduleEveryMinutes":{"description":"Intervalo do cron da versão publicada","type":"integer","nullable":true},"nextRunAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"approvedHosts":{"description":"Hosts que uma pessoa aprovou para os ensaios","type":"array","items":{"type":"string"}},"pendingHosts":{"description":"Hosts da versão mais nova ainda esperando aprovação","type":"array","items":{"type":"string"}},"createdAt":{"description":"Quando foi criado","type":"string","format":"date-time"},"updatedAt":{"description":"Última alteração","type":"string","format":"date-time"},"direction":{"description":"De onde vêm e para onde vão os dados, pelo sistema do catálogo e pelo manifesto; null enquanto não está claro","type":"object","properties":{"source":{"description":"Slug do sistema do catálogo de onde vêm os dados (zoppy para a Zoppy)","type":"string"},"target":{"description":"Slug do sistema do catálogo para onde vão os dados (zoppy para a Zoppy)","type":"string"}},"required":["source","target"],"nullable":true},"lastRun":{"description":"A execução mais recente, ensaios inclusos; null antes da primeira","type":"object","properties":{"id":{"description":"Id da execução","type":"string","format":"uuid"},"status":{"description":"running, succeeded, partial, failed ou timed_out","type":"string","enum":["running","succeeded","partial","failed","timed_out"]},"mode":{"description":"live escreve de verdade; dry_run é um ensaio","type":"string","enum":["live","dry_run"],"x-enumNames":["live","dryRun"]},"startedAt":{"description":"Quando começou","type":"string","format":"date-time"},"finishedAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"counters":{"description":"Contagens do ctx.count, por objeto e tipo (read, created, updated, skipped, failed)","type":"object","additionalProperties":{"type":"object","additionalProperties":{"type":"integer"}}},"quarantined":{"description":"Registros que a execução mandou para a quarentena","type":"integer"}},"required":["id","status","mode","startedAt","finishedAt","counters","quarantined"],"nullable":true},"heldWritesCount":{"description":"Escritas em outros sistemas guardadas ou confirmadas, esperando para sair","type":"integer","minimum":0,"exclusiveMinimum":false},"agentId":{"description":"Primeiro agente local do manifesto (da versão publicada ou, antes de publicar, da mais nova)","type":"string","nullable":true}},"required":["id","name","description","systemId","status","pausedReason","pausedAt","headSeq","publishedSeq","scheduleEveryMinutes","nextRunAt","approvedHosts","pendingHosts","createdAt","updatedAt","direction","lastRun","heldWritesCount","agentId"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector de outra loja ou inexistente (connect.connector_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"],"example":{"type":"connect.connector_not_found","title":"Não encontramos esse conector.","status":404}}}}}},"security":[{"bearer":[]}],"summary":"Conector","tags":["connectors"]}},"/connectors/{connectorId}/versions":{"get":{"description":"Todas as versões do conector, da mais nova à mais antiga.","operationId":"ConnectorsController_versions","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"responses":{"200":{"description":"Versões","content":{"application/json":{"schema":{"description":"Versões, da mais nova à mais antiga","type":"array","items":{"type":"object","properties":{"seq":{"description":"Número da versão","type":"integer"},"origin":{"description":"copilot (escrita pela IA), restore ou cli (enviada pela CLI zoppy-connect)","type":"string","enum":["copilot","restore","cli"],"x-enumNames":["copilot","restore","cli"]},"summary":{"description":"O que mudou, em português","type":"string","nullable":true},"authorUserId":{"description":"Quem escreveu ou restaurou","type":"string"},"restoredFromSeq":{"description":"Versão que ela restaurou","type":"integer","nullable":true},"rehearsedAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"needsFullRehearsal":{"description":"Uma amostra limpa foi cortada e nenhum ensaio completo passou desde então: ensaie com scope full","type":"boolean"},"writesWithoutLookup":{"description":"Criações sem consulta anterior vistas no último ensaio desta versão (connect.write_without_lookup); enquanto a lista não estiver vazia, rehearsedAt fica null e publicar responde 409. Um ensaio limpo esvazia a lista","type":"array","items":{"type":"object","properties":{"method":{"description":"Método HTTP da criação","type":"string"},"host":{"description":"Host chamado","type":"string"},"path":{"description":"Caminho chamado, sem query","type":"string"},"count":{"description":"Quantas vezes o ensaio fez essa chamada","type":"integer"}},"required":["method","host","path","count"]}},"published":{"description":"Se esta é a versão que roda de verdade","type":"boolean"},"createdAt":{"description":"Quando foi escrita","type":"string","format":"date-time"}},"required":["seq","origin","summary","authorUserId","restoredFromSeq","rehearsedAt","needsFullRehearsal","writesWithoutLookup","published","createdAt"]}}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector de outra loja ou inexistente (connect.connector_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"],"example":{"type":"connect.connector_not_found","title":"Não encontramos esse conector.","status":404}}}}}},"security":[{"bearer":[]}],"summary":"Versões","tags":["connectors"]},"post":{"description":"Grava o código e o manifesto de uma pasta como versão nova (origin cli), por cima de baseSeq. Se outra versão entrou depois de baseSeq, recusa com 409 e não grava nada. A versão nova segue o mesmo ciclo: só roda depois de um ensaio limpo e de publicar. Segredos não passam por aqui: os que faltam voltam em missingSecrets, para preencher na tela do conector.","operationId":"ConnectorPushesController_push","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"baseSeq":{"description":"headSeq de onde a pasta partiu; uma versão mais nova recusa com 409 connect.version_conflict e nada é gravado","type":"integer","minimum":0,"exclusiveMinimum":false},"code":{"description":"Código TypeScript do conector (connector.ts)","type":"string","minLength":1,"maxLength":200000},"manifest":{"description":"Manifesto da versão (manifest.json); conferido como o de qualquer outra versão","type":"object","additionalProperties":{}},"summary":{"description":"O que mudou, em português","type":"string","maxLength":500,"nullable":true,"default":null}},"required":["baseSeq","code","manifest"]}}}},"responses":{"201":{"description":"Versão gravada","content":{"application/json":{"schema":{"type":"object","properties":{"connectorId":{"description":"Id do conector","type":"string","format":"uuid"},"seq":{"description":"Número da nova versão; mande como baseSeq no próximo push","type":"integer"},"baseSeq":{"description":"Versão sobre a qual ela foi escrita","type":"integer"},"origin":{"description":"Sempre cli: enviada pela CLI zoppy-connect","type":"string","enum":["cli"]},"summary":{"description":"O que mudou","type":"string","nullable":true},"publishedSeq":{"description":"Versão que roda de verdade; a nova só roda depois de um ensaio limpo e de publicar","type":"integer","nullable":true},"pendingHosts":{"description":"Hosts da nova versão esperando aprovação na tela do conector","type":"array","items":{"type":"string"}},"missingSecrets":{"description":"Segredos da nova versão sem valor; preenchidos só na tela do conector","type":"array","items":{"type":"string"}},"zoppyAccessMissing":{"description":"A versão chama a Zoppy e o acesso da loja a ela não está ativo","type":"boolean"}},"required":["connectorId","seq","baseSeq","origin","summary","publishedSeq","pendingHosts","missingSecrets","zoppyAccessMissing"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso, Connect não liberado ou token sem connect:build (connect.forbidden_role, connect.feature_disabled, connect.insufficient_scope)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector de outra loja ou inexistente (connect.connector_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"409":{"description":"Outra versão entrou depois de baseSeq (connect.version_conflict); meta traz baseSeq e headSeq","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"],"example":{"type":"connect.version_conflict","title":"O conector mudou enquanto você editava. Abra a versão mais nova e tente de novo.","status":409,"meta":{"baseSeq":1,"headSeq":2}}}}}},"422":{"description":"Manifesto inválido, código que não compila ou agente indisponível (connect.invalid_manifest, connect.invalid_code, connect.agent_not_available)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Enviar uma versão pela CLI","tags":["cli"]}},"/connectors/{connectorId}/versions/{seq}":{"get":{"description":"Código e manifesto de uma versão.","operationId":"ConnectorsController_version","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}},{"name":"seq","required":true,"in":"path","description":"Número da versão","schema":{"description":"Número da versão","type":"integer","minimum":1,"exclusiveMinimum":false}}],"responses":{"200":{"description":"Versão","content":{"application/json":{"schema":{"type":"object","properties":{"seq":{"description":"Número da versão","type":"integer"},"origin":{"description":"copilot (escrita pela IA), restore ou cli (enviada pela CLI zoppy-connect)","type":"string","enum":["copilot","restore","cli"],"x-enumNames":["copilot","restore","cli"]},"summary":{"description":"O que mudou, em português","type":"string","nullable":true},"authorUserId":{"description":"Quem escreveu ou restaurou","type":"string"},"restoredFromSeq":{"description":"Versão que ela restaurou","type":"integer","nullable":true},"rehearsedAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"needsFullRehearsal":{"description":"Uma amostra limpa foi cortada e nenhum ensaio completo passou desde então: ensaie com scope full","type":"boolean"},"writesWithoutLookup":{"description":"Criações sem consulta anterior vistas no último ensaio desta versão (connect.write_without_lookup); enquanto a lista não estiver vazia, rehearsedAt fica null e publicar responde 409. Um ensaio limpo esvazia a lista","type":"array","items":{"type":"object","properties":{"method":{"description":"Método HTTP da criação","type":"string"},"host":{"description":"Host chamado","type":"string"},"path":{"description":"Caminho chamado, sem query","type":"string"},"count":{"description":"Quantas vezes o ensaio fez essa chamada","type":"integer"}},"required":["method","host","path","count"]}},"published":{"description":"Se esta é a versão que roda de verdade","type":"boolean"},"createdAt":{"description":"Quando foi escrita","type":"string","format":"date-time"},"code":{"description":"Código TypeScript do conector","type":"string"},"manifest":{"description":"Manifesto da versão","type":"object","additionalProperties":{}}},"required":["seq","origin","summary","authorUserId","restoredFromSeq","rehearsedAt","needsFullRehearsal","writesWithoutLookup","published","createdAt","code","manifest"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector ou versão inexistente (connect.version_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Versão","tags":["connectors"]}},"/connectors/{connectorId}/versions/{seq}/diff":{"get":{"description":"Diff unificado do código e do manifesto, da versão `from` até a `seq`.","operationId":"ConnectorsController_diff","parameters":[{"name":"from","required":true,"in":"query","description":"Versão mais antiga a comparar","schema":{"description":"Versão mais antiga a comparar","type":"integer","minimum":1,"exclusiveMinimum":false}},{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}},{"name":"seq","required":true,"in":"path","description":"Número da versão","schema":{"description":"Número da versão","type":"integer","minimum":1,"exclusiveMinimum":false}}],"responses":{"200":{"description":"Diff","content":{"application/json":{"schema":{"type":"object","properties":{"fromSeq":{"description":"Versão mais antiga","type":"integer"},"toSeq":{"description":"Versão mais nova","type":"integer"},"same":{"description":"Se nada mudou","type":"boolean"},"code":{"description":"Diff unificado do código","type":"string"},"manifest":{"description":"Diff unificado do manifesto formatado","type":"string"}},"required":["fromSeq","toSeq","same","code","manifest"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector ou versão inexistente (connect.version_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Diferença entre versões","tags":["connectors"]}},"/connectors/{connectorId}/versions/{seq}/restore":{"post":{"description":"Escreve uma versão nova com o código e o manifesto de seq. Recusa se outra versão entrou depois de baseSeq.","operationId":"ConnectorsController_restore","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}},{"name":"seq","required":true,"in":"path","description":"Número da versão","schema":{"description":"Número da versão","type":"integer","minimum":1,"exclusiveMinimum":false}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"baseSeq":{"description":"headSeq que a pessoa viu; uma versão mais nova recusa com connect.version_conflict","type":"integer","minimum":0,"exclusiveMinimum":false}},"required":["baseSeq"]}}}},"responses":{"201":{"description":"Versão nova","content":{"application/json":{"schema":{"type":"object","properties":{"seq":{"description":"Número da versão","type":"integer"},"origin":{"description":"copilot (escrita pela IA), restore ou cli (enviada pela CLI zoppy-connect)","type":"string","enum":["copilot","restore","cli"],"x-enumNames":["copilot","restore","cli"]},"summary":{"description":"O que mudou, em português","type":"string","nullable":true},"authorUserId":{"description":"Quem escreveu ou restaurou","type":"string"},"restoredFromSeq":{"description":"Versão que ela restaurou","type":"integer","nullable":true},"rehearsedAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"needsFullRehearsal":{"description":"Uma amostra limpa foi cortada e nenhum ensaio completo passou desde então: ensaie com scope full","type":"boolean"},"writesWithoutLookup":{"description":"Criações sem consulta anterior vistas no último ensaio desta versão (connect.write_without_lookup); enquanto a lista não estiver vazia, rehearsedAt fica null e publicar responde 409. Um ensaio limpo esvazia a lista","type":"array","items":{"type":"object","properties":{"method":{"description":"Método HTTP da criação","type":"string"},"host":{"description":"Host chamado","type":"string"},"path":{"description":"Caminho chamado, sem query","type":"string"},"count":{"description":"Quantas vezes o ensaio fez essa chamada","type":"integer"}},"required":["method","host","path","count"]}},"published":{"description":"Se esta é a versão que roda de verdade","type":"boolean"},"createdAt":{"description":"Quando foi escrita","type":"string","format":"date-time"}},"required":["seq","origin","summary","authorUserId","restoredFromSeq","rehearsedAt","needsFullRehearsal","writesWithoutLookup","published","createdAt"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector ou versão inexistente (connect.version_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"409":{"description":"Outra versão entrou antes (connect.version_conflict)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Restaurar versão","tags":["connectors"]}},"/connectors/{connectorId}/publish/preview":{"post":{"description":"Mostra o que muda ao publicar a versão mais nova e devolve o token da confirmação (10 minutos, uso único). Recusa se a versão não tem um ensaio limpo que leu a origem inteira.","operationId":"ConnectorsController_previewPublish","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"responses":{"200":{"description":"Prévia","content":{"application/json":{"schema":{"type":"object","properties":{"title":{"description":"O que vai acontecer, em português","type":"string"},"changes":{"description":"Cada consequência, em português","type":"array","items":{"type":"string"}},"token":{"description":"Mande de volta para aplicar; vale por 10 minutos e só para este estado","type":"string"},"expiresAt":{"description":"Quando o token deixa de valer","type":"string","format":"date-time"}},"required":["title","changes","token","expiresAt"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector de outra loja ou inexistente (connect.connector_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"],"example":{"type":"connect.connector_not_found","title":"Não encontramos esse conector.","status":404}}}}},"409":{"description":"Versão sem ensaio limpo que leu a origem inteira (connect.not_rehearsed), ou cujo último ensaio criou registros sem consultar antes (connect.write_without_lookup); Estado do conector não permite a mudança (connect.connector_transition_refused)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Prévia de publicar","tags":["connectors"]}},"/connectors/{connectorId}/publish":{"post":{"description":"Publica a versão mais nova com o token da prévia.","operationId":"ConnectorsController_publish","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"description":"Token da prévia","type":"string","minLength":1}},"required":["token"]}}}},"responses":{"200":{"description":"Conector","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"description":"Id do conector","type":"string","format":"uuid"},"name":{"description":"Nome que a loja deu ao conector","type":"string"},"description":{"description":"O que o conector faz","type":"string","nullable":true},"systemId":{"description":"Sistema do catálogo de onde ele partiu","type":"string","format":"uuid","nullable":true},"status":{"description":"draft, enabled ou paused","type":"string","enum":["draft","enabled","paused"],"x-enumNames":["draft","enabled","paused"]},"pausedReason":{"description":"Por que está pausado: manual, failures, emergency ou zoppy_token_revoked","type":"string","enum":["manual","failures","emergency","zoppy_token_revoked"],"x-enumNames":["manual","failures","emergency","zoppyTokenRevoked"],"nullable":true},"pausedAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"headSeq":{"description":"Versão mais nova, publicada ou não; null antes da primeira","type":"integer","nullable":true},"publishedSeq":{"description":"Versão que roda de verdade","type":"integer","nullable":true},"scheduleEveryMinutes":{"description":"Intervalo do cron da versão publicada","type":"integer","nullable":true},"nextRunAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"approvedHosts":{"description":"Hosts que uma pessoa aprovou para os ensaios","type":"array","items":{"type":"string"}},"pendingHosts":{"description":"Hosts da versão mais nova ainda esperando aprovação","type":"array","items":{"type":"string"}},"createdAt":{"description":"Quando foi criado","type":"string","format":"date-time"},"updatedAt":{"description":"Última alteração","type":"string","format":"date-time"},"direction":{"description":"De onde vêm e para onde vão os dados, pelo sistema do catálogo e pelo manifesto; null enquanto não está claro","type":"object","properties":{"source":{"description":"Slug do sistema do catálogo de onde vêm os dados (zoppy para a Zoppy)","type":"string"},"target":{"description":"Slug do sistema do catálogo para onde vão os dados (zoppy para a Zoppy)","type":"string"}},"required":["source","target"],"nullable":true},"lastRun":{"description":"A execução mais recente, ensaios inclusos; null antes da primeira","type":"object","properties":{"id":{"description":"Id da execução","type":"string","format":"uuid"},"status":{"description":"running, succeeded, partial, failed ou timed_out","type":"string","enum":["running","succeeded","partial","failed","timed_out"]},"mode":{"description":"live escreve de verdade; dry_run é um ensaio","type":"string","enum":["live","dry_run"],"x-enumNames":["live","dryRun"]},"startedAt":{"description":"Quando começou","type":"string","format":"date-time"},"finishedAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"counters":{"description":"Contagens do ctx.count, por objeto e tipo (read, created, updated, skipped, failed)","type":"object","additionalProperties":{"type":"object","additionalProperties":{"type":"integer"}}},"quarantined":{"description":"Registros que a execução mandou para a quarentena","type":"integer"}},"required":["id","status","mode","startedAt","finishedAt","counters","quarantined"],"nullable":true},"heldWritesCount":{"description":"Escritas em outros sistemas guardadas ou confirmadas, esperando para sair","type":"integer","minimum":0,"exclusiveMinimum":false},"agentId":{"description":"Primeiro agente local do manifesto (da versão publicada ou, antes de publicar, da mais nova)","type":"string","nullable":true}},"required":["id","name","description","systemId","status","pausedReason","pausedAt","headSeq","publishedSeq","scheduleEveryMinutes","nextRunAt","approvedHosts","pendingHosts","createdAt","updatedAt","direction","lastRun","heldWritesCount","agentId"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector de outra loja ou inexistente (connect.connector_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"],"example":{"type":"connect.connector_not_found","title":"Não encontramos esse conector.","status":404}}}}},"409":{"description":"O conector mudou depois da prévia ou o token já foi usado (connect.confirmation_stale); token expirado ou de outra prévia (connect.confirmation_refused); Versão sem ensaio limpo que leu a origem inteira (connect.not_rehearsed), ou cujo último ensaio criou registros sem consultar antes (connect.write_without_lookup); Estado do conector não permite a mudança (connect.connector_transition_refused)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Publicar","tags":["connectors"]}},"/connectors/{connectorId}/enable/preview":{"post":{"description":"Mostra o que muda ao ligar o conector publicado no cron do manifesto e devolve o token da confirmação. Um conector que fala com a Zoppy exige o acesso à Zoppy ativo.","operationId":"ConnectorsController_previewEnable","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"responses":{"200":{"description":"Prévia","content":{"application/json":{"schema":{"type":"object","properties":{"title":{"description":"O que vai acontecer, em português","type":"string"},"changes":{"description":"Cada consequência, em português","type":"array","items":{"type":"string"}},"token":{"description":"Mande de volta para aplicar; vale por 10 minutos e só para este estado","type":"string"},"expiresAt":{"description":"Quando o token deixa de valer","type":"string","format":"date-time"}},"required":["title","changes","token","expiresAt"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector de outra loja ou inexistente (connect.connector_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"],"example":{"type":"connect.connector_not_found","title":"Não encontramos esse conector.","status":404}}}}},"409":{"description":"Estado do conector não permite a mudança (connect.connector_transition_refused)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Prévia de ligar","tags":["connectors"]}},"/connectors/{connectorId}/enable":{"post":{"description":"Liga o conector publicado com o token da prévia; a primeira execução sai agora.","operationId":"ConnectorsController_enable","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"description":"Token da prévia","type":"string","minLength":1}},"required":["token"]}}}},"responses":{"200":{"description":"Conector","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"description":"Id do conector","type":"string","format":"uuid"},"name":{"description":"Nome que a loja deu ao conector","type":"string"},"description":{"description":"O que o conector faz","type":"string","nullable":true},"systemId":{"description":"Sistema do catálogo de onde ele partiu","type":"string","format":"uuid","nullable":true},"status":{"description":"draft, enabled ou paused","type":"string","enum":["draft","enabled","paused"],"x-enumNames":["draft","enabled","paused"]},"pausedReason":{"description":"Por que está pausado: manual, failures, emergency ou zoppy_token_revoked","type":"string","enum":["manual","failures","emergency","zoppy_token_revoked"],"x-enumNames":["manual","failures","emergency","zoppyTokenRevoked"],"nullable":true},"pausedAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"headSeq":{"description":"Versão mais nova, publicada ou não; null antes da primeira","type":"integer","nullable":true},"publishedSeq":{"description":"Versão que roda de verdade","type":"integer","nullable":true},"scheduleEveryMinutes":{"description":"Intervalo do cron da versão publicada","type":"integer","nullable":true},"nextRunAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"approvedHosts":{"description":"Hosts que uma pessoa aprovou para os ensaios","type":"array","items":{"type":"string"}},"pendingHosts":{"description":"Hosts da versão mais nova ainda esperando aprovação","type":"array","items":{"type":"string"}},"createdAt":{"description":"Quando foi criado","type":"string","format":"date-time"},"updatedAt":{"description":"Última alteração","type":"string","format":"date-time"},"direction":{"description":"De onde vêm e para onde vão os dados, pelo sistema do catálogo e pelo manifesto; null enquanto não está claro","type":"object","properties":{"source":{"description":"Slug do sistema do catálogo de onde vêm os dados (zoppy para a Zoppy)","type":"string"},"target":{"description":"Slug do sistema do catálogo para onde vão os dados (zoppy para a Zoppy)","type":"string"}},"required":["source","target"],"nullable":true},"lastRun":{"description":"A execução mais recente, ensaios inclusos; null antes da primeira","type":"object","properties":{"id":{"description":"Id da execução","type":"string","format":"uuid"},"status":{"description":"running, succeeded, partial, failed ou timed_out","type":"string","enum":["running","succeeded","partial","failed","timed_out"]},"mode":{"description":"live escreve de verdade; dry_run é um ensaio","type":"string","enum":["live","dry_run"],"x-enumNames":["live","dryRun"]},"startedAt":{"description":"Quando começou","type":"string","format":"date-time"},"finishedAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"counters":{"description":"Contagens do ctx.count, por objeto e tipo (read, created, updated, skipped, failed)","type":"object","additionalProperties":{"type":"object","additionalProperties":{"type":"integer"}}},"quarantined":{"description":"Registros que a execução mandou para a quarentena","type":"integer"}},"required":["id","status","mode","startedAt","finishedAt","counters","quarantined"],"nullable":true},"heldWritesCount":{"description":"Escritas em outros sistemas guardadas ou confirmadas, esperando para sair","type":"integer","minimum":0,"exclusiveMinimum":false},"agentId":{"description":"Primeiro agente local do manifesto (da versão publicada ou, antes de publicar, da mais nova)","type":"string","nullable":true}},"required":["id","name","description","systemId","status","pausedReason","pausedAt","headSeq","publishedSeq","scheduleEveryMinutes","nextRunAt","approvedHosts","pendingHosts","createdAt","updatedAt","direction","lastRun","heldWritesCount","agentId"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector de outra loja ou inexistente (connect.connector_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"],"example":{"type":"connect.connector_not_found","title":"Não encontramos esse conector.","status":404}}}}},"409":{"description":"O conector mudou depois da prévia ou o token já foi usado (connect.confirmation_stale); token expirado ou de outra prévia (connect.confirmation_refused); Estado do conector não permite a mudança (connect.connector_transition_refused)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Ligar","tags":["connectors"]}},"/connectors/{connectorId}/pause/preview":{"post":{"description":"Mostra o que muda ao pausar o conector ligado e devolve o token da confirmação.","operationId":"ConnectorsController_previewPause","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"responses":{"200":{"description":"Prévia","content":{"application/json":{"schema":{"type":"object","properties":{"title":{"description":"O que vai acontecer, em português","type":"string"},"changes":{"description":"Cada consequência, em português","type":"array","items":{"type":"string"}},"token":{"description":"Mande de volta para aplicar; vale por 10 minutos e só para este estado","type":"string"},"expiresAt":{"description":"Quando o token deixa de valer","type":"string","format":"date-time"}},"required":["title","changes","token","expiresAt"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector de outra loja ou inexistente (connect.connector_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"],"example":{"type":"connect.connector_not_found","title":"Não encontramos esse conector.","status":404}}}}},"409":{"description":"Estado do conector não permite a mudança (connect.connector_transition_refused)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Prévia de pausar","tags":["connectors"]}},"/connectors/{connectorId}/pause":{"post":{"description":"Pausa o conector ligado com o token da prévia; ele para de rodar até ser ligado de novo.","operationId":"ConnectorsController_pause","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"description":"Token da prévia","type":"string","minLength":1}},"required":["token"]}}}},"responses":{"200":{"description":"Conector","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"description":"Id do conector","type":"string","format":"uuid"},"name":{"description":"Nome que a loja deu ao conector","type":"string"},"description":{"description":"O que o conector faz","type":"string","nullable":true},"systemId":{"description":"Sistema do catálogo de onde ele partiu","type":"string","format":"uuid","nullable":true},"status":{"description":"draft, enabled ou paused","type":"string","enum":["draft","enabled","paused"],"x-enumNames":["draft","enabled","paused"]},"pausedReason":{"description":"Por que está pausado: manual, failures, emergency ou zoppy_token_revoked","type":"string","enum":["manual","failures","emergency","zoppy_token_revoked"],"x-enumNames":["manual","failures","emergency","zoppyTokenRevoked"],"nullable":true},"pausedAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"headSeq":{"description":"Versão mais nova, publicada ou não; null antes da primeira","type":"integer","nullable":true},"publishedSeq":{"description":"Versão que roda de verdade","type":"integer","nullable":true},"scheduleEveryMinutes":{"description":"Intervalo do cron da versão publicada","type":"integer","nullable":true},"nextRunAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"approvedHosts":{"description":"Hosts que uma pessoa aprovou para os ensaios","type":"array","items":{"type":"string"}},"pendingHosts":{"description":"Hosts da versão mais nova ainda esperando aprovação","type":"array","items":{"type":"string"}},"createdAt":{"description":"Quando foi criado","type":"string","format":"date-time"},"updatedAt":{"description":"Última alteração","type":"string","format":"date-time"},"direction":{"description":"De onde vêm e para onde vão os dados, pelo sistema do catálogo e pelo manifesto; null enquanto não está claro","type":"object","properties":{"source":{"description":"Slug do sistema do catálogo de onde vêm os dados (zoppy para a Zoppy)","type":"string"},"target":{"description":"Slug do sistema do catálogo para onde vão os dados (zoppy para a Zoppy)","type":"string"}},"required":["source","target"],"nullable":true},"lastRun":{"description":"A execução mais recente, ensaios inclusos; null antes da primeira","type":"object","properties":{"id":{"description":"Id da execução","type":"string","format":"uuid"},"status":{"description":"running, succeeded, partial, failed ou timed_out","type":"string","enum":["running","succeeded","partial","failed","timed_out"]},"mode":{"description":"live escreve de verdade; dry_run é um ensaio","type":"string","enum":["live","dry_run"],"x-enumNames":["live","dryRun"]},"startedAt":{"description":"Quando começou","type":"string","format":"date-time"},"finishedAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"counters":{"description":"Contagens do ctx.count, por objeto e tipo (read, created, updated, skipped, failed)","type":"object","additionalProperties":{"type":"object","additionalProperties":{"type":"integer"}}},"quarantined":{"description":"Registros que a execução mandou para a quarentena","type":"integer"}},"required":["id","status","mode","startedAt","finishedAt","counters","quarantined"],"nullable":true},"heldWritesCount":{"description":"Escritas em outros sistemas guardadas ou confirmadas, esperando para sair","type":"integer","minimum":0,"exclusiveMinimum":false},"agentId":{"description":"Primeiro agente local do manifesto (da versão publicada ou, antes de publicar, da mais nova)","type":"string","nullable":true}},"required":["id","name","description","systemId","status","pausedReason","pausedAt","headSeq","publishedSeq","scheduleEveryMinutes","nextRunAt","approvedHosts","pendingHosts","createdAt","updatedAt","direction","lastRun","heldWritesCount","agentId"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector de outra loja ou inexistente (connect.connector_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"],"example":{"type":"connect.connector_not_found","title":"Não encontramos esse conector.","status":404}}}}},"409":{"description":"O conector mudou depois da prévia ou o token já foi usado (connect.confirmation_stale); token expirado ou de outra prévia (connect.confirmation_refused); Estado do conector não permite a mudança (connect.connector_transition_refused)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Pausar","tags":["connectors"]}},"/connectors/{connectorId}/hosts/preview":{"post":{"description":"Mostra o que muda ao aprovar hosts novos da versão mais nova e devolve o token da confirmação (10 minutos).","operationId":"ConnectorsController_previewHosts","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"hosts":{"description":"Hosts da versão mais nova a aprovar","type":"array","minItems":1,"maxItems":20,"items":{"type":"string","minLength":1,"maxLength":253}}},"required":["hosts"]}}}},"responses":{"200":{"description":"Prévia","content":{"application/json":{"schema":{"type":"object","properties":{"title":{"description":"O que vai acontecer, em português","type":"string"},"changes":{"description":"Cada consequência, em português","type":"array","items":{"type":"string"}},"token":{"description":"Mande de volta para aplicar; vale por 10 minutos e só para este estado","type":"string"},"expiresAt":{"description":"Quando o token deixa de valer","type":"string","format":"date-time"}},"required":["title","changes","token","expiresAt"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector de outra loja ou inexistente (connect.connector_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"],"example":{"type":"connect.connector_not_found","title":"Não encontramos esse conector.","status":404}}}}},"422":{"description":"Host fora do manifesto (connect.host_not_declared)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Prévia da aprovação de hosts","tags":["connectors"]}},"/connectors/{connectorId}/hosts/approve":{"post":{"description":"Aprova os hosts da prévia, com o token dela.","operationId":"ConnectorsController_approveHosts","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"hosts":{"description":"Hosts da versão mais nova a aprovar","type":"array","minItems":1,"maxItems":20,"items":{"type":"string","minLength":1,"maxLength":253}},"token":{"description":"Token da prévia","type":"string","minLength":1}},"required":["hosts","token"]}}}},"responses":{"200":{"description":"Conector","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"description":"Id do conector","type":"string","format":"uuid"},"name":{"description":"Nome que a loja deu ao conector","type":"string"},"description":{"description":"O que o conector faz","type":"string","nullable":true},"systemId":{"description":"Sistema do catálogo de onde ele partiu","type":"string","format":"uuid","nullable":true},"status":{"description":"draft, enabled ou paused","type":"string","enum":["draft","enabled","paused"],"x-enumNames":["draft","enabled","paused"]},"pausedReason":{"description":"Por que está pausado: manual, failures, emergency ou zoppy_token_revoked","type":"string","enum":["manual","failures","emergency","zoppy_token_revoked"],"x-enumNames":["manual","failures","emergency","zoppyTokenRevoked"],"nullable":true},"pausedAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"headSeq":{"description":"Versão mais nova, publicada ou não; null antes da primeira","type":"integer","nullable":true},"publishedSeq":{"description":"Versão que roda de verdade","type":"integer","nullable":true},"scheduleEveryMinutes":{"description":"Intervalo do cron da versão publicada","type":"integer","nullable":true},"nextRunAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"approvedHosts":{"description":"Hosts que uma pessoa aprovou para os ensaios","type":"array","items":{"type":"string"}},"pendingHosts":{"description":"Hosts da versão mais nova ainda esperando aprovação","type":"array","items":{"type":"string"}},"createdAt":{"description":"Quando foi criado","type":"string","format":"date-time"},"updatedAt":{"description":"Última alteração","type":"string","format":"date-time"},"direction":{"description":"De onde vêm e para onde vão os dados, pelo sistema do catálogo e pelo manifesto; null enquanto não está claro","type":"object","properties":{"source":{"description":"Slug do sistema do catálogo de onde vêm os dados (zoppy para a Zoppy)","type":"string"},"target":{"description":"Slug do sistema do catálogo para onde vão os dados (zoppy para a Zoppy)","type":"string"}},"required":["source","target"],"nullable":true},"lastRun":{"description":"A execução mais recente, ensaios inclusos; null antes da primeira","type":"object","properties":{"id":{"description":"Id da execução","type":"string","format":"uuid"},"status":{"description":"running, succeeded, partial, failed ou timed_out","type":"string","enum":["running","succeeded","partial","failed","timed_out"]},"mode":{"description":"live escreve de verdade; dry_run é um ensaio","type":"string","enum":["live","dry_run"],"x-enumNames":["live","dryRun"]},"startedAt":{"description":"Quando começou","type":"string","format":"date-time"},"finishedAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"counters":{"description":"Contagens do ctx.count, por objeto e tipo (read, created, updated, skipped, failed)","type":"object","additionalProperties":{"type":"object","additionalProperties":{"type":"integer"}}},"quarantined":{"description":"Registros que a execução mandou para a quarentena","type":"integer"}},"required":["id","status","mode","startedAt","finishedAt","counters","quarantined"],"nullable":true},"heldWritesCount":{"description":"Escritas em outros sistemas guardadas ou confirmadas, esperando para sair","type":"integer","minimum":0,"exclusiveMinimum":false},"agentId":{"description":"Primeiro agente local do manifesto (da versão publicada ou, antes de publicar, da mais nova)","type":"string","nullable":true}},"required":["id","name","description","systemId","status","pausedReason","pausedAt","headSeq","publishedSeq","scheduleEveryMinutes","nextRunAt","approvedHosts","pendingHosts","createdAt","updatedAt","direction","lastRun","heldWritesCount","agentId"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector de outra loja ou inexistente (connect.connector_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"],"example":{"type":"connect.connector_not_found","title":"Não encontramos esse conector.","status":404}}}}},"409":{"description":"Token expirado, de outra prévia ou o conector mudou (connect.confirmation_refused)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Aprovar hosts","tags":["connectors"]}},"/connectors/{connectorId}/secrets":{"get":{"description":"Os segredos que a versão mais nova pede e se cada um já foi preenchido. O valor nunca volta.","operationId":"ConnectorSecretsController_list","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"responses":{"200":{"description":"Segredos","content":{"application/json":{"schema":{"description":"Segredos que a versão mais nova pede","type":"array","items":{"type":"object","properties":{"name":{"description":"Nome que o código usa em ctx.secret","type":"string"},"label":{"description":"O que a pessoa preenche","type":"string"},"help":{"description":"Onde achar o valor","type":"string","nullable":true},"filled":{"description":"Se há valor guardado; o valor nunca volta","type":"boolean"},"setAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true}},"required":["name","label","help","filled","setAt"]}}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector de outra loja ou inexistente (connect.connector_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"],"example":{"type":"connect.connector_not_found","title":"Não encontramos esse conector.","status":404}}}}}},"security":[{"bearer":[]}],"summary":"Segredos pedidos","tags":["connectors"]}},"/connectors/{connectorId}/secrets/{name}":{"put":{"description":"Guarda o valor cifrado, fora do chat. Só aceita nomes que o manifesto da versão mais nova pede.","operationId":"ConnectorSecretsController_set","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}},{"name":"name","required":true,"in":"path","description":"Nome do segredo","schema":{"description":"Nome do segredo","type":"string","pattern":"^[A-Z][A-Z0-9_]{0,63}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"value":{"description":"O valor; guardado criptografado e nunca devolvido","type":"string","minLength":1,"maxLength":8192}},"required":["value"]}}}},"responses":{"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector de outra loja ou inexistente (connect.connector_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"],"example":{"type":"connect.connector_not_found","title":"Não encontramos esse conector.","status":404}}}}},"422":{"description":"O manifesto não pede esse segredo (connect.secret_not_declared)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Preencher segredo","tags":["connectors"]}},"/connect/systems":{"get":{"description":"Sistemas do catálogo, a Zoppy (oficial) primeiro.","operationId":"ConnectSystemsController_search","parameters":[{"name":"search","required":false,"in":"query","description":"Parte do nome ou do slug","schema":{"description":"Parte do nome ou do slug","type":"string","maxLength":80}},{"name":"category","required":false,"in":"query","description":"Categoria do sistema","schema":{"description":"Categoria do sistema","type":"string","enum":["erp","ecommerce","finance","marketing","helpdesk","database","other"],"x-enumNames":["erp","ecommerce","finance","marketing","helpdesk","database","other"]}}],"responses":{"200":{"description":"Sistemas","content":{"application/json":{"schema":{"description":"Sistemas do catálogo, os oficiais primeiro","type":"array","items":{"type":"object","properties":{"id":{"description":"Id do sistema","type":"string","format":"uuid"},"slug":{"description":"Nome curto e estável","type":"string"},"name":{"description":"Nome do sistema","type":"string"},"description":{"description":"O que é o sistema, em uma linha em português","type":"string","nullable":true},"category":{"description":"Categoria","type":"string","enum":["erp","ecommerce","finance","marketing","helpdesk","database","other"],"x-enumNames":["erp","ecommerce","finance","marketing","helpdesk","database","other"]},"runsOn":{"description":"cloud ou local_agent","type":"string","enum":["cloud","local_agent"],"x-enumNames":["cloud","localAgent"]},"accessKind":{"description":"Como a loja dá acesso","type":"string","enum":["token","key_secret","user_password","database"],"x-enumNames":["token","keySecret","userPassword","database"]},"official":{"description":"Se a plataforma mantém o sistema (a Zoppy é)","type":"boolean"},"nativeIntegration":{"description":"Se a Zoppy já integra o sistema nativamente: a IA avisa antes de escrever o mesmo recurso","type":"boolean"},"logoUrl":{"description":"Caminho do logo servido pelo Connect, com a versão dele; null quando não tem","type":"string","nullable":true},"hosts":{"description":"Hosts já conhecidos do sistema","type":"array","items":{"type":"string"}},"docsUrl":{"description":"Documentação oficial","type":"string","nullable":true},"worthBringing":{"description":"O que costuma valer a pena trazer dele","type":"array","items":{"type":"string"}},"usageCount":{"description":"Quantas lojas têm um conector ligado com este sistema; só a contagem","type":"integer","minimum":0,"exclusiveMinimum":false},"comingSoon":{"description":"Aparece no catálogo, mas ainda não aceita conectores","type":"boolean"},"oauthOnly":{"description":"O sistema só dá acesso por OAuth, que o Connect ainda não suporta","type":"boolean"}},"required":["id","slug","name","description","category","runsOn","accessKind","official","nativeIntegration","logoUrl","hosts","docsUrl","worthBringing","usageCount","comingSoon","oauthOnly"]}}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Catálogo de sistemas","tags":["systems-catalog"]}},"/connect/systems/{systemId}":{"get":{"description":"Um sistema do catálogo.","operationId":"ConnectSystemsController_get","parameters":[{"name":"systemId","required":true,"in":"path","description":"Id do sistema no catálogo","schema":{"description":"Id do sistema no catálogo","type":"string","format":"uuid"}}],"responses":{"200":{"description":"Sistema","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"description":"Id do sistema","type":"string","format":"uuid"},"slug":{"description":"Nome curto e estável","type":"string"},"name":{"description":"Nome do sistema","type":"string"},"description":{"description":"O que é o sistema, em uma linha em português","type":"string","nullable":true},"category":{"description":"Categoria","type":"string","enum":["erp","ecommerce","finance","marketing","helpdesk","database","other"],"x-enumNames":["erp","ecommerce","finance","marketing","helpdesk","database","other"]},"runsOn":{"description":"cloud ou local_agent","type":"string","enum":["cloud","local_agent"],"x-enumNames":["cloud","localAgent"]},"accessKind":{"description":"Como a loja dá acesso","type":"string","enum":["token","key_secret","user_password","database"],"x-enumNames":["token","keySecret","userPassword","database"]},"official":{"description":"Se a plataforma mantém o sistema (a Zoppy é)","type":"boolean"},"nativeIntegration":{"description":"Se a Zoppy já integra o sistema nativamente: a IA avisa antes de escrever o mesmo recurso","type":"boolean"},"logoUrl":{"description":"Caminho do logo servido pelo Connect, com a versão dele; null quando não tem","type":"string","nullable":true},"hosts":{"description":"Hosts já conhecidos do sistema","type":"array","items":{"type":"string"}},"docsUrl":{"description":"Documentação oficial","type":"string","nullable":true},"worthBringing":{"description":"O que costuma valer a pena trazer dele","type":"array","items":{"type":"string"}},"usageCount":{"description":"Quantas lojas têm um conector ligado com este sistema; só a contagem","type":"integer","minimum":0,"exclusiveMinimum":false},"comingSoon":{"description":"Aparece no catálogo, mas ainda não aceita conectores","type":"boolean"},"oauthOnly":{"description":"O sistema só dá acesso por OAuth, que o Connect ainda não suporta","type":"boolean"}},"required":["id","slug","name","description","category","runsOn","accessKind","official","nativeIntegration","logoUrl","hosts","docsUrl","worthBringing","usageCount","comingSoon","oauthOnly"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Sistema fora do catálogo (connect.system_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Sistema do catálogo","tags":["systems-catalog"]}},"/connect/systems/{systemId}/logo":{"get":{"description":"O PNG do logo, servido pelo Connect; nunca um link de terceiro.","operationId":"ConnectSystemsController_logo","parameters":[{"name":"systemId","required":true,"in":"path","description":"Id do sistema no catálogo","schema":{"description":"Id do sistema no catálogo","type":"string","format":"uuid"}}],"responses":{"400":{"description":"Entrada inválida (validation_failed)","content":{"image/png":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"image/png":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"image/png":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Sistema sem logo (connect.system_logo_not_found)","content":{"image/png":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Logo do sistema","tags":["systems-catalog"]}},"/connect/systems/{systemId}/notes":{"get":{"description":"O que se sabe do sistema para construir conectores: as notas oficiais primeiro, depois as aprendidas. Uma nota aprendida por outra loja só aparece depois de um ensaio limpo do conector que a escreveu; as desta loja aparecem já, marcadas como pendentes.","operationId":"ConnectSystemsController_notes","parameters":[{"name":"systemId","required":true,"in":"path","description":"Id do sistema no catálogo","schema":{"description":"Id do sistema no catálogo","type":"string","format":"uuid"}}],"responses":{"200":{"description":"Notas","content":{"application/json":{"schema":{"description":"Notas do sistema, as oficiais primeiro","type":"array","items":{"type":"object","properties":{"id":{"description":"Id da nota","type":"string","format":"uuid"},"topic":{"description":"Assunto da nota: documentation, authentication, pagination, limits ou pitfall","type":"string"},"text":{"description":"A nota, em uma linha em português","type":"string"},"official":{"description":"Escrita pela plataforma, não aprendida numa conversa","type":"boolean"},"pending":{"description":"Aprendida por esta loja e esperando um ensaio limpo antes de outras lojas verem","type":"boolean"},"createdAt":{"description":"Quando foi registrada","type":"string","format":"date-time"}},"required":["id","topic","text","official","pending","createdAt"]}}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Sistema fora do catálogo (connect.system_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Notas do sistema","tags":["systems-catalog"]}},"/connect/manifest.schema.json":{"get":{"description":"O manifesto do conector como JSON Schema (draft-07).","operationId":"ConnectSystemsController_manifestSchema","parameters":[],"responses":{"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"JSON Schema do manifesto","tags":["systems-catalog"]}},"/connect/zoppy-token":{"get":{"description":"Se o acesso do Connect à Zoppy está ativo, revogado ou ainda não existe, e os conectores pausados pela revogação.","operationId":"ZoppyTokenController_status","parameters":[],"responses":{"200":{"description":"Acesso","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"description":"Acesso do Connect à Zoppy","type":"string","enum":["active","revoked","missing"]},"externalTokenId":{"description":"Id do ExternalToken na Zoppy","type":"string","nullable":true},"createdByUserId":{"description":"Quem gerou","type":"string","nullable":true},"createdAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"revokedAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"pausedConnectors":{"description":"Conectores pausados porque o acesso foi revogado","type":"array","items":{"type":"object","properties":{"id":{"description":"Id do conector","type":"string","format":"uuid"},"name":{"description":"Nome do conector","type":"string"}},"required":["id","name"]}}},"required":["status","externalTokenId","createdByUserId","createdAt","revokedAt","pausedConnectors"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Acesso à Zoppy","tags":["zoppy-access"]},"post":{"description":"Chamado ao entrar: gera um novo ExternalToken quando não há um ativo e devolve a prévia para religar os conectores pausados pela revogação.","operationId":"ZoppyTokenController_ensure","parameters":[],"responses":{"200":{"description":"Acesso e prévia","content":{"application/json":{"schema":{"type":"object","properties":{"token":{"description":"Acesso depois da chamada","type":"object","properties":{"status":{"description":"Acesso do Connect à Zoppy","type":"string","enum":["active","revoked","missing"]},"externalTokenId":{"description":"Id do ExternalToken na Zoppy","type":"string","nullable":true},"createdByUserId":{"description":"Quem gerou","type":"string","nullable":true},"createdAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"revokedAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"pausedConnectors":{"description":"Conectores pausados porque o acesso foi revogado","type":"array","items":{"type":"object","properties":{"id":{"description":"Id do conector","type":"string","format":"uuid"},"name":{"description":"Nome do conector","type":"string"}},"required":["id","name"]}}},"required":["status","externalTokenId","createdByUserId","createdAt","revokedAt","pausedConnectors"]},"reenable":{"description":"Prévia para religar os conectores pausados; null quando nenhum está pausado","type":"object","properties":{"title":{"description":"O que vai acontecer, em português","type":"string"},"changes":{"description":"Cada consequência, em português","type":"array","items":{"type":"string"}},"token":{"description":"Mande de volta para aplicar; vale por 10 minutos e só para este estado","type":"string"},"expiresAt":{"description":"Quando o token deixa de valer","type":"string","format":"date-time"}},"required":["title","changes","token","expiresAt"],"nullable":true}},"required":["token","reenable"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Loja no plano gratuito da Zoppy (connect.zoppy_free_tier)\n\nPapel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"503":{"description":"Zoppy indisponível (connect.zoppy_token_unavailable)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Garantir o acesso à Zoppy","tags":["zoppy-access"]}},"/connect/zoppy-token/reenable":{"post":{"description":"Religa os conectores pausados pela revogação, com o token da prévia.","operationId":"ZoppyTokenController_reenable","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"description":"Token da prévia","type":"string","minLength":1}},"required":["token"]}}}},"responses":{"200":{"description":"Acesso","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"description":"Acesso do Connect à Zoppy","type":"string","enum":["active","revoked","missing"]},"externalTokenId":{"description":"Id do ExternalToken na Zoppy","type":"string","nullable":true},"createdByUserId":{"description":"Quem gerou","type":"string","nullable":true},"createdAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"revokedAt":{"description":"Instante em ISO 8601","type":"string","format":"date-time","nullable":true},"pausedConnectors":{"description":"Conectores pausados porque o acesso foi revogado","type":"array","items":{"type":"object","properties":{"id":{"description":"Id do conector","type":"string","format":"uuid"},"name":{"description":"Nome do conector","type":"string"}},"required":["id","name"]}}},"required":["status","externalTokenId","createdByUserId","createdAt","revokedAt","pausedConnectors"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"409":{"description":"Token expirado ou a lista mudou (connect.confirmation_refused)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Religar conectores","tags":["zoppy-access"]}},"/connectors/{connectorId}/runs":{"get":{"description":"Lista as execuções do conector, da mais nova para a mais antiga, com status, motivo da falha e contadores; filtra por status e mode e diz o total.","operationId":"ConnectorRunsController_list","parameters":[{"name":"before","required":false,"in":"query","description":"Só execuções iniciadas antes deste instante (o `next` da página anterior)","schema":{"description":"Só execuções iniciadas antes deste instante (o `next` da página anterior)","type":"string","format":"date-time"}},{"name":"limit","required":false,"in":"query","description":"Execuções por página","schema":{"description":"Execuções por página","type":"integer","minimum":1,"exclusiveMinimum":false,"maximum":100,"exclusiveMaximum":false,"default":20}},{"name":"status","required":false,"in":"query","description":"Só execuções nesta situação","schema":{"description":"Só execuções nesta situação","type":"string","enum":["running","succeeded","partial","failed","timed_out"]}},{"name":"mode","required":false,"in":"query","description":"Só execuções reais (live) ou só ensaios (dry_run)","schema":{"description":"Só execuções reais (live) ou só ensaios (dry_run)","type":"string","enum":["live","dry_run"]}},{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"responses":{"200":{"description":"Uma página de execuções","content":{"application/json":{"schema":{"type":"object","properties":{"runs":{"description":"Execuções, da mais nova para a mais antiga","type":"array","items":{"type":"object","properties":{"id":{"description":"Id da execução","type":"string","format":"uuid"},"connectorId":{"description":"Id do conector","type":"string","format":"uuid"},"versionSeq":{"description":"Versão do conector que rodou","type":"integer"},"trigger":{"description":"O que começou","type":"string","enum":["cron","manual","rehearsal","reprocess"]},"mode":{"description":"live grava de verdade; dry_run é ensaio","type":"string","enum":["live","dry_run"]},"rehearsalScope":{"description":"Escopo do ensaio; null numa real","type":"string","enum":["sample","full"],"nullable":true},"status":{"description":"Situação da execução","type":"string","enum":["running","succeeded","partial","failed","timed_out"]},"failureReason":{"description":"Por que falhou ou estourou o tempo (error, time, slices, calls, quarantine, crash...)","type":"string","nullable":true},"cut":{"description":"Ensaio amostra que parou com mais a ler","type":"boolean"},"slices":{"description":"Fatias já fechadas","type":"integer"},"counters":{"description":"Contadores de ctx.count, por objeto","type":"object","additionalProperties":{"type":"object","properties":{"read":{"description":"Registros lidos da origem","type":"integer"},"created":{"description":"Registros criados no destino","type":"integer"},"updated":{"description":"Registros atualizados no destino","type":"integer"},"skipped":{"description":"Registros sem nada a mudar","type":"integer"},"failed":{"description":"Registros que falharam","type":"integer"}},"required":["read","created","updated","skipped","failed"]}},"quarantined":{"description":"Registros que a execução mandou para a quarentena","type":"integer"},"externalWritesSent":{"description":"Escritas que saíram de verdade para outro sistema","type":"integer"},"writesHeldBack":{"description":"Escritas de uma execução real que não saíram: guardadas para confirmação ou planejadas atrás dela","type":"integer"},"cursorKept":{"description":"Execução real com escrita que não saiu: o ponto de onde ela parou não vale, a próxima recomeça do último ponto bom","type":"boolean"},"waitingWriteConfirmation":{"description":"A primeira escrita num sistema ficou guardada e espera a confirmação de uma pessoa","type":"boolean"},"writesAsReads":{"description":"POST/PUT/PATCH/DELETE feitos como leitura (ctx.http.request)","type":"array","items":{"type":"object","properties":{"method":{"description":"Método HTTP da leitura que não foi GET","type":"string"},"host":{"description":"Host chamado","type":"string"},"path":{"description":"Caminho chamado, sem query","type":"string"},"count":{"description":"Quantas vezes a execução fez essa chamada","type":"integer"}},"required":["method","host","path","count"]}},"blockingIssues":{"description":"Problemas do ensaio que impedem publicar mesmo com status succeeded; connect.write_without_lookup: um POST criou registro sem consulta anterior na mesma coleção","type":"array","items":{"type":"object","properties":{"code":{"description":"Código estável do problema (connect.write_without_lookup)","type":"string"},"message":{"description":"O que está errado e como corrigir, em português","type":"string"},"method":{"description":"Método da chamada que causou o problema","type":"string"},"host":{"description":"Host da chamada","type":"string"},"path":{"description":"Caminho da chamada","type":"string"},"count":{"description":"Quantas vezes aconteceu na execução","type":"integer"}},"required":["code","message","method","host","path","count"]}},"startedAt":{"description":"Início","type":"string","format":"date-time"},"finishedAt":{"description":"Fim; null enquanto roda","type":"string","format":"date-time","nullable":true}},"required":["id","connectorId","versionSeq","trigger","mode","rehearsalScope","status","failureReason","cut","slices","counters","quarantined","externalWritesSent","writesHeldBack","cursorKept","waitingWriteConfirmation","writesAsReads","blockingIssues","startedAt","finishedAt"]}},"next":{"description":"Valor de `before` para a próxima página; null quando acabou","type":"string","format":"date-time","nullable":true},"total":{"description":"Quantas execuções o conector tem com os filtros de status e mode, sem contar `before`","type":"integer","minimum":0,"exclusiveMinimum":false}},"required":["runs","next","total"]}}}},"400":{"description":"Parâmetros inválidos","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector não existe nesta loja","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"],"example":{"type":"connect.connector_not_found","title":"Não encontramos este conector.","status":404}}}}}},"security":[{"bearer":[]}],"summary":"Execuções do conector","tags":["runs-and-quarantine"]},"post":{"description":"Abre uma execução real da versão publicada, fora do horário do cron. O conector precisa estar ligado.","operationId":"ConnectorLaunchesController_runNow","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"responses":{"202":{"description":"Execução aberta","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"description":"Id da execução","type":"string","format":"uuid"},"connectorId":{"description":"Id do conector","type":"string","format":"uuid"},"versionSeq":{"description":"Versão do conector que rodou","type":"integer"},"trigger":{"description":"O que começou","type":"string","enum":["cron","manual","rehearsal","reprocess"]},"mode":{"description":"live grava de verdade; dry_run é ensaio","type":"string","enum":["live","dry_run"]},"rehearsalScope":{"description":"Escopo do ensaio; null numa real","type":"string","enum":["sample","full"],"nullable":true},"status":{"description":"Situação da execução","type":"string","enum":["running","succeeded","partial","failed","timed_out"]},"failureReason":{"description":"Por que falhou ou estourou o tempo (error, time, slices, calls, quarantine, crash...)","type":"string","nullable":true},"cut":{"description":"Ensaio amostra que parou com mais a ler","type":"boolean"},"slices":{"description":"Fatias já fechadas","type":"integer"},"counters":{"description":"Contadores de ctx.count, por objeto","type":"object","additionalProperties":{"type":"object","properties":{"read":{"description":"Registros lidos da origem","type":"integer"},"created":{"description":"Registros criados no destino","type":"integer"},"updated":{"description":"Registros atualizados no destino","type":"integer"},"skipped":{"description":"Registros sem nada a mudar","type":"integer"},"failed":{"description":"Registros que falharam","type":"integer"}},"required":["read","created","updated","skipped","failed"]}},"quarantined":{"description":"Registros que a execução mandou para a quarentena","type":"integer"},"externalWritesSent":{"description":"Escritas que saíram de verdade para outro sistema","type":"integer"},"writesHeldBack":{"description":"Escritas de uma execução real que não saíram: guardadas para confirmação ou planejadas atrás dela","type":"integer"},"cursorKept":{"description":"Execução real com escrita que não saiu: o ponto de onde ela parou não vale, a próxima recomeça do último ponto bom","type":"boolean"},"waitingWriteConfirmation":{"description":"A primeira escrita num sistema ficou guardada e espera a confirmação de uma pessoa","type":"boolean"},"writesAsReads":{"description":"POST/PUT/PATCH/DELETE feitos como leitura (ctx.http.request)","type":"array","items":{"type":"object","properties":{"method":{"description":"Método HTTP da leitura que não foi GET","type":"string"},"host":{"description":"Host chamado","type":"string"},"path":{"description":"Caminho chamado, sem query","type":"string"},"count":{"description":"Quantas vezes a execução fez essa chamada","type":"integer"}},"required":["method","host","path","count"]}},"blockingIssues":{"description":"Problemas do ensaio que impedem publicar mesmo com status succeeded; connect.write_without_lookup: um POST criou registro sem consulta anterior na mesma coleção","type":"array","items":{"type":"object","properties":{"code":{"description":"Código estável do problema (connect.write_without_lookup)","type":"string"},"message":{"description":"O que está errado e como corrigir, em português","type":"string"},"method":{"description":"Método da chamada que causou o problema","type":"string"},"host":{"description":"Host da chamada","type":"string"},"path":{"description":"Caminho da chamada","type":"string"},"count":{"description":"Quantas vezes aconteceu na execução","type":"integer"}},"required":["code","message","method","host","path","count"]}},"startedAt":{"description":"Início","type":"string","format":"date-time"},"finishedAt":{"description":"Fim; null enquanto roda","type":"string","format":"date-time","nullable":true}},"required":["id","connectorId","versionSeq","trigger","mode","rehearsalScope","status","failureReason","cut","slices","counters","quarantined","externalWritesSent","writesHeldBack","cursorKept","waitingWriteConfirmation","writesAsReads","blockingIssues","startedAt","finishedAt"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector não existe nesta loja (connect.connector_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"409":{"description":"Conector desligado (connect.connector_not_enabled) ou outra execução em andamento (connect.run_in_progress)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"423":{"description":"Conector ou loja em pausa de emergência (connect.paused)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Rodar agora","tags":["runs-and-quarantine"]}},"/connectors/{connectorId}/runs/{runId}":{"get":{"description":"Passos de cada fatia (chamadas, consultas ao banco local e logs) com dados pessoais mascarados, guardados 30 dias; o erro com o stack nas linhas do TypeScript; as requisições que um ensaio mandaria; as escritas feitas como leitura; os contadores.","operationId":"ConnectorRunsController_detail","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}},{"name":"runId","required":true,"in":"path","description":"Id da execução","schema":{"description":"Id da execução","type":"string","format":"uuid"}}],"responses":{"200":{"description":"A execução","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"description":"Id da execução","type":"string","format":"uuid"},"connectorId":{"description":"Id do conector","type":"string","format":"uuid"},"versionSeq":{"description":"Versão do conector que rodou","type":"integer"},"trigger":{"description":"O que começou","type":"string","enum":["cron","manual","rehearsal","reprocess"]},"mode":{"description":"live grava de verdade; dry_run é ensaio","type":"string","enum":["live","dry_run"]},"rehearsalScope":{"description":"Escopo do ensaio; null numa real","type":"string","enum":["sample","full"],"nullable":true},"status":{"description":"Situação da execução","type":"string","enum":["running","succeeded","partial","failed","timed_out"]},"failureReason":{"description":"Por que falhou ou estourou o tempo (error, time, slices, calls, quarantine, crash...)","type":"string","nullable":true},"cut":{"description":"Ensaio amostra que parou com mais a ler","type":"boolean"},"slices":{"description":"Fatias já fechadas","type":"integer"},"counters":{"description":"Contadores de ctx.count, por objeto","type":"object","additionalProperties":{"type":"object","properties":{"read":{"description":"Registros lidos da origem","type":"integer"},"created":{"description":"Registros criados no destino","type":"integer"},"updated":{"description":"Registros atualizados no destino","type":"integer"},"skipped":{"description":"Registros sem nada a mudar","type":"integer"},"failed":{"description":"Registros que falharam","type":"integer"}},"required":["read","created","updated","skipped","failed"]}},"quarantined":{"description":"Registros que a execução mandou para a quarentena","type":"integer"},"externalWritesSent":{"description":"Escritas que saíram de verdade para outro sistema","type":"integer"},"writesHeldBack":{"description":"Escritas de uma execução real que não saíram: guardadas para confirmação ou planejadas atrás dela","type":"integer"},"cursorKept":{"description":"Execução real com escrita que não saiu: o ponto de onde ela parou não vale, a próxima recomeça do último ponto bom","type":"boolean"},"waitingWriteConfirmation":{"description":"A primeira escrita num sistema ficou guardada e espera a confirmação de uma pessoa","type":"boolean"},"writesAsReads":{"description":"POST/PUT/PATCH/DELETE feitos como leitura (ctx.http.request)","type":"array","items":{"type":"object","properties":{"method":{"description":"Método HTTP da leitura que não foi GET","type":"string"},"host":{"description":"Host chamado","type":"string"},"path":{"description":"Caminho chamado, sem query","type":"string"},"count":{"description":"Quantas vezes a execução fez essa chamada","type":"integer"}},"required":["method","host","path","count"]}},"blockingIssues":{"description":"Problemas do ensaio que impedem publicar mesmo com status succeeded; connect.write_without_lookup: um POST criou registro sem consulta anterior na mesma coleção","type":"array","items":{"type":"object","properties":{"code":{"description":"Código estável do problema (connect.write_without_lookup)","type":"string"},"message":{"description":"O que está errado e como corrigir, em português","type":"string"},"method":{"description":"Método da chamada que causou o problema","type":"string"},"host":{"description":"Host da chamada","type":"string"},"path":{"description":"Caminho da chamada","type":"string"},"count":{"description":"Quantas vezes aconteceu na execução","type":"integer"}},"required":["code","message","method","host","path","count"]}},"startedAt":{"description":"Início","type":"string","format":"date-time"},"finishedAt":{"description":"Fim; null enquanto roda","type":"string","format":"date-time","nullable":true},"steps":{"description":"Passos de todas as fatias guardadas, em ordem","type":"array","items":{"type":"object","properties":{"at":{"description":"Quando aconteceu","type":"string"},"kind":{"description":"Chamada HTTP, consulta ao banco local ou log","type":"string","enum":["http","sql","log"]},"method":{"description":"Método da chamada","type":"string"},"target":{"description":"URL ou banco chamado, com os segredos como marcadores","type":"string"},"status":{"description":"Status da resposta","type":"integer"},"durationMs":{"description":"Duração da chamada","type":"integer"},"errorCode":{"description":"Código de recusa do gateway","type":"string","nullable":true},"request":{"description":"Resumo do que foi enviado, dados pessoais mascarados"},"response":{"description":"Resumo do que voltou, dados pessoais mascarados"},"message":{"description":"Texto do log","type":"string"},"data":{"description":"Dados do log, mascarados"},"level":{"description":"Nível do log (info, warn ou error); só nos passos de log","type":"string","enum":["info","warn","error"]},"agentId":{"description":"Agente local que rodou a consulta; só nos passos sql, null quando não se sabe","type":"string","nullable":true}},"required":["at","kind"]}},"stepsExpired":{"description":"Parte dos passos já saiu do lake (guardados 30 dias)","type":"boolean"},"error":{"description":"O erro da última fatia que falhou","type":"object","properties":{"name":{"type":"string"},"message":{"type":"string"},"stack":{"description":"Stack trace nas linhas do TypeScript","type":"string","nullable":true},"frames":{"description":"Frames do stack que apontam para arquivos TypeScript","type":"array","items":{"type":"object","properties":{"function":{"description":"Função do frame","type":"string","nullable":true},"file":{"description":"Arquivo TypeScript do conector","type":"string"},"line":{"description":"Linha no TypeScript","type":"integer"},"column":{"description":"Coluna no TypeScript","type":"integer"}},"required":["function","file","line","column"]}}},"required":["name","message","stack","frames"],"nullable":true},"plannedRequests":{"description":"A requisição que eu mandaria: escritas que não saíram","type":"array","items":{"type":"object","properties":{"at":{"description":"Quando o código pediu a escrita","type":"string"},"method":{"description":"Método","type":"string"},"url":{"description":"URL, com segredos como marcadores","type":"string"},"query":{"description":"Parâmetros da query string","type":"object","additionalProperties":{"type":"string"}},"headers":{"description":"Cabeçalhos, com segredos como marcadores","type":"object","additionalProperties":{"type":"string"}},"body":{"description":"Corpo (resumo)","type":"string","nullable":true}},"required":["at","method","url","query","headers","body"]}}},"required":["id","connectorId","versionSeq","trigger","mode","rehearsalScope","status","failureReason","cut","slices","counters","quarantined","externalWritesSent","writesHeldBack","cursorKept","waitingWriteConfirmation","writesAsReads","blockingIssues","startedAt","finishedAt","steps","stepsExpired","error","plannedRequests"]}}}},"400":{"description":"Parâmetros inválidos","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Execução não existe neste conector","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"],"example":{"type":"connect.run_not_found","title":"Não encontramos esta execução.","status":404}}}}}},"security":[{"bearer":[]}],"summary":"Detalhe da execução","tags":["runs-and-quarantine"]}},"/connectors/{connectorId}/quarantine":{"get":{"description":"Registros que o conector separou com ctx.quarantine, com o motivo, a versão e quantas vezes voltaram; dados pessoais mascarados. Ficam 30 dias depois da última mudança.","operationId":"ConnectorQuarantineController_list","parameters":[{"name":"status","required":false,"in":"query","description":"Situação dos registros","schema":{"description":"Situação dos registros","type":"string","enum":["open","resolved","discarded"],"default":"open"}},{"name":"limit","required":false,"in":"query","description":"Quantos registros","schema":{"description":"Quantos registros","type":"integer","minimum":1,"exclusiveMinimum":false,"maximum":500,"exclusiveMaximum":false,"default":50}},{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"responses":{"200":{"description":"Os registros","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"description":"Id do registro na quarentena","type":"string","format":"uuid"},"runId":{"description":"Execução que mandou o registro para cá por último","type":"string","format":"uuid"},"slice":{"description":"Fatia dessa execução","type":"integer"},"versionSeq":{"description":"Versão do conector que recusou","type":"integer"},"object":{"description":"Objeto do registro (campo object do registro); null quando o registro não diz","type":"string","nullable":true},"externalId":{"description":"Id do registro no sistema de origem (externalId ou id do registro), mascarado; null quando não há","type":"string","nullable":true},"httpStatus":{"description":"Status HTTP da recusa, do registro (httpStatus, status, error.status) ou do motivo; null quando não há","type":"integer","nullable":true},"record":{"description":"O registro, com dados pessoais mascarados"},"reason":{"description":"O motivo dado pelo conector, mascarado","type":"string"},"attempts":{"description":"Quantas vezes o mesmo registro voltou para a quarentena","type":"integer"},"status":{"description":"Situação","type":"string","enum":["open","resolved","discarded"]},"correctedAt":{"description":"Quando uma pessoa corrigiu valores","type":"string","format":"date-time","nullable":true},"reprocessRunId":{"description":"Reprocesso em andamento que levou o registro","type":"string","format":"uuid","nullable":true},"resolvedByRunId":{"description":"Reprocesso que resolveu o registro","type":"string","format":"uuid","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"resolvedAt":{"description":"Quando foi resolvido ou descartado","type":"string","format":"date-time","nullable":true}},"required":["id","runId","slice","versionSeq","object","externalId","httpStatus","record","reason","attempts","status","correctedAt","reprocessRunId","resolvedByRunId","createdAt","updatedAt","resolvedAt"]}}}}},"400":{"description":"Parâmetros inválidos","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector não existe nesta loja (connect.connector_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Quarentena do conector","tags":["runs-and-quarantine"]}},"/connectors/{connectorId}/quarantine/{itemId}":{"patch":{"description":"Troca os campos informados do registro; ele volta no próximo reprocesso com os valores novos.","operationId":"ConnectorQuarantineController_correct","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}},{"name":"itemId","required":true,"in":"path","description":"Id do registro na quarentena","schema":{"description":"Id do registro na quarentena","type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"values":{"description":"Campos do registro a trocar; os outros ficam como estão","type":"object","additionalProperties":{}}},"required":["values"],"example":{"values":{"cpf":"12345678909"}}}}}},"responses":{"200":{"description":"O registro corrigido","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"description":"Id do registro na quarentena","type":"string","format":"uuid"},"runId":{"description":"Execução que mandou o registro para cá por último","type":"string","format":"uuid"},"slice":{"description":"Fatia dessa execução","type":"integer"},"versionSeq":{"description":"Versão do conector que recusou","type":"integer"},"object":{"description":"Objeto do registro (campo object do registro); null quando o registro não diz","type":"string","nullable":true},"externalId":{"description":"Id do registro no sistema de origem (externalId ou id do registro), mascarado; null quando não há","type":"string","nullable":true},"httpStatus":{"description":"Status HTTP da recusa, do registro (httpStatus, status, error.status) ou do motivo; null quando não há","type":"integer","nullable":true},"record":{"description":"O registro, com dados pessoais mascarados"},"reason":{"description":"O motivo dado pelo conector, mascarado","type":"string"},"attempts":{"description":"Quantas vezes o mesmo registro voltou para a quarentena","type":"integer"},"status":{"description":"Situação","type":"string","enum":["open","resolved","discarded"]},"correctedAt":{"description":"Quando uma pessoa corrigiu valores","type":"string","format":"date-time","nullable":true},"reprocessRunId":{"description":"Reprocesso em andamento que levou o registro","type":"string","format":"uuid","nullable":true},"resolvedByRunId":{"description":"Reprocesso que resolveu o registro","type":"string","format":"uuid","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"resolvedAt":{"description":"Quando foi resolvido ou descartado","type":"string","format":"date-time","nullable":true}},"required":["id","runId","slice","versionSeq","object","externalId","httpStatus","record","reason","attempts","status","correctedAt","reprocessRunId","resolvedByRunId","createdAt","updatedAt","resolvedAt"]}}}},"400":{"description":"Corpo inválido","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Registro não está aberto neste conector","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"],"example":{"type":"connect.quarantine_item_not_found","title":"Este registro não está mais na quarentena.","status":404}}}}},"422":{"description":"O registro não tem campos (connect.quarantine_record_not_object)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Corrigir um registro da quarentena","tags":["runs-and-quarantine"]}},"/connectors/{connectorId}/quarantine/{itemId}/discard":{"post":{"description":"O registro sai da quarentena sem ser reprocessado.","operationId":"ConnectorQuarantineController_discard","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}},{"name":"itemId","required":true,"in":"path","description":"Id do registro na quarentena","schema":{"description":"Id do registro na quarentena","type":"string","format":"uuid"}}],"responses":{"200":{"description":"O registro descartado","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"description":"Id do registro na quarentena","type":"string","format":"uuid"},"runId":{"description":"Execução que mandou o registro para cá por último","type":"string","format":"uuid"},"slice":{"description":"Fatia dessa execução","type":"integer"},"versionSeq":{"description":"Versão do conector que recusou","type":"integer"},"object":{"description":"Objeto do registro (campo object do registro); null quando o registro não diz","type":"string","nullable":true},"externalId":{"description":"Id do registro no sistema de origem (externalId ou id do registro), mascarado; null quando não há","type":"string","nullable":true},"httpStatus":{"description":"Status HTTP da recusa, do registro (httpStatus, status, error.status) ou do motivo; null quando não há","type":"integer","nullable":true},"record":{"description":"O registro, com dados pessoais mascarados"},"reason":{"description":"O motivo dado pelo conector, mascarado","type":"string"},"attempts":{"description":"Quantas vezes o mesmo registro voltou para a quarentena","type":"integer"},"status":{"description":"Situação","type":"string","enum":["open","resolved","discarded"]},"correctedAt":{"description":"Quando uma pessoa corrigiu valores","type":"string","format":"date-time","nullable":true},"reprocessRunId":{"description":"Reprocesso em andamento que levou o registro","type":"string","format":"uuid","nullable":true},"resolvedByRunId":{"description":"Reprocesso que resolveu o registro","type":"string","format":"uuid","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"resolvedAt":{"description":"Quando foi resolvido ou descartado","type":"string","format":"date-time","nullable":true}},"required":["id","runId","slice","versionSeq","object","externalId","httpStatus","record","reason","attempts","status","correctedAt","reprocessRunId","resolvedByRunId","createdAt","updatedAt","resolvedAt"]}}}},"400":{"description":"Parâmetros inválidos","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Registro não está aberto neste conector","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"],"example":{"type":"connect.quarantine_item_not_found","title":"Este registro não está mais na quarentena.","status":404}}}}}},"security":[{"bearer":[]}],"summary":"Descartar um registro da quarentena","tags":["runs-and-quarantine"]}},"/connectors/{connectorId}/quarantine/reprocess/preview":{"post":{"description":"Escolhe os registros (os informados ou os abertos mais novos, até 500) e devolve um token de uso único para confirmar. Nada roda ainda.","operationId":"ConnectorQuarantineController_preview","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"itemIds":{"description":"Registros a reprocessar; sem a lista, os abertos mais novos até 500","type":"array","minItems":1,"maxItems":500,"items":{"type":"string","format":"uuid"}}}}}}},"responses":{"200":{"description":"A prévia","content":{"application/json":{"schema":{"type":"object","properties":{"itemIds":{"description":"Os registros que o reprocesso vai levar","type":"array","items":{"type":"string","format":"uuid"}},"count":{"description":"Quantos registros","type":"integer"},"left":{"description":"Abertos que ficam para o próximo reprocesso","type":"integer"},"versionSeq":{"description":"Versão publicada que vai rodar","type":"integer"},"confirmationToken":{"description":"Token de uso único para confirmar este reprocesso","type":"string"},"expiresAt":{"description":"Até quando o token vale","type":"string","format":"date-time"}},"required":["itemIds","count","left","versionSeq","confirmationToken","expiresAt"]}}}},"400":{"description":"Corpo inválido","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Um dos registros não está aberto","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"],"example":{"type":"connect.quarantine_item_not_found","title":"Este registro não está mais na quarentena.","status":404}}}}},"409":{"description":"Conector não está ligado","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"],"example":{"type":"connect.connector_not_enabled","title":"Ligue o conector antes de rodar ou reprocessar.","status":409}}}}},"422":{"description":"Nada aberto para reprocessar (connect.quarantine_empty)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Prévia do reprocesso","tags":["runs-and-quarantine"]}},"/connectors/{connectorId}/quarantine/reprocess":{"post":{"description":"Com o token da prévia, abre uma execução reprocess da versão publicada que recebe os registros em ctx.input.quarantined. O que ela não mandar de volta para a quarentena sai como resolvido quando ela termina bem.","operationId":"ConnectorQuarantineController_reprocess","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"itemIds":{"description":"Os itemIds devolvidos pela prévia","type":"array","minItems":1,"maxItems":500,"items":{"type":"string","format":"uuid"}},"confirmationToken":{"description":"O token da prévia","type":"string","minLength":1}},"required":["itemIds","confirmationToken"]}}}},"responses":{"200":{"description":"A execução de reprocesso","content":{"application/json":{"schema":{"description":"A execução de reprocesso, igual a um item da lista de execuções; recebe os registros em ctx.input.quarantined","type":"object","properties":{"id":{"description":"Id da execução","type":"string","format":"uuid"},"connectorId":{"description":"Id do conector","type":"string","format":"uuid"},"versionSeq":{"description":"Versão do conector que rodou","type":"integer"},"trigger":{"description":"O que começou","type":"string","enum":["cron","manual","rehearsal","reprocess"]},"mode":{"description":"live grava de verdade; dry_run é ensaio","type":"string","enum":["live","dry_run"]},"rehearsalScope":{"description":"Escopo do ensaio; null numa real","type":"string","enum":["sample","full"],"nullable":true},"status":{"description":"Situação da execução","type":"string","enum":["running","succeeded","partial","failed","timed_out"]},"failureReason":{"description":"Por que falhou ou estourou o tempo (error, time, slices, calls, quarantine, crash...)","type":"string","nullable":true},"cut":{"description":"Ensaio amostra que parou com mais a ler","type":"boolean"},"slices":{"description":"Fatias já fechadas","type":"integer"},"counters":{"description":"Contadores de ctx.count, por objeto","type":"object","additionalProperties":{"type":"object","properties":{"read":{"description":"Registros lidos da origem","type":"integer"},"created":{"description":"Registros criados no destino","type":"integer"},"updated":{"description":"Registros atualizados no destino","type":"integer"},"skipped":{"description":"Registros sem nada a mudar","type":"integer"},"failed":{"description":"Registros que falharam","type":"integer"}},"required":["read","created","updated","skipped","failed"]}},"quarantined":{"description":"Registros que a execução mandou para a quarentena","type":"integer"},"externalWritesSent":{"description":"Escritas que saíram de verdade para outro sistema","type":"integer"},"writesHeldBack":{"description":"Escritas de uma execução real que não saíram: guardadas para confirmação ou planejadas atrás dela","type":"integer"},"cursorKept":{"description":"Execução real com escrita que não saiu: o ponto de onde ela parou não vale, a próxima recomeça do último ponto bom","type":"boolean"},"waitingWriteConfirmation":{"description":"A primeira escrita num sistema ficou guardada e espera a confirmação de uma pessoa","type":"boolean"},"writesAsReads":{"description":"POST/PUT/PATCH/DELETE feitos como leitura (ctx.http.request)","type":"array","items":{"type":"object","properties":{"method":{"description":"Método HTTP da leitura que não foi GET","type":"string"},"host":{"description":"Host chamado","type":"string"},"path":{"description":"Caminho chamado, sem query","type":"string"},"count":{"description":"Quantas vezes a execução fez essa chamada","type":"integer"}},"required":["method","host","path","count"]}},"blockingIssues":{"description":"Problemas do ensaio que impedem publicar mesmo com status succeeded; connect.write_without_lookup: um POST criou registro sem consulta anterior na mesma coleção","type":"array","items":{"type":"object","properties":{"code":{"description":"Código estável do problema (connect.write_without_lookup)","type":"string"},"message":{"description":"O que está errado e como corrigir, em português","type":"string"},"method":{"description":"Método da chamada que causou o problema","type":"string"},"host":{"description":"Host da chamada","type":"string"},"path":{"description":"Caminho da chamada","type":"string"},"count":{"description":"Quantas vezes aconteceu na execução","type":"integer"}},"required":["code","message","method","host","path","count"]}},"startedAt":{"description":"Início","type":"string","format":"date-time"},"finishedAt":{"description":"Fim; null enquanto roda","type":"string","format":"date-time","nullable":true}},"required":["id","connectorId","versionSeq","trigger","mode","rehearsalScope","status","failureReason","cut","slices","counters","quarantined","externalWritesSent","writesHeldBack","cursorKept","waitingWriteConfirmation","writesAsReads","blockingIssues","startedAt","finishedAt"]}}}},"400":{"description":"Corpo inválido","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Um dos registros não está aberto","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"],"example":{"type":"connect.quarantine_item_not_found","title":"Este registro não está mais na quarentena.","status":404}}}}},"409":{"description":"Prévia expirada ou diferente (connect.confirmation_stale), conector desligado ou execução em andamento (connect.run_in_progress)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"423":{"description":"Pausa de emergência (connect.paused)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Reprocessar a quarentena","tags":["runs-and-quarantine"]}},"/connectors/{connectorId}/rehearsals":{"post":{"description":"Abre um ensaio (dry_run) da versão mais nova: lê de verdade, inclusive no banco local; as escritas não saem e aparecem em plannedRequests. A amostra lê a primeira fatia e, se cortada, marca needsFullRehearsal; o completo lê a origem inteira, que publicar exige.","operationId":"ConnectorLaunchesController_rehearse","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"scope":{"description":"sample lê só a primeira fatia; full lê a origem inteira, que publicar exige","type":"string","enum":["sample","full"],"default":"sample"}}}}}},"responses":{"202":{"description":"Ensaio aberto","content":{"application/json":{"schema":{"type":"object","properties":{"runId":{"description":"Id da execução do ensaio; acompanhe em GET /connectors/{connectorId}/runs/{runId}","type":"string","format":"uuid"},"connectorId":{"description":"Id do conector","type":"string","format":"uuid"},"versionSeq":{"description":"Versão em edição que o ensaio roda","type":"integer"},"scope":{"description":"Escopo do ensaio","type":"string","enum":["sample","full"]}},"required":["runId","connectorId","versionSeq","scope"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector não existe nesta loja (connect.connector_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"409":{"description":"Host esperando aprovação (connect.hosts_awaiting_approval), segredo ou acesso à Zoppy faltando (connect.access_incomplete), outra execução em andamento (connect.run_in_progress) ou conector sem versão (connect.connector_without_version)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"],"example":{"type":"connect.hosts_awaiting_approval","title":"Aprove estes hosts antes de ensaiar: api.erp.com.br","status":409}}}}},"423":{"description":"Conector ou loja em pausa de emergência (connect.paused)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Ensaiar a versão em edição","tags":["runs-and-quarantine"]}},"/connect/agents":{"get":{"description":"Cada agente com o estado (conectado, versão, visto por último), o que a lista local dele alcança e os conectores que o usam.","operationId":"ConnectAgentsController_list","parameters":[],"responses":{"200":{"description":"Agentes, do mais novo ao mais antigo","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"description":"Id do agente local","type":"string","format":"uuid"},"name":{"description":"O nome dado na tela ou, sem ele, o nome da máquina","type":"string"},"status":{"description":"active: pode abrir o túnel; revoked: cortado de vez","type":"string","enum":["active","revoked"]},"connected":{"description":"Se o túnel dele com o gateway está aberto agora","type":"boolean"},"agentVersion":{"description":"Versão do zoppy-agent instalada","type":"string"},"contractVersion":{"description":"A versão do contrato do túnel que ele fala","type":"integer"},"platform":{"description":"Instalação escolhida no pareamento (windows, linux ou docker); null para agentes pareados antes disso","type":"string","enum":["windows","linux","docker"],"nullable":true},"os":{"description":"windows, linux...","type":"string"},"arch":{"description":"Arquitetura da máquina (amd64, arm64...)","type":"string"},"hostname":{"description":"A máquina onde ele roda","type":"string"},"reach":{"description":"O que a lista local dele alcança, como o agente informa: quem decide é a lista da loja naquela máquina","type":"array","items":{"type":"object","properties":{"kind":{"description":"http: uma API dentro da rede; sql: um banco de dados","type":"string","enum":["http","sql"]},"host":{"description":"Como está escrito na máquina do agente: um nome, um IP, *.sufixo ou um CIDR","type":"string"},"port":{"description":"Porta","type":"integer"},"engine":{"description":"Para sql: sqlserver, oracle, firebird, mysql ou postgres","type":"string"},"database":{"description":"Para sql: o banco como o servidor o conhece","type":"string"}},"required":["kind","host"]}},"lastSeenAt":{"description":"Último sinal de vida do agente","type":"string","format":"date-time","nullable":true},"connectedAt":{"description":"Quando o túnel abriu pela última vez","type":"string","format":"date-time","nullable":true},"disconnectedAt":{"description":"Quando o túnel caiu pela última vez","type":"string","format":"date-time","nullable":true},"offlineSince":{"description":"Preenchido enquanto os administradores têm um aviso aberto de agente fora do ar","type":"string","format":"date-time","nullable":true},"keyRotationDueAt":{"description":"Quando o agente troca a chave dele (a cada 90 dias)","type":"string","format":"date-time"},"pairedAt":{"description":"Quando foi pareado","type":"string","format":"date-time"},"revokedAt":{"description":"Quando foi revogado; null enquanto ativo","type":"string","format":"date-time","nullable":true},"connectors":{"description":"Os conectores cujo manifesto manda chamadas por este agente","type":"array","items":{"type":"object","properties":{"id":{"description":"Id do conector","type":"string","format":"uuid"},"name":{"description":"Nome do conector","type":"string"},"status":{"description":"Estado do conector: draft, enabled ou paused","type":"string"}},"required":["id","name","status"]}}},"required":["id","name","status","connected","agentVersion","contractVersion","platform","os","arch","hostname","reach","lastSeenAt","connectedAt","disconnectedAt","offlineSince","keyRotationDueAt","pairedAt","revokedAt","connectors"]}}}}},"403":{"description":"Token ausente ou papel sem acesso: só MASTER e ADMIN (connect.unauthorized, connect.forbidden_role)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Agentes locais da loja","tags":["local-agents"]}},"/connect/agents/pairing-codes":{"post":{"description":"Código de uso único, válido por 30 minutos, que a instalação do agente pede. Só aparece esta vez: guardamos apenas o hash.","operationId":"ConnectAgentsController_createPairingCode","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"description":"O nome que o agente recebe (SRV-MATRIZ); sem ele, o nome da máquina","type":"string","minLength":1,"maxLength":80},"platform":{"description":"Onde o agente vai ser instalado: windows, linux ou docker","type":"string","enum":["windows","linux","docker"]}},"example":{"name":"SRV-MATRIZ","platform":"windows"}}}}},"responses":{"201":{"description":"O código e quando vence","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"description":"XXXX-XXXX: digitado na instalação do agente (zoppy-agent pair <code>), uma vez, em até 30 minutos","type":"string"},"expiresAt":{"description":"Até quando o código vale","type":"string","format":"date-time"},"name":{"description":"O nome pedido para o agente; null quando não foi dado","type":"string","nullable":true},"platform":{"description":"Onde o agente vai ser instalado, como foi pedido; null quando não foi dito","type":"string","enum":["windows","linux","docker"],"nullable":true},"pairUrl":{"description":"Onde o agente pareia: o host de agentes do gateway","type":"string","format":"uri"}},"required":["code","expiresAt","name","platform","pairUrl"]}}}},"403":{"description":"Token ausente ou papel sem acesso: só MASTER e ADMIN (connect.unauthorized, connect.forbidden_role)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Gerar código de pareamento","tags":["local-agents"]}},"/connect/agents/{agentId}":{"get":{"description":"O estado do agente e os conectores que o usam.","operationId":"ConnectAgentsController_get","parameters":[{"name":"agentId","required":true,"in":"path","description":"Id do agente local","schema":{"type":"string"}}],"responses":{"200":{"description":"O agente","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"description":"Id do agente local","type":"string","format":"uuid"},"name":{"description":"O nome dado na tela ou, sem ele, o nome da máquina","type":"string"},"status":{"description":"active: pode abrir o túnel; revoked: cortado de vez","type":"string","enum":["active","revoked"]},"connected":{"description":"Se o túnel dele com o gateway está aberto agora","type":"boolean"},"agentVersion":{"description":"Versão do zoppy-agent instalada","type":"string"},"contractVersion":{"description":"A versão do contrato do túnel que ele fala","type":"integer"},"platform":{"description":"Instalação escolhida no pareamento (windows, linux ou docker); null para agentes pareados antes disso","type":"string","enum":["windows","linux","docker"],"nullable":true},"os":{"description":"windows, linux...","type":"string"},"arch":{"description":"Arquitetura da máquina (amd64, arm64...)","type":"string"},"hostname":{"description":"A máquina onde ele roda","type":"string"},"reach":{"description":"O que a lista local dele alcança, como o agente informa: quem decide é a lista da loja naquela máquina","type":"array","items":{"type":"object","properties":{"kind":{"description":"http: uma API dentro da rede; sql: um banco de dados","type":"string","enum":["http","sql"]},"host":{"description":"Como está escrito na máquina do agente: um nome, um IP, *.sufixo ou um CIDR","type":"string"},"port":{"description":"Porta","type":"integer"},"engine":{"description":"Para sql: sqlserver, oracle, firebird, mysql ou postgres","type":"string"},"database":{"description":"Para sql: o banco como o servidor o conhece","type":"string"}},"required":["kind","host"]}},"lastSeenAt":{"description":"Último sinal de vida do agente","type":"string","format":"date-time","nullable":true},"connectedAt":{"description":"Quando o túnel abriu pela última vez","type":"string","format":"date-time","nullable":true},"disconnectedAt":{"description":"Quando o túnel caiu pela última vez","type":"string","format":"date-time","nullable":true},"offlineSince":{"description":"Preenchido enquanto os administradores têm um aviso aberto de agente fora do ar","type":"string","format":"date-time","nullable":true},"keyRotationDueAt":{"description":"Quando o agente troca a chave dele (a cada 90 dias)","type":"string","format":"date-time"},"pairedAt":{"description":"Quando foi pareado","type":"string","format":"date-time"},"revokedAt":{"description":"Quando foi revogado; null enquanto ativo","type":"string","format":"date-time","nullable":true},"connectors":{"description":"Os conectores cujo manifesto manda chamadas por este agente","type":"array","items":{"type":"object","properties":{"id":{"description":"Id do conector","type":"string","format":"uuid"},"name":{"description":"Nome do conector","type":"string"},"status":{"description":"Estado do conector: draft, enabled ou paused","type":"string"}},"required":["id","name","status"]}}},"required":["id","name","status","connected","agentVersion","contractVersion","platform","os","arch","hostname","reach","lastSeenAt","connectedAt","disconnectedAt","offlineSince","keyRotationDueAt","pairedAt","revokedAt","connectors"]}}}},"403":{"description":"Token ausente ou papel sem acesso: só MASTER e ADMIN (connect.unauthorized, connect.forbidden_role)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Nenhum agente local com esse id na loja (connect.agent_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Um agente local","tags":["local-agents"]}},"/connect/agents/{agentId}/revoke":{"post":{"description":"Corta o túnel do agente na hora e recusa toda conexão dele depois. Não tem volta: para usar a máquina de novo, gere um código e pareie outro agente.","operationId":"ConnectAgentsController_revoke","parameters":[{"name":"agentId","required":true,"in":"path","description":"Id do agente local","schema":{"type":"string"}}],"responses":{"200":{"description":"O agente, revogado","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"description":"Id do agente local","type":"string","format":"uuid"},"name":{"description":"O nome dado na tela ou, sem ele, o nome da máquina","type":"string"},"status":{"description":"active: pode abrir o túnel; revoked: cortado de vez","type":"string","enum":["active","revoked"]},"connected":{"description":"Se o túnel dele com o gateway está aberto agora","type":"boolean"},"agentVersion":{"description":"Versão do zoppy-agent instalada","type":"string"},"contractVersion":{"description":"A versão do contrato do túnel que ele fala","type":"integer"},"platform":{"description":"Instalação escolhida no pareamento (windows, linux ou docker); null para agentes pareados antes disso","type":"string","enum":["windows","linux","docker"],"nullable":true},"os":{"description":"windows, linux...","type":"string"},"arch":{"description":"Arquitetura da máquina (amd64, arm64...)","type":"string"},"hostname":{"description":"A máquina onde ele roda","type":"string"},"reach":{"description":"O que a lista local dele alcança, como o agente informa: quem decide é a lista da loja naquela máquina","type":"array","items":{"type":"object","properties":{"kind":{"description":"http: uma API dentro da rede; sql: um banco de dados","type":"string","enum":["http","sql"]},"host":{"description":"Como está escrito na máquina do agente: um nome, um IP, *.sufixo ou um CIDR","type":"string"},"port":{"description":"Porta","type":"integer"},"engine":{"description":"Para sql: sqlserver, oracle, firebird, mysql ou postgres","type":"string"},"database":{"description":"Para sql: o banco como o servidor o conhece","type":"string"}},"required":["kind","host"]}},"lastSeenAt":{"description":"Último sinal de vida do agente","type":"string","format":"date-time","nullable":true},"connectedAt":{"description":"Quando o túnel abriu pela última vez","type":"string","format":"date-time","nullable":true},"disconnectedAt":{"description":"Quando o túnel caiu pela última vez","type":"string","format":"date-time","nullable":true},"offlineSince":{"description":"Preenchido enquanto os administradores têm um aviso aberto de agente fora do ar","type":"string","format":"date-time","nullable":true},"keyRotationDueAt":{"description":"Quando o agente troca a chave dele (a cada 90 dias)","type":"string","format":"date-time"},"pairedAt":{"description":"Quando foi pareado","type":"string","format":"date-time"},"revokedAt":{"description":"Quando foi revogado; null enquanto ativo","type":"string","format":"date-time","nullable":true},"connectors":{"description":"Os conectores cujo manifesto manda chamadas por este agente","type":"array","items":{"type":"object","properties":{"id":{"description":"Id do conector","type":"string","format":"uuid"},"name":{"description":"Nome do conector","type":"string"},"status":{"description":"Estado do conector: draft, enabled ou paused","type":"string"}},"required":["id","name","status"]}}},"required":["id","name","status","connected","agentVersion","contractVersion","platform","os","arch","hostname","reach","lastSeenAt","connectedAt","disconnectedAt","offlineSince","keyRotationDueAt","pairedAt","revokedAt","connectors"]}}}},"403":{"description":"Token ausente ou papel sem acesso: só MASTER e ADMIN (connect.unauthorized, connect.forbidden_role)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Nenhum agente local com esse id na loja (connect.agent_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Revogar um agente local","tags":["local-agents"]}},"/connectors/{connectorId}/external-writes":{"get":{"description":"Se o conector escreve fora, em quais sistemas as escritas já saem sem perguntar e as escritas guardadas esperando a confirmação de uma pessoa, exatamente como sairiam (segredos como marcadores).","operationId":"ConnectorExternalWritesController_overview","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"responses":{"200":{"description":"Escritas do conector","content":{"application/json":{"schema":{"type":"object","properties":{"externalWrites":{"description":"Se a versão publicada (ou a mais nova, antes de publicar) escreve fora","type":"boolean"},"confirmedHosts":{"description":"Sistemas em que as escritas já saem sem perguntar","type":"array","items":{"type":"string"}},"needsConfirmation":{"description":"Há escrita esperando uma pessoa confirmar","type":"boolean"},"heldWrites":{"description":"Escritas guardadas, da mais nova para a mais antiga","type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"runId":{"description":"Execução que guardou a escrita","type":"string","format":"uuid"},"versionSeq":{"description":"Versão do conector que pediu a escrita","type":"integer"},"host":{"description":"Sistema que recebe a escrita","type":"string"},"status":{"description":"held espera a pessoa; confirmed ainda não saiu; sending saindo; sent saiu; failed pode ter chegado e nunca é repetida; discarded não sai mais","type":"string","enum":["held","confirmed","sending","sent","failed","discarded"],"x-enumNames":["held","confirmed","sending","sent","failed","discarded"]},"method":{"type":"string"},"url":{"description":"Como o código pediu; segredos aparecem como marcadores","type":"string"},"query":{"type":"object","additionalProperties":{"type":"string"}},"headers":{"type":"object","additionalProperties":{"type":"string"}},"body":{"description":"Corpo com dados pessoais mascarados","type":"string","nullable":true},"heldAt":{"description":"Instante ISO 8601","type":"string","format":"date-time"},"confirmedAt":{"description":"Instante ISO 8601","type":"string","format":"date-time","nullable":true},"confirmedByUserId":{"type":"string","nullable":true},"sentAt":{"description":"Instante ISO 8601","type":"string","format":"date-time","nullable":true},"responseStatus":{"description":"Status HTTP que o outro sistema respondeu","type":"integer","nullable":true},"failureCode":{"type":"string","nullable":true},"notice":{"description":"Aviso para a pessoa quando a escrita pode ter chegado ao outro sistema","type":"string","nullable":true}},"required":["id","runId","versionSeq","host","status","method","url","query","headers","body","heldAt","confirmedAt","confirmedByUserId","sentAt","responseStatus","failureCode","notice"]}},"notice":{"description":"O que vai para o outro sistema não tem desfazer","type":"string"}},"required":["externalWrites","confirmedHosts","needsConfirmation","heldWrites","notice"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector ou escrita guardada de outra loja ou inexistente (connect.connector_not_found, connect.held_write_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Escritas em outros sistemas","tags":["held-writes"]}},"/connectors/{connectorId}/external-writes/{heldWriteId}/preview":{"post":{"description":"Mostra a escrita guardada e o que acontece ao confirmar; devolve o token da confirmação (10 minutos).","operationId":"ConnectorExternalWritesController_preview","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}},{"name":"heldWriteId","required":true,"in":"path","description":"Id da escrita guardada","schema":{"description":"Id da escrita guardada","type":"string","format":"uuid"}}],"responses":{"200":{"description":"Prévia com token","content":{"application/json":{"schema":{"type":"object","properties":{"title":{"description":"O que vai acontecer","type":"string"},"changes":{"description":"Cada consequência","type":"array","items":{"type":"string"}},"token":{"description":"Mande de volta para confirmar; vale 10 minutos e para esse estado exato da escrita","type":"string"},"expiresAt":{"description":"Quando o token para de valer","type":"string","format":"date-time"},"write":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"runId":{"description":"Execução que guardou a escrita","type":"string","format":"uuid"},"versionSeq":{"description":"Versão do conector que pediu a escrita","type":"integer"},"host":{"description":"Sistema que recebe a escrita","type":"string"},"status":{"description":"held espera a pessoa; confirmed ainda não saiu; sending saindo; sent saiu; failed pode ter chegado e nunca é repetida; discarded não sai mais","type":"string","enum":["held","confirmed","sending","sent","failed","discarded"],"x-enumNames":["held","confirmed","sending","sent","failed","discarded"]},"method":{"type":"string"},"url":{"description":"Como o código pediu; segredos aparecem como marcadores","type":"string"},"query":{"type":"object","additionalProperties":{"type":"string"}},"headers":{"type":"object","additionalProperties":{"type":"string"}},"body":{"description":"Corpo com dados pessoais mascarados","type":"string","nullable":true},"heldAt":{"description":"Instante ISO 8601","type":"string","format":"date-time"},"confirmedAt":{"description":"Instante ISO 8601","type":"string","format":"date-time","nullable":true},"confirmedByUserId":{"type":"string","nullable":true},"sentAt":{"description":"Instante ISO 8601","type":"string","format":"date-time","nullable":true},"responseStatus":{"description":"Status HTTP que o outro sistema respondeu","type":"integer","nullable":true},"failureCode":{"type":"string","nullable":true},"notice":{"description":"Aviso para a pessoa quando a escrita pode ter chegado ao outro sistema","type":"string","nullable":true}},"required":["id","runId","versionSeq","host","status","method","url","query","headers","body","heldAt","confirmedAt","confirmedByUserId","sentAt","responseStatus","failureCode","notice"]}},"required":["title","changes","token","expiresAt","write"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector ou escrita guardada de outra loja ou inexistente (connect.connector_not_found, connect.held_write_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"409":{"description":"A escrita já foi decidida (connect.held_write_decided)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"502":{"description":"A escrita pode ter chegado e nunca é repetida (connect.held_write_send_uncertain)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Prévia da primeira escrita","tags":["held-writes"]}},"/connectors/{connectorId}/external-writes/{heldWriteId}/confirm":{"post":{"description":"Manda uma vez a escrita guardada, exatamente como está. Depois dela, as escritas do conector nesse sistema saem sem perguntar, até uma versão publicada escrever num sistema novo. O que vai para o outro sistema não tem desfazer.","operationId":"ConnectorExternalWritesController_confirm","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}},{"name":"heldWriteId","required":true,"in":"path","description":"Id da escrita guardada","schema":{"description":"Id da escrita guardada","type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"description":"O token da prévia; vale 10 minutos e para esse estado da escrita","type":"string","minLength":1}},"required":["token"]}}}},"responses":{"200":{"description":"Escrita enviada (ou já enviada antes)","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"runId":{"description":"Execução que guardou a escrita","type":"string","format":"uuid"},"versionSeq":{"description":"Versão do conector que pediu a escrita","type":"integer"},"host":{"description":"Sistema que recebe a escrita","type":"string"},"status":{"description":"held espera a pessoa; confirmed ainda não saiu; sending saindo; sent saiu; failed pode ter chegado e nunca é repetida; discarded não sai mais","type":"string","enum":["held","confirmed","sending","sent","failed","discarded"],"x-enumNames":["held","confirmed","sending","sent","failed","discarded"]},"method":{"type":"string"},"url":{"description":"Como o código pediu; segredos aparecem como marcadores","type":"string"},"query":{"type":"object","additionalProperties":{"type":"string"}},"headers":{"type":"object","additionalProperties":{"type":"string"}},"body":{"description":"Corpo com dados pessoais mascarados","type":"string","nullable":true},"heldAt":{"description":"Instante ISO 8601","type":"string","format":"date-time"},"confirmedAt":{"description":"Instante ISO 8601","type":"string","format":"date-time","nullable":true},"confirmedByUserId":{"type":"string","nullable":true},"sentAt":{"description":"Instante ISO 8601","type":"string","format":"date-time","nullable":true},"responseStatus":{"description":"Status HTTP que o outro sistema respondeu","type":"integer","nullable":true},"failureCode":{"type":"string","nullable":true},"notice":{"description":"Aviso para a pessoa quando a escrita pode ter chegado ao outro sistema","type":"string","nullable":true}},"required":["id","runId","versionSeq","host","status","method","url","query","headers","body","heldAt","confirmedAt","confirmedByUserId","sentAt","responseStatus","failureCode","notice"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector ou escrita guardada de outra loja ou inexistente (connect.connector_not_found, connect.held_write_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"409":{"description":"connect.held_write_confirmation_refused (prévia vencida ou de outro estado), connect.held_write_decided (já saiu, está saindo ou foi trocada), connect.held_write_outdated (a versão publicada não escreve mais nesse sistema), connect.held_write_connector_paused (o conector está pausado: a escrita fica confirmada e sai sozinha quando ele for ligado de novo)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"502":{"description":"connect.held_write_relay_failed: não saiu agora e continua confirmada; sai sozinha em até alguns minutos ou numa nova confirmação. connect.held_write_send_uncertain: falhou no meio do caminho, pode ter chegado e nunca é repetida","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Confirmar a primeira escrita","tags":["held-writes"]}},"/connectors/{connectorId}/external-writes/{heldWriteId}/discard/preview":{"post":{"description":"Mostra a escrita guardada (ou confirmada e ainda não enviada) e o que acontece ao descartar; devolve o token de uso único do descarte (10 minutos).","operationId":"ConnectorExternalWritesController_previewDiscard","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}},{"name":"heldWriteId","required":true,"in":"path","description":"Id da escrita guardada","schema":{"description":"Id da escrita guardada","type":"string","format":"uuid"}}],"responses":{"200":{"description":"Prévia com token","content":{"application/json":{"schema":{"type":"object","properties":{"title":{"description":"O que vai acontecer","type":"string"},"changes":{"description":"Cada consequência","type":"array","items":{"type":"string"}},"token":{"description":"Mande de volta para confirmar; vale 10 minutos e para esse estado exato da escrita","type":"string"},"expiresAt":{"description":"Quando o token para de valer","type":"string","format":"date-time"},"write":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"runId":{"description":"Execução que guardou a escrita","type":"string","format":"uuid"},"versionSeq":{"description":"Versão do conector que pediu a escrita","type":"integer"},"host":{"description":"Sistema que recebe a escrita","type":"string"},"status":{"description":"held espera a pessoa; confirmed ainda não saiu; sending saindo; sent saiu; failed pode ter chegado e nunca é repetida; discarded não sai mais","type":"string","enum":["held","confirmed","sending","sent","failed","discarded"],"x-enumNames":["held","confirmed","sending","sent","failed","discarded"]},"method":{"type":"string"},"url":{"description":"Como o código pediu; segredos aparecem como marcadores","type":"string"},"query":{"type":"object","additionalProperties":{"type":"string"}},"headers":{"type":"object","additionalProperties":{"type":"string"}},"body":{"description":"Corpo com dados pessoais mascarados","type":"string","nullable":true},"heldAt":{"description":"Instante ISO 8601","type":"string","format":"date-time"},"confirmedAt":{"description":"Instante ISO 8601","type":"string","format":"date-time","nullable":true},"confirmedByUserId":{"type":"string","nullable":true},"sentAt":{"description":"Instante ISO 8601","type":"string","format":"date-time","nullable":true},"responseStatus":{"description":"Status HTTP que o outro sistema respondeu","type":"integer","nullable":true},"failureCode":{"type":"string","nullable":true},"notice":{"description":"Aviso para a pessoa quando a escrita pode ter chegado ao outro sistema","type":"string","nullable":true}},"required":["id","runId","versionSeq","host","status","method","url","query","headers","body","heldAt","confirmedAt","confirmedByUserId","sentAt","responseStatus","failureCode","notice"]}},"required":["title","changes","token","expiresAt","write"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector ou escrita guardada de outra loja ou inexistente (connect.connector_not_found, connect.held_write_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"409":{"description":"A escrita já saiu, está saindo, falhou ou foi descartada (connect.held_write_decided)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"],"example":{"type":"connect.held_write_decided","title":"Essa escrita já foi decidida.","status":409}}}}}},"security":[{"bearer":[]}],"summary":"Prévia do descarte da escrita guardada","tags":["held-writes"]}},"/connectors/{connectorId}/external-writes/{heldWriteId}/discard":{"post":{"description":"Com o token da prévia, a escrita guardada ou confirmada passa a descartada e não sai mais; a próxima execução que escrever nesse sistema guarda outra para confirmar. Só vale enquanto ela não começou a sair.","operationId":"ConnectorExternalWritesController_discard","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}},{"name":"heldWriteId","required":true,"in":"path","description":"Id da escrita guardada","schema":{"description":"Id da escrita guardada","type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"description":"O token da prévia; vale 10 minutos e para esse estado da escrita","type":"string","minLength":1}},"required":["token"]}}}},"responses":{"200":{"description":"Escrita descartada","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"runId":{"description":"Execução que guardou a escrita","type":"string","format":"uuid"},"versionSeq":{"description":"Versão do conector que pediu a escrita","type":"integer"},"host":{"description":"Sistema que recebe a escrita","type":"string"},"status":{"description":"held espera a pessoa; confirmed ainda não saiu; sending saindo; sent saiu; failed pode ter chegado e nunca é repetida; discarded não sai mais","type":"string","enum":["held","confirmed","sending","sent","failed","discarded"],"x-enumNames":["held","confirmed","sending","sent","failed","discarded"]},"method":{"type":"string"},"url":{"description":"Como o código pediu; segredos aparecem como marcadores","type":"string"},"query":{"type":"object","additionalProperties":{"type":"string"}},"headers":{"type":"object","additionalProperties":{"type":"string"}},"body":{"description":"Corpo com dados pessoais mascarados","type":"string","nullable":true},"heldAt":{"description":"Instante ISO 8601","type":"string","format":"date-time"},"confirmedAt":{"description":"Instante ISO 8601","type":"string","format":"date-time","nullable":true},"confirmedByUserId":{"type":"string","nullable":true},"sentAt":{"description":"Instante ISO 8601","type":"string","format":"date-time","nullable":true},"responseStatus":{"description":"Status HTTP que o outro sistema respondeu","type":"integer","nullable":true},"failureCode":{"type":"string","nullable":true},"notice":{"description":"Aviso para a pessoa quando a escrita pode ter chegado ao outro sistema","type":"string","nullable":true}},"required":["id","runId","versionSeq","host","status","method","url","query","headers","body","heldAt","confirmedAt","confirmedByUserId","sentAt","responseStatus","failureCode","notice"]}}}},"400":{"description":"Corpo inválido","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector ou escrita guardada de outra loja ou inexistente (connect.connector_not_found, connect.held_write_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"409":{"description":"connect.held_write_decided (já saiu, está saindo, falhou ou foi descartada), connect.held_write_confirmation_refused (prévia vencida, de outro estado ou já usada)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Descartar a escrita guardada","tags":["held-writes"]}},"/connectors/{connectorId}/build":{"get":{"description":"As mensagens da conversa em que a IA constrói o conector, o gasto da conversa e do mês em reais e se a conversa parou no teto.","operationId":"ConnectorBuildController_conversation","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"responses":{"200":{"description":"A conversa","content":{"application/json":{"schema":{"type":"object","properties":{"connectorId":{"type":"string","format":"uuid"},"messages":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["text"]},"author":{"type":"string","enum":["person","ai"]},"text":{"type":"string"}},"required":["id","kind","author","text"]},{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["activity"]},"activity":{"type":"string","enum":["reading_docs","connecting","counting","discovering_tables","writing_version","rehearsing","masked_secret"],"x-enumNames":["readingDocs","connecting","counting","discoveringTables","writingVersion","rehearsing","maskedSecret"]},"detail":{"type":"string"}},"required":["id","kind","activity","detail"]},{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["access_request"]},"secrets":{"type":"array","items":{"type":"string"}},"agentId":{"type":"string","nullable":true}},"required":["id","kind","secrets","agentId"]},{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["host_request"]},"hosts":{"type":"array","items":{"type":"string"}}},"required":["id","kind","hosts"]},{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["secret_reuse_request"]},"fromConnectorId":{"description":"O conector da mesma loja e do mesmo sistema de onde viria o acesso","type":"string"},"fromName":{"type":"string"},"secrets":{"description":"Os segredos que seriam copiados, só os nomes","type":"array","items":{"type":"string"}}},"required":["id","kind","fromConnectorId","fromName","secrets"]}]}},"spend":{"type":"object","properties":{"currency":{"description":"Moeda dos valores (BRL)","type":"string"},"conversationSpent":{"description":"Gasto desta conversa de construção, em reais","type":"number"},"conversationCap":{"description":"Teto por conversa de construção, em reais","type":"number"},"monthSpent":{"description":"Gasto da loja no mês com copiloto e construção, em reais","type":"number"},"monthCap":{"description":"Teto mensal da loja, em reais","type":"number"}},"required":["currency","conversationSpent","conversationCap","monthSpent","monthCap"]},"stopped":{"description":"O teto da conversa ou o mensal foi atingido: a conversa para","type":"boolean"},"answering":{"description":"A IA está respondendo a última mensagem","type":"boolean"}},"required":["connectorId","messages","spend","stopped","answering"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"503":{"description":"IA de construção não disponível neste ambiente (connect.build_unavailable)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Conversa de construção","tags":["ai-build"]}},"/connectors/{connectorId}/build/messages":{"post":{"description":"Guarda a mensagem (com segredos colados mascarados) e põe a resposta da IA na fila; a conversa volta com answering true. Com o teto atingido, nada é mandado e a conversa volta com stopped true.","operationId":"ConnectorBuildController_send","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"description":"A mensagem da pessoa, já mascarada pela tela","type":"string","minLength":1,"maxLength":2000},"maskedSecret":{"description":"Se a tela escondeu um segredo colado antes de mandar","type":"boolean","default":false}},"required":["text"]}}}},"responses":{"200":{"description":"A conversa","content":{"application/json":{"schema":{"type":"object","properties":{"connectorId":{"type":"string","format":"uuid"},"messages":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["text"]},"author":{"type":"string","enum":["person","ai"]},"text":{"type":"string"}},"required":["id","kind","author","text"]},{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["activity"]},"activity":{"type":"string","enum":["reading_docs","connecting","counting","discovering_tables","writing_version","rehearsing","masked_secret"],"x-enumNames":["readingDocs","connecting","counting","discoveringTables","writingVersion","rehearsing","maskedSecret"]},"detail":{"type":"string"}},"required":["id","kind","activity","detail"]},{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["access_request"]},"secrets":{"type":"array","items":{"type":"string"}},"agentId":{"type":"string","nullable":true}},"required":["id","kind","secrets","agentId"]},{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["host_request"]},"hosts":{"type":"array","items":{"type":"string"}}},"required":["id","kind","hosts"]},{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["secret_reuse_request"]},"fromConnectorId":{"description":"O conector da mesma loja e do mesmo sistema de onde viria o acesso","type":"string"},"fromName":{"type":"string"},"secrets":{"description":"Os segredos que seriam copiados, só os nomes","type":"array","items":{"type":"string"}}},"required":["id","kind","fromConnectorId","fromName","secrets"]}]}},"spend":{"type":"object","properties":{"currency":{"description":"Moeda dos valores (BRL)","type":"string"},"conversationSpent":{"description":"Gasto desta conversa de construção, em reais","type":"number"},"conversationCap":{"description":"Teto por conversa de construção, em reais","type":"number"},"monthSpent":{"description":"Gasto da loja no mês com copiloto e construção, em reais","type":"number"},"monthCap":{"description":"Teto mensal da loja, em reais","type":"number"}},"required":["currency","conversationSpent","conversationCap","monthSpent","monthCap"]},"stopped":{"description":"O teto da conversa ou o mensal foi atingido: a conversa para","type":"boolean"},"answering":{"description":"A IA está respondendo a última mensagem","type":"boolean"}},"required":["connectorId","messages","spend","stopped","answering"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"409":{"description":"A IA ainda responde a mensagem anterior (connect.build_turn_in_progress)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"503":{"description":"IA de construção não disponível neste ambiente (connect.build_unavailable)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Mandar mensagem à IA de construção","tags":["ai-build"]}},"/connectors/{connectorId}/build/handoff":{"post":{"description":"Leva o resumo que o Copiloto escreveu para a conversa de construção, que segue daí no modo construção.","operationId":"ConnectorBuildController_handoff","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"summary":{"description":"O resumo que o Copiloto escreveu da conversa","type":"string","minLength":1,"maxLength":4000}},"required":["summary"]}}}},"responses":{"200":{"description":"A conversa","content":{"application/json":{"schema":{"type":"object","properties":{"connectorId":{"type":"string","format":"uuid"},"messages":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["text"]},"author":{"type":"string","enum":["person","ai"]},"text":{"type":"string"}},"required":["id","kind","author","text"]},{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["activity"]},"activity":{"type":"string","enum":["reading_docs","connecting","counting","discovering_tables","writing_version","rehearsing","masked_secret"],"x-enumNames":["readingDocs","connecting","counting","discoveringTables","writingVersion","rehearsing","maskedSecret"]},"detail":{"type":"string"}},"required":["id","kind","activity","detail"]},{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["access_request"]},"secrets":{"type":"array","items":{"type":"string"}},"agentId":{"type":"string","nullable":true}},"required":["id","kind","secrets","agentId"]},{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["host_request"]},"hosts":{"type":"array","items":{"type":"string"}}},"required":["id","kind","hosts"]},{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["secret_reuse_request"]},"fromConnectorId":{"description":"O conector da mesma loja e do mesmo sistema de onde viria o acesso","type":"string"},"fromName":{"type":"string"},"secrets":{"description":"Os segredos que seriam copiados, só os nomes","type":"array","items":{"type":"string"}}},"required":["id","kind","fromConnectorId","fromName","secrets"]}]}},"spend":{"type":"object","properties":{"currency":{"description":"Moeda dos valores (BRL)","type":"string"},"conversationSpent":{"description":"Gasto desta conversa de construção, em reais","type":"number"},"conversationCap":{"description":"Teto por conversa de construção, em reais","type":"number"},"monthSpent":{"description":"Gasto da loja no mês com copiloto e construção, em reais","type":"number"},"monthCap":{"description":"Teto mensal da loja, em reais","type":"number"}},"required":["currency","conversationSpent","conversationCap","monthSpent","monthCap"]},"stopped":{"description":"O teto da conversa ou o mensal foi atingido: a conversa para","type":"boolean"},"answering":{"description":"A IA está respondendo a última mensagem","type":"boolean"}},"required":["connectorId","messages","spend","stopped","answering"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"503":{"description":"IA de construção não disponível neste ambiente (connect.build_unavailable)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Receber a conversa do Copiloto","tags":["ai-build"]}},"/connectors/{connectorId}/fix":{"post":{"description":"Leva uma execução que terminou com erro para a conversa de construção: a IA lê a execução, corrige a versão em edição e ensaia.","operationId":"ConnectorBuildController_fix","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"runId":{"description":"A execução com erro","type":"string","minLength":1,"maxLength":64},"note":{"description":"O que a pessoa quer acrescentar","type":"string","maxLength":2000,"default":""}},"required":["runId"]}}}},"responses":{"200":{"description":"O pedido entrou na conversa","content":{"application/json":{"schema":{"type":"object","properties":{"connectorId":{"description":"O conector cuja conversa recebeu o pedido","type":"string","format":"uuid"}},"required":["connectorId"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Execução de outro conector ou inexistente (connect.fix_run_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"409":{"description":"Execução ainda rodando ou IA respondendo (connect.run_still_running, connect.build_turn_in_progress)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"503":{"description":"IA de construção não disponível neste ambiente (connect.build_unavailable)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Pedir para a IA corrigir","tags":["ai-build"]}},"/copilot/conversation":{"get":{"description":"A conversa de quem está logado com o Copiloto, o gasto do mês em reais e se o teto mensal foi atingido.","operationId":"ConnectCopilotController_conversation","parameters":[],"responses":{"200":{"description":"A conversa","content":{"application/json":{"schema":{"type":"object","properties":{"messages":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["text"]},"author":{"type":"string","enum":["person","ai"]},"text":{"type":"string"}},"required":["id","kind","author","text"]},{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["activity"]},"activity":{"type":"string","enum":["reading_run","reading_quarantine","reading_agents","reading_catalog","reading_connectors","reading_docs","masked_secret"],"x-enumNames":["readingRun","readingQuarantine","readingAgents","readingCatalog","readingConnectors","readingDocs","maskedSecret"]},"detail":{"type":"string"},"at":{"type":"string","nullable":true}},"required":["id","kind","activity","detail","at"]},{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["handoff_offer"]},"connectorId":{"description":"null quando a proposta é de um conector novo, criado no sim","type":"string","nullable":true},"connectorName":{"type":"string"}},"required":["id","kind","connectorId","connectorName"]},{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["handed_off"]},"connectorName":{"type":"string"}},"required":["id","kind","connectorName"]}]}},"spend":{"type":"object","properties":{"currency":{"type":"string"},"monthSpent":{"description":"Gasto da loja no mês com copiloto e construção, em reais","type":"number"},"monthCap":{"description":"Teto mensal, em reais","type":"number"},"buildConversationCap":{"description":"Teto por conversa de construção, em reais","type":"number"}},"required":["currency","monthSpent","monthCap","buildConversationCap"]},"capReached":{"description":"O teto mensal foi atingido: copiloto e construção param","type":"boolean"}},"required":["messages","spend","capReached"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"503":{"description":"IA de construção não disponível neste ambiente (connect.build_unavailable)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Conversa do Copiloto","tags":["copilot"]}},"/copilot/messages":{"post":{"description":"O Copiloto lê o contexto da tela e da loja, só para leitura, e responde. Pedido de construir ou corrigir vira uma proposta de troca para o modo construção.","operationId":"ConnectCopilotController_send","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"description":"A mensagem, já mascarada pela tela","type":"string","minLength":1,"maxLength":2000},"maskedSecret":{"description":"Se a tela escondeu um segredo colado","type":"boolean","default":false},"context":{"type":"object","properties":{"path":{"description":"O caminho da tela aberta, como /app/connectors/<id>/runs/<id>","type":"string","maxLength":300},"params":{"description":"Os itens abertos na tela (connectorId, runId)","type":"object","additionalProperties":{"type":"string","maxLength":64}}},"required":["path","params"]}},"required":["text","context"]}}}},"responses":{"200":{"description":"A conversa com a resposta","content":{"application/json":{"schema":{"type":"object","properties":{"messages":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["text"]},"author":{"type":"string","enum":["person","ai"]},"text":{"type":"string"}},"required":["id","kind","author","text"]},{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["activity"]},"activity":{"type":"string","enum":["reading_run","reading_quarantine","reading_agents","reading_catalog","reading_connectors","reading_docs","masked_secret"],"x-enumNames":["readingRun","readingQuarantine","readingAgents","readingCatalog","readingConnectors","readingDocs","maskedSecret"]},"detail":{"type":"string"},"at":{"type":"string","nullable":true}},"required":["id","kind","activity","detail","at"]},{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["handoff_offer"]},"connectorId":{"description":"null quando a proposta é de um conector novo, criado no sim","type":"string","nullable":true},"connectorName":{"type":"string"}},"required":["id","kind","connectorId","connectorName"]},{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["handed_off"]},"connectorName":{"type":"string"}},"required":["id","kind","connectorName"]}]}},"spend":{"type":"object","properties":{"currency":{"type":"string"},"monthSpent":{"description":"Gasto da loja no mês com copiloto e construção, em reais","type":"number"},"monthCap":{"description":"Teto mensal, em reais","type":"number"},"buildConversationCap":{"description":"Teto por conversa de construção, em reais","type":"number"}},"required":["currency","monthSpent","monthCap","buildConversationCap"]},"capReached":{"description":"O teto mensal foi atingido: copiloto e construção param","type":"boolean"}},"required":["messages","spend","capReached"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"429":{"description":"Teto mensal de IA da loja atingido (connect.ai_month_cap_reached)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"503":{"description":"IA de construção não disponível neste ambiente (connect.build_unavailable)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Perguntar ao Copiloto","tags":["copilot"]}},"/copilot/handoff":{"post":{"description":"Aceita a proposta do Copiloto: cria o conector quando a proposta é de um novo e devolve o resumo que segue para a construção.","operationId":"ConnectCopilotController_handoff","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"offerId":{"description":"A proposta de troca que a pessoa aceitou","type":"string","format":"uuid"}},"required":["offerId"]}}}},"responses":{"200":{"description":"O conector e o resumo","content":{"application/json":{"schema":{"type":"object","properties":{"connectorId":{"description":"O conector da conversa de construção","type":"string","format":"uuid"},"summary":{"description":"O resumo que segue para a construção","type":"string"}},"required":["connectorId","summary"]}}}},"400":{"description":"Entrada inválida (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Proposta inexistente ou já aceita (connect.handoff_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"503":{"description":"IA de construção não disponível neste ambiente (connect.build_unavailable)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Aceitar a troca para o modo construção","tags":["copilot"]}},"/oauth/authorizations/{requestId}":{"get":{"description":"O que a tela de consentimento mostra: o aplicativo, a loja, para onde a pessoa volta e as permissões pedidas.","operationId":"OAuthConsentController_authorization","parameters":[{"name":"requestId","required":true,"in":"path","description":"Id do pedido de conexão","schema":{"description":"Id do pedido de conexão","type":"string","format":"uuid"}}],"responses":{"200":{"description":"O pedido","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"description":"Id do pedido de conexão","type":"string","format":"uuid"},"client":{"description":"O aplicativo que pede acesso","type":"object","properties":{"name":{"description":"Nome com que o aplicativo se registrou (ex.: \"Claude\")","type":"string"},"redirectHost":{"description":"Para onde a pessoa volta depois de decidir","type":"string"}},"required":["name","redirectHost"]},"company":{"description":"A loja que o aplicativo vai acessar","type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["id","name"]},"audience":{"description":"mcp (agentes de IA) ou api (CLI do Connect)","type":"string","enum":["mcp","api"]},"scopes":{"description":"As permissões pedidas, todas marcadas por padrão","type":"array","items":{"type":"object","properties":{"scope":{"description":"A permissão","type":"string","enum":["connect:read","connect:operate","connect:build"]},"label":{"description":"O que ela deixa o aplicativo fazer, em português","type":"string"}},"required":["scope","label"]}},"expiresAt":{"description":"Até quando o pedido vale","type":"string","format":"date-time"}},"required":["id","client","company","audience","scopes","expiresAt"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Pedido inexistente, vencido ou já decidido (connect.oauth_request_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Pedido de conexão de um aplicativo","tags":["app-connections"]}},"/oauth/authorizations/{requestId}/decision":{"post":{"description":"Grava a decisão e devolve para onde levar o navegador: o aplicativo, com o código ou com a recusa.","operationId":"OAuthConsentController_decide","parameters":[{"name":"requestId","required":true,"in":"path","description":"Id do pedido de conexão","schema":{"description":"Id do pedido de conexão","type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"approve":{"description":"true para permitir o acesso, false para recusar","type":"boolean"},"scopes":{"description":"As permissões marcadas na tela; só valem as que o aplicativo pediu. Ignorado ao recusar","type":"array","maxItems":3,"items":{"type":"string","enum":["connect:read","connect:operate","connect:build"]},"default":[]}},"required":["approve"]}}}},"responses":{"200":{"description":"A decisão","content":{"application/json":{"schema":{"type":"object","properties":{"redirectUrl":{"description":"Para onde levar o navegador agora: o aplicativo, com o código ou com a recusa","type":"string","format":"uri"}},"required":["redirectUrl"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Pedido inexistente, vencido ou já decidido (connect.oauth_request_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"422":{"description":"Nenhuma permissão marcada (connect.oauth_no_scope)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Permitir ou recusar a conexão","tags":["app-connections"]}},"/connectors/{connectorId}/secret-reuse":{"get":{"description":"Os outros conectores da loja do mesmo sistema que já têm segredos preenchidos, e quais deles este conector pede e ainda não tem. Só nomes; o valor nunca volta.","operationId":"ConnectorSecretReuseController_offers","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"responses":{"200":{"description":"Ofertas de reaproveitamento","content":{"application/json":{"schema":{"description":"De onde dá para reaproveitar o acesso","type":"array","items":{"type":"object","properties":{"fromConnectorId":{"description":"Conector da mesma loja e do mesmo sistema","type":"string","format":"uuid"},"fromName":{"description":"Nome desse conector","type":"string"},"filled":{"description":"Segredos que ele já tem preenchidos (só os nomes; o valor nunca volta)","type":"array","items":{"type":"string"}},"reusable":{"description":"Os que este conector pede, ainda não tem e podem vir de lá","type":"array","items":{"type":"string"}}},"required":["fromConnectorId","fromName","filled","reusable"]}}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector de outra loja ou inexistente (connect.connector_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"De onde reaproveitar o acesso","tags":["access-reuse"]},"post":{"description":"O sim da pessoa: copia, cifrados, os segredos que este conector pede e ainda não tem a partir de outro conector da loja do mesmo sistema. A IA só pede; quem reaproveita é a pessoa.","operationId":"ConnectorSecretReuseController_reuse","parameters":[{"name":"connectorId","required":true,"in":"path","description":"Id do conector","schema":{"description":"Id do conector","type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"fromConnectorId":{"description":"O conector da mesma loja e do mesmo sistema de onde vêm os segredos","type":"string","format":"uuid"}},"required":["fromConnectorId"]}}}},"responses":{"200":{"description":"Segredos reaproveitados","content":{"application/json":{"schema":{"type":"object","properties":{"reused":{"description":"Segredos copiados, cifrados, do outro conector; o valor nunca passa pelo chat","type":"array","items":{"type":"string"}}},"required":["reused"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Conector de outra loja ou inexistente (connect.connector_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"422":{"description":"Outro sistema ou nada a reaproveitar (connect.secret_reuse_refused, reason not_same_system ou nothing_to_reuse)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Reaproveitar o acesso","tags":["access-reuse"]}},"/connect/docs":{"get":{"description":"O índice das páginas do Connect (o que é, conceitos, ciclo do conector, execuções, escritas, erros e limites), as mesmas do site de documentação.","operationId":"ConnectDocsController_index","parameters":[],"responses":{"200":{"description":"Páginas","content":{"application/json":{"schema":{"description":"Páginas da documentação do Connect","type":"array","items":{"type":"object","properties":{"slug":{"description":"Id da página, o último segmento do caminho dela","type":"string","pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","maxLength":64},"path":{"description":"Caminho da página no site da documentação, sem barras nas pontas","type":"string","pattern":"^[a-z0-9-]+(?:\\/[a-z0-9-]+)*$"},"title":{"description":"Título, em pt-BR","type":"string","minLength":1},"description":{"description":"Resumo de uma frase, em pt-BR","type":"string","minLength":1},"order":{"type":"integer","minimum":0,"exclusiveMinimum":false},"audience":{"description":"loja: equipe da loja, sem código; tecnico: quem lê código de conector; todos: todo mundo","type":"string","enum":["loja","tecnico","todos"]}},"required":["slug","path","title","description","order","audience"]}}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Páginas da documentação","tags":["docs"]}},"/connect/docs/{slug}":{"get":{"description":"Uma página da documentação do Connect em Markdown, em pt-BR, com os limites preenchidos pelos valores deste ambiente.","operationId":"ConnectDocsController_page","parameters":[{"name":"slug","required":true,"in":"path","description":"Id da página","schema":{"description":"Id da página","type":"string","pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","maxLength":64}}],"responses":{"200":{"description":"Página","content":{"application/json":{"schema":{"type":"object","properties":{"slug":{"description":"Id da página, o último segmento do caminho dela","type":"string","pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","maxLength":64},"path":{"description":"Caminho da página no site da documentação, sem barras nas pontas","type":"string","pattern":"^[a-z0-9-]+(?:\\/[a-z0-9-]+)*$"},"title":{"description":"Título, em pt-BR","type":"string","minLength":1},"description":{"description":"Resumo de uma frase, em pt-BR","type":"string","minLength":1},"order":{"type":"integer","minimum":0,"exclusiveMinimum":false},"audience":{"description":"loja: equipe da loja, sem código; tecnico: quem lê código de conector; todos: todo mundo","type":"string","enum":["loja","tecnico","todos"]},"markdown":{"description":"O corpo da página em Markdown, pt-BR, com os limites preenchidos","type":"string"}},"required":["slug","path","title","description","order","audience","markdown"]}}}},"400":{"description":"Slug inválido (validation_failed)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"401":{"description":"Token ausente, inválido ou expirado (connect.unauthorized)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"403":{"description":"Papel sem acesso ou Connect não liberado (connect.forbidden_role, connect.feature_disabled)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}},"404":{"description":"Página inexistente (connect.doc_not_found)","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"description":"Código estável do erro, para máquinas (ex.: connect.connector_not_found)","type":"string"},"title":{"description":"Nome da classe do erro","type":"string"},"status":{"description":"Status HTTP","type":"integer"},"detail":{"description":"Mensagem em pt-BR, segura para mostrar a quem usa a tela","type":"string"},"requestId":{"description":"Id de correlação: passe ao suporte para achar o rastro completo","type":"string","nullable":true},"meta":{"description":"Detalhes estruturados seguros para a tela (erros de campo, ids)","type":"object","additionalProperties":{}}},"required":["type","title","status","detail","requestId"]}}}}},"security":[{"bearer":[]}],"summary":"Página da documentação","tags":["docs"]}}},"info":{"title":"API do Zoppy Connect","description":"API do Zoppy Connect. Todo erro segue o formato problem+json: `{ type, title, status, detail, requestId, meta? }`; o `requestId` liga a resposta aos logs.","version":"0.1.0","contact":{}},"tags":[{"name":"identity","x-displayName":"Identidade e termos"},{"name":"connectors","x-displayName":"Conectores"},{"name":"runs-and-quarantine","x-displayName":"Execuções e quarentena"},{"name":"systems-catalog","x-displayName":"Catálogo de sistemas"},{"name":"zoppy-access","x-displayName":"Acesso à Zoppy"},{"name":"cli","x-displayName":"CLI"},{"name":"local-agents","x-displayName":"Agentes locais"},{"name":"held-writes","x-displayName":"Escritas guardadas"},{"name":"ai-build","x-displayName":"Construção com IA"},{"name":"copilot","x-displayName":"Copiloto"},{"name":"app-connections","x-displayName":"Conexão de aplicativos"},{"name":"access-reuse","x-displayName":"Reaproveitamento de acesso"},{"name":"docs","x-displayName":"Documentação"}],"servers":[{"url":"https://api-connect.zoppy.com.br","description":"Produção"},{"url":"https://api-connect-staging.zoppy.com.br","description":"Staging"}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{}}}