feat: enhance time synchronization and Jitsi configuration handling

- Implemented a comprehensive time synchronization mechanism that applies GMT offsets based on user configuration, ensuring accurate timestamps across the application.
- Updated the Jitsi configuration to include SSH settings, allowing for better integration with Docker setups.
- Refactored the backend queries and mutations to handle the new SSH configuration fields, ensuring secure and flexible server management.
- Enhanced error handling and logging for time synchronization processes, providing clearer feedback for users and developers.
This commit is contained in:
2025-11-22 18:18:16 -03:00
parent 54089f5eca
commit c056506ce5
17 changed files with 1765 additions and 257 deletions

View File

@@ -369,38 +369,23 @@ export const registrarPonto = mutation({
throw new Error('Configuração de ponto não encontrada');
}
// Obter configuração de ponto para GMT offset (buscar configuração ativa)
const configPonto = await ctx.db
.query('configuracaoPonto')
.withIndex('by_ativo', (q) => q.eq('ativo', true))
.first();
// Converter timestamp para data/hora com ajuste de GMT
// O timestamp está em UTC, precisamos aplicar o GMT offset
const gmtOffset = configPonto?.gmtOffset ?? 0;
// Converter timestamp para data/hora
// O timestamp pode vir ajustado com GMT offset do frontend (se GMT !== 0)
// ou em UTC puro (se GMT === 0). Usamos UTC methods para extrair os valores
// diretamente do timestamp recebido, seja ele ajustado ou não
const dataObj = new Date(args.timestamp);
// Usar UTC methods porque:
// - Se GMT === 0: timestamp está em UTC puro, métodos UTC extraem corretamente
// - Se GMT !== 0: timestamp já vem ajustado do frontend, métodos UTC extraem o horário ajustado
const hora = dataObj.getUTCHours();
const minuto = dataObj.getUTCMinutes();
const segundo = dataObj.getUTCSeconds();
// Calcular horário ajustado manualmente a partir de UTC
const dataUTC = new Date(args.timestamp);
let hora = dataUTC.getUTCHours() + gmtOffset;
const minuto = dataUTC.getUTCMinutes();
const segundo = dataUTC.getUTCSeconds();
// Ajustar hora se ultrapassar os limites do dia
let diasOffset = 0;
if (hora >= 24) {
hora = hora - 24;
diasOffset = 1;
} else if (hora < 0) {
hora = hora + 24;
diasOffset = -1;
}
// Calcular data ajustada
const dataAjustada = new Date(args.timestamp);
if (diasOffset !== 0) {
dataAjustada.setUTCDate(dataAjustada.getUTCDate() + diasOffset);
}
const data = dataAjustada.toISOString().split('T')[0]!; // YYYY-MM-DD
// Obter data no formato YYYY-MM-DD usando UTC
const ano = dataObj.getUTCFullYear();
const mes = String(dataObj.getUTCMonth() + 1).padStart(2, '0');
const dia = String(dataObj.getUTCDate()).padStart(2, '0');
const data = `${ano}-${mes}-${dia}`;
// Verificar se já existe registro no mesmo minuto
const funcionarioId = usuario.funcionarioId; // Já verificado acima, não é undefined
@@ -544,7 +529,7 @@ export const registrarPonto = mutation({
} | null = null;
if (
configPonto?.validarLocalizacao !== false &&
config.validarLocalizacao !== false &&
args.informacoesDispositivo?.latitude &&
args.informacoesDispositivo?.longitude
) {
@@ -553,7 +538,7 @@ export const registrarPonto = mutation({
usuario.funcionarioId,
args.informacoesDispositivo.latitude,
args.informacoesDispositivo.longitude,
configPonto?.toleranciaDistanciaMetros ?? 100
config.toleranciaDistanciaMetros ?? 100
);
validacaoGeofencing = geofencing;
@@ -822,6 +807,7 @@ export const obterEstatisticas = query({
args: {
dataInicio: v.string(), // YYYY-MM-DD
dataFim: v.string(), // YYYY-MM-DD
funcionarioId: v.optional(v.id('funcionarios')),
},
handler: async (ctx, args) => {
const usuario = await getCurrentUserFunction(ctx);
@@ -831,11 +817,16 @@ export const obterEstatisticas = query({
// TODO: Verificar permissão (RH ou TI)
const registros = await ctx.db
let registros = await ctx.db
.query('registrosPonto')
.withIndex('by_data', (q) => q.gte('data', args.dataInicio).lte('data', args.dataFim))
.collect();
// Filtrar por funcionário se fornecido
if (args.funcionarioId) {
registros = registros.filter((r) => r.funcionarioId === args.funcionarioId);
}
const totalRegistros = registros.length;
const dentroDoPrazo = registros.filter((r) => r.dentroDoPrazo).length;
const foraDoPrazo = totalRegistros - dentroDoPrazo;