Documentação Técnica
← Voltar

Documentação Técnica

Stack, arquitetura, banco de dados e instruções de deploy do BBrain.

Stack Tecnológica

Runtime
Node.js nativo
Framework
Nenhum (http built-in)
Hospedagem
Fly.io — free tier (GRU)
Banco de dados
Google Sheets API v4
Email
Gmail SMTP TLS 465
Frontend
HTML + CSS + JS vanilla
Idiomas
PT / EN / FR / ES / DE

Arquitetura

O BBrain é uma aplicação monolítica simples. Não há frameworks, ORMs ou dependências externas além da googleapis.

Browser (cliente)
    │
    ↓ HTTP (JSON REST)
    │
Fly.io — server.js  ← Node.js nativo, porta 3000
    ├── Google Sheets API v4  ← banco de dados
    └── Gmail SMTP (465/TLS)  ← emails de reset

Autenticação

Mecanismo

A senha é armazenada como SHA-256 hash. Nunca há texto puro em disco ou memória. A função readAuth() segue esta ordem de prioridade:

  1. authCache (Google Sheets) — carregado no boot via initSheets(). Prioridade máxima — garante que a senha definida pelo usuário persiste entre deploys sem ser sobrescrita.
  2. BBRAIN_PASSWORD_HASH — hash SHA-256 definido diretamente como secret no Fly.io. Usado se não há Sheets configurado.
  3. BBRAIN_PASSWORD — senha provisória em texto. O servidor calcula o hash em runtime e força troca de senha no primeiro login.
  4. Arquivo localauth.json na raiz. Fallback para desenvolvimento local.

MASTER_ADMIN

brunomassa é o admin master vitalício, hardcoded em server.js como MASTER_ADMIN. Email fixo: brunobrm@gmail.com. Esse usuário não pode ser alterado por nenhum deploy, reset de senha ou venda do produto.

LEGACY_USERS

Usuárias com acesso vitalício e mensagem de primeiro acesso: Karina Lisboa Cerqueira Massa (klisboacerqueira@gmail.com) e Cecília Lisboa Massa. No primeiro login, o sistema exibe uma mensagem especial e a persiste no rodapé do app via localStorage.

Troca forçada de senha

Quando o login retorna force_password_change: true, o frontend exibe um formulário obrigatório antes de liberar o app. A nova senha é salva via POST /api/auth/change-password com o token Bearer. Após a troca, force_password_change é gravado como false na aba Config do Sheets.

Token de sessão

Após login bem-sucedido, o servidor gera um token aleatório (32 bytes). O token é salvo no localStorage do browser com validade de 30 dias e enviado no header Authorization: Bearer <token> em todas as requisições. O frontend invalida o token localmente ao trocar de dia (expiração diária por cliente).

Banco de Dados

O Google Sheets funciona como banco relacional simples. A planilha possui três abas:

Aba: Ideas

ColunaTipoDescrição
idstringID gerado no servidor (YYYYMMDD-XXXXX)
textstringTexto da ideia
sourcestringOrigem: web, whatsapp, api
whatsapp_fromstringNúmero de origem (só WhatsApp)
created_atISO 8601Data/hora de criação
statusstringnova, em_analise, no_roadmap, arquivada
tagsJSON arrayTags atribuídas
evaluationstringAvaliação gerada pela IA
roadmap_phasestringbacklog, planejado, em_execucao, concluido
connectionsJSON arrayIDs de ideias relacionadas
session_idstringID da sessão em que foi capturada
updated_atISO 8601Última atualização

Aba: Sessions

ColunaTipoDescrição
idstringID gerado no servidor
started_atISO 8601Início da sessão
ended_atISO 8601Fim da sessão
locationstringLocal da sessão
initial_thoughtsstringPensamento inicial do check-in
duration_minutesnumberDuração calculada em minutos
features_workedJSON arrayFeatures trabalhadas na sessão
ideas_capturedJSON arrayIDs das ideias capturadas
social_contentstringPost sugerido para redes sociais

Aba: Config

Persiste autenticação e configurações de usuário entre deploys.

ChaveTipoDescrição
password_hashstringSHA-256 hash da senha
usernamestringNome de usuário
emailstringEmail para recuperação de senha
force_password_changeboolSe true, força troca de senha no próximo login
planstringPlano atual: free, pro, power
reminder_frequencystringFrequência de lembretes: daily, every2days, every15days, monthly
reminder_timestringHorário do lembrete (HH:MM)
reminder_channelsstringCanais: email, whatsapp ou ambos
last_reminderISO 8601Timestamp do último lembrete enviado

Service Account

