Skip to content

feat(guia): tutorial guiado do cliente novo + planos SaaS/Completo + gates de 12m - #35

Merged
BarryBits merged 2 commits into
mainfrom
feat/guia-cliente-e-gates
Jul 29, 2026
Merged

feat(guia): tutorial guiado do cliente novo + planos SaaS/Completo + gates de 12m#35
BarryBits merged 2 commits into
mainfrom
feat/guia-cliente-e-gates

Conversation

@BarryBits

Copy link
Copy Markdown
Owner

O sistema passa a se explicar sozinho pro dono que entra pela primeira vez, e os gates de maturidade sobem pra refletir o produto real.

Docs: mapa-guia-cliente.md (o mapa das 14 telas, escrito lendo o código) e guia-cliente-conteudo.md (a mecânica + as 22 copys).

⚠️ Antes de mergear

As duas migrations já foram aplicadas no remoto (profiles.guia_visto e o CHECK de client_onboarding.plano_tipo). Por isso o db/snapshot/ vai marcado 🔴 obsoleto — re-dump pendente.

O guia — 3 mecanismos, 1 registro de conteúdo

Três componentes com três copys próprias divergem entre si em poucos meses. Aqui os três leem de src/lib/guia/conteudo.ts.

Mecanismo Estado anterior
Tour existia, desatualizado
Trilho da Jornada construído e desligado
Faixa de entrada não existia
Chat 3 sugestões genéricas

Tour — o CTA final ia pra /financeiro/dre?tab=extratos, que é um redirect que descarta o ?tab: o cliente terminava o onboarding no Cockpit vazio, não na Ingestão. Prometia Comercial/Gestão (OFF por flag) e apontava o item Cockpit dizendo que ali se importa extrato (isso migrou pra Apuração; o id onboarding-nav-financeiro foi junto). O passo do seletor de empresa virou condicional — só com mais de um CNPJ.

Trilho da Jornada — as triggers da migration 20260530000000 avançavam jornada_etapa no banco e <JornadaBanner não era renderizado em lugar nenhum: o banco sabia onde o cliente estava e ninguém mostrava a ele. Ligado no topo da Apuração, com os alvos remapeados pras abas reais. E a etapa tour_completo era "ação manual da UI" que ninguém disparava — o trilho nasceria invisível pra sempre mesmo depois de renderizado.

Faixa de entrada (nova) — um bloco por tela, 4 slots fixos, "Entendi" persistido em profiles.guia_visto. Orçamento duro (título ≤60 chars, corpo ≤55 palavras) guardado por teste: copy que estoure quebra o build. 10 das 13 faixas saem de um ponto só — o CasaDoGrupoShell deriva o id da aba corrente.

Chat — disclaimer honesto sobre o que ele não faz (não mexe em dado, não executa) e sugestões por tela.

Planos: SaaS e Completo

Substituem os 3 da era de módulos. O CHECK segue aceitando os legados porque há contrato real gravado com eles — converter seria reescrever dado de cliente por adivinhação, e isso é decisão de negócio, não de migration.

Junto: máscara BRL de verdade no valor do contrato (o parse antigo transformava "36.000,00" em 36 reais), o checkbox de módulos saiu (não ativava nada — os módulos são semeados na criação do projeto) e o placeholder duplicado dos selects sumiu. PlanoTipo estava duplicado em dois services; unificado em constants/planos.ts.

Gates

Plano de Voo: de 3 para 12 meses. Deixou de ser contagem e virou cobertura da janela anterior à entrada do cliente (janela-12m.ts): 12 meses velhos, ou 12 com buraco no meio, não destravam. Ancorado na entrada e não no mês corrente — o gate é de profundidade de histórico, então quem sobe 12 meses de OFX na primeira semana destrava na primeira semana.

Iniciativas: só abrem com Plano de Voo aprovado. A rota redireciona pro Plano; a sidebar mostra cadeado.

O checklist de documentos ainda pedia "extratos dos últimos 3 meses" — o cliente entregaria exatamente o pedido e nunca destravaria o Plano. Corrigido pra 12.

