Auth — visão geral
A autenticação no Fayz é abstraída por um contrato: o AuthAdapter. O mesmo useAuth vale rodando contra o Supabase em produção ou contra um adapter mock nos previews. O backend de auth é um detalhe que você troca — o código que consome auth não muda.
O contrato: AuthAdapter
Um adapter implementa as operações de sessão — getSession, signIn, signUp, signOut, signInWithOAuth, resetPassword, onAuthStateChange e afins. O @fayz-ai/auth traz dois de fábrica:
createSupabaseAuthAdapter({ supabaseUrl, supabaseAnonKey })— auth real via Supabase Auth. Mapeia usuário e sessão do Supabase para os tipos do Fayz (AuthUser,AuthSession).createMockAuthAdapter()— um usuário simulado persistido emlocalStorage, para desenvolvimento e previews sem backend. Ele já vem "logado" como um usuário demo.
Trocar de um para o outro é trocar a factory — nada mais.
Consumindo: AuthProvider + useAuth
Num app código-primeiro, você monta o AuthProvider na raiz, passando o adapter escolhido, e consome o estado com o hook useAuth:
import { AuthProvider, useAuth, createSupabaseAuthAdapter } from '@fayz-ai/auth'
const adapter = createSupabaseAuthAdapter({
supabaseUrl: import.meta.env.VITE_SUPABASE_URL,
supabaseAnonKey: import.meta.env.VITE_SUPABASE_ANON_KEY,
})
function Root() {
return (
<AuthProvider adapter={adapter}>
<App />
</AuthProvider>
)
}
function UserBadge() {
const { user, isAuthenticated, signOut } = useAuth()
if (!isAuthenticated) return <span>Visitante</span>
return <button onClick={signOut}>{user?.fullName}</button>
}
O useAuth expõe user, session, isLoading, isAuthenticated, error e as ações (signIn, signUp, signOut, signInWithOAuth, resetPassword, …). Chamá-lo fora de um <AuthProvider> lança um erro — de propósito.
Como isso se aplica no scaffold manifesto-primeiro
Aqui está a parte honesta. No app gerado pelo fayz create — o caminho manifesto-primeiro — você não monta o AuthProvider à mão. O runtime da plataforma lê o backend.provider do manifesto e conecta o adapter correspondente por você: mock usa o adapter simulado; supabase usa o adapter real com as credenciais do seu .env.local. A auth "acompanha" o backend que você declara — trocar o provider no manifesto já troca o adapter de auth.
O AuthProvider / useAuth explícitos que você viu acima são o caminho código-primeiro: apps que montam a própria árvore React (via defineSaas ou headless) e querem controle direto sobre onde a sessão entra. Os dois caminhos usam o mesmo contrato AuthAdapter — muda só quem monta o provider.
Resumo: manifesto-primeiro → o adapter de auth segue backend.provider, sem código. Código-primeiro / headless → você monta o AuthProvider com o adapter da sua escolha. Contrato idêntico nos dois.
Auth e o multi-tenant
A sessão resolvida pela auth é o que alimenta a função public.user_tenant_ids() no banco — ou seja, é a auth que decide, na ponta, quais linhas o RLS deixa você ver. Auth e isolamento andam juntos; veja RLS e multi-tenant.
Próximo: crie a sua primeira capacidade em Incubator.