Pular para o conteúdo principal

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 Error se 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âmicos
  • getStaticDeviceData(): 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);