-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Vicente Augusto edited this page Jun 6, 2026
·
1 revision
SaaS B2B Multi-tenant de Gerenciamento Clínico Odontológico
Stack: Node.js · Express · TypeScript · Prisma ORM v7 · PostgreSQL · Docker
- Estrutura de pastas definida (
controllers,services,routes,middlewares,types,shared,lib,docs,__tests__) - Docker Compose com PostgreSQL 16
- Prisma v7 configurado com
prisma.config.ts+ adapter@prisma/adapter-pg -
tsconfig.jsonconfigurado para CommonJS + Node 24 -
tsxcomo runner de desenvolvimento -
.envcomDATABASE_URL,JWT_SECRET,JWT_EXPIRES_IN -
server.tscom Express + CORS + JSON parser - Health check endpoint
GET /health
- Schema multi-tenant com modelo
Tenantcomo entidade máxima - Enums tipados:
TenantPlan,UserRole,AppointmentStatus,AppointmentType,Room,PaymentMethod,TransactionType,Gender - Models:
Tenant,Clinic,User,Patient,Appointment,Product,Supplier,Transaction - Soft delete em
Patient,Product,Supplier - Índices compostos para queries multi-tenant (
tenantId + clinicId) -
@@unique([tenantId, cpf])emPatient - Migrations aplicadas e banco sincronizado
-
auth.types.ts— DTOs eJwtPayloadcomtenantId + clinicId -
auth.service.ts— register, login, getMe com isolamento multi-tenant -
auth.middleware.ts—authenticate(JWT) +authorize(...roles)(RBAC) -
auth.controller.ts— controllers comnext(error) -
auth.routes.ts— POST /register, POST /login, GET /me - Hash de senha com
bcryptjs(salt 12) - JWT assinado com
tenantId,clinicId,role - Validação de
tenant.isActiveeuser.isActiveno login -
lastLoginAtatualizado em fire-and-forget
-
patient.types.ts— CreatePatientDTO, UpdatePatientDTO, PatientFiltersDTO -
patient.service.ts— CRUD completo + soft delete + paginação + filtros por nome/CPF -
patient.controller.ts— todos os controllers comnext(error) -
patient.routes.ts— CRUD com RBAC por role
-
AppError— classe de erro customizada comstatusCode -
errorHandler.middleware.ts— middleware global de erro -
prisma.ts— singleton do PrismaClient comglobalThispattern -
routes/index.ts— agregador central de rotas
-
appointment.types.ts -
appointment.service.ts— CRUD + validação de conflito de sala/dentista/horário -
appointment.controller.ts -
appointment.routes.ts - Regra: não permitir dois agendamentos na mesma sala no mesmo horário
- Regra: não permitir dentista com dois agendamentos simultâneos
- Filtros: por data, dentista, sala, status, paciente
- Endpoint de mudança de status:
PATCH /appointments/:id/status
-
transaction.types.ts -
transaction.service.ts— RECEITA e DESPESA -
transaction.controller.ts -
transaction.routes.ts - Criação automática de
Transactionao finalizarAppointment - Relatório financeiro por período (
GET /transactions/report) - Filtros: por tipo, método de pagamento, período, categoria
- Instalar e configurar
zod - Schemas de validação para todos os DTOs (auth, patient, appointment, transaction)
- Middleware
validate(schema)reutilizável
-
product.types.ts -
product.service.ts— CRUD + alertas de estoque mínimo -
product.controller.ts -
product.routes.ts - Endpoint
GET /products/low-stock— produtos abaixo dominQuantity - Endpoint
GET /products/expiring— produtos próximos do vencimento
-
supplier.types.ts -
supplier.service.ts -
supplier.controller.ts -
supplier.routes.ts
-
clinic.service.ts— CRUD de clínicas por tenant - Apenas
ADMINpode criar/editar clínicas - Endpoint
GET /clinics— lista filiais do tenant
-
user.service.ts— CRUD de usuários por clínica -
PATCH /users/:id/status— ativar/desativar usuário -
PATCH /users/:id/role— alterar role (apenas ADMIN) -
PATCH /auth/change-password— troca de senha
-
GET /dashboard— métricas gerais da clínica- Total de pacientes ativos
- Agendamentos do dia
- Receita do mês
- Produtos em estoque crítico
-
GET /reports/appointments— relatório de agendamentos por período -
GET /reports/revenue— relatório financeiro consolidado
- CRUD de tenants (rota protegida por role
SUPER_ADMIN) - Gestão de planos (
STANDARD,PREMIUM,ENTERPRISE) - Endpoint de ativação/desativação de tenant
-
auth.service.test.ts— register, login, getMe -
patient.service.test.ts— CRUD, validação CPF duplicado -
appointment.service.test.ts— conflito de horário/sala -
AppError.test.ts— statusCode e instanceof
-
auth.routes.test.ts— POST /register, POST /login, GET /me -
patient.routes.test.ts— CRUD completo com JWT -
appointment.routes.test.ts
- Instalar
vitestoujest+supertest - Banco de dados de teste isolado (schema separado ou SQLite)
- Factories de dados com
@faker-js/faker - Coverage mínimo de 70%
- Swagger/OpenAPI com
swagger-jsdoc+swagger-ui-express(já instalado) -
GET /docs— UI interativa da API - Documentar todos os endpoints com exemplos de request/response
- README.md com instruções de setup, variáveis de ambiente e scripts
- CONTRIBUTING.md — guia de contribuição e padrões do projeto
[FEAT] Módulo Appointments — CRUD + validação de conflito
[FEAT] Módulo Transactions — financeiro com criação automática
[FEAT] Validação de inputs com Zod em todos os módulos
[FEAT] Módulo Products — estoque com alertas
[FEAT] Módulo Suppliers — fornecedores
[FEAT] Módulo Users — gestão de usuários por clínica
[FEAT] Módulo Clinics — gestão de filiais por tenant
[FEAT] Dashboard endpoint com métricas consolidadas
[FEAT] Relatórios financeiros por período
[TEST] Setup vitest + supertest
[TEST] Testes unitários — Auth Service
[TEST] Testes unitários — Patient Service
[TEST] Testes de integração — rotas Auth
[DOCS] Swagger — documentação completa da API
[DOCS] README.md com setup completo
[INFRA] Pipeline CI/CD com GitHub Actions
[INFRA] Dockerfile para produção
[INFRA] Rate limiting com express-rate-limit
[INFRA] Helmet.js para segurança de headers
[INFRA] Logger estruturado com pino ou winston
-
Isolamento por banco — campo
databaseUrlnoTenantjá previsto no schema para clientes Enterprise com banco dedicado - Multi-clínica por usuário — permitir que um dentista atenda em múltiplas filiais do mesmo tenant
- Notificações — lembretes de consulta via WhatsApp/SMS (integração Twilio ou Z-API)
- Prontuário digital — upload de radiografias e documentos por paciente
- Agenda visual — endpoint otimizado para renderizar calendário semanal por sala/dentista
-
Plano de assinatura — limitar features por
TenantPlan(ex: STANDARD sem relatórios avançados) - Auditoria — log de todas as ações por usuário (quem criou, editou, deletou)
- App mobile — consumir a mesma API com React Native
backend/
├── prisma/
│ ├── schema.prisma
│ └── migrations/
├── prisma.config.ts
├── tsconfig.json
├── docker-compose.yml
├── .env
└── src/
├── server.ts
├── controllers/
│ ├── auth.controller.ts
│ └── patient.controller.ts
├── services/
│ ├── auth.service.ts
│ └── patient.service.ts
├── routes/
│ ├── index.ts
│ ├── auth.routes.ts
│ └── patient.routes.ts
├── middlewares/
│ ├── auth.middleware.ts
│ └── errorHandler.middleware.ts
├── types/
│ ├── auth.types.ts
│ └── patient.types.ts
├── shared/
│ └── AppError.ts
├── lib/
│ └── prisma.ts
├── docs/
└── __tests__/