個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
Vamboo — Next.js + TypeScript + Supabase Projeto real (não é mais só protótipo estático) do Vamboo: roteiro, despesas e hospedagem, com login de verdade. 1. Crie um projeto em https://supabase.com (se ainda não tiver). 2. Rode as migrations de supabase/migrations/ — veja a seção 2 abaixo pra duas formas de fazer isso (CLI, recomendado, ou colar no SQL Editor). 3. Em Settings > API, copie a Project URL e a anon public key (ou publishable key, em projetos mais novos — é o mesmo valor pro NEXT_PUBLIC_SUPABASE_ANON_KEY). 4. Copie .env.local.example para .env.local e preencha:檢視完整 README ↗
Projeto real (não é mais só protótipo estático) do Vamboo: roteiro, despesas e hospedagem, com login de verdade.
supabase/migrations/ — veja a seção 2 abaixo pra
duas formas de fazer isso (CLI, recomendado, ou colar no SQL Editor).Project URL e a anon public key
(ou publishable key, em projetos mais novos — é o mesmo valor pro
NEXT_PUBLIC_SUPABASE_ANON_KEY)..env.local.example para .env.local e preencha:
NEXT_PUBLIC_SUPABASE_URL=...
NEXT_PUBLIC_SUPABASE_ANON_KEY=...
DOCS_ENCRYPTION_KEY=... # gere com `openssl rand -base64 32`
O Supabase não expõe uma API REST genérica pra "rodar SQL arbitrário" (por
segurança) — o jeito certo de aplicar migrations por fora do dashboard é a
CLI oficial, que já está instalada localmente como dependência do projeto
(npx supabase ..., não precisa instalar nada global).
npx supabase login — abre o navegador pra gerar um access token.npx supabase link --project-ref hqeufkxtgvdxcbbsqajz — liga esta pasta
ao seu projeto (vai pedir a senha do banco, a que você definiu ao criar o
projeto no Supabase — se não lembrar, dá pra resetar em
Settings > Database).supabase/migrations/20250101000000_initial_schema.sql (o schema
base) já foi rodado antes manualmente pelo SQL Editor, avise a CLI que
ela já está aplicada — senão ela tenta recriar tabela que já existe:
npx supabase migration repair --status applied 20250101000000
npx supabase db push
Isso roda só as migrations que ainda não foram aplicadas nesse projeto.npx supabase migration new nome_da_mudanca
cria o arquivo vazio já com timestamp certo em supabase/migrations/;
edite o SQL e rode npx supabase db push de novo.Sem instalar/logar em nada: abra cada arquivo de supabase/migrations/ na
ordem do nome (o timestamp no início do nome é a ordem), cole no SQL
Editor do dashboard e rode um de cada vez.
Pra quando o banco fica com dado de teste bagunçado ou schema inconsistente e é mais fácil recomeçar do que consertar:
supabase/reset.sql — ⚠️ destrutivo, apaga todas as tabelas,
views, funções e tipos do app (não mexe em auth.users, login
continua funcionando). Cole no SQL Editor e rode.supabase/recreate.sql — recria o schema inteiro do zero, já com
tudo (equivalente às 3 migrations de supabase/migrations/ juntas).
Cole no SQL Editor e rode logo em seguida.Em Authentication > Providers no Supabase:
http://localhost:3000/auth/callback (e depois a URL de produção) na lista
de Redirect URLs.Sem isso configurado, os botões de Google/Microsoft aparecem mas dão erro — o e-mail/senha funciona independente disso.
O convite de pessoas pra uma trip (aba "Pessoas" > "Convidar") manda um e-mail de verdade com um link de aceite. Isso usa o SMTP da sua própria conta do Gmail (via Nodemailer) — sem custo, sem precisar de domínio próprio nem criar conta em serviço nenhum.
.env.local:
[email protected]
GMAIL_APP_PASSWORD=a-senha-de-16-caracteres-gerada
npm run dev (variáveis de ambiente só carregam na
inicialização) e teste convidando alguém numa trip.Diferente de provedores como Resend/SendGrid em modo de teste, o Gmail via SMTP manda pra qualquer destinatário desde o primeiro e-mail — não tem limitação de "só entrega pro seu próprio endereço". O limite prático é o do Gmail normal (por volta de 500 e-mails/dia numa conta pessoal).
Sem GMAIL_USER/GMAIL_APP_PASSWORD configuradas, o convite mostra um erro
claro na tela em vez de travar — e o link de convite gerado
(/convite/[token]) continua existindo, só não é enviado por e-mail
automaticamente.
npm install
npm run dev
Abra http://localhost:3000 — vai te mandar pro login.
O Vamboh também roda como um app nativo do Windows — uma janela do Electron que carrega o site publicado (mesma tela de login, mesmo dashboard depois de autenticar). Não é uma reimplementação: é o mesmo app web, só empacotado numa janela própria em vez de um navegador.
Por padrão aponta pra https://vamboo.vercel.app.
Download: ainda não há uma release publicada — assim que o
instalador (.exe, gerado em desktop/dist/ conforme abaixo) for
anexado como uma Release do repositório, o link
entra aqui.
cd desktop
npm install
VAMBOO_DESKTOP_URL=http://localhost:3000 npm run dev
(no PowerShell: $env:VAMBOO_DESKTOP_URL="http://localhost:3000"; npm run dev)
Isso abre a janela do Electron apontando pro seu npm run dev local.
cd desktop
npm install
npm run build:win
O instalador (.exe) é gerado em desktop/dist/, já apontando pra
https://vamboo.vercel.app. Pra apontar pra outra URL, troque a
constante APP_URL em desktop/main.js antes de rodar o build.
supabase/migrations/20250101000300_transport_expenses_and_roles.sql./perfil): foto e documentos (RG, passaporte, outro), com
número do documento opcional — também encriptados./convite/[token], válido por
7 dias e que só a pessoa dona do e-mail convidado consegue aceitar (confere
com o e-mail da conta logada). Quem aceitar vira colaborador com um de dois
papéis: visualizador (só vê a trip) ou administrador (edita
roteiro/despesas/pessoas e também pode convidar gente) — só quem criou a
trip pode promover/rebaixar um colaborador. Veja
supabase/migrations/20250101000200_trip_sharing.sql (convite base),
20250101000300_transport_expenses_and_roles.sql (papel de administrador)
e 20250101000400_invite_expiry_and_identity.sql (validade + checagem de
identidade).lib/invites.ts): só simula o envio com um
delay e uma mensagem de sucesso — não manda nada de verdade. Precisaria da
WhatsApp Cloud API (Meta) ou um provedor tipo Twilio, com número comercial
verificado e template de mensagem aprovado.Só os campos que de fato precisam de proteção extra ficam encriptados — o resto (nome da trip, valores, datas etc.) fica em texto normal, senão totais, ordenação e RLS quebrariam:
pgcrypto. A chave mora no Supabase
Vault (não dá pra usar alter database ... set num projeto hospedado —
falta permissão de superusuário). Escrita e leitura são transparentes
pro app: um trigger encripta ao salvar, uma função de coluna computada
(reservation_number_decrypted, document_number_decrypted) decripta ao
ler — e só decripta linhas que a RLS já liberou pro dono.lib/crypto.ts, chave em DOCS_ENCRYPTION_KEY no .env.local, nunca
exposta ao navegador) antes de subir pro Storage, e decripta só na hora
de você pedir pra ver.Isso protege contra vazamento de backup/dump ou acesso casual às tabelas — não contra alguém com acesso de superusuário/service role ao Postgres, o que é uma limitação inerente de criptografia feita dentro do próprio banco.
app/
login/page.tsx tela de login (client component)
auth/callback/route.ts troca o código do OAuth pela sessão
dashboard/page.tsx busca as trips (server component)
dashboard/DashboardClient.tsx grid + criar trip (client component)
trips/[id]/page.tsx busca a trip completa (server component)
trips/[id]/TripDetailClient.tsx abas, formulários, convite (client component)
perfil/page.tsx busca perfil + documentos (server component)
perfil/PerfilClient.tsx foto + documentos (client component)
convite/[token]/page.tsx busca o convite pelo token (server component)
convite/[token]/AcceptInviteClient.tsx aceitar convite (client component)
api/hotel-files/ upload/download encriptado de comprovante
api/personal-docs/ upload/download/delete encriptado de documento
api/profile-photo/ upload encriptado de foto de perfil
api/invites/ cria o convite e manda o e-mail (Gmail SMTP)
globals.css todos os tokens visuais (cores, fontes, etc)
components/ Logo, TripCard, SummaryCard, Modal, InviteModal
lib/
supabase/client.ts cliente Supabase pro navegador
supabase/server.ts cliente Supabase pro servidor
dates.ts noites, status da linha do tempo, sobreposição
invites.ts e-mail real via /api/invites; WhatsApp ainda MOCADO
email.ts envio de e-mail via SMTP do Gmail (server-only)
crypto.ts encriptar/decriptar arquivos (AES-256-GCM)
secureStorage.ts upload/download encriptado no Supabase Storage
types.ts tipos TypeScript do schema
middleware.ts protege /dashboard, /trips e /perfil, redireciona pro login
supabase/migrations/ schema + migrations, aplicar via CLI (seção 2)
supabase/config.toml config da Supabase CLI
desktop/ app Electron (Windows) — janela nativa carregando o site (seção 5.1)
GMAIL_USER/GMAIL_APP_PASSWORD pra convidar gente de
verdade por e-mail (seção 4)..env.local cadastradas lá (incluindo DOCS_ENCRYPTION_KEY,
GMAIL_USER e GMAIL_APP_PASSWORD).