🔗 Relacionamentos ORM - Saúde Livre
Documentação completa dos relacionamentos entre modelos do banco de dados, seguindo convenções de ORMs populares (Laravel Eloquent, Sequelize, TypeORM).
📋 Índice
🎯 Visão Geral
Este documento descreve todos os relacionamentos entre as entidades do sistema Saúde Livre, utilizando a nomenclatura padrão de ORMs:
- hasOne / belongsTo - Relacionamento 1:1
- hasMany / belongsTo - Relacionamento 1:N
- belongsToMany - Relacionamento N:N
- Polimórficos - Relacionamentos que podem apontar para múltiplos modelos
📦 Módulos
1. USERS (Usuários)
javascript
class User {
// Relacionamentos 1:1
hasOne(Company) // Usuário CNPJ tem uma empresa
hasOne(HealthCredit) // Usuário possui um crédito saúde
hasOne(SavingsAccount) // Usuário possui uma conta poupança saúde
// Relacionamentos 1:N
hasMany(Dependent) // Usuário tem múltiplos dependentes
hasMany(UserAddress) // Usuário tem múltiplos endereços
hasMany(Appointment) // Usuário faz múltiplos agendamentos
hasMany(Transaction) // Usuário realiza múltiplas transações
hasMany(Insurance) // Usuário possui múltiplos seguros
hasMany(Cashback) // Usuário recebe múltiplos cashbacks
hasMany(MedicalDocument) // Usuário possui múltiplos documentos médicos
hasMany(Vaccine) // Usuário possui múltiplas vacinas
hasMany(Notification) // Usuário recebe múltiplas notificações
hasMany(Review) // Usuário escreve múltiplas avaliações
hasMany(PixKey) // Usuário possui múltiplas chaves PIX
hasMany(MedicationReminder) // Usuário possui múltiplos lembretes
}Campos principais:
id(UUID, PK)type(ENUM: 'CPF', 'CNPJ')cpf_cnpj(STRING, UNIQUE)email,phone(UNIQUE)password_hashactive,email_verified,phone_verified
2. COMPANY (Empresas)
javascript
class Company {
// Relacionamentos
belongsTo(User) // Empresa pertence a um usuário (1:1)
}Campos principais:
id(UUID, PK)user_id(FK)cnpj(UNIQUE)legal_name,trade_nameemployees_count
3. DEPENDENT (Dependentes)
javascript
class Dependent {
// Relacionamentos
belongsTo(User) // Dependente pertence a um usuário
hasMany(Appointment) // Dependente participa de múltiplos agendamentos
hasMany(MedicalDocument) // Dependente possui múltiplos documentos
hasMany(Vaccine) // Dependente recebe múltiplas vacinas
}Campos principais:
id(UUID, PK)user_id(FK)cpf(UNIQUE)relationship(ENUM: 'filho', 'filha', 'pai', 'mae', 'conjuge', 'pet')birth_date
4. PROVIDER (Rede Credenciada)
javascript
class Provider {
// Relacionamentos 1:N
hasMany(Professional) // Provider emprega múltiplos profissionais
hasMany(Service) // Provider oferece múltiplos serviços
hasMany(Appointment) // Provider recebe múltiplos agendamentos
hasMany(Review) // Provider recebe múltiplas avaliações
hasMany(PixKey) // Provider possui múltiplas chaves PIX
hasMany(Vaccine) // Provider aplica múltiplas vacinas
// Relacionamentos 1:1
hasOne(FinancialSettings) // Provider possui configurações financeiras
}Campos principais:
id(UUID, PK)type(ENUM: 'clinica', 'hospital', 'laboratorio', etc.)cnpj(UNIQUE)coordinates(JSON: {lat, lng})business_hours(JSON)rating,reviews_countverified
5. PROFESSIONAL (Profissionais)
javascript
class Professional {
// Relacionamentos
belongsTo(Provider) // Profissional trabalha para um provider
hasMany(Appointment) // Profissional atende múltiplos agendamentos
hasMany(Review) // Profissional recebe múltiplas avaliações
hasMany(Prescription) // Profissional prescreve múltiplas receitas
hasMany(Vaccine) // Profissional aplica múltiplas vacinas
}Campos principais:
id(UUID, PK)provider_id(FK)cpf(UNIQUE)specialtycouncil_number(CRM, CRO, etc.)availability(JSON)rating,reviews_count
6. SERVICE (Serviços)
javascript
class Service {
// Relacionamentos
belongsTo(Provider) // Serviço pertence a um provider
hasMany(Appointment) // Serviço é agendado em múltiplos appointments
}Campos principais:
id(UUID, PK)provider_id(FK)name,categoryprice_table,price_platformduration_minutes
7. APPOINTMENT (Agendamentos)
javascript
class Appointment {
// Relacionamentos N:1
belongsTo(User) // Agendamento pertence a um usuário (obrigatório)
belongsTo(Dependent) // Agendamento pode ser para um dependente (opcional)
belongsTo(Provider) // Agendamento pertence a um provider
belongsTo(Professional) // Agendamento com um profissional
belongsTo(Service) // Agendamento de um serviço
// Relacionamentos 1:1
hasOne(Teleconsultation) // Agendamento pode ter uma teleconsulta
hasOne(Transaction) // Agendamento gera uma transação
hasOne(Review) // Agendamento pode receber uma avaliação
hasOne(InsuranceClaim) // Agendamento pode gerar insurance claim
// Relacionamentos 1:N
hasMany(AppointmentDocument) // Agendamento gera múltiplos documentos
hasMany(AppointmentHistory) // Agendamento tem histórico de mudanças
}Campos principais:
id(UUID, PK)user_id,dependent_id(nullable)provider_id,professional_id,service_idappointment_date,appointment_timestatus(ENUM: 'pending', 'confirmed', 'in_progress', 'completed', 'cancelled')format(ENUM: 'presencial', 'tele_atendimento')
8. TRANSACTION (Financeiro)
javascript
class Transaction {
// Relacionamentos N:1
belongsTo(User) // Transação pertence a um usuário
belongsTo(Appointment) // Transação pode ser de um agendamento
// Relacionamentos 1:N
hasMany(PaymentSplit) // Transação divide em múltiplos splits
// Relacionamentos 1:1
hasOne(Cashback) // Transação pode gerar cashback
hasOne(HealthCreditTransaction) // Transação pode usar crédito saúde
}Campos principais:
id(UUID, PK)user_id,appointment_id(nullable)type(ENUM: 'payment', 'refund', 'credit', 'debit')amount,platform_fee,net_amountstatus(ENUM: 'pending', 'processing', 'completed', 'failed', 'refunded')payment_method(ENUM: 'pix', 'credit_card', 'debit_card', etc.)external_id(ID no gateway)
9. PAYMENT_SPLIT (Divisão de Pagamentos)
javascript
class PaymentSplit {
// Relacionamentos
belongsTo(Transaction) // Split pertence a uma transação
// Polimórfico
// recipient pode ser Provider ou Professional
}Campos principais:
id(UUID, PK)transaction_id(FK)recipient_id(FK - polimórfico)recipient_type(ENUM: 'provider', 'professional', 'platform')amount,percentagestatus(ENUM: 'pending', 'transferred', 'completed')
10. HEALTH_CREDIT (Crédito Saúde)
javascript
class HealthCredit {
// Relacionamentos
belongsTo(User) // Crédito saúde pertence a um usuário
hasMany(HealthCreditTransaction) // Crédito tem múltiplas transações
}Campos principais:
id(UUID, PK)user_id(FK)balance,credit_limit,available_limitinterest_ratestatus(ENUM: 'active', 'blocked', 'suspended')
11. MEDICAL_DOCUMENT (Documentos Médicos)
javascript
class MedicalDocument {
// Relacionamentos N:1
belongsTo(User) // Documento pertence a um usuário
belongsTo(Dependent) // Documento pode ser de um dependente
belongsTo(Appointment) // Documento pode ser de um agendamento
// Relacionamentos 1:1
hasOne(Prescription) // Documento pode ser uma prescrição
}Campos principais:
id(UUID, PK)user_id,dependent_id(nullable),appointment_id(nullable)type(ENUM: 'exam', 'prescription', 'vaccine', 'report', 'other')file_url,file_name,file_sizedocument_date
12. PRESCRIPTION (Receitas)
javascript
class Prescription {
// Relacionamentos
belongsTo(MedicalDocument) // Prescrição é um documento médico
belongsTo(Professional) // Prescrição feita por um profissional
belongsTo(User) // Prescrição para um usuário
hasMany(MedicationReminder) // Prescrição gera múltiplos lembretes
}Campos principais:
id(UUID, PK)medical_document_id(FK)professional_id(FK)medications(JSON array)valid_untilactive
13. VACCINE (Vacinas)
javascript
class Vaccine {
// Relacionamentos
belongsTo(User) // Vacina pertence a um usuário
belongsTo(Dependent) // Vacina pode ser de um dependente
belongsTo(Provider) // Vacina aplicada em um provider
belongsTo(Professional) // Vacina aplicada por um profissional
}Campos principais:
id(UUID, PK)user_id,dependent_id(nullable)provider_id,professional_idvaccine_name,batch_numberapplication_date,next_dose_date
14. NOTIFICATION (Notificações)
javascript
class Notification {
// Relacionamentos
belongsTo(User) // Notificação pertence a um usuário
}Campos principais:
id(UUID, PK)user_id(FK)type(ENUM: 'appointment', 'payment', 'reminder', 'alert', 'promotion')channel(ENUM: 'push', 'email', 'sms', 'whatsapp')status(ENUM: 'pending', 'sent', 'delivered', 'read', 'failed')
15. REVIEW (Avaliações)
javascript
class Review {
// Relacionamentos
belongsTo(User) // Avaliação feita por um usuário
belongsTo(Provider) // Avaliação de um provider (nullable)
belongsTo(Professional) // Avaliação de um profissional (nullable)
belongsTo(Appointment) // Avaliação de um agendamento
}Campos principais:
id(UUID, PK)user_id(FK)provider_id,professional_id(nullable)appointment_id(FK)rating(INTEGER: 1-5)comment,tags(JSON)verified
🔗 Tipos de Relacionamentos
Relacionamentos 1:1 (hasOne / belongsTo)
User↔CompanyUser↔HealthCreditUser↔SavingsAccountAppointment↔TeleconsultationAppointment↔TransactionAppointment↔ReviewAppointment↔InsuranceClaimProvider↔FinancialSettingsMedicalDocument↔Prescription
Relacionamentos 1:N (hasMany / belongsTo)
User→DependentsUser→UserAddressesUser→AppointmentsUser→TransactionsUser→InsurancesUser→CashbacksUser→MedicalDocumentsUser→VaccinesUser→NotificationsUser→ReviewsUser→PixKeysProvider→ProfessionalsProvider→ServicesProvider→AppointmentsProfessional→AppointmentsProfessional→PrescriptionsService→AppointmentsAppointment→AppointmentDocumentsAppointment→AppointmentHistoryTransaction→PaymentSplitsHealthCredit→HealthCreditTransactionsInsurance→InsuranceClaimsSavingsAccount→SavingsTransactionsPrescription→MedicationReminders
Relacionamentos Polimórficos
PixKey
ownerpode serUserouProvider- Campo:
owner_type(ENUM: 'user', 'provider')
TeleconsultationMessage
senderpode serUserouProfessional- Campo:
sender_type(ENUM: 'user', 'professional')
PaymentSplit
recipientpode serProvider,ProfessionalouPlatform- Campo:
recipient_type(ENUM: 'provider', 'professional', 'platform')
Relacionamentos N:N (belongsToMany)
Atualmente não há relacionamentos N:N no modelo. Possíveis implementações futuras:
User↔Services(favoritos)User↔Providers(favoritos)User↔Professionals(favoritos)
📊 Resumo
Total de Modelos: 30+
Relacionamentos por Tipo:
- 1:1: 9 relacionamentos
- 1:N: 25+ relacionamentos
- Polimórficos: 3 relacionamentos
- N:N: 0 (podem ser implementados no futuro)
Ações de Delete (onDelete):
- CASCADE: Remove registros relacionados automaticamente
- RESTRICT: Impede deleção se houver registros relacionados
- SET NULL: Define FK como NULL ao deletar
Convenções de Nomenclatura:
- Foreign Keys:
{model}_id(ex:user_id,provider_id) - Relacionamentos: camelCase (ex:
appointments,medicalDocuments) - Polimórficos:
{model}_type+{model}_id(ex:owner_type,owner_id)
💡 Notas de Implementação
Laravel Eloquent
php
// Exemplo: User model
public function appointments()
{
return $this->hasMany(Appointment::class);
}
public function healthCredit()
{
return $this->hasOne(HealthCredit::class);
}Sequelize
javascript
// Exemplo: User model
User.hasMany(Appointment, { foreignKey: 'user_id' });
User.hasOne(HealthCredit, { foreignKey: 'user_id' });TypeORM
typescript
// Exemplo: User entity
@OneToMany(() => Appointment, appointment => appointment.user)
appointments: Appointment[];
@OneToOne(() => HealthCredit, healthCredit => healthCredit.user)
healthCredit: HealthCredit;Última atualização: 2025-01-26