尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗Hub pessoal de ferramentas. Hoje tem dois apps:
| App | Acesso | O que é |
|---|---|---|
| Voos | aberto (editor privado) | Tarifas do Flight Tracker, com datas, link de compra e editor de rotas |
| Finanças | privado | Patrimônio, extrato de todos os bancos, gastos por categoria, metas e investimentos, via Open Finance |
Next.js 16 + Convex. Login com Face ID / Touch ID (passkey) e senha de reserva.
Só existe um usuário, então não há cadastro nem e-mail.
TOSO_PASSWORD).| Peça | Papel |
|---|---|
src/proxy.ts | Barra os apps privados antes de renderizar (redireciona para /entrar) |
src/lib/session.ts | Sessão = JWT assinado num cookie HttpOnly. Sem tabela de sessões |
src/app/api/auth/** | Senha, cadastro e entrada com passkey (@simplewebauthn), sair |
convex/ | Passkeys cadastradas, trava de senha e a lista de atividade |
Cada página e rota privada confere a sessão de novo, para não depender só do proxy. A senha trava por 15 minutos depois de 5 erros. O Face ID não passa por essa trava, então errar a senha nunca te tranca para fora.
As funções do Convex são públicas por natureza (qualquer um com a URL pode
chamá-las). Por isso todas exigem TOSO_SERVER_SECRET, que só o servidor do
Next conhece. O navegador nunca fala com o Convex direto.
Perdeu um aparelho? Ajustes → Face ID e passkeys → Remover.
npx convex dev. Ele cria o projeto e grava NEXT_PUBLIC_CONVEX_URL no
.env.local.TOSO_SERVER_SECRET (gere com
openssl rand -base64 48). Faça o mesmo no deployment de dev.Em vercel.com/new, importe brunoUC/toso-one e
cadastre as variáveis de ambiente:
| Variável | Valor |
|---|---|
CONVEX_DEPLOY_KEY | A deploy key do passo 1.3 |
TOSO_SERVER_SECRET | O mesmo valor cadastrado no Convex |
TOSO_SESSION_SECRET | Outro segredo: openssl rand -base64 48 |
TOSO_PASSWORD | Sua senha de reserva. Use uma frase longa |
FLIGHTS_URL | Endereço do Flight Tracker na Vercel, sem barra no fim |
FLIGHTS_EDIT_PASSWORD | O mesmo valor de MONITOR_EDIT_PASSWORD do projeto do Flight Tracker |
O vercel.json já cuida do resto: com CONVEX_DEPLOY_KEY presente, o build
publica as funções do Convex e depois compila o Next com a URL certa.
Editor de rotas. Quem grava no GitHub é a API do próprio Flight
Tracker (api/ daquele repositório), que já tem o token. O toso one só
repassa os pedidos com a senha dela. Sem FLIGHTS_EDIT_PASSWORD, a página
de Voos funciona normalmente e o editor mostra o que falta.
Abra o site no iPhone → Entrar → senha → Ativar Face ID. Repita no Mac (Touch ID). Pronto.
Passkeys ficam presas ao domínio. Se depois você ligar um domínio próprio
(ex. one.toso.dev), cadastre o Face ID de novo nele.
npm install
cp .env.example .env.local # preencha TOSO_PASSWORD e os segredos
npx convex dev # em um terminal: banco + funções
npm run dev # em outro: http://localhost:3000
Sem Convex configurado o app funciona só com senha: o Face ID aparece como indisponível em Ajustes.
O Flight Tracker continua coletando sozinho no GitHub Actions e publicando
um data.json na Vercel. O toso one lê esse arquivo (cache de 10 min).
/voos: na frente, a busca e o mapa (Brasil, Europa e o Japão num
recorte), desenhado no servidor com d3-geo sobre o world-atlas
1:110m. Cada destino é um ponto na cor do melhor preço contra a rota:
verde até o alvo, âmbar até o teto, vermelho acima, cinza sem dados.
Abaixo, um card por destino (Lisboa, Madri, Roma, Atenas, Viena e Tóquio
em destaque; os outros em "Outros destinos") com o menor preço entre as
origens, a distância até o alvo/teto em R$ e %, as origens com link para o
detalhe e as datas do destino, que dá para ajustar ali mesmo com sessão.
api/search.py do Flight
Tracker; sempre oferece o link da mesma busca no Google Flights
(src/lib/gflights.ts monta o tfs igual à fast-flights). "Monitorar
estas datas" cria a rota (ida de 3 dias antes a 3 depois, estadia ±2
dias) ou alarga a janela da que já existe. Sem sessão, só o link./voos/ORIGEM-DESTINO: o "bilhete" da melhor tarifa, calendário com o
menor preço visto para cada dia de ida, as voltas consultadas de cada dia
com preço, horário e a avaliação do próprio Google (baixo/típico/alto),
a tabela de todas as tarifas vistas nos últimos 45 dias e o histórico.
Cada tarifa tem um link que reabre exatamente aquela busca no Google
Flights (mesmas datas, executiva, 1 adulto, BRL) para conferir o preço de
agora e comprar./voos/rotas (privado): rotas agrupadas por destino. Adicionar várias
origens × vários destinos de uma vez, trocar o destino de um grupo ou a
origem de uma rota, aplicar datas em lote, pausar, horários da coleta e
"coletar agora" com o andamento das execuções.A busca de aeroportos aceita cidade em português, nome ou código, sobre a
base do OurAirports (domínio público) em
src/data/airports.json. Para regerar: scripts/build-airports.py (gera
também src/data/airport-coords.json, as coordenadas usadas só no mapa).
O histórico de preços é indexado por ORIGEM-DESTINO: trocar a origem ou
o destino de uma rota começa um histórico novo (o antigo fica guardado).
O Google só mostra os voos de volta depois que se escolhe a ida, então a coleta conhece o horário da ida, e da volta só a data. O link de cada tarifa abre a busca com as duas datas.
Os dados vêm do Open Finance pela Meu Pluggy
(gratuito). Nenhuma senha de banco passa por aqui: os bancos foram
conectados no Meu Pluggy, com consentimento de 12 meses, e o Convex lê pela
API da Pluggy com PLUGGY_CLIENT_ID / PLUGGY_CLIENT_SECRET (só nas
variáveis de ambiente do Convex).
Leitura (convex/financas/sync.ts): duas vezes por dia (06:17 e
18:17, convex/crons.ts) e no botão "Atualizar". Na primeira vez de cada
banco busca o último ano; depois, os últimos 15 dias. Guarda contas,
movimentações (com o JSON completo da Pluggy à parte), investimentos e
uma fotografia diária do patrimônio.
Classificação (convex/financas/taxonomy.ts), nesta ordem: regras
suas → PIX/TED entre suas contas (CPF ou nome do titular) → nomes
conhecidos → tipo de estabelecimento (MCC) → categoria do banco → Claude
Haiku (convex/financas/ai.ts, só com ANTHROPIC_API_KEY no Convex).
Corrigir uma movimentação com "sempre que for…" cria uma regra pela
pessoa, loja ou descrição e reclassifica o passado na hora.
Gastos contam cartão, PIX, boleto e débito. Pagamento de fatura, aplicação, resgate e transferência entre suas contas ficam de fora, para não contar a mesma compra duas vezes.
Telas: /financas (painel), /financas/extrato (todos os bancos,
com filtros), /financas/m/<id> (detalhe e tudo o que o banco mandou),
/financas/regras.
Semana na XP (convex/financas/weekly.ts, /api/agente/semana):
todo sábado às 09:13 uma tarefa agendada do Claude Code (na assinatura,
sem custo de API) lê os números da semana, pesquisa na web (Selic, Copom,
CDI, o que a XP oferece) e devolve a análise. Os números são do código:
saldo dos investimentos da XP hoje contra 7 dias atrás (finInvSnap, uma
fotografia por investimento a cada leitura), menos aportes e mais
resgates, e o CDI do mesmo período pela série 12 do Banco Central. O
perfil é conservador: só liquidez D+0/D+1, tudo pela XP. A rota exige
TOSO_AGENT_TOKEN (na Vercel e nas variáveis do ambiente do Claude Code)
e só lê os números da semana e grava a análise. A primeira semana não tem
base de 7 dias atrás, então só mostra a análise.
Aviso de fatura (convex/financas/cards.ts): todo dia às 08:23, se a
fatura de um banco fecha em até 3 dias e a conta dele não cobre, manda um
push com quanto transferir (com 10% de folga, mínimo R$ 100) e de onde:
XP primeiro, depois o banco com mais folga. Sem a data de fechamento da
Pluggy, estima 7 dias antes do vencimento. Um aviso por banco e
fechamento; as faturas dos próximos 5 dias também aparecem no painel e,
quando falta dinheiro, no topo do Orçamento.
Notificações (convex/push.ts, public/sw.js): Web Push. No iPhone,
adicione o toso one à Tela de Início, abra por lá e ative em Ajustes →
Notificações. As chaves VAPID nascem sozinhas no Convex na primeira vez
( no Convex troca o remetente, padrão
).
Conectar outro banco: conecte no Meu Pluggy e rode
npx convex run --prod financas/sync:addItems '{"itemIds":["<id>"]}'.
src/lib/apps.ts (nome, ícone, cor, private).src/app/(shell)/<href>/page.tsx. Se for privado, comece com
await requireSession("/<href>").O card no hub, o item no menu e a proteção do proxy saem da entrada no registro.
src/app/globals.css. As cores das séries dos gráficos foram
validadas para daltonismo e contraste contra a superfície de cada tema;
trocar uma cor exige validar de novo.src/components/charts/, em SVG próprio, sem biblioteca:
linha com área e crosshair, colunas, barra de alocação, medidor de meta,
sparkline e mapa de calor (com tabela alternativa).PUSH_SUBJECThttps://toso-one.vercel.app