Pular para conteúdo

Insights de IA — Fluida

Atualizado: 2026-06-22 Status: implementado e ativado em produção (mobile + web + backend) Handoff de entrega: .context/handoffs/2026-06-22-cartoes-fatura-insights.md Handoff de design: design_handoff_insights_ia/design_handoff_insights/

Esta página é a referência canônica da feature Insights Fluida. Para padrões gerais de frontend, ver Frontend Architecture. Para o motor de insights por dimensão que a antecede, ver MVP-3 — Hub de Cartões + Insights Globais e MVP-2 — AI Insights v2.


1. Visão

"Fluida" é o redesenho da tela de Insights de IA: troca o dump de JSON por uma leitura editorial — uma retrospectiva guiada, com textos curtos intercalados a comparativos e gráficos, de densidade baixa e tom analítico. Mesmo conceito em mobile e web.

Os insights são gerados diário ou semanalmente: a IA lê transações, metas, orçamentos, cartões e carteira e produz um insight geral + insights detalhados por tema. A tela Fluida é a leitura desse conteúdo, organizada como uma matéria:

  1. Masthead — logo + seletor de cadência (Diário/Semanal) + abas de tema (Geral · Transações · Metas · Orçamentos · Cartões) + alternador claro/escuro.
  2. Lead editorial — kicker (tema) + selo de severidade + tempo de leitura; headline serifada (Newsreader) + parágrafo de abertura.
  3. Beats intercalados (o coração do "fluido"):
  4. Comparativos ("Como se compara") — mini-cards ontem · anteontem · vs. semana.
  5. Texto curto (capitular no primeiro parágrafo).
  6. Gráfico ("O ritmo de saídas") — barras dos últimos 7 dias / 6 semanas, com o pico destacado.
  7. Texto curto + pull-stat (destaque numérico, ex.: "55% das despesas").
  8. Pontos de atenção (lista de alertas por severidade).
  9. "Para onde seguir agora" — bloco teal com a recomendação de fechamento.
  10. Procedência da IA — modelo, data de geração, nota de privacidade.

No web, alguns beats ficam lado a lado (texto + número/visual), com largura de leitura ~740px; no mobile, empilham.

Recorte por feature

Cada página de feature (Transações, Metas, Orçamentos, Cartões, Carteira) exibe uma section "Insights de IA" compacta com apenas o recorte daquela dimensão (lead + destaques + "ler na íntegra" → leva à tela principal). O mesmo conteúdo, recortado por dimensão.


2. Decisão de dados (princípio central)

A IA gera o TEXTO; o backend CALCULA os números.

  • O summary/parágrafos vêm da geração de IA já existente (motor de insights por dimensão — MVP-3).
  • Os blocos retro (comparativos), series (gráfico) e highlights (destaques numéricos) são derivados das transações pelo backend — determinísticos, auditáveis, sem alucinação.
  • O lead (severity, title, lead, next_step, read_min) é derivado deterministicamente do summary, sem nova chamada ao LLM (ver §4).

Vantagem: números sempre corretos e baratos; texto rico onde a IA agrega valor. O cliente (app/web) não calcula — só renderiza o payload.


3. Arquitetura

3.1 Backend (auraxis-api, Flask)

A geração de insight existente é enriquecida com os campos Fluida, on-the-fly, na serialização (REST + GraphQL).

Arquivo Papel
app/services/insight_fluida_builder.py enrich_insight_payload(payload, *, user_id, anchor) — injeta paragraphs, retro, series, highlights, lead. Reusa weekly_summary._aggregate_range para os agregados.
app/services/insight_lead_builder.py build_lead(...) + helpers derive_severity / derive_title_and_lead / derive_next_step / resolve_read_min. Tudo string/número — sem LLM.
app/services/weekly_summary.py _aggregate_range(*, user_id, start, end) -> (income, expense, count) para transações PAGAS (exclui soft-deleted e impact_policy == CARDS_ONLY). Fonte única dos agregados.

PRs: #1502 (payload estruturado) e #1508 (lead editorial). Exposto em REST e na mutation GraphQL generateAiInsight.

3.2 Mobile (auraxis-app, React Native + Expo + Tamagui)

  • Tela: features/insights/screens/insights-fluida-screen.tsx (Fluida) vs. features/insights/screens/ai-insights-screen.tsx (legada). O switch por flag está em app/(private)/insights.tsx.
  • Mapper: features/insights/fluida/insight-to-fluida-vm.tsUserInsight (payload real) → InsightFluidaVM, com fallback mock-safe: se o insight é null, não tem corpo, ou é payload legado, cai para o recorte mock (selectFluidaVM); lead e corpo caem independentemente.
  • Recorte por feature: shared/insights/insight-section.tsx (InsightSection) — section compacta plugada nas 5 páginas de feature; renderiza null quando não há vm; gated pela flag.
  • Beats/charts: barras em RN puro com animação de crescimento a partir da baseline (hook de bar-grow); sem lib de chart pesada.
  • Fonte serifada: @expo-google-fonts/newsreader (^0.4.1) — JS-only, carregada via expo-font, por isso OTA-friendly (não exige rebuild nativo).

