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.
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, o mock populado é responsabilidade da plataforma; aqui você faz na mão.
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:
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 }),
})
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.
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:
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:
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:
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:
// 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:
{
"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.