Access Log Service
Gerencia o registro de acessos ao sistema, coletando informações do dispositivo e enviando logs de entrada do usuário.
Visão Geral
O AccessLogService é responsável por:
- Registrar acessos ao sistema
- Coletar informações do dispositivo automaticamente
- Enviar dados estáticos e dinâmicos do dispositivo
- Monitorar estado da bateria, memória e armazenamento
- Rastrear versões de aplicativo e sistema operacional
O serviço coleta automaticamente dados do dispositivo através do device-collector, combinando informações estáticas (modelo, fabricante, versão) com dados dinâmicos (bateria, memória, armazenamento).
Localização: services/access-log/access-log.service.ts
Endpoints Utilizados
Base URL
Todos os endpoints são relativos à base URL configurada em services/api.service.ts
Métodos
sendAccessLog(baseData)
Envia log de acesso combinando dados base com informações coletadas do dispositivo.
Endpoint: POST /logAcesso
Parâmetros:
type BaseData = {
idOrganization: string;
idSolucao: string;
idUsuario: string;
};
Body: JSON com dados base do usuário + dados coletados automaticamente do dispositivo
Retorno:
Promise<AccessLogResponseSchema>;
Exemplo de uso:
import { accessLogServiceInstance } from "@/services/access-log/access-log.service.instance";
// Enviar log de acesso
const logResult = await accessLogServiceInstance.sendAccessLog({
idOrganization: "org-001",
idSolucao: "sol-001",
idUsuario: "user-123",
});
console.log("Log registrado:", logResult.nuReg);
Tratamento de erros:
- Lança
Errorse o status da resposta não for 2xx - Mensagem:
AccessLogService.sendAccessLog failed: {status}
Estruturas de Dados
Interface AccessLogRegisterSchema
interface AccessLogRegisterSchema {
nuReg: string;
idOrganization: string;
idSolucao: string;
idUsuario: string;
urlErp?: string;
urlApividya?: string;
nomeApp?: string;
baseOs?: string;
batteryLevel?: number;
brand?: string;
carrier?: string;
systemVersion?: string;
locationEnabled?: boolean;
versaoApp?: string;
codVend?: string;
totalMemory?: number;
version?: string;
hashNotch?: boolean;
isAirplaneModeOn?: boolean;
isEmulator?: boolean;
isLandscape?: boolean;
isPinOrFingerprintSet?: string;
systemName?: string;
isTablet?: boolean;
firstInstallTime: string;
fontScale?: number;
freeDiskStorage?: number;
manufacturer?: string;
availableLocationProviders?: string;
tempoLoadingSeg?: number;
model?: string;
readableVersion?: string;
isBatteryCharging?: boolean;
apiLevel?: string;
powerState?: string;
totalDiskCapacity?: number;
usedMemory?: number;
hasDynamicIsland?: boolean;
supportedAbis?: string;
userAgent?: string;
uniqueId?: string;
deviceType?: string;
tempoLoadingMin?: number;
novoLogin?: boolean;
pulaSyncProd?: boolean;
}
Interface AccessLogResponseSchema
interface AccessLogResponseSchema {
nuReg: string;
urlErp?: string;
urlApividya?: string;
nomeApp?: string;
baseOs?: string;
batteryLevel?: number;
brand?: string;
carrier?: string;
systemVersion?: string;
locationEnabled?: boolean;
versaoApp?: string;
codVend?: string;
totalMemory?: number;
version?: string;
hashNotch?: boolean;
isAirplaneModeOn?: boolean;
isEmulator?: boolean;
isLandscape?: boolean;
isPinOrFingerprintSet?: string;
systemName?: string;
isTablet?: boolean;
firstInstallTime: string;
fontScale?: number;
freeDiskStorage?: number;
manufacturer?: string;
availableLocationProviders?: string;
tempoLoadingSeg?: number;
model?: string;
readableVersion?: string;
isBatteryCharging?: boolean;
apiLevel?: string;
powerState?: string;
totalDiskCapacity?: number;
usedMemory?: number;
hasDynamicIsland?: boolean;
supportedAbis?: string;
userAgent?: string;
uniqueId?: string;
deviceType?: string;
tempoLoadingMin?: number;
novoLogin?: boolean;
pulaSyncProd?: boolean;
solucao: string;
organizacao: string;
hasNotch: boolean;
nomeUsu: string;
deviceIsCompatible: boolean;
}
Componentes Relacionados
Device Collector
Módulo que coleta informações do dispositivo automaticamente.
Localização: services/access-log/device-collector.ts
Funções:
getDeviceData(): Combina dados estáticos e dinâmicosgetStaticDeviceData(): Coleta dados que não mudam (modelo, fabricante)getDynamicDeviceData(): Coleta dados variáveis (bateria, memória)
Bibliotecas Utilizadas
O serviço utiliza bibliotecas específicas para coleta de informações do dispositivo:
Expo Battery (expo-battery)
Biblioteca do Expo para acesso a informações da bateria.
Por que usar:
- Acompanha o versionamento do SDK do Expo
- Garante compatibilidade entre versões
- Manutenção e atualizações gerenciadas pelo time do Expo
Dados coletados:
- Nível de bateria (
batteryLevel) - Estado de carregamento (
isBatteryCharging) - Estado de energia (
powerState)
Expo File System (expo-file-system)
Biblioteca do Expo para acesso ao sistema de arquivos.
Por que usar:
- Acompanha o versionamento do SDK do Expo
- Garante compatibilidade entre versões
- API consistente e bem documentada
Dados coletados:
- Espaço livre em disco (
freeDiskStorage) - Capacidade total do disco (
totalDiskCapacity)
React Native Device Info (react-native-device-info)
Biblioteca especializada em informações do dispositivo.
Por que usar:
- Fornece informações detalhadas sobre o dispositivo físico
- Ampla cobertura de dados do sistema operacional
- Suporte robusto para Android e iOS
Dados coletados:
- Marca e fabricante (
brand,manufacturer) - Modelo do dispositivo (
model) - Sistema operacional (
systemName,systemVersion) - Nível de API (
apiLevel) - Memória total e usada (
totalMemory,usedMemory) - ABIs suportadas (
supportedAbis) - Tipo de dispositivo (
deviceType,isTablet) - Modo avião (
isAirplaneMode) - E muitos outros dados técnicos
Casos de Uso
Registrar Acesso no Login
async function logUserAccess(
userId: string,
orgId: string,
solutionId: string,
) {
try {
const log = await accessLogServiceInstance.sendAccessLog({
idUsuario: userId,
idOrganization: orgId,
idSolucao: solutionId,
});
console.log(`Acesso registrado: ${log.nuReg}`);
console.log(`Dispositivo compatível: ${log.deviceIsCompatible}`);
return log;
} catch (error) {
console.error("Erro ao registrar acesso:", error);
throw error;
}
}
// Exemplo de uso
await logUserAccess("user-123", "org-001", "sol-001");
Verificar Compatibilidade do Dispositivo
async function checkDeviceCompatibility(
userId: string,
orgId: string,
solutionId: string,
) {
const log = await accessLogServiceInstance.sendAccessLog({
idUsuario: userId,
idOrganization: orgId,
idSolucao: solutionId,
});
if (!log.deviceIsCompatible) {
console.warn("Dispositivo não compatível");
console.log("Modelo:", log.model);
console.log("Sistema:", log.systemName, log.systemVersion);
}
return log.deviceIsCompatible;
}
Testes
Localização
services/access-log/access-log.service.test.ts
Executar Testes
# Teste específico do serviço
npx jest services/access-log/access-log.service.test.ts
# Modo watch
npx jest services/access-log/access-log.service.test.ts --watch
# Com coverage
npx jest services/access-log/access-log.service.test.ts --coverage
Casos de Teste
- ✅
sendAccessLog: registro de acesso com sucesso - ✅
sendAccessLog: tratamento de erros para status não-2xx - ✅ Coleta automática de dados do dispositivo
Mocks
Localização
__mocks__/access-log.mock.ts
Dados Disponíveis
Mock com dados completos de log de acesso:
- Informações do dispositivo (marca, modelo, sistema)
- Estado da bateria e carregamento
- Uso de memória e armazenamento
- Configurações do sistema
- Dados de compatibilidade
Exemplo de uso em testes:
import {
accessLogResponseMock,
accessLogPayloadMock,
} from "@/__mocks__/access-log.mock";
// Mock sendAccessLog
const apiWithoutAccessToken: any = {
post: jest.fn(async () => ({
status: 201,
data: accessLogResponseMock,
})),
};
const service = new AccessLogService({ apiWithoutAccessToken });
const result = await service.sendAccessLog({
idOrganization: "org-001",
idSolucao: "sol-001",
idUsuario: "user-123",
});
expect(result).toEqual(accessLogResponseMock);