mirror of
https://github.com/melgarafael/DeskcommCRM.git
synced 2026-10-02 01:28:34 +08:00
fix(realtime): setAuth é assíncrono — o await fecha a segunda janela
A dúvida residual era: "o conserto garante que `setAuth` seja CHAMADO, não que tenha EFEITO sobre uma conexão que ainda não existe". O tipo de retorno respondeu antes de qualquer experimento — `setAuth(token?): Promise<void>`. Sem `await`, a flag `autenticou` virava true quando a CHAMADA saía, não quando o token era APLICADO ao socket, e a promessa memoizada resolvia antes disso. Como é essa promessa que os hooks esperam para assinar, o `subscribe` podia correr com o socket ainda anônimo — e assinatura anônima com RLS por `auth.uid()` recebe ZERO linhas, em silêncio, com o canal respondendo SUBSCRIBED. Mesmo sintoma do defeito da memo, por outro caminho: lá a memo guardava a falha, aqui a promessa resolvia cedo demais. ISTO É CERCA, NÃO MEDIÇÃO — e é por isso que vale. A alternativa seria instrumentar o hook para provocar a corrida, o que é mexer no mecanismo sob teste; a orientação foi declarar a dúvida em vez de persegui-la, EXCETO se existisse sinal de conexão que a removesse por construção. O `Promise` do `setAuth` é esse sinal, e esperá-lo custa uma palavra. O achado veio de ler a assinatura da API, não de rodar nada. A dúvida estava escrita como limite conhecido e o limite acabou tendo conserto. Board segue nascendo `authenticated` em duas rodadas com a assinatura apagada entre elas. Os três unitários da memo seguem verdes. typecheck 0 · lint 0 erros. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013dxBNZMjUzBx8xWs8DvGvP
This commit is contained in:
co-authored by
Claude Opus 5
parent
416b1e2690
commit
02298924da
@@ -41,6 +41,11 @@ export interface UseRealtimeChannelOpts {
|
||||
* if (!res.ok) return → 401/500: memo FICAVA, setAuth nunca corria
|
||||
* if (token) setAuth(token) → corpo sem token: memo FICAVA, idem
|
||||
*
|
||||
* E havia uma SEGUNDA janela, achada depois pelo tipo de retorno: `setAuth`
|
||||
* é assíncrono, e chamá-lo sem `await` fazia a promessa memoizada resolver
|
||||
* antes de o token estar no socket. Quem assinasse nesse intervalo assinava
|
||||
* anônimo — o mesmo sintoma, por outro caminho.
|
||||
*
|
||||
* Ou seja: UM ÚNICO 401 transitório — sessão ainda estabelecendo, cookie em
|
||||
* renovação — deixava TODOS os canais criados depois anônimos pelo resto
|
||||
* daquele carregamento. E a recuperação estava escrita justamente para o
|
||||
@@ -70,7 +75,18 @@ export function authenticateRealtime(supabase: ReturnType<typeof createClient>):
|
||||
const body = (await res.json()) as { data?: { access_token?: string } };
|
||||
const token = body.data?.access_token;
|
||||
if (token) {
|
||||
supabase.realtime.setAuth(token);
|
||||
// ⚠️ O `await` NÃO É DECORATIVO: `setAuth` devolve `Promise<void>`.
|
||||
//
|
||||
// Sem ele, `autenticou` virava true quando a CHAMADA saía, não quando
|
||||
// o token era APLICADO ao socket — e a promessa memoizada resolvia
|
||||
// antes disso. Como quem assina espera essa promessa, o `subscribe`
|
||||
// podia correr com o socket ainda anônimo, e uma assinatura anônima
|
||||
// com RLS por `auth.uid()` recebe ZERO linhas em silêncio.
|
||||
//
|
||||
// A dúvida era: "o conserto garante que setAuth seja CHAMADO, não que
|
||||
// tenha EFEITO". O tipo de retorno respondeu — havia mesmo uma janela,
|
||||
// e esperar por ela custa uma palavra. É cerca, não medição.
|
||||
await supabase.realtime.setAuth(token);
|
||||
autenticou = true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user