✏️ Modo Edição
VitaTrack — Especificação Técnica e de Produto
📋

Resumo do Projeto

Visão Geral
VitaTrack é um aplicativo web de acompanhamento fitness que unifica alimentação, atividade física, check-in de metas, evolução de peso e chat com IA — substituindo múltiplos apps por uma plataforma única e integrada.
🎯 Problema que resolve
Quem leva saúde a sério acaba preso num ciclo frustrante: um app para dieta, outro para treino, uma planilha para o peso, um lembrete manual para o jejum — e nenhum deles conversa entre si.

Sem uma visão integrada, é difícil entender padrões, manter consistência e sentir evolução real. A motivação cai justamente porque o esforço existe, mas o progresso não aparece com clareza.

VitaTrack elimina essa fragmentação, reunindo tudo em uma única experiência coesa e motivadora.
✨ Diferenciais
  • Análise de foto de refeição por IA (macros automáticos)
  • Kanban visual de atividades com métricas históricas
  • Sistema de streaks com recompensas (refeição livre, etc.)
  • Chat com IA via N8N para sugestões personalizadas
  • Jejum intermitente integrado à alimentação
👥 Público-alvo
Pessoas que acompanham ativamente saúde e fitness e querem uma ferramenta unificada, visual e motivacional.
📱 Plataforma
Web app responsivo (desktop + mobile). React SPA com backend Node.js e Supabase como banco de dados.
🌐 Deploy
Frontend: Cloudflare Pages. Backend: Render. Banco: Supabase cloud (free tier disponível).
⚙️

Stack Tecnológico

Técnico
🖥️ Frontend
React 18 + ViteFramework principal + bundler
Shadcn/uiComponentes UI (todos instalados)
Tailwind CSS v4Estilização utilitária
React Router v6Roteamento client-side
TanStack QueryCache e estado servidor
RechartsGráficos de evolução
next-themesDark / Light mode
AxiosHTTP com credentials (cookies)
🔧 Backend
Node.js + ExpressServidor HTTP + rotas API
supabase-jsClient PostgreSQL (Supabase)
bcryptjsHash de senhas
jsonwebtokenGeração e validação de JWT
cookie-parserLeitura de cookies HTTP-only
multerUpload de imagens (fotos)
@google/generative-aiGemini Flash — análise de foto
cors + dotenv + helmetSegurança e configuração
🌐 Serviços Externos
ServiçoUsoCustoLimite free
SupabaseBanco de dados PostgreSQLGratuito500MB / 50k linhas
Google Gemini FlashAnálise nutricional de fotoGratuito1.500 req/dia
N8NOrquestração do chat IASelf-hostedIlimitado (self-hosted)
Cloudflare PagesDeploy do frontendGratuitoProjetos pessoais
RenderDeploy do backendGratuito750h/mês
🗓️

Ordem de Implementação

Planejamento
0 / 10 entregues
Clique nos itens para marcar como entregue
  • 1.
    Scaffold do Projeto
    Estrutura de pastas, Vite + React, Tailwind, Shadcn/ui (todos componentes), temas dark/light + 8 cores, variáveis de ambiente.
  • 2.
    Autenticação
    Login, cadastro, JWT em HTTP-only cookie, middleware de proteção de rotas, contexto de usuário no frontend.
  • 3.
    Layout Base
    Sidebar responsiva, Navbar, ThemeToggle, proteção de rotas privadas (PrivateRoute), estrutura de páginas.
  • 4.
    Dashboard
    Widgets de resumo: calorias do dia, streak atual, próximo treino, peso atual, % check-in.
  • 5.
    Alimentação + Jejum
    CRUD de refeições, timer de jejum, upload de foto → Gemini Flash → macros automáticos + edição manual.
  • 6.
    Atividades (Kanban)
    Kanban drag-and-drop, cadastro de atividades recorrentes, métricas de conclusão/adiamento/cancelamento.
  • 7.
    Check-in Diário
    Lista de tarefas do dia, toggles, cálculo de porcentagem, histórico de check-ins.
  • 8.
    Streaks & Bônus
    Lógica de streak automática, bônus (ex: 5 dias seguidos = refeição livre), painel de conquistas.
  • 9.
    Progresso & Relatórios
    Gráficos Recharts (peso semanal, calorias, macros, atividades), filtros por período.
  • 10.
    Chat IA (N8N)
    Interface de chat, integração com webhook N8N, envio de contexto do usuário, histórico de mensagens.
