# Rodando local com dados de exemplo

O `backend: { provider: "mock" }` deixa o app rodar sem env — mas "modo mock" não significa "modo populado". Os providers mock **nascem vazios**: você abre a agenda e não há agendamentos, abre o financeiro e não há lançamentos. A promessa de "dados de exemplo" só se cumpre quando você **semeia** o provider na construção. Esta página é o mapa direto dos seams de seed, mais dois detalhes que mordem quem consome os pacotes publicados: o dashboard em mock e o `FAYZ_SDK_SOURCE`.

{% callout type="info" %}
Isto é sobre o segundo caminho de consumo — código que importa os pacotes `@fayz-ai/*` publicados e monta o app em `src/` (via `defineSaas` / plugin factories), não o app manifesto-primeiro que a plataforma renderiza. Se você está no fluxo do [Quickstart](/pt-BR/docs/quickstart), o mock populado é responsabilidade da plataforma; aqui você faz na mão.
{% /callout %}

## Por que o mock nasce vazio

Um provider mock é uma implementação em memória do contrato de dados de um plugin. Ele existe para o app **compilar e rodar sem backend** — não para adivinhar que loja você está construindo. Sem seed, a lista está vazia por design. Semear é passar os objetos de domínio na construção do provider; a partir daí o mock os trata como o "banco" existente (cria, edita, filtra em cima deles).

Há quatro seams, do mais específico (um plugin) ao mais genérico (uma entidade CRUD).

## Agenda: `createMockAgendaProvider({ seed })`

`createMockAgendaProvider` aceita um `MockAgendaSeed` (de `@fayz-ai/plugin-agenda`). Você passa o provider semeado para a factory do plugin via `dataProvider`:

```ts
import { createAgendaPlugin, createMockAgendaProvider } from '@fayz-ai/plugin-agenda'
import type { MockAgendaSeed } from '@fayz-ai/plugin-agenda'

const seed: MockAgendaSeed = {
  professionals: [
    { id: 'p1', name: 'Ana', /* … */ },
  ],
  bookings: [
    { id: 'b1', professionalId: 'p1', startsAt: '2026-07-20T14:00:00Z', /* … */ },
  ],
  // schedules? também aceito; qualquer coleção omitida cai no exemplo embutido
}

export const agenda = createAgendaPlugin({
  dataProvider: createMockAgendaProvider({ seed }),
})
```

{% callout type="tip" %}
**Atalho:** `createMockAgendaProvider()` **sem seed** já traz um exemplo pronto — uma agenda estilo salão com profissionais e horários embutidos. É o jeito mais rápido de ver a agenda populada; use o `seed` só quando quiser dados do seu próprio cenário (uma clínica, um estúdio). Qualquer coleção que você **omitir** no seed cai de volta nesse exemplo embutido.
{% /callout %}

## Financeiro: `createMockFinancialProvider({ seed })`

Mesma forma para o financeiro. O `MockFinancialSeed` (de `@fayz-ai/plugin-financial`) pré-popula o ledger — faturas, movimentos, contas, métodos de pagamento:

```ts
import { createFinancialPlugin, createMockFinancialProvider } from '@fayz-ai/plugin-financial'
import type { MockFinancialSeed } from '@fayz-ai/plugin-financial'

const seed: MockFinancialSeed = {
  invoices: [ /* … */ ],
  movements: [ /* … */ ],
  // bankAccounts? cai em duas contas padrão quando ausente; o resto fica vazio se omitido
}

export const financial = createFinancialPlugin({
  dataProvider: createMockFinancialProvider({ seed }),
})
```

Diferente da agenda, o financeiro **não** inventa faturas/movimentos quando o seed é omitido — as coleções ficam vazias (exceto `bankAccounts`, que cai em duas contas padrão). Se quer o módulo populado, passe o seed.

## Uma entidade qualquer: `createMockProvider(entityDef, initialData)`

Para CRUD genérico — um plugin próprio, uma entidade sua — `@fayz-ai/core` expõe `createMockProvider`. O segundo argumento é o array inicial:

```ts
import { createMockProvider } from '@fayz-ai/core'

const provider = createMockProvider(clientEntityDef, [
  { id: 'c1', name: 'Cliente Exemplo', email: 'exemplo@teste.com' },
  { id: 'c2', name: 'Outro Cliente', email: 'outro@teste.com' },
])
```

O primeiro argumento pode ser o `EntityDef` (de onde ele deriva os campos pesquisáveis e a ordenação padrão) ou só um array de chaves pesquisáveis. `initialData` default é `[]` — por isso o vazio.

## Uma página CRUD do SaaS: `createCrudPage(entity, { mockData })`

No nível de página, `createCrudPage` (de `@fayz-ai/saas`) aceita `mockData` direto nas opções — útil quando você monta uma tela de listagem sem provider explícito:

```ts
import { createCrudPage } from '@fayz-ai/saas'

const ClientsPage = createCrudPage(clientEntity, {
  mockData: [
    { id: 'c1', name: 'Cliente Exemplo' },
    { id: 'c2', name: 'Outro Cliente' },
  ],
})
```

## O dashboard em mock mostra zeros

O `plugin-dashboard` lê o Supabase **direto** para compor seus KPIs — ele não passa pelos providers mock dos outros plugins. Em modo mock, sem Supabase configurado, os cards vêm **zerados**. Semear a agenda ou o financeiro não muda isso: o dashboard não enxerga esses seeds.

A saída honesta é **não** contar com o dashboard embutido em modo mock, e sim registrar **widgets custom com `compute`** que derivam dos mesmos seeds. Um widget do tipo KPI aceita um `compute?: () => Promise<KpiValue>` — você calcula o número a partir dos seus dados de exemplo:

```ts
// um widget que deriva o número dos seeds, em vez de ler o Supabase
{
  id: 'custom:faturas-abertas',
  compute: async () => ({ value: seed.invoices.filter((i) => i.status === 'open').length }),
}
```

Assim o painel reflete o cenário mock em vez de mostrar zeros. Quando você trocar para o backend Supabase real, o dashboard embutido passa a computar de verdade e esses widgets custom viram opcionais.

## `FAYZ_SDK_SOURCE`: fixe os pacotes publicados

O helper `fayzVite` (de `@fayz-ai/sdk/vite`) tem um comportamento de conveniência para o monorepo: se um checkout do `fayz-sdk` existir **ao lado** do app (em `../../fayz-sdk`), ele aliassa os imports `@fayz-ai/*` para o **código-fonte local** desse monorepo, não para o `node_modules`. Ótimo para quem desenvolve o SDK; uma armadilha para um app standalone que só quer consumir os pacotes publicados — de repente o app roda contra fonte não publicada que por acaso está no disco.

O controle é a env `FAYZ_SDK_SOURCE`. Um app standalone deve fixá-la em `published` nos scripts, garantindo que ele sempre resolva os pacotes de `node_modules`:

```json
{
  "scripts": {
    "dev": "FAYZ_SDK_SOURCE=published vite",
    "build": "FAYZ_SDK_SOURCE=published vite build"
  }
}
```

Com `FAYZ_SDK_SOURCE=published`, o `fayzVite` ignora qualquer checkout vizinho e usa exatamente as versões dos seus `dependencies` — que é o que você quer ao testar o app como um dev externo testaria.

---

Próximo: o segundo caminho de consumo em [Headless](/pt-BR/docs/apps/headless).