Validação

  • tsc --noEmit 0 erros
  • vitest 1408/1408 (151 arquivos)
  • eslint 0 erro novo — provado cruzando as linhas do diff com a saída JSON
  • next build OK

Não validado ao vivo: só o tour foi visto rodando numa sessão real. Faixa, trilho da Jornada e os dois gates ainda não passaram por smoke em tela.

🤖 Generated with Claude Code

BarryBits and others added 2 commits July 29, 2026 00:25
…ava mais

Dois bugs pré-existentes que só apareceram ao percorrer o cadastro de um cliente
novo de ponta a ponta. Nenhum tem relação com a trilha do guia — vão num commit
próprio pra poderem ser cherry-picked como hotfix.

1) criar cliente estava QUEBRADO nos dois caminhos da UI

`criarGrupo` espalhava `...co` no insert de `companies`, levando junto a chave
`bank_accounts` — que não é coluna, é TABELA à parte (FK company_id). O PostgREST
respondia PGRST204 ("Could not find the 'bank_accounts' column of 'companies'").

Não era caso de borda: o wizard /clientes/novo monta o map e o ClienteSheet manda
`bank_accounts: []`, então a chave ia SEMPRE. O caminho irmão do mesmo arquivo
(`adicionarEmpresa`) já fazia o strip certo; faltava aqui.

2) sessão sem profile derrubava o app com ERR_TOO_MANY_REDIRECTS

Usuário autenticado cuja role não resolve (linha ausente em `profiles`) fazia
`resolveLandingPath` devolver "/login" — e o middleware, processando /login,
redirecionava pra /login. Loop infinito.

O detalhe cruel: o destino da falha era a própria tela de login, então a pessoa
não conseguia nem se reautenticar pra sair do estado. Agora o middleware nunca
redireciona uma rota pra ela mesma.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…gates de 12m

O sistema passa a se explicar sozinho pro dono que entra pela primeira vez, e os
gates de maturidade sobem pra refletir o produto real. Docs: mapa-guia-cliente.md
(o mapa das 14 telas, escrito lendo o código) e guia-cliente-conteudo.md (a
mecânica + as 22 copys).

## O guia — 3 mecanismos, 1 registro de conteúdo

Três componentes com três copys próprias divergem entre si em poucos meses. Aqui
os três leem de `src/lib/guia/conteudo.ts`.

- TOUR (existia, desatualizado): o CTA final ia pra `/financeiro/dre?tab=extratos`,
  que é um redirect que DESCARTA o `?tab` — o cliente terminava o onboarding no
  Cockpit vazio, não na Ingestão. Prometia Comercial/Gestão (OFF por flag) e
  apontava o item Cockpit dizendo que ali se importa extrato (migrou pra
  Apuração; o id `onboarding-nav-financeiro` foi junto). O passo do seletor de
  empresa virou CONDICIONAL: só com mais de um CNPJ.

- TRILHO DA JORNADA (existia e estava DESLIGADO): as triggers da migration
  20260530000000 avançavam `jornada_etapa` no banco e `<JornadaBanner` não era
  renderizado em lugar nenhum — o banco sabia onde o cliente estava e ninguém
  mostrava. Ligado no topo da Apuração, com os alvos remapeados pras abas reais
  (`?aba=ingestao|categorizacao|dre`; o vocabulário antigo não existia em rota
  nenhuma). A etapa `tour_completo` era "ação manual da UI" e NINGUÉM disparava:
  o trilho nasceria invisível pra sempre. O fim do tour agora a avança.

- FAIXA DE ENTRADA (nova): um bloco por tela, 4 slots fixos, botão "Entendi"
  persistido em `profiles.guia_visto`. Orçamento duro (título ≤60 chars, corpo
  ≤55 palavras) guardado por TESTE — copy que estoure quebra o build. 10 das 13
  faixas saem de um ponto só: o CasaDoGrupoShell deriva o id da aba corrente.

- CHAT: disclaimer honesto sobre o que ele NÃO faz (não mexe em dado, não executa)
  e sugestões POR TELA, no lugar de 3 genéricas iguais em qualquer rota.