🔐

Autenticação

Técnico
Decisão: Não utilizamos Supabase Auth para evitar tokens expostos no localStorage. A autenticação é 100% gerenciada pelo backend Express via HTTP-only cookies.
🔄 Fluxo de Login
[React] ──POST /api/auth/login { email, password }──► [Express]
                                                            │
                                              Busca usuário no Supabase
                                                            │
                                              bcrypt.compare(password, hash)
                                                            │
                                              jwt.sign({ userId, email })
                                                            │
                                    res.cookie('vt_token', jwt, {
                                      httpOnly: true,  ← JS não acessa
                                      secure: true,    ← somente HTTPS
                                      sameSite: 'strict', ← anti-CSRF
                                      maxAge: 7 * 24 * 60 * 60 * 1000
                                    })
                                                            │
[React] ◄── { user: { id, name, email } } ─────────────────┘
                  (sem token visível)
🛡️ Proteção de Rotas (Backend)
Middleware authGuard.js aplicado em todas as rotas protegidas:

req.cookies.vt_tokenjwt.verify() → injeta req.user

Em caso de token inválido ou ausente: 401 Unauthorized
🔒 Proteção de Rotas (Frontend)
Componente PrivateRoute verifica estado de autenticação via GET /api/auth/me (usa cookie automaticamente).

Usuário não autenticado → redirect /login
Usuário autenticado em /login → redirect /dashboard
🗝️ Endpoints de Auth
MétodoRotaDescriçãoAuth?
POST/api/auth/registerCadastro de usuário + peso inicial
POST/api/auth/loginLogin → seta cookie JWT
GET/api/auth/meRetorna dados do usuário logado
POST/api/auth/logoutLimpa cookie JWT
🗄️

Banco de Dados

Técnico — Supabase PostgreSQL
📐 Schema Principal
┌─────────────────────────────────────────────────────────────────┐
│  users                                                          │
│  id (uuid PK) · name · email (unique) · password_hash          │
│  avatar_url · created_at                                        │
└───────────────────────────┬─────────────────────────────────────┘
                            │ 1:1
              ┌─────────────▼──────────────┐
              │  user_profiles             │
              │  user_id (FK) · height_cm  │
              │  birth_date · goal (enum)  │
              │  activity_level · theme    │
              │  color_scheme              │
              └────────────────────────────┘

┌───────────────────────┐   ┌───────────────────────────┐
│  meals                │   │  meal_nutrients           │
│  id · user_id (FK)    │──►│  meal_id (FK)             │
│  meal_type · photo_url│   │  calories · protein_g     │
│  description · date   │   │  carbs_g · fat_g · fiber_g│
│  time · source (ai|   │   │  source (ai|manual)       │
│  manual)              │   └───────────────────────────┘
└───────────────────────┘

┌───────────────────────┐   ┌─────────────────────────────┐
│  fasting_sessions     │   │  workouts                   │
│  id · user_id (FK)    │   │  id · user_id (FK)          │
│  start_at · end_at    │   │  activity_id (FK) · date    │
│  goal_hours · status  │   │  duration_min · notes       │
└───────────────────────┘   │  status (done|skip|delay)  │
                            └─────────────────────────────┘

┌──────────────────────────┐   ┌────────────────────────────┐
│  activities (catálogo)   │   │  daily_checkins            │
│  id · user_id (FK)       │   │  id · user_id (FK) · date  │
│  name · category · icon  │   │  items (jsonb[])           │
│  frequency · target_days │   │  completion_pct            │
│  color                   │   └────────────────────────────┘
└──────────────────────────┘

┌────────────────────────────┐   ┌────────────────────────────┐
│  weight_entries            │   │  streaks                   │
│  id · user_id (FK) · date  │   │  id · user_id (FK) · type  │
│  weight_kg · notes         │   │  current · best · last_date│
└────────────────────────────┘   └────────────────────────────┘

┌────────────────────────────┐   ┌────────────────────────────┐
│  bonuses                   │   │  chat_messages             │
│  id · user_id (FK) · type  │   │  id · user_id (FK)         │
│  reason · expires_at       │   │  role (user|assistant)     │
│  used_at · status          │   │  content · created_at      │
└────────────────────────────┘   └────────────────────────────┘
🏗️

