尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗Sistema completo para clínicas odontológicas: site da clínica com agendamento online e painel administrativo para a equipe (agenda visual, profissionais, pacientes e configurações). Pensado como white-label: você troca nome, cores e logo em um único arquivo e entrega o produto com a sua marca.
Site público da clínica (/clinica/<slug>)
/agendar/<slug>) que mostra só horários realmente livres.Painel da clínica (/dashboard, com login)
Perfis de acesso: Administrador, Recepção e Dentista (o dentista vê a agenda e bloqueia apenas a própria agenda).
Requisitos: Node.js 18.18+ (recomendado 20) e Docker (ou qualquer PostgreSQL 14+).
cp .env.example .env # ajuste se não for usar o banco do Docker
npm install
npm run db:up # sobe o PostgreSQL local (docker-compose.yml)
npm run db:setup # cria as tabelas e carrega a clínica de demonstração
npm run dev # http://localhost:3000
Logins da demonstração (clínica fictícia Sorriso Pleno Odontologia):
| Perfil | Senha | |
|---|---|---|
| Administrador | [email protected] | admin123 |
| Recepção | [email protected] | recepcao123 |
| Dentista | [email protected] | dentista123 |
Site da clínica: http://localhost:3000/clinica/sorriso-pleno
.env):
DATABASE_URL: conexão usada pela aplicação.DIRECT_URL: conexão direta usada pelas migrations. Localmente é igual à
DATABASE_URL; em provedores com pool (Supabase, Neon), use a URL do pool
na DATABASE_URL e a conexão direta na DIRECT_URL.prisma/migrations e são aplicadas com
npm run db:migrate (o npm run build também aplica, o que facilita o deploy).prisma/schema.prisma e rode
npx prisma migrate dev --name descricao-da-mudanca para gerar a migration.npm run db:seed. O seed é idempotente (pode rodar
de novo sem duplicar). Em produção ele também pode ser disparado por
GET /api/seed?key=<SEED_SECRET>; sem SEED_SECRET definido, a rota fica desligada.npm run prisma:studio.Tudo fica em src/config/white-label.ts:
| Campo | O que muda |
|---|---|
productName, productTagline, productDescription | Nome e textos do produto (aba do navegador, login, página inicial, rodapé do painel) |
logoUrl | Logo do produto. null usa o ícone padrão. Aceita URL ou arquivo em /public (ex.: "/images/logo.svg") |
colors.primary / secondary / accent | Paleta do sistema inteiro: o Tailwind gera as variáveis de cor a partir daqui |
dentistColors | Paleta sugerida para diferenciar profissionais na agenda |
contact | E-mail, telefone e WhatsApp comercial na página inicial (vazio = oculto) |
defaults | Texto padrão do botão de agendamento e duração padrão da consulta |
demo | Clínica de demonstração em destaque e quadro de credenciais no login |
Depois de alterar, reinicie o npm run dev (as cores são lidas no build do CSS).
Antes de entregar a um cliente, em src/config/white-label.ts:
demo.showCredentialsOnLogin: false para esconder o quadro de credenciais;demo.clinicSlug: null para remover os atalhos da demonstração.Também troque as senhas da demonstração ou crie a clínica real direto no banco.
Cada clínica pode ainda ter identidade própria (logo, cores, imagens e textos do site) em Administração > Identidade visual. O que a clínica salva no banco tem prioridade sobre o padrão do arquivo de configuração.
POST /api/uploads (só Administrador) confere o tipo real do arquivo
(JPG, PNG ou WebP; SVG é recusado) e o limite de 3 MB.Asset do próprio PostgreSQL e são servidas por
GET /api/assets/<id> com cache longo (navegador e CDN). Assim o sistema
funciona em qualquer hospedagem, sem contratar armazenamento de arquivos.src/app/api/uploads/route.ts (que devolve a URL
final da imagem); o resto do sistema só guarda essa URL.O agendamento online (/api/public/availability) cruza, para o dia escolhido:
A criação do agendamento (/api/public/appointments) revalida tudo isso dentro
de uma transação serializável, então dois pacientes não conseguem pegar o mesmo
horário. Na agenda interna, a equipe pode encaixar consultas fora da grade, mas
nunca sobre um bloqueio ou outra consulta do mesmo profissional.
Fuso: todos os horários são tratados no horário de Brasília (UTC-3), independente
do fuso do servidor ou do navegador (src/lib/dates.ts).
DATABASE_URL e DIRECT_URL (veja Banco de dados);NEXTAUTH_SECRET: string aleatória longa (openssl rand -base64 32);NEXTAUTH_URL: URL pública do sistema (ex.: https://agenda.suaclinica.com.br);SEED_SECRET (opcional): libera /api/seed para carregar a demonstração.O arquivo vercel.json fixa a região gru1 (São Paulo); ajuste se o banco
estiver em outra região, para reduzir a latência.
src/
config/white-label.ts # marca, cores e textos do produto
app/
page.tsx # página inicial do produto
login/ # login
clinica/[slug]/ # site público da clínica
agendar/[slug]/ # agendamento online
dashboard/ # painel (agenda, dentistas, pacientes, administracao...)
api/ # rotas internas (sessão) e públicas (api/public/*)
components/
ui/ # componentes shadcn/ui
dashboard/ # menu lateral e barra superior do painel
lib/
assets.ts # validação e limpeza das imagens enviadas
image-compress.ts # redimensiona/comprime imagem no navegador
public-clinic.ts # dados públicos da clínica (site e prévia)
availability.ts # horários livres, grade e bloqueios
dates.ts # horário de Brasília
validation.ts # schemas Zod
demo-seed.ts # clínica de demonstração
notifications.ts # ponto de integração para e-mail/WhatsApp
prisma/
schema.prisma # modelo de dados
migrations/ # histórico de migrations
docker-compose.yml # PostgreSQL local
Clinic: a clínica (multi-clínica por clinicId), com identidade visual e duração da consulta.User: acesso ao painel (ADMIN, RECEPTIONIST, DENTIST).Dentist, DentistSchedule: profissional e sua grade semanal.WorkingHour: funcionamento da clínica por dia da semana.TimeBlock: bloqueios de agenda (profissional ou clínica inteira).Patient, Contact: pacientes e contatos (WhatsApp, telefone, e-mail).Service: serviços exibidos no site e vinculáveis à consulta.Appointment: consultas, com status e serviço.ContactMessage: mensagens do formulário do site.Asset: imagens enviadas pelo painel.clinicId da sessão, nunca do navegador: uma clínica
não acessa dados de outra.src/middleware.ts protege /dashboard/*; alterações de cadastro e configuração
exigem perfil Administrador.src/lib/notifications.ts é chamado a cada agendamento criado ou remarcado.
Hoje só registra em log; é o lugar para plugar e-mail (Resend, SES) ou
WhatsApp (Meta Cloud API, Twilio) sem mexer nas telas.
As fotos em public/images/demo/ são do Unsplash
(Unsplash License: uso livre, inclusive comercial). As pessoas nas fotos não são
os profissionais fictícios da demonstração. Substitua pelas imagens da clínica real.