Synaplan
Open-source AI platform for companies: self-hosted AI agents, GDPR-compliant chatbot widget, RAG knowledge base, WhatsApp and Outlook AI, MCP, multi-model routing. Docker, Kubernetes or hosted in Germ
翻訳待ち
No updates detected yet. GitHub releases will appear here.
Agendamento online para barbearias com Next.js 16 e Supabase: sem reservas duplicadas (exclusion constraint), fuso horário, RLS e lembretes por e-mail. Projeto de portfólio.
翻訳待ち
Loading the full README. The saved excerpt is shown below.
Navalha de Ouro — agendamento online para barbearias Projeto de portfólio com dados fictícios, desenvolvido com assistência de IA (Claude Code). Não há clientes, barbearias ou agendamentos reais. Demonstração: navalha-de-ouro-agendamento.vercel.app (contas de demonstração em configuração) · Status do CI: ver aba Actions Barbearias pequenas costumam agendar por mensagens e caderno. Isso gera horários duplicados, faltas sem aviso e nenhuma visão do faturamento. O cliente não sabe quais horários estão livres sem perguntar.Read the full README ↗
Projeto de portfólio com dados fictícios, desenvolvido com assistência de IA (Claude Code). Não há clientes, barbearias ou agendamentos reais.
Demonstração: navalha-de-ouro-agendamento.vercel.app (contas de demonstração em configuração) · Status do CI: ver aba Actions
▶ Vídeo da demonstração (1 a 2 min, com legenda em cada funcionalidade).
Capturas com os dados fictícios da demonstração.
Barbearias pequenas costumam agendar por mensagens e caderno. Isso gera horários duplicados, faltas sem aviso e nenhuma visão do faturamento. O cliente não sabe quais horários estão livres sem perguntar.
Público: clientes que querem marcar sozinhos, barbeiros que precisam ver e bloquear a própria agenda e o gerente que acompanha a operação.
| Perfil | O que faz |
|---|---|
| Cliente | Cadastro/login, agendamento em etapas (serviço → profissional → dia → horário), cancelamento e reagendamento até 2 h antes, histórico, e-mails recebidos |
| Profissional | Agenda semanal, expediente por dia da semana, bloqueios (folga, almoço), registro de “concluído” / “não compareceu” |
| Gerente | Tudo do profissional para toda a equipe, indicadores (agendamentos, taxa de cancelamento, faturamento previsto e realizado), cadastro de serviços com preço e duração |
E-mails de confirmação, lembrete 24 h antes e cancelamento, sem duplicidade.
| Perfil | Senha | |
|---|---|---|
| Cliente | [email protected] | demo12345 |
| Barbeiro | [email protected] | demo12345 |
| Gerente | [email protected] | demo12345 |
Os dados e as senhas são redefinidos diariamente (workflow Redefinir demonstração).
Duas pessoas clicando no mesmo horário ao mesmo tempo é uma condição de corrida clássica. Verificar na aplicação (“está livre?” → “insere”) não resolve, porque as duas verificações podem passar antes de qualquer inserção. A solução é uma restrição de exclusão no PostgreSQL:
constraint bookings_no_overlap
exclude using gist (professional_id with =, period with &&)
where (status <> 'cancelled')
period é um tstzrange semiaberto [início, fim). O Postgres garante que nenhum par de
agendamentos ativos do mesmo profissional se sobreponha; a segunda transação recebe o erro
23P01, traduzido para “Este horário acabou de ficar indisponível”.
Verificado por pnpm test:concorrencia (N sessões reservando o mesmo horário → exatamente 1 sucesso).
Tudo é gravado em UTC (timestamptz). O expediente é guardado em hora local (time + dia da
semana) e convertido no banco, na data consultada, com o fuso da barbearia
((data + hora) at time zone 'America/Sao_Paulo'). Assim, mudanças de horário de verão são
respeitadas e o fuso do servidor ou do navegador não interfere. A interface exibe sempre no fuso da
barbearia, com testes cobrindo datas perto da meia-noite.
Fila notification_outbox (padrão transactional outbox):
unique (booking_id, kind) → cada agendamento tem no máximo um e-mail de cada tipo;FOR UPDATE SKIP LOCKED → execuções paralelas não pegam o mesmo item;Idempotency-Key no Resend → reprocessar após falha parcial não reenvia;O agendador é o pg_cron + pg_net do Supabase (a cada 5 min), porque o cron do plano gratuito da Vercel roda no máximo uma vez por dia.
book_appointment, cancel_booking) que aplicam disponibilidade, prazos e permissões numa transação.O plano gratuito do Supabase permite 2 projetos ativos, e o portfólio tem 6 aplicações. Este app
usa o schema barbearia num projeto Supabase compartilhado com outras demos. O isolamento é
explícito: perfis próprios por schema, políticas que exigem perfil neste app, migrações
separadas e um teste automatizado garantindo que um usuário de outro app não enxerga nada daqui.
Identidade visual baseada no sistema luxury do open-design
(licença Apache-2.0): preto laqueado e dourado, títulos em serifa didone (Playfair Display). Os tokens foram adaptados em src/app/globals.css, com
tons de texto ajustados para contraste AA (WCAG 4,5:1) e a cor da marca separada em preenchimento
(botões) e texto (links e foco). Cada app do portfólio usa um sistema diferente.
Navegador ──► Next.js 16 (App Router, Server Components, Server Actions) ──► Supabase
│ proxy.ts renova a sessão ├─ Auth
│ validação com Zod ├─ Postgres (schema barbearia, RLS, funções)
└─ /api/cron/emails ◄── pg_cron + pg_net (a cada 5 min) └─ Vault (segredo do cron)
└──► Resend (e-mail) Sentry (erros, sem dados pessoais)
Tecnologias: Next.js 16 · React 19 · TypeScript · Tailwind CSS 4 · Supabase (Postgres, Auth, RLS, pg_cron) · Zod · Resend · Sentry · Vitest · PGlite · GitHub Actions · Vercel.
Requisitos: Node 20.9+ (recomendado 24), pnpm, um projeto Supabase.
pnpm install
cp .env.example .env.local # preencha com as chaves do seu projeto
This is the beginning of the README. Read the rest at the original. Read the full README ↗