Arquitetura de Pastas

Técnico
📁 Frontend
frontend/
├── src/
│   ├── components/
│   │   ├── ui/           ← Shadcn (todos)
│   │   ├── layout/
│   │   │   ├── Sidebar.jsx
│   │   │   ├── Navbar.jsx
│   │   │   └── ThemeToggle.jsx
│   │   └── features/     ← por módulo
│   ├── pages/
│   │   ├── auth/
│   │   │   ├── Login.jsx
│   │   │   └── Register.jsx
│   │   ├── Dashboard.jsx
│   │   ├── Nutrition.jsx
│   │   ├── Workouts.jsx  ← Kanban
│   │   ├── Checkin.jsx
│   │   ├── Progress.jsx
│   │   ├── Reports.jsx
│   │   ├── Chat.jsx
│   │   └── Profile.jsx
│   ├── hooks/
│   │   ├── useAuth.js
│   │   ├── useTheme.js
│   │   └── useStreak.js
│   ├── services/
│   │   ├── api.js        ← axios instance
│   │   ├── auth.service.js
│   │   └── ...
│   ├── store/
│   │   └── AuthContext.jsx
│   └── lib/utils.js
├── components.json       ← Shadcn config
└── vite.config.js
📁 Backend
backend/
├── src/
│   ├── config/
│   │   ├── supabase.js
│   │   └── env.js
│   ├── middleware/
│   │   ├── authGuard.js
│   │   └── errorHandler.js
│   ├── routes/
│   │   ├── auth.routes.js
│   │   ├── user.routes.js
│   │   ├── nutrition.routes.js
│   │   ├── workout.routes.js
│   │   ├── activity.routes.js
│   │   ├── checkin.routes.js
│   │   ├── progress.routes.js
│   │   ├── streak.routes.js
│   │   └── chat.routes.js
│   ├── controllers/      ← lógica por rota
│   ├── services/
│   │   ├── streak.service.js
│   │   ├── bonus.service.js
│   │   ├── gemini.service.js
│   │   └── n8n.service.js
│   └── server.js
└── .env
🔌

Integrações

Técnico
📸 Análise de Foto — Google Gemini Flash
Quando o usuário faz upload de uma foto de refeição, o backend envia a imagem ao Gemini Flash com um prompt estruturado. A resposta é um JSON com os macronutrientes estimados, que o usuário pode revisar e ajustar manualmente antes de salvar.
POST /api/nutrition/analyze-photo
  → multer processa upload (buffer em memória)
  → gemini.service.js envia imagem + prompt:
     "Analise o prato da imagem. Retorne JSON:
      { foods: string[], calories: number,
        protein_g: number, carbs_g: number,
        fat_g: number, fiber_g: number }"
  ← { foods, calories, protein_g, carbs_g, fat_g, fiber_g }
🤖 Chat IA — N8N Webhook
O backend enriquece cada mensagem do usuário com seu contexto fitness atual (últimos 7 dias de refeições, treinos, peso, streaks) antes de enviar ao N8N. O N8N decide qual IA usar e retorna a resposta.
POST /api/chat/message
  → authGuard verifica cookie
  → n8n.service.js monta payload:
     {
       message: "Como melhorar meu cardápio?",
       user_context: {
         weight_trend: [...],
         avg_calories: 1850,
         workouts_last_7d: [...],
         streak_workout: 4,
         pending_bonus: "refeição livre"
       }
     }
  → POST ${N8N_WEBHOOK_URL}
  ← { reply: "Com base nos seus dados..." }
  → salva em chat_messages (user + assistant)
  ← { message } para o frontend
🚪

Telas — Login & Cadastro

UX / Produto
🔑 Login
Campos: Email, Senha
Ações: "Entrar", "Esqueci minha senha", "Criar conta"

Comportamento:
  • Validação em tempo real (email inválido, senha vazia)
  • Loading state no botão durante requisição
  • Toast de erro em credenciais inválidas
  • Redirect automático ao dashboard se já logado
  • Lembra sessão por 7 dias (cookie persistente)
📝 Cadastro (múltiplas etapas)
Etapa 1 — Conta: Nome, Email, Senha, Confirmar senha

