feat: implement error handling and logging in server hooks to capture and notify on 404 and 500 errors, enhancing server reliability and monitoring

This commit is contained in:
2025-12-08 11:52:27 -03:00
parent e1f1af7530
commit fdfbd8b051
31 changed files with 7305 additions and 932 deletions

View File

@@ -59,6 +59,85 @@ async function recalcularBancoHorasPeriodo(
}
}
/**
* Helper para verificar se um funcionário tem licença ou atestado ativo
* Retorna true se há algum registro ativo (data atual entre dataInicio e dataFim)
*/
export async function verificarLicencaAtiva(
ctx: QueryCtx | MutationCtx,
funcionarioId: Id<'funcionarios'>,
dataAtual?: Date
): Promise<boolean> {
// Normalizar data atual para comparar apenas a parte da data (sem hora)
const hoje = dataAtual || new Date();
const hojeStr = hoje.toISOString().split('T')[0]; // Formato: "YYYY-MM-DD"
console.log(
`[verificarLicencaAtiva] Verificando funcionário ${funcionarioId}, data atual: ${hojeStr}`
);
// Buscar atestados e licenças do funcionário
const [atestados, licencas] = await Promise.all([
ctx.db
.query('atestados')
.withIndex('by_funcionario', (q) => q.eq('funcionarioId', funcionarioId))
.collect(),
ctx.db
.query('licencas')
.withIndex('by_funcionario', (q) => q.eq('funcionarioId', funcionarioId))
.collect()
]);
console.log(
`[verificarLicencaAtiva] Encontrados ${atestados.length} atestados e ${licencas.length} licenças`
);
// Verificar se há algum atestado ativo
for (const atestado of atestados) {
// Normalizar datas para formato "YYYY-MM-DD" (pode vir como "YYYY-MM-DD" ou "YYYY-MM-DDTHH:mm:ss")
const inicioStr = atestado.dataInicio.includes('T')
? atestado.dataInicio.split('T')[0]
: atestado.dataInicio.substring(0, 10);
const fimStr = atestado.dataFim.includes('T')
? atestado.dataFim.split('T')[0]
: atestado.dataFim.substring(0, 10);
console.log(
`[verificarLicencaAtiva] Atestado: ${inicioStr} a ${fimStr}, hoje: ${hojeStr}, ativo: ${hojeStr >= inicioStr && hojeStr <= fimStr}`
);
// Comparar strings de data diretamente (formato ISO permite comparação lexicográfica)
if (hojeStr >= inicioStr && hojeStr <= fimStr) {
console.log(`[verificarLicencaAtiva] ✅ Atestado ativo encontrado!`);
return true;
}
}
// Verificar se há alguma licença ativa
for (const licenca of licencas) {
// Normalizar datas para formato "YYYY-MM-DD" (pode vir como "YYYY-MM-DD" ou "YYYY-MM-DDTHH:mm:ss")
const inicioStr = licenca.dataInicio.includes('T')
? licenca.dataInicio.split('T')[0]
: licenca.dataInicio.substring(0, 10);
const fimStr = licenca.dataFim.includes('T')
? licenca.dataFim.split('T')[0]
: licenca.dataFim.substring(0, 10);
console.log(
`[verificarLicencaAtiva] Licença: ${inicioStr} a ${fimStr}, hoje: ${hojeStr}, ativa: ${hojeStr >= inicioStr && hojeStr <= fimStr}`
);
// Comparar strings de data diretamente (formato ISO permite comparação lexicográfica)
if (hojeStr >= inicioStr && hojeStr <= fimStr) {
console.log(`[verificarLicencaAtiva] ✅ Licença ativa encontrada!`);
return true;
}
}
console.log(`[verificarLicencaAtiva] ❌ Nenhuma licença/atestado ativo encontrado`);
return false;
}
// ========== QUERIES ==========
/**
@@ -238,6 +317,19 @@ export const listarPorPeriodo = query({
}
});
/**
* Verificar se o funcionário atual tem licença/atestado ativo
*/
export const verificarStatusLicenca = query({
args: {
funcionarioId: v.id('funcionarios')
},
returns: v.boolean(),
handler: async (ctx, args) => {
return await verificarLicencaAtiva(ctx, args.funcionarioId);
}
});
/**
* Obter dados para gráficos
*/
@@ -816,6 +908,15 @@ export const criarAtestadoMedico = mutation({
// Recalcular banco de horas para todas as datas do período do atestado
await recalcularBancoHorasPeriodo(ctx, args.funcionarioId, args.dataInicio, args.dataFim);
// Atualizar status do funcionário imediatamente
console.log(
`[criarAtestadoMedico] Atualizando status do funcionário ${args.funcionarioId} após criar atestado`
);
await ctx.runMutation(internal.ferias.atualizarStatusFuncionario, {
funcionarioId: args.funcionarioId
});
console.log(`[criarAtestadoMedico] Status atualizado com sucesso`);
return atestadoId;
}
});
@@ -864,6 +965,11 @@ export const criarDeclaracaoComparecimento = mutation({
// Recalcular banco de horas para todas as datas do período da declaração
await recalcularBancoHorasPeriodo(ctx, args.funcionarioId, args.dataInicio, args.dataFim);
// Atualizar status do funcionário imediatamente
await ctx.runMutation(internal.ferias.atualizarStatusFuncionario, {
funcionarioId: args.funcionarioId
});
return atestadoId;
}
});
@@ -920,6 +1026,11 @@ export const criarLicencaMaternidade = mutation({
// Recalcular banco de horas para todas as datas do período da licença
await recalcularBancoHorasPeriodo(ctx, args.funcionarioId, args.dataInicio, args.dataFim);
// Atualizar status do funcionário imediatamente
await ctx.runMutation(internal.ferias.atualizarStatusFuncionario, {
funcionarioId: args.funcionarioId
});
return licencaId;
}
});
@@ -969,6 +1080,11 @@ export const criarLicencaPaternidade = mutation({
// Recalcular banco de horas para todas as datas do período da licença
await recalcularBancoHorasPeriodo(ctx, args.funcionarioId, args.dataInicio, args.dataFim);
// Atualizar status do funcionário imediatamente
await ctx.runMutation(internal.ferias.atualizarStatusFuncionario, {
funcionarioId: args.funcionarioId
});
return licencaId;
}
});
@@ -1025,6 +1141,11 @@ export const prorrogarLicencaMaternidade = mutation({
prorrogacaoId
);
// Atualizar status do funcionário imediatamente
await ctx.runMutation(internal.ferias.atualizarStatusFuncionario, {
funcionarioId: licencaOriginal.funcionarioId
});
return prorrogacaoId;
}
});
@@ -1055,6 +1176,11 @@ export const excluirAtestado = mutation({
args.id
);
// Atualizar status do funcionário imediatamente
await ctx.runMutation(internal.ferias.atualizarStatusFuncionario, {
funcionarioId: atestado.funcionarioId
});
return null;
}
});
@@ -1085,6 +1211,11 @@ export const excluirLicenca = mutation({
args.id
);
// Atualizar status do funcionário imediatamente
await ctx.runMutation(internal.ferias.atualizarStatusFuncionario, {
funcionarioId: licenca.funcionarioId
});
return null;
}
});