Modelo de Dados
Introdução ao documento
Este documento registra entidades, relacionamentos e regras de integridade do modelo de dados.
Versionamento
- Versão do documento: 1.0.0
- Última atualização: 2026-03-09
- Responsável: Marivaldo Vinicius
Referencial teórico
Escopo e fontes
- Fonte principal: migrations e models Eloquent
- Banco de dados: MySQL (principal) e Redshift/PostgreSQL (analítico)
Relacionado: docs/architecture/c4-component.md
Entidades principais
User
Representa usuários do sistema administrativo. Utiliza Laravel Sanctum para autenticação via API e Spatie Permissions para controle de acesso baseado em roles.
Campos principais:
id: Chave primárianame: Nome do usuárioemail: Email único (único)password: Senha hasheadaemail_verified_at: Timestamp de verificação de email (nullable)remember_token: Token para "lembrar-me"created_at,updated_at: Timestamps
Relacionamentos:
- Possui múltiplos tokens de acesso (Sanctum) via
personal_access_tokens - Possui múltiplos roles via tabela pivot
model_has_roles(Spatie Permissions) - Possui múltiplas permissões diretas via tabela pivot
model_has_permissions(Spatie Permissions)
MaintenanceMode
Controla modo de manutenção do sistema. Permite ativar/desativar manutenção por slug específico.
Campos principais:
id: Chave primáriatitle: Título da manutençãomessage: Mensagem curta (máx 100 caracteres, nullable)description: Descrição completa (text, nullable)slug: Identificador único da manutenção (máx 100 caracteres)active: Status ativo/inativo (boolean, default false)created_at,updated_at: Timestamps
Regras:
- Slug deve ser único para identificar diferentes tipos de manutenção
- Quando
active = true, middlewareRedirectIfMaintenanceModeActiveredireciona usuários
VisibleColumnsConfig
Configuração de colunas visíveis para role Facilitador_Limitado. Permite controlar quais colunas podem ser visualizadas por usuários com permissões limitadas.
Campos principais:
id: Chave primáriacolumns: Array JSON com lista de nomes de colunas permitidascreated_at,updated_at: Timestamps
Regras:
- Apenas um registro é mantido (singleton)
- Colunas são armazenadas como array JSON
- Por padrão, email é oculto para facilitadores limitados
PlainTextToken
Armazena tokens de acesso em texto plano para referência. Relacionado com tokens do Laravel Sanctum.
Campos principais:
id: Chave primáriatoken_id: ID do token relacionado (integer)plain_text_token: Token em texto plano (text)created_at,updated_at: Timestamps
Nota: Tokens são armazenados em texto plano apenas no momento de criação para exibição ao usuário. Após isso, apenas o hash é mantido em personal_access_tokens.
PersonalAccessToken (Sanctum)
Tokens de acesso para autenticação via API. Gerenciado pelo Laravel Sanctum.
Campos principais:
id: Chave primáriatokenable_type: Tipo do modelo (polimórfico)tokenable_id: ID do modelo (polimórfico)name: Nome do tokentoken: Hash do token (único, 64 caracteres)abilities: Abilities do token (text, nullable)last_used_at: Último uso (timestamp, nullable)expires_at: Expiração (timestamp, nullable)created_at,updated_at: Timestamps
Relacionamentos:
- Pertence a um modelo (polimórfico) - geralmente
User
Permissions e Roles (Spatie)
Sistema de permissões e roles baseado no pacote Spatie Permissions.
Tabelas:
permissions: Permissões individuaisroles: Roles (papéis) que agrupam permissõesmodel_has_permissions: Relação muitos-para-muitos entre modelos e permissõesmodel_has_roles: Relação muitos-para-muitos entre modelos e rolesrole_has_permissions: Relação muitos-para-muitos entre roles e permissões
Estrutura:
- Permissões e roles têm
nameeguard_name(único por combinação) - Relacionamentos polimórficos permitem atribuir permissões/roles a qualquer modelo
- Cascade delete garante integridade referencial
Relacionamentos
User ↔ PersonalAccessToken
- Tipo: 1:N (um usuário pode ter múltiplos tokens)
- Via:
tokenable_type = 'App\Models\User'etokenable_id = users.id - Cascade: Tokens são deletados quando usuário é deletado
User ↔ Roles
- Tipo: N:N (muitos-para-muitos)
- Via: Tabela pivot
model_has_roles - Campos pivot:
role_id,model_type,model_id - Cascade: Relação deletada quando role ou usuário é deletado
User ↔ Permissions
- Tipo: N:N (muitos-para-muitos)
- Via: Tabela pivot
model_has_permissions - Campos pivot:
permission_id,model_type,model_id - Cascade: Relação deletada quando permissão ou usuário é deletado
Roles ↔ Permissions
- Tipo: N:N (muitos-para-muitos)
- Via: Tabela pivot
role_has_permissions - Campos pivot:
role_id,permission_id - Cascade: Relação deletada quando role ou permissão é deletado
PlainTextToken ↔ PersonalAccessToken
- Tipo: 1:1 (relação lógica via
token_id) - Nota: Não há foreign key, apenas referência lógica
Campos relevantes
Chaves primárias
- Todas as entidades principais usam
idcomo chave primária auto-incrementável (bigInteger)
Chaves únicas
users.email: Email únicopersonal_access_tokens.token: Hash do token únicopermissions.name + guard_name: Combinação únicaroles.name + guard_name: Combinação únicamaintenance_modes.slug: Slug único
Timestamps
- Todas as entidades principais possuem
created_ateupdated_at personal_access_tokenspossui tambémlast_used_ateexpires_at
Campos especiais
users.password: Hash bcryptusers.remember_token: Token para sessão persistentevisible_columns_config.columns: Array JSONpersonal_access_tokens.abilities: Text nullable para abilities do tokenpersonal_access_tokens.tokenable_typeetokenable_id: Relação polimórfica
Regras de integridade
Constraints
- Foreign keys com cascade delete nas tabelas de relacionamento Spatie
- Unique constraints em combinações de campos (email, token, name+guard_name)
- Indexes em campos de busca frequente (email, token, timestamps)
Validações
- Email deve ser válido e único
- Password deve ser hasheado antes de armazenar
- Slug de manutenção deve ser único
- Colunas visíveis devem ser array de strings
Estado e transições
maintenance_modes.active: Boolean que controla se manutenção está ativausers.email_verified_at: Nullable timestamp indica se email foi verificadopersonal_access_tokens.expires_at: Nullable timestamp indica expiração do token
ERD (Mermaid)
Observações sobre dados analíticos
O sistema também acessa dados analíticos do Redshift (PostgreSQL) para:
- Tabela
inscricoes: Dados de inscrições comprimidos e cacheados - Tabela
appointments: Dados de agendamentos comprimidos e cacheados
Esses dados não são persistidos no MySQL, apenas consultados e cacheados para otimização de performance.