Etapa 2 — Perfil Físico: Peso atual (kg), Altura (cm), Data de nascimento, Nível de atividade

Etapa 3 — Objetivo:
  • Perda de peso
  • Ganho de massa
  • Manutenção / Saúde geral
  • Definição muscular
Progresso visual de etapas (Step Indicator com Shadcn Progress)
vitatrack.app/login
⚡ VitaTrack
Bem-vindo de volta
Email
seu@email.com
Senha
••••••••
Entrar
Não tem conta? Criar conta
🏠

Dashboard

UX / Produto
Página principal após login. Visão consolidada do dia atual e progresso recente. Acesso rápido a registros frequentes.
vitatrack.app/dashboard
Bom dia, Augusto 👋
Domingo, 22 de março de 2026
🔥 4
Dias de streak
1.840
Calorias hoje
78,5
Peso atual (kg)
67%
Check-in hoje
Check-in do dia
4/6 concluídos
🥗 Última refeição
Almoço — 12h30
Arroz, frango grelhado, salada
520 kcal · 38g prot
🏋️ Próxima atividade
Musculação — Hoje
Treino B (costas + bíceps)
Pendente
📐 Widgets do Dashboard
WidgetDescriçãoAção rápida
Streak atualDias consecutivos de atividade + animação de fogoVer histórico
Calorias do diaTotal consumido vs meta. Barra de progresso por macroAdicionar refeição
Peso atualÚltimo peso registrado + seta de tendência (↑↓→)Registrar peso
Check-in hoje% de tarefas concluídas com barra de progressoAbrir check-in
Jejum intermitenteTimer se houver jejum ativo (ex: 14h32min restantes)Encerrar jejum
Próxima atividadePrimeira atividade pendente do kanbanMarcar como feita
Bônus disponívelBanner se houver bônus desbloqueado (ex: refeição livre)Usar bônus
🥗

Alimentação & Jejum

UX / Produto
🍽️ Lista de Refeições do Dia
Agrupadas por tipo: Café da manhã, Almoço, Lanche, Jantar, Ceia.

Para cada refeição:
  • Foto (se houver) ou ícone padrão
  • Nome/descrição dos alimentos
  • Calorias + macros em pills
  • Horário do registro
  • Botões: editar, excluir
📸 Nova Refeição com Foto
Passo 1: Selecionar tipo de refeição
Passo 2: Upload de foto (câmera ou galeria)
Passo 3: IA analisa → exibe resultado:
🤖 Identificado: Arroz branco, frango grelhado, brócolis
Calorias: ~520 kcal | Proteína: 38g | Carbs: 52g | Gordura: 8g
Passo 4: Usuário edita macros se necessário
Passo 5: Salvar refeição
⏱️ Jejum Intermitente
Timer circular mostrando progresso do jejum atual:

68%
Protocolo: 16/8
Restam 5h12min
Botões: Iniciar jejum / Encerrar jejum
Histórico de janelas de jejum da semana
Meta: exibir streaks de jejum completo
📊 Resumo Nutricional do Dia
Calorias1.840 / 2.200 kcal
Proteína120g / 160g
Carboidratos210g / 250g
Gordura55g / 70g

Refeições de hoje
☕ Café da manhã380 kcal
🍱 Almoço720 kcal
🥤 Lanche220 kcal
🌙 Jantar520 kcal
🎉 Bônus ativo: Refeição livre disponível hoje!
🏋️

Atividades — Visão Kanban

UX / Produto — Funcionalidade Central
As atividades físicas são gerenciadas em um Kanban visual com 4 colunas. Cada card representa uma atividade do dia/semana. O usuário arrasta os cards entre colunas ou usa botões de ação rápida. Cada movimentação é registrada no histórico para métricas futuras.
vitatrack.app/workouts
Atividades — Semana de 22/03
+ Nova atividade 📅 Semana
A Fazer 3
🏋️ Musculação — B
Hoje Costas + Bíceps
🧘 Yoga
Amanhã 30 min
🚴 Bike
Qua 45 min
Em andamento 1
🏃 Corrida
Agora 5km
Concluída 2
🏋️ Musculação — A
Seg 60 min
🏊 Natação
Ter 40 min
Adiada / Pulada 1
🧘 Meditação
Dom Adiada
📋 Colunas do Kanban
ColunaSignificado
A FazerAtividade agendada, ainda não iniciada
Em AndamentoAtividade iniciada, com timer/progresso
ConcluídaAtividade finalizada — conta para streak
Adiada/PuladaMovida para outro dia ou descartada
📊 Métricas por Atividade
Cada atividade do catálogo acumula métricas históricas:
  • Total concluídas — contagem absoluta
  • Taxa de conclusão — % feitas vs planejadas
  • Média de adiamentos por sessão
  • Sequência atual / recorde (streak)
  • Frequência por dia da semana (ex: "você treina mais na segunda")
  • Histórico mensal no estilo GitHub contributions
