Merge remote-tracking branch 'origin' into feat-pedidos

This commit is contained in:
2025-12-02 00:58:10 -03:00
38 changed files with 9633 additions and 3679 deletions

View File

@@ -759,24 +759,6 @@ 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'),
@@ -807,26 +789,6 @@ export default defineSchema({
.index('by_ativo', ['ativo'])
.index('by_data_inicio', ['dataInicio']),
// Perfis Customizados
// 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
@@ -843,30 +805,6 @@ export default defineSchema({
atualizadoEm: v.number()
}).index('by_ativo', ['ativo']),
// Configuração de Jitsi Meet
configuracaoJitsi: defineTable({
domain: v.string(), // Domínio do servidor Jitsi (ex: "localhost:8443" ou "meet.example.com")
appId: v.string(), // ID da aplicação Jitsi
roomPrefix: v.string(), // Prefixo para nomes de salas
useHttps: v.boolean(), // Usar HTTPS
acceptSelfSignedCert: v.optional(v.boolean()), // Aceitar certificados autoassinados (útil para desenvolvimento)
// Configurações SSH/Docker para configuração automática do servidor
sshHost: v.optional(v.string()), // Host SSH para acesso ao servidor Docker (ex: "192.168.1.100" ou "servidor.local")
sshPort: v.optional(v.number()), // Porta SSH (padrão: 22)
sshUsername: v.optional(v.string()), // Usuário SSH
sshPasswordHash: v.optional(v.string()), // Hash da senha SSH (criptografada)
sshKeyPath: v.optional(v.string()), // Caminho para chave SSH (alternativa à senha)
dockerComposePath: v.optional(v.string()), // Caminho do docker-compose.yml (ex: "/home/user/jitsi-docker")
jitsiConfigPath: v.optional(v.string()), // Caminho base das configurações Jitsi (ex: "~/.jitsi-meet-cfg")
ativo: v.boolean(), // Configuração ativa
testadoEm: v.optional(v.number()), // Timestamp do último teste de conexão
configuradoEm: v.optional(v.number()), // Timestamp da última configuração do servidor Docker
configuradoNoServidor: v.optional(v.boolean()), // Indica se a configuração foi aplicada no servidor
configuradoNoServidorEm: v.optional(v.number()), // Timestamp de quando foi configurado no servidor
configuradoPor: v.id('usuarios'), // Usuário que configurou
atualizadoEm: v.number() // Timestamp de atualização
}).index('by_ativo', ['ativo']),
// Fila de Emails
notificacoesEmail: defineTable({
destinatario: v.string(), // email
@@ -1791,26 +1729,6 @@ export default defineSchema({
.index('by_registro', ['registroId'])
.index('by_data', ['criadoEm']),
// Dispensas de Registro - Períodos onde funcionário está dispensado de registrar ponto
dispensasRegistro: defineTable({
funcionarioId: v.id('funcionarios'),
gestorId: v.id('usuarios'),
dataInicio: v.string(), // YYYY-MM-DD
horaInicio: v.number(),
minutoInicio: v.number(),
dataFim: v.string(), // YYYY-MM-DD
horaFim: v.number(),
minutoFim: v.number(),
motivo: v.string(),
isento: v.boolean(), // Se true, não expira (casos excepcionais)
ativo: v.boolean(),
criadoEm: v.number()
})
.index('by_funcionario', ['funcionarioId'])
.index('by_gestor', ['gestorId'])
.index('by_ativo', ['ativo'])
.index('by_data_inicio', ['dataInicio'])
.index('by_data_fim', ['dataFim']),
// Configurações Gerais
config: defineTable({
comprasSetorId: v.optional(v.id('setores')),
@@ -1881,5 +1799,104 @@ export default defineSchema({
})
.index('by_pedidoId', ['pedidoId'])
.index('by_usuarioId', ['usuarioId'])
.index('by_data', ['data'])
.index('by_data', ['data']),
// 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"
// Informações de Rede
ipAddress: v.optional(v.string()),
ipPublico: v.optional(v.string()),
ipLocal: v.optional(v.string()),
userAgent: v.optional(v.string()),
device: v.optional(v.string()),
browser: v.optional(v.string()),
sistema: v.optional(v.string()),
// Informações de Localização (por IP)
latitude: v.optional(v.number()),
longitude: v.optional(v.number()),
endereco: v.optional(v.string()),
cidade: v.optional(v.string()),
estado: v.optional(v.string()),
pais: v.optional(v.string()),
// Informações de Localização (GPS do navegador)
latitudeGPS: v.optional(v.number()),
longitudeGPS: v.optional(v.number()),
precisaoGPS: v.optional(v.number()),
enderecoGPS: v.optional(v.string()),
cidadeGPS: v.optional(v.string()),
estadoGPS: v.optional(v.string()),
paisGPS: v.optional(v.string()),
timestamp: v.number()
})
.index('by_usuario', ['usuarioId'])
.index('by_sucesso', ['sucesso'])
.index('by_timestamp', ['timestamp'])
.index('by_ip', ['ipAddress']),
// 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}}
htmlCorpo: v.optional(v.string()), // versão HTML do corpo (com wrapper)
variaveis: v.optional(v.array(v.string())), // ["motivo", "senha", etc.]
categoria: v.optional(v.union(v.literal('email'), v.literal('chat'), v.literal('ambos'))), // categoria do template
tags: v.optional(v.array(v.string())), // tags para organização
criadoPor: v.optional(v.id('usuarios')),
criadoEm: v.number()
})
.index('by_codigo', ['codigo'])
.index('by_tipo', ['tipo'])
.index('by_criado_por', ['criadoPor'])
.index('by_categoria', ['categoria']),
// Configuração de Jitsi Meet
configuracaoJitsi: defineTable({
domain: v.string(), // Domínio do servidor Jitsi (ex: "localhost:8443" ou "meet.example.com")
appId: v.string(), // ID da aplicação Jitsi
roomPrefix: v.string(), // Prefixo para nomes de salas
useHttps: v.boolean(), // Usar HTTPS
acceptSelfSignedCert: v.optional(v.boolean()), // Aceitar certificados autoassinados (útil para desenvolvimento)
ativo: v.boolean(), // Configuração ativa
testadoEm: v.optional(v.number()), // Timestamp do último teste de conexão
configuradoEm: v.optional(v.number()), // Timestamp da última configuração do servidor Docker
configuradoNoServidor: v.optional(v.boolean()), // Indica se a configuração foi aplicada no servidor
configuradoNoServidorEm: v.optional(v.number()), // Timestamp de quando foi configurado no servidor
configuradoPor: v.id('usuarios'), // Usuário que configurou
atualizadoEm: v.number(), // Timestamp de atualização
jitsiConfigPath: v.optional(v.string()), // Caminho da configuração do Jitsi no servidor (ex: "~/.jitsi-meet-cfg")
sshUsername: v.optional(v.string()), // Usuário SSH para acesso ao servidor
sshPasswordHash: v.optional(v.string()), // Hash da senha SSH (criptografada)
sshPort: v.optional(v.number()) // Porta SSH (padrão: 22)
}).index('by_ativo', ['ativo']),
// Dispensas de Registro - Períodos onde funcionário está dispensado de registrar ponto
dispensasRegistro: defineTable({
funcionarioId: v.id('funcionarios'),
gestorId: v.id('usuarios'),
dataInicio: v.string(), // YYYY-MM-DD
horaInicio: v.number(),
minutoInicio: v.number(),
dataFim: v.string(), // YYYY-MM-DD
horaFim: v.number(),
minutoFim: v.number(),
motivo: v.string(),
isento: v.boolean(), // Se true, não expira (casos excepcionais)
ativo: v.boolean(),
criadoEm: v.number()
})
.index('by_funcionario', ['funcionarioId'])
.index('by_gestor', ['gestorId'])
.index('by_ativo', ['ativo'])
.index('by_data_inicio', ['dataInicio'])
.index('by_data_fim', ['dataFim'])
});