Merge remote-tracking branch 'origin/feat-cotrole_acesso' into feat-funcionarios-ferias
This commit is contained in:
@@ -192,6 +192,13 @@ export default defineSchema({
|
||||
criadoEm: v.number(),
|
||||
atualizadoEm: v.number(),
|
||||
|
||||
// Controle de Bloqueio e Segurança
|
||||
bloqueado: v.optional(v.boolean()),
|
||||
motivoBloqueio: v.optional(v.string()),
|
||||
dataBloqueio: v.optional(v.number()),
|
||||
tentativasLogin: v.optional(v.number()), // contador de tentativas falhas
|
||||
ultimaTentativaLogin: v.optional(v.number()), // timestamp da última tentativa
|
||||
|
||||
// Campos de Chat e Perfil
|
||||
avatar: v.optional(v.string()), // "avatar-1" até "avatar-15" ou storageId
|
||||
fotoPerfil: v.optional(v.id("_storage")),
|
||||
@@ -214,17 +221,22 @@ export default defineSchema({
|
||||
.index("by_email", ["email"])
|
||||
.index("by_role", ["roleId"])
|
||||
.index("by_ativo", ["ativo"])
|
||||
.index("by_status_presenca", ["statusPresenca"]),
|
||||
.index("by_status_presenca", ["statusPresenca"])
|
||||
.index("by_bloqueado", ["bloqueado"]),
|
||||
|
||||
roles: defineTable({
|
||||
nome: v.string(), // "admin", "ti", "usuario_avancado", "usuario"
|
||||
nome: v.string(), // "admin", "ti_master", "ti_usuario", "usuario_avancado", "usuario"
|
||||
descricao: v.string(),
|
||||
nivel: v.number(), // 0 = admin, 1 = ti, 2 = usuario_avancado, 3 = usuario
|
||||
nivel: v.number(), // 0 = admin, 1 = ti_master, 2 = ti_usuario, 3+ = customizado
|
||||
setor: v.optional(v.string()), // "ti", "rh", "financeiro", etc.
|
||||
customizado: v.optional(v.boolean()), // se é um perfil customizado criado por TI_MASTER
|
||||
criadoPor: v.optional(v.id("usuarios")), // usuário TI_MASTER que criou este perfil
|
||||
editavel: v.optional(v.boolean()), // se pode ser editado (false para roles fixas)
|
||||
})
|
||||
.index("by_nome", ["nome"])
|
||||
.index("by_nivel", ["nivel"])
|
||||
.index("by_setor", ["setor"]),
|
||||
.index("by_setor", ["setor"])
|
||||
.index("by_customizado", ["customizado"]),
|
||||
|
||||
permissoes: defineTable({
|
||||
nome: v.string(), // "funcionarios.criar", "simbolos.editar", etc.
|
||||
@@ -300,6 +312,128 @@ export default defineSchema({
|
||||
.index("by_tipo", ["tipo"])
|
||||
.index("by_timestamp", ["timestamp"]),
|
||||
|
||||
// Logs de Login Detalhados
|
||||
logsLogin: defineTable({
|
||||
usuarioId: v.optional(v.id("usuarios")), // pode ser null se falha antes de identificar usuário
|
||||
matriculaOuEmail: v.string(), // tentativa de login
|
||||
sucesso: v.boolean(),
|
||||
motivoFalha: v.optional(v.string()), // "senha_incorreta", "usuario_bloqueado", "usuario_inexistente"
|
||||
ipAddress: v.optional(v.string()),
|
||||
userAgent: v.optional(v.string()),
|
||||
device: v.optional(v.string()),
|
||||
browser: v.optional(v.string()),
|
||||
sistema: v.optional(v.string()),
|
||||
timestamp: v.number(),
|
||||
})
|
||||
.index("by_usuario", ["usuarioId"])
|
||||
.index("by_sucesso", ["sucesso"])
|
||||
.index("by_timestamp", ["timestamp"])
|
||||
.index("by_ip", ["ipAddress"]),
|
||||
|
||||
// Logs de Atividades
|
||||
logsAtividades: defineTable({
|
||||
usuarioId: v.id("usuarios"),
|
||||
acao: v.string(), // "criar", "editar", "excluir", "bloquear", "desbloquear", etc.
|
||||
recurso: v.string(), // "funcionarios", "simbolos", "usuarios", "perfis", etc.
|
||||
recursoId: v.optional(v.string()), // ID do recurso afetado
|
||||
detalhes: v.optional(v.string()), // JSON com detalhes da ação
|
||||
timestamp: v.number(),
|
||||
})
|
||||
.index("by_usuario", ["usuarioId"])
|
||||
.index("by_acao", ["acao"])
|
||||
.index("by_recurso", ["recurso"])
|
||||
.index("by_timestamp", ["timestamp"])
|
||||
.index("by_recurso_id", ["recurso", "recursoId"]),
|
||||
|
||||
// Histórico de Bloqueios
|
||||
bloqueiosUsuarios: defineTable({
|
||||
usuarioId: v.id("usuarios"),
|
||||
motivo: v.string(),
|
||||
bloqueadoPor: v.id("usuarios"), // ID do TI_MASTER que bloqueou
|
||||
dataInicio: v.number(),
|
||||
dataFim: v.optional(v.number()), // quando foi desbloqueado
|
||||
desbloqueadoPor: v.optional(v.id("usuarios")),
|
||||
ativo: v.boolean(), // se é o bloqueio atual ativo
|
||||
})
|
||||
.index("by_usuario", ["usuarioId"])
|
||||
.index("by_bloqueado_por", ["bloqueadoPor"])
|
||||
.index("by_ativo", ["ativo"])
|
||||
.index("by_data_inicio", ["dataInicio"]),
|
||||
|
||||
// Perfis Customizados
|
||||
perfisCustomizados: defineTable({
|
||||
nome: v.string(),
|
||||
descricao: v.string(),
|
||||
nivel: v.number(), // >= 3
|
||||
roleId: v.id("roles"), // role correspondente criada
|
||||
criadoPor: v.id("usuarios"), // TI_MASTER que criou
|
||||
criadoEm: v.number(),
|
||||
atualizadoEm: v.number(),
|
||||
})
|
||||
.index("by_nome", ["nome"])
|
||||
.index("by_nivel", ["nivel"])
|
||||
.index("by_criado_por", ["criadoPor"])
|
||||
.index("by_role", ["roleId"]),
|
||||
|
||||
// Templates de Mensagens
|
||||
templatesMensagens: defineTable({
|
||||
codigo: v.string(), // "USUARIO_BLOQUEADO", "SENHA_RESETADA", etc.
|
||||
nome: v.string(),
|
||||
tipo: v.union(
|
||||
v.literal("sistema"), // predefinido, não editável
|
||||
v.literal("customizado") // criado por TI_MASTER
|
||||
),
|
||||
titulo: v.string(),
|
||||
corpo: v.string(), // pode ter variáveis {{variavel}}
|
||||
variaveis: v.optional(v.array(v.string())), // ["motivo", "senha", etc.]
|
||||
criadoPor: v.optional(v.id("usuarios")),
|
||||
criadoEm: v.number(),
|
||||
})
|
||||
.index("by_codigo", ["codigo"])
|
||||
.index("by_tipo", ["tipo"])
|
||||
.index("by_criado_por", ["criadoPor"]),
|
||||
|
||||
// Configuração de Email/SMTP
|
||||
configuracaoEmail: defineTable({
|
||||
servidor: v.string(), // smtp.gmail.com
|
||||
porta: v.number(), // 587, 465, etc.
|
||||
usuario: v.string(),
|
||||
senhaHash: v.string(), // senha criptografada
|
||||
emailRemetente: v.string(),
|
||||
nomeRemetente: v.string(),
|
||||
usarSSL: v.boolean(),
|
||||
usarTLS: v.boolean(),
|
||||
ativo: v.boolean(),
|
||||
testadoEm: v.optional(v.number()),
|
||||
configuradoPor: v.id("usuarios"),
|
||||
atualizadoEm: v.number(),
|
||||
}).index("by_ativo", ["ativo"]),
|
||||
|
||||
// Fila de Emails
|
||||
notificacoesEmail: defineTable({
|
||||
destinatario: v.string(), // email
|
||||
destinatarioId: v.optional(v.id("usuarios")),
|
||||
assunto: v.string(),
|
||||
corpo: v.string(), // HTML ou texto
|
||||
templateId: v.optional(v.id("templatesMensagens")),
|
||||
status: v.union(
|
||||
v.literal("pendente"),
|
||||
v.literal("enviando"),
|
||||
v.literal("enviado"),
|
||||
v.literal("falha")
|
||||
),
|
||||
tentativas: v.number(),
|
||||
ultimaTentativa: v.optional(v.number()),
|
||||
erroDetalhes: v.optional(v.string()),
|
||||
enviadoPor: v.id("usuarios"),
|
||||
criadoEm: v.number(),
|
||||
enviadoEm: v.optional(v.number()),
|
||||
})
|
||||
.index("by_status", ["status"])
|
||||
.index("by_destinatario", ["destinatarioId"])
|
||||
.index("by_enviado_por", ["enviadoPor"])
|
||||
.index("by_criado_em", ["criadoEm"]),
|
||||
|
||||
configuracaoAcesso: defineTable({
|
||||
chave: v.string(), // "sessao_duracao", "max_tentativas_login", etc.
|
||||
valor: v.string(),
|
||||
|
||||
Reference in New Issue
Block a user