⚙️ Cadastro de Atividade (Catálogo)
O usuário cria um catálogo pessoal de atividades recorrentes. Cada atividade tem:
Identidade
  • Nome (ex: "Musculação A")
  • Categoria (força, cardio, mobilidade, esporte...)
  • Ícone emoji
  • Cor de destaque
Frequência
  • Dias da semana (checkbox)
  • Hora preferida
  • Duração estimada (min)
  • Meta de vezes/semana
Progresso
  • Gera cards automaticamente no Kanban
  • Conta para streaks gerais
  • Exibe mini-card de histórico
  • Notificação de lembrete (futuro)

Check-in Diário

UX / Produto
Lista de compromissos do dia que o usuário se propôs a cumprir. Pode incluir atividades físicas, hábitos alimentares, hidratação, sono etc. Ao final do dia, o % de conclusão é registrado no histórico.
vitatrack.app/checkin
Check-in de hoje
22 de março de 2026
4 / 6
Beber 2L de água
Café da manhã saudável
Almoço dentro da meta calórica
Treino de musculação
Dormir 8 horas
Jantar antes das 20h
+ Adicionar item ao check-in
📐 Funcionalidades
  • Lista de itens editável pelo usuário
  • Itens recorrentes (pré-carregados todo dia)
  • Toggle (feito / não feito) com animação
  • % calculada em tempo real
  • Adiar item (move para amanhã)
  • Histórico de check-ins por semana/mês
  • Heatmap mensal (estilo GitHub)
  • Recorde de dias com 100%
🔗 Integração com Atividades
Quando o usuário move um card de atividade para "Concluída" no Kanban, o item correspondente no check-in é automaticamente marcado como feito — e vice-versa.

Sincronização bidirecional
📈

Progresso & Evolução

UX / Produto
📊 Gráficos e Visualizações
GráficoTipoPeríodoDados
Evolução de pesoLinha suavizada4 semanas / 3 meses / 1 anoPeso semanal + linha de tendência
Calorias diáriasBarras7 / 14 / 30 diasConsumido vs meta. Cor: verde/vermelho
Macros médiosPizza / DonutSemana atual vs anterior% proteína, carbs, gordura
Atividades por semanaBarras empilhadas8 semanasConcluídas, adiadas, puladas
Heatmap de atividadeGrid mensalÚltimos 12 mesesIntensidade por dia (estilo GitHub)
Streak históricoTimelineTodo períodoInício e fim de cada streak
⚖️ Registro de Peso Semanal
Ao criar a conta, o usuário registra o peso inicial. Semanalmente (sugerido toda segunda-feira), o app solicita novo registro via banner no dashboard.

Dados exibidos: Peso atual | Diferença desde o início | Diferença desde a semana anterior | % de gordura (se disponível)

Meta de peso: Configurada no perfil. Progresso exibido em barra e % restante.
📊

Relatórios

UX / Produto
📋 Relatório Semanal
Gerado automaticamente toda segunda-feira. Resumo da semana anterior:

  • Atividades concluídas / adiadas / puladas
  • Média calórica diária vs meta
  • Média de macros vs meta
  • Dias de jejum completo
  • % de check-in médio
  • Variação de peso
  • Bônus ganhos na semana
  • Destaque: "Melhor dia da semana" e "Pior dia"
🔍 Filtros de Relatório
O usuário pode gerar relatórios customizados:

Período: Últimos 7, 14, 30 dias | Mês específico | Intervalo customizado

Módulos:
Alimentação Atividades Peso Check-in Jejum Streaks

