Lalabase
Tickets, Doku, Zeiterfassung und Kundengespräche an einem Ort, durchsuchbar per KI. Für Softwarefirmen mit Kundenprojekten. Open Source: auf deinem eigenen Server oder in unserer Cloud in Deutschland.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证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.
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
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.查看完整 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
barbearia.supabase/migrations/ (SQL Editor ou supabase db push) e depois supabase/seed.sql.pnpm seed:demopnpm dev e acesse http://localhost:3000supabase/cron.sql após o deploy.pnpm test # regras de negócio + banco (PGlite) — não precisa de Docker
pnpm test:concorrencia # reservas simultâneas contra um Supabase real
pnpm lint && pnpm typecheck && pnpm build
Os testes de banco aplicam as migrações reais num PGlite (Postgres em WebAssembly) com um stub
mínimo do Supabase (auth.users, auth.uid(), papéis anon/authenticated/service_role). Eles
cobrem: sobreposição, fuso, bloqueios, prazos de cancelamento, reagendamento atômico, RLS,
isolamento entre apps, fila de e-mails e redefinição da demo.
O teste de concorrência roda contra o Supabase real porque o PGlite tem uma única conexão.
shop_id).supabase gen types).Veja docs/guia-de-estudo.md para revisar o projeto e explicar suas decisões em entrevistas.
O código, os testes e a documentação foram produzidos com assistência do Claude Code (Anthropic), sob minha direção e revisão. As decisões estão registradas neste README e no histórico de commits.