Merge remote-tracking branch 'origin/master' into feat-ajuste-acesso

This commit is contained in:
2025-10-30 14:01:08 -03:00
76 changed files with 15420 additions and 1212 deletions

View File

@@ -24,11 +24,24 @@ export default defineSchema({
uf: v.string(),
telefone: v.string(),
email: v.string(),
matricula: v.string(),
matricula: v.optional(v.string()),
admissaoData: v.optional(v.string()),
desligamentoData: v.optional(v.string()),
simboloId: v.id("simbolos"),
simboloTipo: simboloTipo,
gestorId: v.optional(v.id("usuarios")),
statusFerias: v.optional(v.union(
v.literal("ativo"),
v.literal("em_ferias")
)),
// Regime de trabalho (para cálculo correto de férias)
regimeTrabalho: v.optional(v.union(
v.literal("clt"), // CLT - Consolidação das Leis do Trabalho
v.literal("estatutario_pe"), // Servidor Público Estadual de Pernambuco
v.literal("estatutario_federal"), // Servidor Público Federal
v.literal("estatutario_municipal") // Servidor Público Municipal
)),
// Dados Pessoais Adicionais (opcionais)
nomePai: v.optional(v.string()),
@@ -133,7 +146,8 @@ export default defineSchema({
.index("by_simboloId", ["simboloId"])
.index("by_simboloTipo", ["simboloTipo"])
.index("by_cpf", ["cpf"])
.index("by_rg", ["rg"]),
.index("by_rg", ["rg"])
.index("by_gestor", ["gestorId"]),
atestados: defineTable({
funcionarioId: v.id("funcionarios"),
@@ -143,11 +157,109 @@ export default defineSchema({
descricao: v.string(),
}),
ferias: defineTable({
solicitacoesFerias: defineTable({
funcionarioId: v.id("funcionarios"),
dataInicio: v.string(),
dataFim: v.string(),
}),
anoReferencia: v.number(),
status: v.union(
v.literal("aguardando_aprovacao"),
v.literal("aprovado"),
v.literal("reprovado"),
v.literal("data_ajustada_aprovada")
),
periodos: v.array(
v.object({
dataInicio: v.string(),
dataFim: v.string(),
diasCorridos: v.number(),
})
),
observacao: v.optional(v.string()),
motivoReprovacao: v.optional(v.string()),
gestorId: v.optional(v.id("usuarios")),
dataAprovacao: v.optional(v.number()),
dataReprovacao: v.optional(v.number()),
historicoAlteracoes: v.optional(
v.array(
v.object({
data: v.number(),
usuarioId: v.id("usuarios"),
acao: v.string(),
periodosAnteriores: v.optional(v.array(v.object({
dataInicio: v.string(),
dataFim: v.string(),
diasCorridos: v.number(),
}))),
})
)
),
})
.index("by_funcionario", ["funcionarioId"])
.index("by_status", ["status"])
.index("by_funcionario_and_status", ["funcionarioId", "status"])
.index("by_ano", ["anoReferencia"]),
notificacoesFerias: defineTable({
destinatarioId: v.id("usuarios"),
solicitacaoFeriasId: v.id("solicitacoesFerias"),
tipo: v.union(
v.literal("nova_solicitacao"),
v.literal("aprovado"),
v.literal("reprovado"),
v.literal("data_ajustada")
),
lida: v.boolean(),
mensagem: v.string(),
})
.index("by_destinatario", ["destinatarioId"])
.index("by_destinatario_and_lida", ["destinatarioId", "lida"]),
// Períodos aquisitivos e saldos de férias
periodosAquisitivos: defineTable({
funcionarioId: v.id("funcionarios"),
anoReferencia: v.number(), // Ano do período aquisitivo (ex: 2024)
dataInicio: v.string(), // Data de início do período aquisitivo
dataFim: v.string(), // Data de fim do período aquisitivo
diasDireito: v.number(), // Dias de férias que tem direito (30 ou proporcional)
diasUsados: v.number(), // Dias já usados
diasPendentes: v.number(), // Dias em solicitações aguardando aprovação
diasDisponiveis: v.number(), // Dias disponíveis = direito - usados - pendentes
abonoPermitido: v.boolean(), // Se pode vender 1/3 das férias
diasAbono: v.number(), // Dias vendidos como abono pecuniário
status: v.union(
v.literal("ativo"), // Período vigente
v.literal("vencido"), // Período vencido (não tirou férias)
v.literal("concluido") // Período totalmente utilizado
),
})
.index("by_funcionario", ["funcionarioId"])
.index("by_funcionario_and_ano", ["funcionarioId", "anoReferencia"])
.index("by_funcionario_and_status", ["funcionarioId", "status"]),
times: defineTable({
nome: v.string(),
descricao: v.optional(v.string()),
gestorId: v.id("usuarios"),
ativo: v.boolean(),
cor: v.optional(v.string()), // Cor para identificação visual
}).index("by_gestor", ["gestorId"]),
timesMembros: defineTable({
timeId: v.id("times"),
funcionarioId: v.id("funcionarios"),
dataEntrada: v.number(),
dataSaida: v.optional(v.number()),
ativo: v.boolean(),
})
.index("by_time", ["timeId"])
.index("by_funcionario", ["funcionarioId"])
.index("by_time_and_ativo", ["timeId", "ativo"]),
cursos: defineTable({
funcionarioId: v.id("funcionarios"),
descricao: v.string(),
data: v.string(),
certificadoId: v.optional(v.id("_storage")),
}).index("by_funcionario", ["funcionarioId"]),
simbolos: defineTable({
nome: v.string(),
@@ -220,7 +332,8 @@ export default defineSchema({
.index("by_role", ["roleId"])
.index("by_ativo", ["ativo"])
.index("by_status_presenca", ["statusPresenca"])
.index("by_bloqueado", ["bloqueado"]),
.index("by_bloqueado", ["bloqueado"])
.index("by_funcionarioId", ["funcionarioId"]),
roles: defineTable({
nome: v.string(), // "admin", "ti_master", "ti_usuario", "usuario_avancado", "usuario"
@@ -520,4 +633,54 @@ export default defineSchema({
})
.index("by_conversa", ["conversaId", "iniciouEm"])
.index("by_usuario", ["usuarioId"]),
// Tabelas de Monitoramento do Sistema
systemMetrics: defineTable({
timestamp: v.number(),
// Métricas de Sistema
cpuUsage: v.optional(v.number()),
memoryUsage: v.optional(v.number()),
networkLatency: v.optional(v.number()),
storageUsed: v.optional(v.number()),
// Métricas de Aplicação
usuariosOnline: v.optional(v.number()),
mensagensPorMinuto: v.optional(v.number()),
tempoRespostaMedio: v.optional(v.number()),
errosCount: v.optional(v.number()),
})
.index("by_timestamp", ["timestamp"]),
alertConfigurations: defineTable({
metricName: v.string(),
threshold: v.number(),
operator: v.union(
v.literal(">"),
v.literal("<"),
v.literal(">="),
v.literal("<="),
v.literal("==")
),
enabled: v.boolean(),
notifyByEmail: v.boolean(),
notifyByChat: v.boolean(),
createdBy: v.id("usuarios"),
lastModified: v.number(),
})
.index("by_enabled", ["enabled"]),
alertHistory: defineTable({
configId: v.id("alertConfigurations"),
metricName: v.string(),
metricValue: v.number(),
threshold: v.number(),
timestamp: v.number(),
status: v.union(v.literal("triggered"), v.literal("resolved")),
notificationsSent: v.object({
email: v.boolean(),
chat: v.boolean(),
}),
})
.index("by_timestamp", ["timestamp"])
.index("by_status", ["status"])
.index("by_config", ["configId", "timestamp"]),
});