# 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 em `localStorage`, 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`:

```tsx
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>
  )
}
```

```tsx
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.

{% callout type="info" %}
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.
{% /callout %}

## 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](/pt-BR/docs/dados/rls).

---

Próximo: crie a sua primeira capacidade em [Incubator](/pt-BR/docs/plugins-proprios/incubator).