## Planos: SaaS e Completo

Substituem os 3 da era de módulos. O CHECK segue aceitando os legados porque há
contrato real gravado com eles — converter seria reescrever dado de cliente por
adivinhação, e isso é decisão de negócio, não de migration.

Junto: máscara BRL de verdade no valor do contrato (o parse antigo virava
"36.000,00" em 36 reais), o checkbox de módulos saiu (não ativava nada — os
módulos são semeados na criação do projeto) e o placeholder duplicado dos selects
sumiu (o FormSelect já injeta o dele).

`PlanoTipo` estava duplicado em dois services; unificado em constants/planos.ts.

## Gates

- PLANO DE VOO: de 3 meses para os 12 da JANELA anterior à entrada do cliente
  (janela-12m.ts). Deixou de ser contagem e virou cobertura: 12 meses velhos, ou
  12 com buraco no meio, não destravam. Ancorado na ENTRADA e não no mês corrente
  — o gate é de profundidade de histórico, então quem sobe 12 meses de OFX na
  primeira semana destrava na primeira semana.

- INICIATIVAS: só abrem com Plano de Voo APROVADO (iniciativas-gate.ts). A rota
  redireciona pro Plano; a sidebar mostra cadeado.

O checklist de documentos ainda pedia "extratos dos últimos 3 meses" — o cliente
entregaria o pedido e nunca destravaria o Plano. Corrigido pra 12.

## Migrations (JÁ APLICADAS no remoto)

- 20260728000000_profiles_guia_visto
- 20260728120000_plano_tipo_saas_completo

Por isso o db/snapshot vai marcado 🔴 obsoleto: re-dump pendente.

Validação: tsc 0 · vitest 1408/1408 · eslint 0 erro novo (provado cruzando as
linhas do diff com a saída json) · next build OK.

NÃO validado ao vivo: só o tour foi visto rodando. Faixa, trilho e gates não
passaram por smoke em tela.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 29, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
atr-os Ready Ready Preview, Comment Jul 29, 2026 3:41am

@supabase

supabase Bot commented Jul 29, 2026

Copy link
Copy Markdown

Updates to Preview Branch (feat/guia-cliente-e-gates) ↗︎

Deployments Status Updated
Database Wed, 29 Jul 2026 03:37:35 UTC
Services Wed, 29 Jul 2026 03:37:35 UTC
APIs Wed, 29 Jul 2026 03:37:35 UTC

Tasks are run on every commit but only new migration files are pushed.
Close and reopen this PR if you want to apply changes from existing seed or migration files.

Tasks Status Updated
Configurations Wed, 29 Jul 2026 03:37:41 UTC
Migrations Wed, 29 Jul 2026 03:37:42 UTC
Seeding ⏸️ Wed, 29 Jul 2026 03:37:31 UTC
Edge Functions ⏸️ Wed, 29 Jul 2026 03:37:31 UTC

❌ Branch Error • Wed, 29 Jul 2026 03:37:43 UTC

ERROR: relation "projects" does not exist (SQLSTATE 42P01)
At statement: 0
-- ============================================================
-- ATR OS - Migration: Project Lifecycle States
-- ============================================================
-- Adiciona campos de lifecycle para o fluxo de onboarding:
-- aguardando_docs → diagnostico_7d → plano_entregue → em_execucao → concluido
-- ============================================================

-- 1. Adicionar colunas de timestamp para cada etapa do lifecycle
ALTER TABLE projects
ADD COLUMN IF NOT EXISTS docs_solicitados_em timestamptz,
ADD COLUMN IF NOT EXISTS docs_recebidos_em timestamptz,
ADD COLUMN IF NOT EXISTS diagnostico_deadline timestamptz,
ADD COLUMN IF NOT EXISTS plano_entregue_em timestamptz,
ADD COLUMN IF NOT EXISTS execucao_inicio timestamptz,
ADD COLUMN IF NOT EXISTS execucao_deadline timestamptz

View logs for this Workflow Run ↗︎.
Learn more about Supabase for Git ↗︎.

@BarryBits
BarryBits merged commit 93caf7e into main Jul 29, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant