API RESTful para gerenciamento de consultas médicas, desenvolvida com Node.js, Express, TypeScript e Prisma ORM.
- Sobre o Projeto
- Tecnologias
- Funcionalidades
- Arquitetura
- Pré-requisitos
- Instalação
- Configuração
- Execução
- Estrutura do Projeto
- API Endpoints
- Banco de Dados
- Segurança
- Scripts Disponíveis
- Contribuindo
Sistema completo para gerenciamento de consultas médicas que permite:
- Cadastro e autenticação de usuários (Médicos, Pacientes e Administradores)
- Gerenciamento de especialidades médicas
- Controle de agenda de médicos com slots de horários
- Agendamento e gestão de consultas
- Sistema de permissões baseado em perfis
- Node.js - Ambiente de execução JavaScript
- TypeScript - Superset JavaScript com tipagem estática
- Express 5 - Framework web minimalista
- Prisma - ORM moderno para Node.js e TypeScript
- MySQL - Sistema de gerenciamento de banco de dados
- Helmet - Headers de segurança HTTP
- CORS - Controle de acesso entre origens
- bcryptjs - Hash de senhas
- jsonwebtoken - Autenticação JWT
- express-rate-limit - Limitação de requisições
- Zod - Validação de schemas TypeScript-first
- Pino - Logger de alta performance
- tsx - Executor TypeScript para desenvolvimento
- ts-node - Executor TypeScript
- dotenv - Gerenciamento de variáveis de ambiente
- ✅ Login com email e senha
- ✅ Geração de tokens JWT
- ✅ Middleware de autenticação
- ✅ Sistema de permissões por perfil (ADMIN, MEDICO, PACIENTE)
- ✅ Cadastro de médicos e pacientes
- ✅ Atualização de perfis
- ✅ Ativação/desativação de contas
- ✅ CRUD completo de especialidades médicas
- ✅ Associação de múltiplas especialidades a médicos
- ✅ Criação de slots de horários disponíveis
- ✅ Visualização de agenda por médico
- ✅ Filtros por data e especialidade
- ✅ Controle de status dos slots (DISPONIVEL, OCUPADO, BLOQUEADO)
- ✅ Agendamento de consultas
- ✅ Visualização de consultas por paciente/médico
- ✅ Cancelamento de consultas
- ✅ Atualização de status (AGENDADA, REALIZADA, CANCELADA)
O projeto segue uma arquitetura em camadas:
┌─────────────────────────────────────┐
│ Routes (Rotas) │
├─────────────────────────────────────┤
│ Middlewares (Validação) │
├─────────────────────────────────────┤
│ Controllers (Lógica) │
├─────────────────────────────────────┤
│ Prisma ORM (Acesso a Dados) │
├─────────────────────────────────────┤
│ MySQL Database │
└─────────────────────────────────────┘
- MVC Pattern - Separação de responsabilidades
- Middleware Pattern - Processamento em cadeia
- Repository Pattern - Abstração de acesso a dados via Prisma
- Dependency Injection - Injeção de dependências
Antes de começar, certifique-se de ter instalado:
- Node.js (versão 18 ou superior)
- npm ou yarn
- MySQL (versão 8 ou superior)
- Git
- Clone o repositório
git clone https://github.com/enriconovellino/ProjDevWebBack.git
cd ProjDevWebBack- Instale as dependências
npm install- Crie o arquivo
.envna raiz do projeto:
# Database
DATABASE_URL="mysql://usuario:senha@localhost:3306/nome_do_banco"
# Server
PORT=3000
NODE_ENV=development
# JWT
JWT_SECRET=seu_segredo_super_secreto_aqui_min_32_caracteres
JWT_EXPIRES_IN=7d
# CORS (opcional)
CORS_ORIGIN=http://localhost:3000- Configure o banco de dados
Crie o banco de dados MySQL:
CREATE DATABASE nome_do_banco CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;- Execute as migrations
npm run prisma:migrate- Execute o seed (opcional) - Popula o banco com dados iniciais:
npm run prisma:seednpm run devO servidor estará disponível em http://localhost:3000
# Build
npm run build
# Start
npm startVerifique se o servidor está rodando:
curl http://localhost:3000/healthProjDevWebBack/
├── controllers/ # Lógica de negócio
│ ├── agenda.controller.ts
│ ├── auth.controller.ts
│ ├── consulta.controller.ts
│ ├── especialidade.controller.ts
│ ├── medico.controller.ts
│ └── paciente.controller.ts
├── middlewares/ # Middlewares da aplicação
│ ├── auth.middleware.ts
│ ├── authorization.middleware.ts
│ ├── errorHandler.middleware.ts
│ └── validation.middleware.ts
├── routes/ # Definição de rotas
│ ├── index.ts
│ ├── agenda.route.ts
│ ├── auth.route.ts
│ ├── consulta.route.ts
│ ├── especialidade.route.ts
│ ├── medico.route.ts
│ └── paciente.route.ts
├── validations/ # Schemas de validação Zod
│ ├── agenda.validation.ts
│ ├── auth.validation.ts
│ ├── consulta.validation.ts
│ ├── especialidade.validation.ts
│ ├── medico.validation.ts
│ ├── paciente.validation.ts
│ └── pagination.validation.ts
├── utils/ # Utilitários
│ ├── jwt.util.ts
│ ├── logger.util.ts
│ └── prisma.util.ts
├── types/ # Definições TypeScript
│ └── express/
│ └── index.d.ts
├── prisma/ # Prisma ORM
│ ├── schema.prisma # Schema do banco de dados
│ ├── seed.ts # Dados iniciais
│ └── migrations/ # Histórico de migrations
├── server.ts # Ponto de entrada da aplicação
├── package.json
└── tsconfig.json
http://localhost:3000/api
Realiza login e retorna token JWT
Request Body:
{
"email": "[email protected]",
"senha": "senha123"
}Response:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"usuario": {
"id": 1,
"email": "[email protected]",
"nome": "Nome do Usuário",
"perfil": "PACIENTE"
}
}Lista todos os médicos (requer autenticação)
Query Parameters:
page(opcional): Número da página (padrão: 1)limit(opcional): Itens por página (padrão: 10)especialidade_id(opcional): Filtrar por especialidade
Headers:
Authorization: Bearer <token>
Cria um novo médico (requer perfil ADMIN)
Request Body:
{
"nome": "Dr. João Silva",
"email": "[email protected]",
"senha": "senha123",
"cpf": "12345678900",
"crm": "12345-SP",
"telefone": "(11) 98765-4321",
"duracao_minutos": 30,
"especialidades": [1, 2]
}Busca um médico por ID
Atualiza um médico (requer perfil ADMIN ou ser o próprio médico)
Desativa um médico (requer perfil ADMIN)
Lista todos os pacientes (requer perfil ADMIN)
Cria um novo paciente
Request Body:
{
"nome": "Maria Santos",
"email": "[email protected]",
"senha": "senha123",
"cpf": "98765432100",
"telefone": "(11) 91234-5678",
"data_nascimento": "1990-05-15"
}Busca um paciente por ID
Atualiza um paciente
Desativa um paciente
Lista todas as especialidades
Cria uma nova especialidade (requer perfil ADMIN)
Request Body:
{
"nome": "Cardiologia",
"codigo": "CARDIO"
}Atualiza uma especialidade (requer perfil ADMIN)
Desativa uma especialidade (requer perfil ADMIN)
Lista slots de agenda de um médico
Query Parameters:
data_inicio: Data inicial (ISO 8601)data_fim: Data final (ISO 8601)status: Filtrar por status (DISPONIVEL, OCUPADO, BLOQUEADO)
Cria slots de horários para um médico (requer perfil MEDICO ou ADMIN)
Request Body:
{
"medico_id": 1,
"data_inicio": "2025-11-10T08:00:00Z",
"data_fim": "2025-11-10T18:00:00Z",
"duracao_minutos": 30
}Atualiza um slot (requer perfil MEDICO ou ADMIN)
Remove um slot (requer perfil MEDICO ou ADMIN)
Lista consultas (filtradas por perfil)
Query Parameters:
status: Filtrar por status (AGENDADA, REALIZADA, CANCELADA)data_inicio: Data inicialdata_fim: Data final
Agenda uma nova consulta
Request Body:
{
"paciente_id": 1,
"medico_id": 2,
"agenda_slot_id": 5
}Busca uma consulta por ID
Atualiza o status de uma consulta
Request Body:
{
"status": "REALIZADA"
}Cancela uma consulta
- Armazena dados de autenticação e perfil
- Relacionamento 1:1 com Medico ou Paciente
- Dados específicos de médicos (CRM, duração de consulta)
- Relacionamento N:N com Especialidade
- Dados específicos de pacientes (data de nascimento)
- Especialidades médicas disponíveis
- Relacionamento N:N com Medico
- Slots de horários na agenda dos médicos
- Controle de disponibilidade
- Registro de consultas agendadas
- Relaciona Paciente, Médico e AgendaSlot
┌──────────┐ 1:1 ┌─────────┐ N:N ┌────────────────┐
│ Usuario │────────────▶│ Medico │◀───────────▶│ Especialidade │
└──────────┘ └─────────┘ └────────────────┘
│ │
│ 1:1 │ 1:N
│ │
▼ ▼
┌──────────┐ ┌─────────────┐
│ Paciente │ │ AgendaSlot │
└──────────┘ └─────────────┘
│ │
│ N:1 │ 1:1
└───────────▶┌──────────┐◀───────
│ Consulta │
└──────────┘
-
Autenticação JWT
- Tokens com expiração configurável
- Validação em todas as rotas protegidas
-
Autorização por Perfil
- ADMIN: Acesso total
- MEDICO: Gerencia própria agenda e consultas
- PACIENTE: Visualiza e agenda próprias consultas
-
Hash de Senhas
- Utilização de bcryptjs com salt rounds
-
Rate Limiting
- Limite de 100 requisições por IP a cada 15 minutos
-
Helmet
- Headers de segurança HTTP configurados
-
CORS
- Controle de origens permitidas
-
Validação de Dados
- Validação com Zod em todas as entradas
- ✅ Nunca commitar o arquivo
.env - ✅ Usar senhas fortes para JWT_SECRET
- ✅ Implementar HTTPS em produção
- ✅ Manter dependências atualizadas
- ✅ Realizar backups regulares do banco de dados
# Desenvolvimento
npm run dev # Inicia o servidor em modo watch
# Build
npm run build # Compila TypeScript para JavaScript
# Produção
npm start # Inicia o servidor compilado
# Prisma
npm run prisma:migrate # Executa migrations do Prisma
npm run prisma:seed # Popula banco com dados iniciais
npx prisma studio # Abre interface visual do banco
npx prisma generate # Gera o Prisma ClientPara testar a API, você pode usar:
- Postman - [Collection disponível]
- Insomnia - Cliente REST
- curl - Linha de comando
- Thunder Client - Extensão do VS Code
# Health Check
curl http://localhost:3000/health
# Login
curl -X POST http://localhost:3000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","senha":"admin123"}'
# Listar Médicos (com autenticação)
curl http://localhost:3000/api/medicos \
-H "Authorization: Bearer SEU_TOKEN_AQUI"Contribuições são bem-vindas! Para contribuir:
- Faça um fork do projeto
- Crie uma branch para sua feature (
git checkout -b feature/MinhaFeature) - Commit suas mudanças (
git commit -m 'Adiciona MinhaFeature') - Push para a branch (
git push origin feature/MinhaFeature) - Abra um Pull Request
- Use TypeScript para todo código novo
- Siga as convenções do ESLint/Prettier (se configurados)
- Documente funções complexas
- Escreva commits descritivos
Este projeto está sob a licença ISC.
- Enrico Novellino e Gigio Moura Melo - GitHub
Para dúvidas ou sugestões:
- Abra uma issue
- Entre em contato via e-mail