Exportar: PDF ou CSV (futuro)
📈 KPIs Principais do Relatório
85%
Taxa de conclusão de atividades
1.920
Média kcal/dia
-1,2kg
Variação de peso
72%
Check-in médio
🤖

Chat com IA

UX / Produto
Chat contextualizado: a IA recebe automaticamente os dados do usuário (peso, refeições, treinos da semana) antes de responder. Não é necessário descrever o histórico — a IA já sabe.
vitatrack.app/chat
🤖
Olá! Analisando seus dados da semana: você está com 4 dias de streak de treino, média de 1.920 kcal/dia e perdeu 1,2kg. Parabéns! O que posso ajudar?
Consegue sugerir um cardápio para amanhã com foco em proteína?
🤖
Claro! Considerando sua meta de 160g de proteína/dia:
☀️ Café: Ovos mexidos + iogurte grego
🍱 Almoço: Frango + quinoa + brócolis
🥤 Lanche: Shake de proteína + banana
🌙 Jantar: Salmão + batata-doce
Pergunte algo sobre seus dados...
💬 Sugestões de Perguntas
🥗 "Sugira um cardápio para esta semana"
💪 "Como melhorar meu progresso?"
📊 "Analise minha evolução do mês"
🏋️ "Que treinos posso adicionar?"
⚡ "Estou próximo de algum bônus?"
📦 Contexto enviado ao N8N
Cada mensagem é enriquecida com:
  • Peso atual e tendência
  • Média calórica dos últimos 7 dias
  • Médias de macros da semana
  • Atividades concluídas/pendentes
  • Streak atual
  • Bônus disponíveis
  • Objetivo do usuário (meta de perfil)
👤

Perfil & Configurações

UX / Produto
👤 Dados Pessoais
  • Foto de perfil (upload)
  • Nome completo
  • Email (somente leitura)
  • Data de nascimento
  • Altura (cm)
  • Peso atual (kg) — manual ou via registro
  • Objetivo (perda de peso, ganho de massa etc.)
  • Nível de atividade
🎨 Aparência & Preferências
Tema: Light / Dark / Sistema

Cor do app: Seletor visual com as 8 cores (igual ao topo deste documento)

Metas nutricionais:
  • Calorias diárias
  • Meta de proteína (g)
  • Meta de carboidratos (g)
  • Meta de gordura (g)
Jejum: Protocolo preferido (16/8, 18/6, 5:2...)
Notificações: Lembretes de check-in e treino (futuro)
🔑 Segurança
Alterar senha (requer senha atual). Encerrar sessão em todos os dispositivos. Excluir conta (com confirmação).
🔥

Streaks & Bônus

Sistema de Gamificação
🔥 Tipos de Streak
StreakCritério
TreinoPelo menos 1 atividade concluída por dia
AlimentaçãoTodas as refeições registradas no dia
JejumJejum completo (meta de horas atingida)
Check-inCheck-in do dia com ≥ 80% concluído
PerfeitoTodos os 4 streaks ativos no mesmo dia
🎁 Sistema de Bônus
ConquistaBônus
5 dias seguidos de treino🍽️ Refeição livre
7 dias de jejum completo🎯 Meta calórica +15% por 1 dia
30 dias de check-in🏆 Conquista "Consistente"
Perda de 2kg⭐ Conquista + registro no perfil
10 dias de dia perfeito🔥 Conquista "Elite"
Bônus "Refeição Livre": Quando desbloqueado, aparece banner no Dashboard e na tela de Alimentação. O usuário pode "usar" o bônus — esse dia não conta negativamente para as métricas de calorias. O bônus expira em 7 dias se não utilizado.
🎨

Design System

Shadcn/ui + Tailwind
🎨 Paleta de Cores (8 variações)
Violet
Padrão
Blue
Green
Orange
Red
Rose
Yellow
Neutral
📦 Componentes Shadcn/ui Utilizados
ButtonInputLabelCardBadgeAvatarDropdownMenuSelectDialogSheetToastProgressTabsTableCalendarPopoverSeparatorSkeletonSwitchTextareaCheckboxRadioGroupAlertAlertDialogCommandFormScrollAreaSliderTooltipAccordionChartNavigationMenu
Fonte recomendada: Geist Sans (mesma do Shadcn/ui) — importar via next/font ou fontsource.
Ícones: lucide-react — biblioteca padrão do Shadcn/ui.