mindflow v0.3 — Rotinas Completas + Eventos
Status: 📋 Planejando · Base: v0.2.2 (Neo-brutalism design) · Data alvo: 2026-07
A v0.3 completa as 4 rotinas, adiciona a aba Eventos (Copa do Mundo) e implementa arquivamento. Vocabulário mais humano e fluido.
Escopo fechado
mindmap
root((mindflow v0.3))
4 Rotinas
Briefing já pronto
Ajudar com brisa
Bota o papo em dia
O Doutor
Aba Eventos
Copa do Mundo
v0.4 Google Calendar
Funcionalidades
Arquivamento
Schema metadados v1
Guardrail soft setup
Bot
tool_use 3 ferramentas
Infra
CI/CD GitHub Actions
Features por prioridade
P0 — Completar as Rotinas
Ajudar com brisa - O que faz: usuário digita ideia vaga → IA estrutura em algo acionável - Retorna: versão refinada com opções de próximo passo - Card: já existe visualmente (grid-2), só precisa do backend
Configurar setup - O que faz: onboarding guiado — quais áreas de vida, contexto inicial - Salva perfil no ContextStore para enriquecer respostas futuras - Card: já existe visualmente (grid-2), só precisa do backend
P1 — Bot Telegram com tool_use
O bot atual responde com contexto do banco mas não usa tool_use. Com tool_use:
- get_context(query) — busca semântica no VectorStore
- set_context(key, value) — salva informação explicitamente
- create_note(text, kind) — captura nota direto do Telegram
P2 — Infra
CI/CD GitHub Actions
- pytest no push para mindflow/main
- Falha bloqueia merge
Streaming SSE no chat (se reativado) - Respostas token por token - Elimina a espera com tela em branco
O que NÃO entra na v0.3
- ❌ Multi-usuário
- ❌ Integração Google Calendar
- ❌ Captura de voz (Whisper)
- ❌ Redesign adicional — v0.2.2 é a base
Base técnica (herda da v0.2.2)
| Componente | Estado |
|---|---|
| Design Neo-brutalism Light Mode | ✅ v0.2.2 |
| Briefing com tool_use + histórico | ✅ v0.2.2 |
| Token localStorage (sem cookie) | ✅ v0.2.1 |
| VectorStore Gemini embeddings | ✅ v0.2.0 |
| Bot Telegram no mindflow | ✅ v0.1.0 |
Sessões planejadas
| Sessão | Escopo | Estimativa |
|---|---|---|
| S1 | Ajudar com brisa (backend + prompt) | 2h |
| S2 | Configurar setup (backend + onboarding) | 2h |
| S3 | Bot com tool_use (3 ferramentas) | 3h |
| S4 | CI/CD GitHub Actions | 1h |
| S5 | Buffer + ajustes de UX | 2h |
Total estimado: ~10h de trabalho focado.
Para começar:
Sessão 1 — Ajudar com brisa
Decisões Técnicas (pré-implementação)
DT-001 — Schema unificado de metadados
Problema: eventos são salvos com payloads inconsistentes dependendo da origem.
- Captura via web:
{"text": str}— só isso - Briefing (rotina):
{"text": str, "actions": list}— tem actions mas sem tipo/fonte explícita - bot Telegram:
{"text": str}— mesmo payload mínimo da web
Sem type, source, routine_id e importance no payload, não é possível filtrar por tipo de rotina, rastrear a origem do canal ou renderizar o histórico de forma consistente. O source existe na coluna da tabela mas não no payload — quem lê payload não tem acesso a ele diretamente.
Decisão: todos os eventos novos salvam com payload normalizado (schema v1):
{
"text": str, # conteúdo principal (obrigatório)
"type": "capture" | "routine_result" | "system", # categoria semântica
"routine_id": str | None, # "briefing", "brisa", "setup", None
"source": "web" | "telegram", # canal de entrada
"importance": 1 | 2 | 3, # 1=normal, 2=marcante, 3=épico
"tags": list[str], # ["ideia", "decisão", "gratidão"]
"version": "1" # schema version para migrations futuras
}
Mapeamento de defaults por chamador:
| Origem | type |
routine_id |
source |
importance |
|---|---|---|---|---|
POST /api/event (web) |
"capture" |
None |
"web" |
1 |
POST /api/event (telegram) |
"capture" |
None |
"telegram" |
1 |
briefing_routine |
"routine_result" |
"briefing" |
"web" |
1 |
setup completo |
"system" |
"setup" |
"web" |
2 |
O campo kind da coluna SQL permanece como está (ex: "nota", "ideia", "briefing"). O novo campo type no payload é a camada semântica normalizada — os dois coexistem.
Compatibilidade: eventos existentes no banco não são migrados. A lógica de leitura usa fallback:
# Leitura retrocompatível
payload = event.get("payload", {})
text = payload.get("text", "")
event_type = payload.get("type", "capture") # default para eventos antigos
source = payload.get("source") or event.get("source", "web") # coluna como fallback
importance = payload.get("importance", _KIND_IMPORTANCE.get(event.get("kind", "nota"), 1))
Spec completa: /workspace/docs/arquitetura/metadata-schema.md
DT-002 — Guardrail soft de setup
Problema: sem contexto do usuário, a IA (Brisa) responde de forma genérica. O usuário pode não perceber que precisa configurar o perfil para ter respostas mais precisas.
Decisão: guardrail soft — sem bloqueio, apenas aviso informativo. O usuário pode usar todas as funcionalidades mesmo sem setup.
Como verificar se setup foi feito:
# No ContextStore — verificação direta por kind
def has_setup(store: ContextStore) -> bool:
events = store.recent_events(limit=200)
return any(e.get("kind") == "setup" for e in events)
Payload do evento de setup (salvo quando usuário completa o onboarding):
store.log_event("web", "setup", {
"text": "Perfil configurado",
"type": "system",
"routine_id": "setup",
"source": "web",
"importance": 2,
"tags": ["setup", "perfil"],
"version": "1",
"profile": {
"name": str, # nome do usuário
"areas": list[str], # ["saúde", "trabalho", "relacionamentos"]
"tone": "direto" | "amigável", # tom das respostas
"context": str # texto livre de contexto inicial
}
})
Endpoint de status:
GET /api/context/setup-status
Resposta:
{ "configured": true | false }
Implementação sugerida: busca em recent_events(limit=200) por kind == "setup". Simples, sem campo extra no banco.
Banner de aviso — spec UX:
- Texto exato:
"Respostas podem ser menos precisas por falta de contexto. Configure seu perfil para personalizar a Brisa." - Link CTA:
"Configurar agora"→ abre o card "Configurar setup" - Onde aparece: topo do chat (
/api/chat) e topo do briefing, abaixo do header - Quando some: imediatamente após
GET /api/context/setup-statusretornar{"configured": true}(frontend verifica ao carregar) - Estilo: aviso não-bloqueante, cor âmbar (warning), dismissível por sessão (localStorage
setup_banner_dismissed) - Não aparece nas abas de captura (Notas/Ideias) — contexto de captura não depende de perfil
Vocabulário das Rotinas
| Card | Ícone | O que faz | Vibe |
|---|---|---|---|
| Briefing | ⚡ | Brisa resume o que ela sabe sobre você | Saída — Brisa fala |
| Bota o papo em dia | 💬 | Você conta o que mudou, Brisa absorve e atualiza contexto | Entrada — você fala |
| Ajudar com brisa | 🪄 | Refina ideia vaga em algo acionável | Colaborativo |
| O Doutor | 🩺 | Investiga e diagnostica seu sistema de vida. "Tá tudo certo? O que tá pesando?" | Análise e diagnóstico |
O Doutor substitui "Configurar setup" — não é uma tarefa admin, é uma consulta periódica que avalia o estado do seu contexto e sugere ações.
Aba Eventos (nova)
| Card | Conteúdo | Status |
|---|---|---|
| ⚽ Copa do Mundo | Resultados, próximos jogos, tabela | v0.3 |
| 📅 Google Calendar | Eventos da agenda pessoal via MCP | v0.4 |
A aba Eventos é separada das Rotinas — são informações externas, não ações do usuário.
Arquivamento
- Usuário pode arquivar qualquer item (nota, briefing, etc.)
- Arquivados somem do ativo (não aparecem no Briefing nem nas rotinas)
- Arquivados continuam no histórico com visual diferente (marcado como arquivado)
- Endpoint:
POST /api/event/{id}/archive
DT-003 — Copa do Mundo em tempo real (ESPN API)
Decisão: usar a ESPN API pública (sem cadastro/key) — mesma usada no brisa-core.
Por quê ESPN:
- Código já existe em /workspace/brisa-core/brisa/mural/copa_parser.py e copa_updater.py
- Não precisa de API key
- Estável e amplamente usada
- Dados ricos: resultados, próximos jogos, tabela, placar ao vivo
Spec técnica:
# Endpoint novo em mindflow
GET /api/events/copa
# Resposta
{
"next_matches": [
{"teams": "Brasil x Argentina", "date": "2026-06-22 20:00", "venue": "..."},
...
],
"recent_results": [
{"teams": "Espanha 2 x 1 Alemanha", "date": "2026-06-20", "status": "final"},
...
],
"cached_at": "2026-06-21T01:19:00"
}
Cache: 30 minutos (evita chamadas excessivas).
Frontend: card na aba Eventos que carrega via GET /api/events/copa ao abrir a aba.
Sessão planejada: S4 da v0.3 (após as 3 rotinas).
DT-004 — Briefings Personalizados (RFC aprovado)
3 modos, sem tabs, sem banco:
| Modo | Como funciona | Esforço |
|---|---|---|
| Por Contexto (auto) | Brisa detecta kinds dominantes → adapta prompt | P — 1h |
| Por Intenção | Input "O que quer focar?" antes do briefing | P — 45min |
| Por Brisa | Seleciona nota → briefing em torno dela | M — 2h |
RFC completo: /docs/rfc/briefings-personalizados.md
Sessões revisadas (v0.3 finalizado)
| Sessão | Escopo | Estimativa |
|---|---|---|
| S1 | Briefings Personalizados (Modo 1 + 2) + schema metadados v1 | 2h |
| S2 | Ajudar com brisa | 2h |
| S3 | Bota o papo em dia | 2h |
| S4 | O Doutor | 2h |
| S5 | Copa do Mundo (ESPN API) + aba Eventos | 2h |
| S6 | Bot com tool_use (3 ferramentas) | 3h |
| S7 | Arquivamento + guardrail soft | 2h |
| S8 | CI/CD + Buffer | 2h |
Total estimado: ~17h · v0.3 FECHADA
Próximo passo: iniciar S1 quando Lucas confirmar.
DT-005 — Google Calendar via MCP (integração completa)
Decisão: integrar Google Calendar com operações completas (não só leitura).
Operações:
- GET — puxar eventos da agenda para a aba Eventos
- POST — criar evento na agenda a partir do mindflow
- PATCH — modificar evento existente
- DELETE — deletar evento
Via MCP: expor o Calendar como ferramenta MCP para que a Brisa possa interagir diretamente com a agenda durante conversas e briefings.
Visão futura (v0.4+) — Agenda com Contexto: A Brisa sugere e customiza a agenda com base no contexto do usuário: - "Você tem uma reunião importante amanhã — seu histórico mostra que você rende melhor de manhã. Mover pra 9h?" - "Você não capturou nada sobre saúde essa semana. Quer que eu bloqueie 30min hoje pra isso?" - Agenda se adapta ao ritmo real do usuário, não o contrário
Princípio de design dos Eventos:
Eventos têm vida própria (cards de informação), mas PODEM alimentar o contexto da Brisa quando relevante. A conexão acontece por intenção do usuário ou naturalmente quando a Brisa detecta padrões. Não é automático sempre.
Escopo v0.3: - Aba Eventos com Copa (S5) - Google Calendar leitura básica (puxar) — se der tempo
Escopo v0.4: - Calendar CRUD completo via MCP - Agenda customizada por contexto
💡 Backlog de Produto (PO para refinar)
IDEA-001 — A Brisa das 3 (Regra dos 3)
"Tudo em grupos de 3 — a mente absorve melhor o que vem em trios."
O mindflow poderia ter um modo/filosofia onde tudo é apresentado em grupos de 3: - 3 brisas do dia — as 3 notas/pensamentos mais relevantes - 3 do briefing — os 3 insights principais do momento - 3 próximas ações — nunca mais que 3 coisas ativas ao mesmo tempo - 3 áreas de foco — trabalho, saúde, relações (ou as que o usuário escolher)
Inspiração: a Regra dos 3 é usada em retórica, GTD simplificado, e design de produto. Reduz sobrecarga cognitiva.
Como poderia funcionar: - A Brisa sempre termina com "As 3 coisas mais importantes agora:" - Briefing retorna no máximo 3 insights + 3 ações - Histórico agrupa em ciclos de 3 dias
Estado: 🌅 Horizonte — PO deve refinar o conceito antes de entrar em roadmap.
Perguntas abertas para o PO: - É um modo opcional ou o padrão do produto? - O "3" é fixo ou configurável pelo usuário? - Como integrar com as rotinas existentes?
📋 Backlog Copa (v0.4)
Itens identificados para a próxima versão da aba Eventos:
| Item | Descrição |
|---|---|
| Grupos e classificação | Tabela de grupos com posição atualizada de cada seleção |
| Timestamp de atualização | Mostrar no topo do card "Última atualização: DD/MM HH:MM" |
Já implementado: timestamp no final do card (
data.cached_at). Para v0.4: mover para o topo e adicionar grupos.