3.3 Web (auraxis-web, Nuxt 4 + TypeScript + Naive UI + ECharts)

  • Feature: app/features/ai-insights/fluida/15 componentes Vue em components/: InsightsFluida.vue (raiz), FluidaMasthead, FluidaCadenceToggle, FluidaThemeTabs, FluidaLead, FluidaSevChip, FluidaReadTime, FluidaCompareBeat, FluidaChartBeat, FluidaTextBeat, FluidaPullStat, FluidaStatTiles, FluidaAlertList, FluidaSeguir, FluidaAiMeta.
  • Mapper: app/features/ai-insights/fluida/model/insight-to-fluida-vm.ts — converte o DTO REST para o view model. Função overlayLead() mapeia o lead do backend: readMin: lead.read_min, nextStep: lead.next_step (corrige o naming snake_case do REST); quando o lead falta, o recorte mock sobrevive verbatim.
  • Switch legado: app/pages/insights.vue<InsightsFluida v-if="isFluidaEnabled" /> vs. <div v-else> (relatório legado), com useFeatureFlag("web.insights.fluida").
  • Gráfico: ECharts (stack já presente na web).
  • Fonte serifada: @nuxtjs/google-fonts (3.2.0) com Newsreader: [500, 600] — só na headline; corpo segue Inter.

Paridade app ↔ web: mesmo contrato de dados e mesma lógica de view model (ambos os mappers se chamam insight-to-fluida-vm.ts e implementam o mesmo overlay com fallback mock-safe).


4. Lead determinístico (sem custo extra de LLM)

build_lead(...) deriva o lead a partir do summary já gerado:

  • severity — heurística sobre a variação de saídas semana-a-semana + concentração do gasto dominante (thresholds: ~+30% → atencao; ~+100% → alerta; ou ~55% de concentração). Níveis: ok (verde) · atencao (âmbar) · alerta (vermelho).
  • read_min — tabela fixa por cadência × escopo: Diário ~15 min (geral) / ~3 min (tema); Semanal ~30 min (geral) / ~5 min (tema).
  • title / lead — extraídos do texto do summary (primeira frase / corpo).
  • next_step — extraído do summary (preferência pela última frase de recomendação).

Nenhuma dessas operações chama o LLM — são string/número. É o ponto exato do follow-up (§6).


5. Feature flags

Flag Repo Arquivo Valor Janela
app.insights.fluida auraxis-app config/feature-flags.json enabled-prod criada 2026-06-21; remover até 2026-12-31
web.insights.fluida auraxis-web config/feature-flags.json enabled-prod criada 2026-06-21; remover até 2027-12-31
  • O default era OFF; toda a feature foi construída atrás da flag, sem tocar produção até o flip (app #618, web #1076).
  • Tela legada preservada em ambos (app: switch por flag; web: v-if/v-else) → rollback imediato desligando a flag.

6. Contrato de dados (payload Fluida)

Por cadência (diario | semanal) e por dimensão (geral + temas transacoes/metas/orcamentos/cartoes):

Campo Tipo Origem Onde aparece
severity ok | atencao | alerta backend (heurística) selo do lead
title (REST: derivado) string backend (do summary) headline serifada
lead string backend (do summary) parágrafo de abertura
paragraphs string[] IA (summary) beats de texto
read_min number backend (tabela) badge de tempo de leitura
next_step string backend (do summary) bloco "para onde seguir"
retro[] { quando, valor, txt }[] backend (agregados) comparativos (só no geral)
series { diaSerie[7], semanaSerie[6] } backend (agregados) gráfico "ritmo de saídas"
highlights[] (temas) { k, v, s }[] backend (agregados) pull-stats / tiles numéricos
alertas[] (geral) lista por severidade backend pontos de atenção

Atenção ao naming REST: o backend serializa em snake_case (read_min, next_step); o mapper web converte para camelCase (readMin, nextStep) no overlayLead(). Foi a correção da PR web #1073.

Referência de formato e tom (mock ancorado em dados reais de Junho/2026): design_handoff_insights_ia/design_handoff_insights/insights-data.js.


7. Tokens de design (referência do handoff)

Escopo .axi, claro/escuro. Atenção: o protótipo usa brand #0E6376; em produção vale a paleta semântica de cada frontend (ver Frontend Architecture e o design system vigente).

  • Tipografia: UI Plus Jakarta Sans (web vigente: Inter); headline serifada Newsreader (peso 500–600); valores em mono tabular (IBM Plex Mono / JetBrains Mono, tabular-nums).
  • Severidade: ok=verde · atencao=âmbar · alerta=vermelho.
  • Sinais: pos #11a36b, neg #e5484d, warn #c77d1a. Raios: cards 14–18, chips 999.

8. Entrega (rastreabilidade)

Camada PRs
Backend (auraxis-api) #1502 payload, #1508 lead
Mobile (auraxis-app) #600, #602, #604, #606, #608, #618 (flip)
Web (auraxis-web) #1071, #1073, #1076 (flip)

Estado: ativada em produção — app por OTA (#618); web e backend deployados. Lead+corpo reais com fallback mock-safe; app↔web em paridade.

Os campos Fluida no app são JS-only (inclusive a fonte Newsreader via @expo-google-fonts/newsreader), por isso a entrega mobile foi OTA-safe. Contraste com o incidente de Cartões, em que libs nativas foram (erroneamente) enviadas por OTA — ver a lição 2026-06-22-licao-deps-nativas-exigem-build.


9. Follow-up aberto

  • Lead 100% gerado pela IA por dimensão. Hoje o lead (title/lead/next_step) é derivado deterministicamente do summary (§4). Para tê-lo gerado pela IA por dimensão, estender o insight_fluida_builder reusando a geração de texto já existente — pedir os campos do lead no mesmo ciclo do summary, para não somar custo de LLM (não abrir nova chamada).
  • Limpeza das flags quando a tela legada for aposentada (janelas na §5).