Skip to content

fix: trava vencida, sondagem descartada no schema JSON e carimbo de renovacao - #3

Merged
elielsousa-pathbit merged 6 commits into
masterfrom
chore/pos-merge
Sep 12, 2026
Merged

elielsousa-pathbit merged 6 commits into
masterfrom
chore/pos-merge

Conversation

@elielsousa-pathbit

Copy link
Copy Markdown
Contributor

Terceira rodada de revisao automatica do PR anterior. Todos os apontamentos viraram regressao em tests/test_health_semantics.py.

O que estava quebrado

Trava de rate limit vencida (P1). rateLimitedUntil guarda o instante em que a janela do provedor reabre — e um prazo, nao uma bandeira. A mera presenca do campo marcava a conexao como limitada, e nada apagava a marca quando o prazo vencia: depois do primeiro 429 a conexao ficava amarela para sempre.

Sondagem descartada (P2, so OminiRTkSync). update_connection_health so escrevia em coluna relacional. Em base com coluna data unica — o formato do 9Router, que instalacoes migradas do OmniRoute mantem — nao havia test_status nem provider_specific_data para receber nada, e a funcao saia por "nao ha campo a gravar". O resultado da sondagem era perdido inteiro.

Saude alegada sem prova (P2). Conexao local recem-criada dizia "ativa" sem nunca ter sido sondada; com CRON_ENABLED=0 ela pode nunca ser. E uma conexao OAuth que o proprio gateway ja carimbou como recusada aparecia saudavel so porque o token ainda nao tinha vencido.

Painel contradizendo o banco (P2). A tela decidia "instancia inalcancavel" pelo tamanho do catalogo. Uma instalacao nova, de pe e sem nenhum modelo baixado, responde 200 com lista vazia — e a tela a anunciava como fora do ar, contradizendo o active que o proprio ciclo acabara de gravar.

lastRefreshAt (P2). Lido pelo painel, escrito por ninguem. "Ultima renovacao" mostrava, na verdade, o horario da ultima verificacao, entao um token parado ha dias parecia recem renovado a cada ciclo.

Documentacao. O exemplo headless desligava o painel sem desligar o HEALTHCHECK da imagem, que so o painel atende: o container ficava eternamente unhealthy e travava qualquer depends_on: service_healthy.

Prova

Suite completa verde nos dois repos.

241 testes verdes.

https://claude.ai/code/session_01Dw2Zc66wvY8QBZJmPBeMsT

…enovacao

Apontamentos da terceira rodada de revisao do PR anterior. Cada um vira
regressao em tests/test_health_semantics.py.

- rateLimitedUntil e um prazo, nao uma bandeira, e a limpeza dele no ciclo
  era decidida procurando o nome do campo nas notas do provider -- que sao
  escritas em portugues e nunca casavam. A trava ficava gravada para
  sempre e a conexao, amarela para sempre. Agora quem decide e o proprio
  prazo.

- update_connection_health so escrevia em coluna relacional. Em base com
  coluna `data` unica (o formato que o 9Router usa e que instalacoes
  migradas do OmniRoute mantem) a sondagem era descartada inteira: a
  funcao saia por "nao ha nada a gravar". Ganhou o ramo JSON, preservando
  o conteudo que ja estava la.

- Uma conexao OAuth que o proprio gateway carimbou como recusada aparecia
  saudavel so porque o token ainda nao tinha vencido.

- Local recem-criada dizia "ativa" sem nunca ter sido sondada.

- O painel decidia "instancia inalcancavel" pelo tamanho do catalogo,
  contradizendo o "ativa" que o ciclo acabara de gravar.

- lastRefreshAt nao era gravado nem projetado: "ultima renovacao" mostrava
  o horario da ultima verificacao.

- Documentacao: o exemplo headless desligava o painel sem desligar o
  HEALTHCHECK, deixando o container eternamente unhealthy.

241 testes verdes.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

Comment thread src/omini_rtksync/database.py Fixed
A primeira correcao tratava `rateLimitedUntil` dentro do ramo de chave de
API. Uma conexao OAuth -- o caso comum no OmniRoute -- passava longe dele e
a marca vencida continuava gravada, deixando a conexao amarela para sempre.

A limpeza passa a acontecer no topo do laco, antes de qualquer ramo, porque
e higiene de estado e nao assunto de um provider. O ramo de chave deixa de
repetir a decisao.

Provado contra o gateway real: trava de 3 horas atras e removida ("Trava de
rate limit vencida removida"), trava com 1 hora pela frente sobrevive
intacta. 242 testes verdes.
No painel de uma stack real aparecia "chave aceita pelo provedor (HTTP 400)"
-- uma frase que o proprio numero parece desmentir.

A classificacao esta certa e e deliberada: a sonda envia corpo vazio de
proposito, e o provedor so chega a reclamar do corpo depois de ter aceitado
a chave; por isso 400 e 404 contam como autenticacao aceita, e so 401/403
(mais o 400 idiomatico do Google AI Studio) marcam recusa. O que faltava era
a frase dizer isso. Agora um 2xx le "autenticacao aceita pelo provedor" e um
4xx le "autenticacao aceita; a sondagem em si foi recusada (HTTP 400)".

De quebra, "Provedor inacessivel, chave nao verificada" virou "Chave nao
verificada": um 4xx nao prova que o provedor esteja inacessivel -- ele
respondeu.

Verificado contra a stack do artigo 0002, com seis provedores reais.
A regra que eu mesmo acabara de introduzir -- honrar o test_status que o
OmniRoute carimbou -- criava a contradicao oposta. `test_status` guarda o
ultimo erro do gateway e nao caduca sozinho: depois que a sonda viva
aprovava a credencial, a linha ficava com credentialState=valid e a tela
dizia "invalid".

Duas pontas:

- models.py so honra o carimbo quando nao ha sonda viva dizendo "valid",
  respeitando o que o proprio docstring da funcao promete;
- cli.py grava test_status="active" no ramo em que a sonda aprova. Alem de
  coerente, e o que o OmniRoute espera: "active" e o unico valor que o
  clearAccountError dele trata como saudavel.

245 testes verdes.
Apontamento da revisao de qualidade no PR #3: o unico except sem comentario
era o que eu havia acabado de acrescentar. A linha corrompida nao pode
bloquear a gravacao da sondagem -- e justamente a conexao que mais precisa
ser diagnosticada.
O risco de bloqueio nao vem de varias sessoes na mesma conta -- os
provedores convivem com isso -- e sim de varias CONTAS saindo pelo mesmo
endereco, que e o estado natural de um gateway com todas elas cadastradas.
Para o provedor, identidades distintas na mesma origem tem o formato de uma
revenda de acesso.

O modelo ja sabia calcular esse vinculo (egress_status/egress_binding) e
nada no painel o mostrava: o operador so descobriria depois do provedor.
Agora cada conexao de nuvem exibe a propria saida, em modo somente leitura
-- quem roteia a requisicao e o gateway, sempre.

Uma decisao de produto vai junto: compartilhar o endereco so vira aviso a
partir da SEGUNDA conta nessa situacao. Sozinha, ela e a unica dona daquele
IP e nao ha o que sinalizar; alertar ali seria alarme falso em toda
instalacao de conta unica.

Verificado contra o gateway real do artigo 0003: sete conexoes, das quais
cinco aparecem como "divide o endereco do gateway com 5 contas".
@elielsousa-pathbit
elielsousa-pathbit merged commit 19f642c into master Sep 12, 2026
5 checks passed
@elielsousa-pathbit
elielsousa-pathbit deleted the chore/pos-merge branch September 12, 2026 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant