API v1

Home — Dashboard Principal

Android: HomeFragment + HomeAdapter + HomeViewModel iOS: HomeViewController

Tela central do app após o login. Exibe uma grade de atalhos para todos os módulos disponíveis ao usuário, com visibilidade controlada por permissões. Inclui rastreamento de localização para motoristas, badge de notificações e botões de contato com a Monisat.

Layout e Grid de Atalhos

Android — HomeFragment + HomeAdapter

A grade é um RecyclerView com GridLayoutManager. O número de colunas é responsivo:

DispositivoColunas
Telefone (padrão)2 colunas
Tablet (sw600dp)3 colunas

Cada botão é representado pela classe interna ButtonData do HomeAdapter:

data class ButtonData(
    val id: Int,
    val text: String,
    val image: Int,       // drawable resource
    var isVisible: Boolean
)

A ordem dos botões é persistida em SharedPreferences("button_layout"), permitindo que o usuário reorganize os atalhos. Botões invisíveis ficam ao final da lista mas não aparecem na UI.

iOS — HomeViewController

Cards são renderizados dinamicamente em um UIScrollView com grade de 2 colunas via addVisibleCards(). Cada card é modelado pelo struct:

struct ScreenInfo {
    let id: Int
    let name: String
    let image: UIImage?
    let backgroundColor: UIColor
    var isVisible: Bool
    var permScreenName: String  // chave de permissão
    var isEnabled: Bool         // false = "em breve" / manutenção
}

Alterações de visibilidade são propagadas via protocolo ScreenInfoDelegatescreenVisibilityChanged(atIndex:isVisible:).

Módulos e Navegação

MóduloAndroid (destino nav)iOS (segue)Perm AndroidPerm iOS
Grid de Viagensnav_grid_tripgridSegue52, 53, 54VEI_V
Viagens (cadastro)nav_trips_buttonsnavCadTripSegue1, 8, 93, 94EMP
Mapa / Rastreamentonav_mapmapSegue1, 8VEI
Veículosnav_gridvehiclesSegue1, 8RAS_C
Minhas Viagensnav_trip_menu_driverdriverSegue1, 8, 99CHE_C
Desconsideraçãonav_disregardnavDisregard1, 8USE
Checklistnav_checklistbuttonsSegue1, 8, 141CHE_C
Relatóriosnav_report1, 115
Jornadanav_journey1, 8, 99
Botão desabilitado (iOS): quando isEnabled = false o card exibe o overlay "Em Breve" e não navega. No Android o mesmo efeito é obtido via botão de "Coming Soon" (HomeAdapter.addComingSoonButton()).

Controle de Permissões

Android

As permissões são lidas de SharedPreferences("DATA"), chave "perms_user" (JSON array de strings). O HomeFragment itera os botões e chama adapter.updateVisibility() com base nos códigos presentes:

// Exemplos de verificação
permissionsJson.contains("52")   // acesso ao Grid
permissionsJson.contains("141")  // acesso ao Checklist
permissionsJson.contains("115")  // acesso a Relatórios

iOS

Permissões são lidas do UserDefaults como strings nomeadas. configButtons() percorre o array screens e define isVisible em cada ScreenInfo:

// Chaves de permissão iOS
"VEI_V"  → Grid de veículos
"EMP"    → Viagens / cadastro
"RAS_C"  → Veículos
"VEI"    → Mapa
"CHE_C"  → Checklist / Minhas Viagens
"USE"    → Desconsideração

Papéis de usuário

PapelAcesso
masterTodos os módulos disponíveis conforme permissões da empresa
motoristaApenas "Minhas Viagens" (nav_trip_menu_driver / driverSegue)
responsavelSubconjunto configurável de módulos
Android: O papel é lido de SharedPreferences("user_id"), chave "user_role". Motoristas recebem onResume() acionando os serviços de localização automaticamente.

Localização em Tempo Real (Motoristas)

Android — FusedLocationProviderClient

Para usuários com papel motorista, o HomeFragment.onResume() solicita permissões de localização em foreground e background. A localização é enviada ao backend via serviço de background.

// Verificação de papel no onResume
if (userRole == "motorista") {
    requestForegroundLocationPermission()
    requestBackgroundLocationPermission()
}

iOS — CLLocationManager + WebSocket

O HomeViewController implementa CLLocationManagerDelegate e URLSessionWebSocketDelegate. A localização é transmitida em tempo real via WebSocket:

// Servidor WebSocket
wss://socket.monisat.online:6001   // produção

// Payload enviado
struct UserLocationData: Codable {
    var lat: CLLocationDegrees
    var lng: CLLocationDegrees
    var time: CLong        // Unix timestamp
    var battery: Int       // nível de bateria (%)
    var interval: Double   // intervalo de envio (segundos)
    var speed: Double      // velocidade (m/s)
}

O WebSocketService mantém resiliência com reconexão automática (exponential backoff) e cache local de localizações para períodos offline (saveInCacheLocation(_:)sendCachedLocations() ao reconectar).

Badge de Notificações

Ambas as plataformas exibem um badge numérico no atalho de notificações indicando mensagens não lidas.

PlataformaImplementaçãoFonte dos dados
AndroidBadge na TextView do botão Notificações no headerFirebase FCM + contagem local
iOSfetchAndUpdateNotificationBadge() chamado no viewWillAppearElasticsearch (POST /usuario_notificacao/_search)

Carrossel PagFriday (iOS)

O iOS exibe um carrossel de conteúdo promocional acima da grade de módulos, modelado por:

struct PagFridayNews {
    // dados do item promocional exibido no carrossel
}

O container (pagFridayContainer) é inserido no topo do UIScrollView e atualizado via chamada à API. Se não houver conteúdo, o container é ocultado.

Botões de Contato

Ambas as plataformas exibem dois botões fixos no rodapé da Home para contato com o suporte Monisat:

BotãoAçãoAndroidiOS
Ligar para Monisattel: intent / URLic_phone_contactÍcone de telefone
Converse com a MonisatDeep link WhatsAppic_whatsapp_contactÍcone WhatsApp

No Android os botões ficam em um MaterialCardView separado por um divisor vertical. Um AlertDialog de confirmação é exibido antes de abrir o discador ou o WhatsApp.

Diálogo de Saída (Android)

O HomeFragment intercepta o botão físico de voltar (OnBackPressedCallback) e exibe um AlertDialog perguntando se o usuário deseja sair do app. Não há comportamento equivalente no iOS (o app fica em background pelo sistema operacional).

API utilizada

GET https://api.monisat.online/searchTrips/{company_id}
Endpoint legado usado pelo HomeViewModel para buscar resumo de viagens da empresa. Autenticação via Client-Id / User-Id / Token nos headers. O company_id é lido de SharedPreferences("DATA").
Este endpoint pertence à API legada (api.monisat.online). A migração para api.monisystem.com/v1 ainda não foi aplicada ao HomeViewModel.
POST https://elastic.monisat.online:443/usuario_notificacao/_search
Elasticsearch — usado pelo iOS para contar notificações não lidas e atualizar o badge na Home.

SharedPreferences relevantes (Android)

Nome do arquivoChaveUso
DATAperms_userJSON array de permissões do usuário
DATAcompany_idEmpresa selecionada (usada na chamada à API)
user_iduser_rolePapel do usuário: master / motorista / responsavel
button_layout(serializado)Ordem e visibilidade dos botões da grade