Acesso à API via service account Google. As credenciais podem ser fornecidas como JSON completo em GOOGLE_CREDENTIALS_JSON ou como variáveis individuais (client_email, private_key, etc). O servidor monta o objeto automaticamente.

Variáveis de Ambiente

VariávelObrigatóriaDescrição
GOOGLE_SHEET_IDSimID da planilha Google Sheets
GOOGLE_CREDENTIALS_JSONSim*JSON completo da service account (minificado)
client_emailSim*Email da service account (alternativa ao JSON)
private_keySim*Chave privada RSA da service account
BBRAIN_PASSWORDNão**Senha provisória em texto — forçará troca no primeiro login
BBRAIN_PASSWORD_HASHNão**SHA-256 da senha (hex) — sem troca forçada
BBRAIN_USERNAMENãoNome de usuário (padrão: brunomassa)
GMAIL_FROMNãoEndereço Gmail remetente para reset de senha
GMAIL_APP_PASSWORDNãoApp Password do Gmail (16 chars)
WHATSAPP_ACCESS_TOKENNãoToken Meta Cloud API para envio via WhatsApp
WHATSAPP_PHONE_NUMBER_IDNãoID do número WhatsApp Business
WHATSAPP_VERIFY_TOKENNãoToken de verificação do webhook Meta
PORTNãoPorta do servidor (padrão: 3000)

* Forneça GOOGLE_CREDENTIALS_JSON ou as variáveis individuais (client_email, private_key, etc.) — o servidor monta as credenciais automaticamente de qualquer uma das formas.

** Se não definidas, o servidor usa a auth salva na aba Config do Sheets (carregada no boot). Isso garante que a senha persiste entre deploys sem redefinir variáveis.

Endpoints da API

MétodoEndpointAuthDescrição
GET/api/ideasSimLista todas as ideias (filtros: ?status=, ?source=)
POST/api/ideasSimCria nova ideia
PATCH/api/ideas/:idSimAtualiza status, tags, evaluation, roadmap_phase, connections
DELETE/api/ideas/:idSimRemove ideia permanentemente
GET/api/sessionsSimLista todas as sessões
POST/api/sessionsSimCria nova sessão (check-in)
PATCH/api/sessions/:idSimEncerra sessão (ended_at, duration_minutes)
GET/api/settingsSimRetorna configurações do usuário (plano, lembretes)
POST/api/settingsSimSalva configurações (plan, reminder_frequency, reminder_time, reminder_channels)
GET/api/report/monthlySimRelatório do mês (?month=2026-03)
GET/api/auth/statusVerifica token ativo
POST/api/auth/loginLogin — retorna token, force_password_change, firstLoginMessage
POST/api/auth/change-passwordSimTroca de senha forçada (requer token válido)
POST/api/auth/logoutSimInvalida o token atual
POST/api/auth/setupConfiguração inicial (primeiro acesso)
POST/api/auth/reset-requestSolicita reset de senha (envia email)
POST/api/auth/resetConfirma reset com código de 6 dígitos
GET/api/versionHealthcheck — retorna versão atual

Deploy

Requisitos

Fly.io CLI instalado (flyctl), autenticado com a conta Aproove. O arquivo fly.toml deve estar na raiz do projeto.

Comando

fly deploy

Fluxo

O Fly.io detecta automaticamente Node.js via Dockerfile ou buildpack. A aplicação é implantada na região GRU (São Paulo) no free tier, com uma máquina compartilhada de 256MB RAM.

Estrutura de Arquivos

projeto/
├── server.js           ← servidor principal (Node.js nativo)
├── fly.toml           ← config do Fly.io
├── Dockerfile         ← imagem Docker
├── .github/workflows/  ← GitHub Actions (fly-deploy.yml)
├── package.json
├── laboratorio/
│   ├── index.html       ← BBrain app (acessado via /entrar)
│   ├── landing.html     ← LP pública (bbrainapp.you/)
│   ├── privacidade.html ← Política de Privacidade (/privacidade)
│   └── DOCUMENTACAO/
│       ├── index.html   ← hub de docs
│       ├── tecnica.html
│       ├── roadmap.html
│       ├── conceito.html
│       ├── investidores.html
│       ├── guia-uso.html
│       ├── api.html
│       └── publicar-app.html

Rotas de front-end

URLArquivoDescrição
/ (bbrainapp.you)landing.htmlLanding page pública com planos
/entrarindex.htmlApp BBrain (autenticado)
/laboratorioindex.htmlAlias para o app
/privacidadeprivacidade.htmlPolítica de Privacidade
/conceitoconceito.htmlConceito do produto
/guiaguia-uso.htmlGuia de uso