Easy-to-manage touch screens
Free, open-source touch screens. Guided USB setup, a drag-and-drop editor and local control. Made for Home Assistant.
Faça o sorteio do amigo oculto (amigo secreto) online e grátis. Mande um link no WhatsApp: cada um descobre quem tirou e já monta a lista de presentes.
Translation pending
LifestyleTypeScript · PLpgSQLGitHub @rod455OnlineOwner 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 ↗A surpresa fica. A complicação sai.
Apps (iPhone e Android, Codemagic):
docs/apps.md· ficha da versão:docs/lojas/novidades-1.0.md· medição:docs/dados/como-medimos.md.Marca e regras de uso em
docs/marca.md(guia completo e arquivos originais emdocs/marca/). O identificador técnico antigo (tirei) continua só em nomes internos, como o projeto Supabase e a pasta do repositório.
App do amigo oculto: o organizador cadastra os nomes, o app sorteia e gera um link para o grupo do WhatsApp. Cada participante abre o link, toca no próprio nome, descobre quem tirou e, na mesma tela, escolhe o próprio presente (com links de afiliado).
Este repositório tem um código só para web, iOS e Android (Expo + Expo Router). A versão web é a que está no ar para testes; os apps nativos saem do mesmo projeto pelo Codemagic (codemagic.yaml).
Referências: a especificação de produto é o arquivo tirei-spec-desenvolvimento.md (fora do repo); a identidade visual está em docs/marca.md.
src/app/ rotas (Expo Router)
index.tsx "/" web: landing page · app: tela 1 (Início)
app.tsx "/app" tela 1 no web (para testar o protótipo)
entrar.tsx "Tenho um convite": cola o link ou código
criar/nome.tsx tela 2 · nome do grupo (1/3)
criar/pessoas.tsx tela 3 · participantes (2/3)
criar/valor.tsx tela 4 · valor, data, pares, Sortear (3/3)
pronto/[codigo].tsx tela 5 · sorteado → WhatsApp / copiar link
painel/[codigo].tsx tela 6 · painel do organizador (status, lembrar, liberar, remover, adicionar)
g/[codigo].tsx link do convite → telas 7, 8 e 9
r/[id].tsx redirecionador de afiliado (registra o clique)
minha-conta.tsx sair e excluir a conta (exigência das lojas)
auth.tsx volta dos links de e-mail no app (amigoocultoja://auth)
src/features/ telas compostas (landing, start, participante, rascunho)
src/components/ UI (Screen, Button, Row, Sheet, ícones)
src/lib/ api (RPCs/Edge Functions), device key, share (WhatsApp), analytics, formatação
src/theme/tokens.ts cores, fontes (Figtree), medidas do sistema visual v2
supabase/migrations/ esquema, RLS e funções (0001_init.sql)
supabase/functions/ Edge Functions: draw_group (sorteio) e repair_group (remover/adicionar)
supabase/functions/_shared/draw.ts algoritmo de sorteio (puro, testado)
tests/draw.test.ts 10.000 sorteios por cenário, distribuição, casos impossíveis, reparo
scripts/postexport.mjs renomeia rotas dinâmicas do export estático para a Vercel
npm install
cp .env.example .env # já vem preenchido com o projeto de testes
npm run web # http://localhost:8081
npm test # testes do sorteio (vitest)
npm run typecheck
npm run build # export estático em dist/ (o que a Vercel publica)
iOS / Android (Expo Go ou development build):
npx expo start # escaneie o QR com o Expo Go
# lojas: Codemagic › workflow "Lojas (iPhone e Android)" (docs/apps.md)
Projeto tirei (região sa-east-1). Tudo que o cliente faz passa por funções RPC security definer ou pelas Edge Functions; nenhuma tabela é legível diretamente (RLS ligado sem policies, exceto products).
Identidade. Dois mecanismos convivem (migração 0002_auth.sql):
device key, 64 hex) guardada localmente; o banco só conhece o hash SHA-256. Assumir um nome vincula o nome à chave./conta); todo o preenchimento anterior fica no rascunho local. O grupo guarda owner_user_id e owner_key_hash; is_owner() aceita qualquer um dos dois, então o organizador vê o painel e "Seus grupos" em qualquer aparelho logado. As Edge Functions leem o JWT do usuário no Authorization.Contas e DNS: quem é dono de cada conta (Supabase, Vercel, Google Cloud, lojas, e-mail) e os registros de DNS ficam fora do repositório, com o dono do projeto.
Para ativar os logins no painel do Supabase (Authentication → Providers / URL Configuration):
Google: criar OAuth Client ID (Web) no Google Cloud, colar client ID/secret no provider Google e adicionar https://qqzlqnvreftablfyonux.supabase.co/auth/v1/callback como redirect no Google.
Apple: Services ID + chave .p8 no provider Apple (exige Apple Developer Program).
URL Configuration: Site URL https://amigoocultoja.com.br e Redirect URLs https://amigoocultoja.com.br/**, amigoocultoja://auth. Sem isso o retorno do Google/Apple é recusado.
E-mails com a marca: os templates (confirmação, redefinir senha, link mágico, troca de e-mail, convite) estão em supabase/templates/ e são gerados por scripts/email-templates.mjs. Para publicar no projeto com um comando (precisa de um token pessoal em supabase.com/dashboard/account/tokens):
O Supabase só aceita templates personalizados com SMTP próprio. O mesmo comando configura o remetente:
SUPABASE_ACCESS_TOKEN=sbp_... \
SMTP_HOST=smtp.resend.com SMTP_PORT=465 SMTP_USER=resend SMTP_PASS=re_... [email protected] SMTP_NAME="Amigo Oculto Já!" \
node scripts/email-templates.mjs --push --site-url=https://amigoocultoja.com.br
# acrescente --autoconfirm para desligar a confirmação de e-mail nos testes
Para testes, Gmail com senha de app (myaccount.google.com/apppasswords, exige verificação em 2 etapas) funciona na hora. Para o lançamento, use Resend (smtp.resend.com, porta 465, usuário resend, senha = API key) ou Brevo, com o domínio verificado, e o remetente [email protected].
Ou cole cada .html e o assunto (.subject.txt) em Authentication → Email Templates. As imagens da marca ficam em public/email/ e são servidas pelo site (/email/logo-dark.png).
E-mail: funciona sem configuração. "Confirm email" vem ligado: o usuário recebe um link e, ao clicar, volta direto para o sorteio. Para testes rápidos, desligue "Confirm email" em Authentication → Providers → Email (ou configure um SMTP próprio: o remetente padrão tem limite baixo de envios por hora).
Segredo do sorteio (P0-04). assignments só é lida por rpc_my_result, que exige a chave do próprio participante. O organizador não tem nenhum privilégio extra: rpc_panel devolve apenas status (não abriu / entrou / viu / lista pronta). O teste em SQL (seção abaixo) tenta ler como anon e como organizador e precisa falhar.
| Função | Quem chama | O que faz |
|---|---|---|
Edge draw_group | organizador | cria grupo + participantes + exclusões, sorteia e grava (service role) |
Edge repair_group | organizador | remove/adiciona pessoa com reparo mínimo (spec §9.3) |
rpc_get_group | qualquer um com o link | nome, valor, data, nomes e quem já entrou |
rpc_claim | participante | vincula o nome ao aparelho (trava) |
rpc_my_result | participante | quem eu tirei + lista dele + minha lista; marca revealed_at |
rpc_set_wish_items | participante | salva até 3 itens de 4 tipos (kind): sugestão do catálogo, busca na Amazon, produto escolhido na Amazon (só o ASIN; a URL é montada com o nosso ID) e texto fora da Amazon (sem link) |
Edge resolve_amazon_link | participante | abre links curtos da Amazon (a.co, amzn.to) seguindo só os redirecionamentos e devolve o ASIN |
rpc_suggestions | participante | 6 produtos dentro do valor, vitrine varia por pessoa |
rpc_resolve_link | qualquer um | registra outbound_clicks e devolve a URL de afiliado |
rpc_panel / rpc_release / rpc_my_groups | organizador | painel, liberar nome, meus grupos |
rpc_nudge | ambos | lembrete anônimo in-app (quem tirou → quem foi tirado; aparece no link da pessoa; 1 a cada 12 h) e registro do lembrete do organizador |
rpc_track | ambos | eventos de analytics (events) |
Afiliados: a tag e os templates de busca ficam em app_settings (affiliate_tag_amazon, search_url_amazon, default_store). ID de associado da Amazon: amigoocultoja-20 (migração 0003_affiliate_tag.sql). A Amazon encerra a conta se não houver 3 vendas qualificadas em 180 dias. O catálogo (products, migração 0005_catalogo_amazon.sql) tem 28 produtos reais da Amazon em 4 faixas (até R$ 50, 100, 200 e 400), com link /dp/ASIN?tag=amigoocultoja-20. O preço guardado é aproximado e serve só para filtrar pelo valor do grupo; a interface mostra a faixa, porque a Amazon não permite exibir preço fixo fora da API oficial. Revise a lista de tempos em tempos: produtos podem sair de estoque.
Os blocos do $$ ... $$ usados na validação estão em supabase/tests/ (RLS: nenhuma tabela legível por anon; ponta a ponta: claim, trava, segredo, lista, painel, sugestões, redirecionador, liberar).
O conector do Supabase trata as palavras delete/revoke como comandos destrutivos e aguarda confirmação. Por isso a função rpc_set_wish_items em produção executa o delete via execute de string e os revoke rodam dentro de do $$ ... $$. O arquivo 0001_init.sql é a versão legível e equivalente; para aplicar via CLI (supabase db push) ele funciona como está.
vercel.json já define build (npm run build), saída (dist/) e as rewrites das rotas dinâmicas (/g/:codigo etc.). O .env não é versionado. As variáveis públicas (EXPO_PUBLIC_SUPABASE_URL, EXPO_PUBLIC_SUPABASE_ANON_KEY, EXPO_PUBLIC_BASE_URL) estão em .env.example; o build (scripts/env.mjs) monta o .env a partir dele quando ele não existe, e variáveis definidas no painel da Vercel ou do Codemagic valem sobre ele. Os IDs do Google (EXPO_PUBLIC_GA4_ID, EXPO_PUBLIC_GOOGLE_ADS_ID, EXPO_PUBLIC_GOOGLE_ADS_CADASTRO) vão no painel da Vercel (ver docs/dados/marketing.md). EXPO_PUBLIC_BASE_URL fixa o domínio dos links de convite em https://amigoocultoja.com.br, mesmo quando o site é aberto em tirei.vercel.app ou numa preview.
Domínio amigoocultoja.com.br: configurado na Vercel (o www redireciona para a raiz). Nos apps, os Universal Links / App Links estão em app.json e os arquivos apple-app-site-association e assetlinks.json em public/.well-known/.
events com os nomes da spec §10).