cleanyourtv-app
A community-built phone app for Clean Your TV: clean up an Android TV from your phone. No laptop, no coding agent, nothing uninstalled.
Hub pessoal de ferramentas.
Translation pending
OtherTypeScript · CSSGitHub @brunoUCOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full 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