Backend - Modelos de Dados¶
Este documento descreve todos os modelos de dados do sistema Billings Ease, incluindo campos, relacionamentos, constraints e exemplos de uso.
Índice¶
- Modelos de Usuário e Autenticação
- Modelos do Método Billings
- Modelos de Perfis
- Modelos de Comunicação
- Modelos Financeiros
- Modelos de Configuração
- Tipos Auxiliares
Atualização importante¶
O domínio de cursos foi expandido e refatorado (bundles, recomendações, reviews, materiais de aula, revenue split e contrato monetário em centavos).
Ver documentação dedicada:
Modelos de Usuário e Autenticação¶
User¶
Modelo principal de usuário do sistema. Representa todos os tipos de usuários (client, professional, admin).
Localização: internal/models/user.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
CreatedAt |
time.Time |
Data de criação | Automático |
UpdatedAt |
time.Time |
Data de atualização | Automático |
DeletedAt |
gorm.DeletedAt |
Soft delete | Index |
Username |
*string |
Nome de usuário (opcional) | Index, pode ser NULL |
Email |
string |
Email (usado para login) | Unique, Not Null |
Password |
string |
Hash da senha (bcrypt) | Not Null, não retornado em JSON |
Name |
string |
Nome completo | Not Null |
UserType |
UserType |
Tipo de usuário | Not Null |
IsActive |
bool |
Se está ativo | Default: true |
EmailVerified |
bool |
Se email foi verificado | Default: false |
EmailVerifiedAt |
*time.Time |
Data de verificação | Opcional |
Tipos de Usuário (UserType):
- client - Cliente (paciente)
- professional - Profissional de saúde
- admin - Administrador
Relacionamentos:
- Accounts - Contas financeiras (1:N)
- Subscriptions - Assinaturas (1:N)
- Cycles - Ciclos menstruais (1:N)
- Observations - Observações diárias (1:N)
- SyncLogs - Logs de sincronização (1:N)
Exemplo de uso:
user := models.User{
Email: "user@example.com",
Password: hashedPassword,
Name: "Maria Silva",
UserType: models.UserTypeClient,
IsActive: true,
}
UserAuthProvider¶
Representa uma identidade externa (OAuth) associada a um usuário. Permite que um usuário tenha múltiplas identidades externas (Google, Apple, etc.).
Localização: internal/models/user_auth_provider.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
UserID |
uint |
Referência ao usuário | Not Null, Index |
Provider |
AuthProvider |
Provedor OAuth | Not Null, Index |
ProviderUserID |
string |
ID do usuário no provedor | Not Null |
Email |
*string |
Email (apenas informativo) | Opcional |
Provedores Suportados (AuthProvider):
- google - Google OAuth
- apple - Apple Sign In
Relacionamentos:
- User - Usuário associado (N:1)
Nota Importante: O ProviderUserID é o identificador único do provedor (sub do token OIDC) e é usado para autenticação. O email é apenas informativo e nunca deve ser usado como identidade.
EmailVerification¶
Token de verificação de email para novos usuários.
Localização: internal/models/email_verification.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
Token |
string |
Token único | Unique, Not Null |
UserID |
uint |
Usuário a verificar | Not Null, Index |
ExpiresAt |
time.Time |
Data de expiração | Not Null |
Used |
bool |
Se foi usado | Default: false |
UsedAt |
*time.Time |
Data de uso | Opcional |
LastResendAt |
*time.Time |
Último reenvio | Index |
Relacionamentos:
- User - Usuário associado (N:1)
PasswordReset¶
Token para recuperação de senha.
Localização: internal/models/password_reset.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
Token |
string |
Token único | Unique, Not Null |
UserID |
uint |
Usuário | Not Null, Index |
ExpiresAt |
time.Time |
Data de expiração | Not Null |
Used |
bool |
Se foi usado | Default: false |
UsedAt |
*time.Time |
Data de uso | Opcional |
Relacionamentos:
- User - Usuário associado (N:1)
Modelos do Método Billings¶
Cycle¶
Representa um ciclo menstrual completo, desde o primeiro dia de sangramento até o dia anterior ao próximo sangramento.
Localização: internal/models/cycle.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
UserID |
uint |
Usuária dona do ciclo | Not Null, Index |
StartDate |
Date |
Primeiro dia de sangramento | Not Null |
EndDate |
*Date |
Último dia do ciclo | Opcional |
Length |
int |
Duração em dias | Calculado |
IsActive |
bool |
Se está ativo | Default: true |
LastSyncedAt |
*time.Time |
Última sincronização | Opcional |
SyncID |
string |
ID para sincronização mobile | Index |
Regras de Negócio: - Apenas um ciclo ativo por usuária - Ciclo começa no primeiro dia de sangramento - Ciclo termina quando novo sangramento é registrado
Relacionamentos:
- User - Usuária dona do ciclo (N:1)
- Observations - Observações do ciclo (1:N)
Exemplo:
cycle := models.Cycle{
UserID: 1,
StartDate: models.NewDate(time.Now()),
IsActive: true,
}
Observation¶
Registro diário dos sinais de fertilidade. Apenas uma observação por dia por usuária.
Localização: internal/models/observation.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
UserID |
uint |
Usuária | Not Null, Index |
CycleID |
*uint |
Ciclo associado | Index, Opcional |
Date |
Date |
Data da observação | Not Null |
Type |
ObservationType |
Tipo de observação | Not Null |
Description |
string |
Descrição | Opcional |
Sensation |
string |
Sensação física | Opcional |
Temperature |
*float64 |
Temperatura basal | Opcional |
Notes |
string |
Notas pessoais | Opcional |
ProfessionalNotes |
string |
Notas do profissional | Opcional |
MoodChanges |
bool |
Mudanças de humor | Default: false |
Cramps |
bool |
Cólicas | Default: false |
BreastPain |
bool |
Dor nos seios | Default: false |
HadIntercourse |
bool |
Teve relação sexual | Default: false |
IsFirstDayOfMenstruation |
bool |
Primeiro dia da menstruação | Default: false |
MucusType |
string |
Tipo de muco | Opcional |
SymbolID |
*uint |
Símbolo escolhido | Index, Opcional |
AppearanceID |
*uint |
Aparência observada | Index, Opcional |
LastSyncedAt |
*time.Time |
Última sincronização | Opcional |
SyncID |
string |
ID para sincronização | Index |
Tipos de Observação (ObservationType):
- dry - Seca
- sticky - Pegajosa
- creamy - Cremosa
- watery - Aquosa
- egg_white - Clara de ovo
- bleeding - Sangramento
Relacionamentos:
- User - Usuária (N:1)
- Cycle - Ciclo associado (N:1, opcional)
- Symbol - Símbolo escolhido (N:1, opcional)
- Appearance - Aparência observada (N:1, opcional)
Regras: - Apenas uma observação por dia por usuária - Deve existir ciclo ativo (exceto em casos especiais)
Symbol¶
Símbolo do Método Billings. Representa diferentes estados do muco cervical.
Localização: internal/models/symbol.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
Name |
string |
Nome único do símbolo | Unique, Not Null |
Description |
string |
Descrição | Opcional |
ImagePath |
string |
Caminho da imagem | Not Null |
RelationImagePath |
*string |
Imagem para relação sexual | Opcional |
Exemplos de Símbolos:
- seca - Período seco
- fertilidade - Período fértil
- fertilidade apice - Ápice de fertilidade
- fluxo - Fluxo
- sangramento sem mancha - Sangramento
- sangramento com mancha - Sangramento com mancha
Relacionamentos:
- Observations - Observações que usam este símbolo (1:N, via Observation.SymbolID)
Nota: A tabela no banco é nomeada symbol (singular).
Sensation¶
Sensação física percebida no muco cervical.
Localização: internal/models/sensation.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
Name |
string |
Nome único | Unique, Not Null |
DisplayName |
string |
Nome para exibição | Not Null |
Description |
string |
Descrição detalhada | Opcional |
IsActive |
bool |
Se está ativa | Default: true |
Order |
int |
Ordem de exibição | Default: 0 |
Exemplos:
- seca - Seca
- pegajosa - Pegajosa
- úmida - Úmida
- lubrificante - Lubrificante
Appearance¶
Aparência visual do muco cervical.
Localização: internal/models/appearance.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
Name |
string |
Nome único | Unique, Not Null |
DisplayName |
string |
Nome para exibição | Not Null |
Description |
string |
Descrição | Opcional |
IsActive |
bool |
Se está ativa | Default: true |
Order |
int |
Ordem de exibição | Default: 0 |
Exemplos:
- ausente - Ausente
- clara - Clara
- opaca - Opaca
- espessa - Espessa
- transparente - Transparente
DayBasedRule¶
Regra baseada em dias do ciclo que define quais símbolos são permitidos ou restritos em determinados períodos.
Localização: internal/models/day_based_rule.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
Name |
string |
Nome da regra | Not Null |
Description |
string |
Descrição | Opcional |
MinDay |
int |
Dia mínimo (inclusive) | Not Null |
MaxDay |
int |
Dia máximo (inclusive) | Not Null |
AllowedSymbolIDs |
UIntArray |
IDs de símbolos permitidos | JSONB |
RestrictedSymbolIDs |
UIntArray |
IDs de símbolos restritos | JSONB |
IsActive |
bool |
Se está ativa | Default: true |
Order |
int |
Ordem de aplicação | Default: 0 |
Exemplo:
rule := models.DayBasedRule{
Name: "Primeiros 15 dias",
MinDay: 1,
MaxDay: 15,
AllowedSymbolIDs: models.UIntArray{1, 2, 3}, // IDs de símbolos permitidos
IsActive: true,
}
CycleComment¶
Comentário de um profissional sobre um ciclo de uma paciente.
Localização: internal/models/cycle_comment.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
CycleID |
uint |
Ciclo comentado | Not Null, Index |
ProfessionalID |
uint |
Profissional que comentou | Not Null, Index |
Content |
string |
Conteúdo do comentário | Not Null |
Relacionamentos:
- Cycle - Ciclo comentado (N:1)
- Professional - Profissional que comentou (N:1)
Regras: - Apenas profissionais podem comentar - Profissional deve estar vinculado à paciente do ciclo
Modelos de Perfis¶
ClientProfile¶
Perfil detalhado de cliente (paciente). Relacionamento 1:1 com User.
Localização: internal/models/client_profile.go
Campos:
Informações Pessoais:
- FullName - Nome completo
- Phone - Telefone
- CellPhone - Celular
- BirthDate - Data de nascimento
- ProfilePhotoKey - Chave da foto no R2
- ProfilePhotoURL - URL completa (calculada, não salva)
- CPF - CPF
- Address - Endereço
Informações de Saúde Menstrual:
- FirstMenstruationDate - Data da menarca
- AverageCycleLength - Duração média do ciclo (dias)
- AveragePeriodLength - Duração média da menstruação (dias)
- LastMenstruationDate - Última menstruação
- HealthNotes - Observações sobre saúde menstrual
Informações Adicionais:
- Objective - Objetivo (engravidar, espaçar, conhecimento)
- IsBreastfeeding - Se está amamentando
- FamilyPlanningHistory - Histórico de métodos (JSON)
- WomanPattern - Padrão Básico de Infertilidade (PBI)
- PBISensationID - ID da sensação do PBI
- PBIAppearanceID - ID da aparência do PBI
Relacionamentos:
- User - Usuário associado (1:1, via UserID)
Constraints:
- UserID é único (garante 1:1)
ProfessionalProfile¶
Perfil detalhado de profissional. Relacionamento 1:1 com User.
Localização: internal/models/professional_profile.go
Campos:
Informações Básicas:
- FullName - Nome completo
- Phone - Telefone
- CellPhone - Celular
- Email - Email
- BirthDate - Data de nascimento
- ProfilePhotoKey - Chave da foto no R2
- ProfilePhotoURL - URL completa (calculada)
- CPFOrCNPJ - CPF ou CNPJ
Informações Profissionais:
- MethodType - Tipo de método que trabalha
- Biography - Biografia ("Quem sou eu")
- Rating - Média de avaliações (1-5)
- RatingCount - Quantidade de avaliações
Documentos:
- ProfessionalCertificateKey - Chave do certificado no R2
- ProfessionalCertificateURL - URL do certificado
- DocumentType - Tipo de documento (CNH, RG, CPF)
- DocumentKey - Chave do documento no R2
- DocumentURL - URL do documento
Status de Aprovação:
- Status - Status (pending, approved, rejected)
- RejectionReason - Motivo da reprovação
- ApprovedBy - ID do admin que aprovou
- ApprovedAt - Data de aprovação
Status Possíveis (ProfileStatus):
- pending - Aguardando aprovação
- approved - Aprovado
- rejected - Rejeitado
Relacionamentos:
- User - Usuário associado (1:1, via UserID)
Constraints:
- UserID é único (garante 1:1)
ProfessionalPatient¶
Relacionamento entre profissional e paciente. N:1 (um profissional pode ter vários pacientes, mas um paciente só pode estar com um profissional).
Localização: internal/models/professional_patient.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
ProfessionalID |
uint |
ID do profissional | Not Null, Index |
PatientID |
uint |
ID do paciente | Not Null, Unique Index |
Status |
LinkStatus |
Status do vínculo | Not Null, Default: pending |
Status Possíveis (LinkStatus):
- pending - Aguardando aprovação da orientadora
- approved - Aprovado pela orientadora
- rejected - Rejeitado pela orientadora
Relacionamentos:
- Professional - Profissional (N:1)
- Patient - Paciente (N:1)
Constraints:
- PatientID é único (garante que um paciente só pode estar com um profissional)
Modelos de Comunicação¶
Message¶
Mensagem entre usuários (cliente ↔ profissional).
Localização: internal/models/message.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
SenderID |
uint |
Remetente | Not Null, Index |
ReceiverID |
uint |
Destinatário | Not Null, Index |
Content |
string |
Conteúdo da mensagem | Not Null |
AttachmentURL |
string |
URL de anexo | Opcional |
IsRead |
bool |
Se foi lida | Default: false |
ReadAt |
*time.Time |
Data de leitura | Opcional |
Relacionamentos:
- Sender - Remetente (N:1)
- Receiver - Destinatário (N:1)
Regras: - Cliente só pode enviar para profissional vinculado - Profissional só pode enviar para pacientes vinculados - Admin pode enviar para qualquer um
Appointment¶
Agendamento entre profissional e paciente.
Localização: internal/models/appointment.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
ProfessionalID |
uint |
Profissional | Not Null, Index |
PatientID |
uint |
Paciente | Not Null, Index |
ScheduledAt |
time.Time |
Data/hora agendada | Not Null |
Duration |
int |
Duração em minutos | Default: 60 |
Status |
AppointmentStatus |
Status do agendamento | Default: pending_confirmation |
VideoCallURL |
string |
URL da videochamada | Opcional |
MeetingID |
string |
ID da reunião | Opcional |
Notes |
string |
Notas | Opcional |
RejectionReason |
string |
Motivo da rejeição | Opcional |
Status Possíveis (AppointmentStatus):
- pending_confirmation - Aguardando confirmação
- scheduled - Agendado
- completed - Concluído
- cancelled - Cancelado
- rejected - Rejeitado
Relacionamentos:
- Professional - Profissional (N:1)
- Patient - Paciente (N:1)
Notification¶
Notificação do sistema para usuários.
Localização: internal/models/notification.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
UserID |
uint |
Usuário destinatário | Not Null, Index |
Type |
NotificationType |
Tipo de notificação | Not Null |
Title |
string |
Título | Not Null |
Message |
string |
Mensagem | Not Null |
IsRead |
bool |
Se foi lida | Default: false |
ReadAt |
*time.Time |
Data de leitura | Opcional |
Metadata |
NotificationMetadata |
Metadados (JSONB) | Opcional |
ReferenceType |
string |
Tipo de referência | Opcional |
ReferenceID |
*uint |
ID da referência | Opcional |
Tipos de Notificação (NotificationType):
- message - Nova mensagem
- appointment - Agendamento
- task - Tarefa
- reminder - Lembrete
- system - Sistema
Metadata:
O campo Metadata é um JSONB que pode armazenar dados adicionais específicos do tipo de notificação.
Relacionamentos:
- User - Usuário destinatário (N:1)
Modelos Financeiros¶
Plan¶
Plano de assinatura disponível.
Localização: internal/models/plan.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
Name |
string |
Nome do plano | Not Null |
Description |
string |
Descrição | Opcional |
Status |
PlanStatus |
Status do plano | Default: active |
CanUseApp |
bool |
Pode usar app | Default: false |
CanUseWeb |
bool |
Pode usar web | Default: false |
CanAccessReports |
bool |
Pode acessar relatórios | Default: false |
CanAccessAPI |
bool |
Pode acessar API | Default: false |
PriceMonthly |
float64 |
Preço mensal | Not Null |
PriceSixMonths |
float64 |
Preço semestral | Not Null |
PriceYearly |
float64 |
Preço anual | Not Null |
Status Possíveis (PlanStatus):
- active - Ativo
- inactive - Inativo
Relacionamentos:
- Subscriptions - Assinaturas deste plano (1:N)
Subscription¶
Assinatura de um usuário a um plano.
Localização: internal/models/subscription.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
UserID |
uint |
Usuário | Not Null, Index |
PlanID |
*uint |
Plano associado | Index, Opcional |
Name |
string |
Nome da assinatura | Not Null |
Description |
string |
Descrição | Opcional |
Amount |
float64 |
Valor | Not Null |
Status |
SubscriptionStatus |
Status | Default: active |
StartDate |
Date |
Data de início | Not Null |
EndDate |
*Date |
Data de término | Opcional |
BillingCycle |
string |
Ciclo de cobrança | Opcional |
PaymentGatewayID |
string |
ID no gateway | Opcional |
Status Possíveis (SubscriptionStatus):
- active - Ativa
- inactive - Inativa
- cancelled - Cancelada
Relacionamentos:
- User - Usuário (N:1)
- Plan - Plano associado (N:1, opcional)
Ciclos de Cobrança:
- monthly - Mensal
- six_months - Semestral
- yearly - Anual
Payment¶
Pagamento de uma assinatura ou transação.
Localização: internal/models/payment.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
UserID |
uint |
Usuário | Not Null, Index |
SubscriptionID |
*uint |
Assinatura associada | Index, Opcional |
Amount |
float64 |
Valor | Not Null |
Status |
PaymentStatus |
Status | Default: pending |
PaymentDate |
*Date |
Data do pagamento | Opcional |
GatewayProvider |
string |
Provedor do gateway | Opcional |
GatewayID |
string |
ID no gateway | Index, Opcional |
GatewayResponse |
string |
Resposta do gateway | Opcional |
Status Possíveis (PaymentStatus):
- pending - Pendente
- completed - Concluído
- failed - Falhou
- cancelled - Cancelado
Relacionamentos:
- User - Usuário (N:1)
- Subscription - Assinatura associada (N:1, opcional)
Account¶
Conta financeira genérica (não relacionada a assinaturas).
Localização: internal/models/account.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
UserID |
uint |
Usuário | Not Null, Index |
Name |
string |
Nome da conta | Not Null |
Description |
string |
Descrição | Opcional |
Amount |
float64 |
Valor | Not Null |
DueDate |
Date |
Data de vencimento | Not Null |
IsPaid |
bool |
Se foi pago | Default: false |
LastSyncedAt |
*time.Time |
Última sincronização | Opcional |
SyncID |
string |
ID para sincronização | Index |
Relacionamentos:
- User - Usuário (N:1)
ProfessionalBankAccount¶
Conta bancária de um profissional para recebimento de pagamentos.
Localização: internal/models/professional_bank_account.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
ProfessionalID |
uint |
Profissional | Not Null, Unique Index |
BankName |
string |
Nome do banco | Not Null |
AccountType |
AccountType |
Tipo de conta | Not Null |
Agency |
string |
Agência | Not Null |
AccountNumber |
string |
Número da conta | Not Null |
CPFOrCNPJ |
string |
CPF ou CNPJ | Not Null |
Tipos de Conta (AccountType):
- checking - Conta Corrente
- savings - Conta Poupança
Relacionamentos:
- Professional - Profissional (1:1, via ProfessionalID)
Constraints:
- ProfessionalID é único (garante uma conta por profissional)
Modelos de Configuração¶
Settings¶
Configurações globais do sistema.
Localização: internal/models/settings.go
Campos: - Apenas campos padrão (ID, CreatedAt, UpdatedAt, DeletedAt)
Nota: Este modelo é uma estrutura base para configurações futuras. A tabela no banco é nomeada settings.
WorkSchedule¶
Horário de trabalho de um profissional.
Localização: internal/models/work_schedule.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
ProfessionalID |
uint |
Profissional | Not Null, Unique Index |
DaysOfWeek |
string |
Dias da semana (JSON array) | Opcional |
StartTime |
string |
Horário de início (HH:MM) | Not Null |
EndTime |
string |
Horário de fim (HH:MM) | Not Null |
AppointmentDuration |
int |
Duração da consulta (minutos) | Default: 60 |
LunchStartTime |
string |
Início do almoço (HH:MM) | Opcional |
LunchEndTime |
string |
Fim do almoço (HH:MM) | Opcional |
Relacionamentos:
- Professional - Profissional (1:1, via ProfessionalID)
Constraints:
- ProfessionalID é único (garante um horário por profissional)
Formato de DaysOfWeek:
JSON array de números: [1,2,3,4,5] (0=Domingo, 1=Segunda, ..., 6=Sábado)
AvailabilitySlot¶
Slot de disponibilidade específico de um profissional.
Localização: internal/models/availability.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
ProfessionalID |
uint |
Profissional | Not Null, Index |
Date |
Date |
Data do slot | Not Null |
StartTime |
string |
Horário de início (HH:MM) | Not Null |
EndTime |
string |
Horário de fim (HH:MM) | Not Null |
IsAvailable |
bool |
Se está disponível | Default: true |
Relacionamentos:
- Professional - Profissional (N:1)
Uso: Usado para definir horários específicos disponíveis além do horário de trabalho padrão.
Course¶
Curso educativo disponível na plataforma.
Localização: internal/models/course.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
Title |
string |
Título | Not Null |
Description |
string |
Descrição | Opcional |
VideoURL |
string |
URL do vídeo | Not Null |
ThumbnailURL |
string |
URL da thumbnail | Opcional |
Duration |
int |
Duração em minutos | Opcional |
Order |
int |
Ordem de exibição | Default: 0 |
SyncLog¶
Log de sincronização entre mobile e backend.
Localização: internal/models/sync.go
Campos:
| Campo | Tipo | Descrição | Constraints |
|---|---|---|---|
ID |
uint |
Identificador único | Primary Key |
UserID |
uint |
Usuário | Not Null, Index |
DeviceID |
string |
ID do dispositivo | Not Null, Index |
SyncType |
string |
Tipo (push, pull) | Opcional |
Status |
string |
Status (success, error) | Opcional |
RecordsCount |
int |
Quantidade de registros | Opcional |
Error |
string |
Erro (se houver) | Opcional |
SyncedAt |
time.Time |
Data da sincronização | Not Null |
Relacionamentos:
- User - Usuário (N:1)
Tipos Auxiliares¶
Date¶
Tipo personalizado para representar datas civis (sem hora/timezone). Armazena apenas a data (YYYY-MM-DD).
Localização: internal/models/date.go
Características:
- Serializa para JSON como string "YYYY-MM-DD"
- Normaliza para UTC à meia-noite
- Implementa driver.Valuer e sql.Scanner para GORM
- Implementa json.Marshaler e json.Unmarshaler
Métodos:
- NewDate(t time.Time) Date - Cria Date a partir de time.Time
- NewDateFromString(s string) (Date, error) - Cria Date a partir de string
- String() string - Retorna "YYYY-MM-DD"
- IsZero() bool - Verifica se é zero
Uso:
date := models.NewDate(time.Now())
dateStr := date.String() // "2024-01-15"
UIntArray¶
Tipo personalizado para arrays de uint armazenados como JSONB.
Localização: internal/models/uint_array.go
Características:
- Armazena arrays de uint como JSONB no PostgreSQL
- Implementa driver.Valuer e sql.Scanner
- Implementa json.Unmarshaler
Uso:
ids := models.UIntArray{1, 2, 3, 4, 5}
// Serializa para JSONB: [1,2,3,4,5]
Relacionamentos Principais¶
Diagrama de Relacionamentos¶
erDiagram
User ||--o{ Cycle : "tem"
User ||--o| ClientProfile : "tem"
User ||--o| ProfessionalProfile : "tem"
User ||--o{ Observation : "faz"
User ||--o{ Subscription : "tem"
User ||--o{ Message : "envia/recebe"
User ||--o{ Appointment : "agenda"
User ||--o{ Notification : "recebe"
Cycle ||--o{ Observation : "contém"
Cycle ||--o{ CycleComment : "tem"
ProfessionalProfile ||--o{ ProfessionalPatient : "atende"
ProfessionalProfile ||--|| WorkSchedule : "tem"
ProfessionalProfile ||--|| ProfessionalBankAccount : "tem"
Plan ||--o{ Subscription : "gera"
Subscription ||--o{ Payment : "tem"
Symbol ||--o{ Observation : "usado_em"
Appearance ||--o{ Observation : "usado_em"
DayBasedRule ||--o{ Symbol : "permite"
Soft Deletes¶
A maioria dos modelos implementa soft deletes através do campo DeletedAt do tipo gorm.DeletedAt. Isso significa que:
- Registros não são fisicamente deletados
- GORM automaticamente filtra registros deletados nas queries normais
- Use
Unscoped()para incluir registros deletados:db.Unscoped().Find(&users) // Inclui deletados
Sincronização Mobile¶
Vários modelos incluem campos para sincronização com mobile:
SyncID- Identificador único do dispositivo mobileLastSyncedAt- Última data de sincronização
Modelos com suporte a sincronização:
- Cycle
- Observation
- Account