DocumentaçãoDocumentationDocumentaciónOne Conecta
ÍndiceIndexÍndice
Baixar .mdDownload .mdBajar .md
Feature · ConfiguraçõesFeature · SettingsFeature · Configuración

ConfiguraçõesSettingsConfiguración

A tela de Configurações do representante de vendas: informações da conta e do app, dados do aparelho, aviso de atualização disponível e — onde o mercado habilita — a placa do veículo, o único campo editável. É uma tela de leitura; a única escrita é a placa, que sobe por uma transação do Dispatcher. The sales rep's Settings screen: account and app info, device info, an "update available" notice and — where the market enables it — the vehicle plate, the only editable field. It's a read screen; the only write is the plate, which is uploaded via a Dispatcher transaction. La pantalla de Configuración del representante de ventas: información de la cuenta y de la app, datos del dispositivo, aviso de actualización disponible y — donde el mercado lo habilita — la matrícula del vehículo, el único campo editable. Es una pantalla de lectura; la única escritura es la matrícula, que se sube mediante una transacción del Dispatcher.

PúblicoAudiencePúblico
Representante · QA · Suporte · DevRep · QA · Support · DevRepresentante · QA · Soporte · Dev
Onde ficaWhereDónde
Menu lateral → ConfiguraçõesDrawer → SettingsMenú lateral → Configuración
EscritaWriteEscritura
Placa → Dispatcher (BR)Plate → Dispatcher (BR)Matrícula → Dispatcher (BR)
AtualizadoUpdatedActualizado
22/07/20262026-07-22
Disponível emAvailable inDisponible en BR CL ZA
01

O que é e para que serveWhat it is and what it's forQué es y para qué sirve

A tela de Configurações reúne, num só lugar, o que o representante de vendas precisa saber sobre a própria sessão e o aparelho, e um punhado de ações de manutenção. Não há preferências de tema, idioma ou notificação aqui — o app resolve isso por mercado e por sistema. O que a tela mostra: The Settings screen gathers, in one place, what the sales rep needs to know about their own session and device, plus a handful of maintenance actions. There are no theme, language or notification preferences here — the app resolves those per market and per system. What the screen shows: La pantalla de Configuración reúne, en un solo lugar, lo que el representante de ventas necesita saber sobre su propia sesión y el dispositivo, más un puñado de acciones de mantenimiento. No hay preferencias de tema, idioma o notificación aquí — la app las resuelve por mercado y por sistema. Lo que la pantalla muestra:

Quem sou eu?Who am I?¿Quién soy?

Usuário, tipo de representante e se é o representante primário — mais a versão do app.Username, rep type and whether it's the primary rep — plus the app version.Usuario, tipo de representante y si es el representante primario — más la versión de la app.

Qual é o aparelho?Which device?¿Qué dispositivo?

Fabricante, modelo, versão do Android e nível de SDK — o que o suporte pede primeiro.Manufacturer, model, Android version and SDK level — what support asks for first.Fabricante, modelo, versión de Android y nivel de SDK — lo primero que pide soporte.

Preciso atualizar?Do I need to update?¿Debo actualizar?

Um card de aviso aparece quando há uma nova versão; tocar abre o fluxo de atualização.A notice card appears when a new version exists; tapping opens the update flow.Aparece una tarjeta de aviso cuando hay una nueva versión; tocarla abre el flujo de actualización.

Placa do veículoVehicle plateMatrícula del vehículo

Onde o mercado habilita, um campo editável para registrar a placa do carro do representante.Where the market enables it, an editable field to record the rep's car plate.Donde el mercado lo habilita, un campo editable para registrar la matrícula del auto del representante.

02

Como acessarHow to openCómo acceder

  1. Abra o menu lateralOpen the drawerAbra el menú lateralToque no ícone de menu numa das telas base (Home, Visitas, Pedidos).Tap the menu icon on one of the base screens (Home, Visits, Orders).Toque el ícono de menú en una de las pantallas base (Home, Visitas, Pedidos).
  2. Toque em "Configurações"Tap "Settings"Toque "Configuración"O item aparece no menu somente onde o mercado o habilita (BR/CL/ZA). A tela é empurrada como rota, com seta de voltar.The item appears in the drawer only where the market enables it (BR/CL/ZA). The screen is pushed as a route, with a back arrow.El ítem aparece en el menú solo donde el mercado lo habilita (BR/CL/ZA). La pantalla se empuja como ruta, con flecha de volver.
  3. A tela abreThe screen opensLa pantalla abreMostra cabeçalho, aviso de atualização (se houver), conta, placa (onde habilitada) e informações do sistema.Shows the header, update notice (if any), account, plate (where enabled) and system info.Muestra el encabezado, aviso de actualización (si lo hay), cuenta, matrícula (donde está habilitada) e información del sistema.
03

Estrutura da telaScreen structureEstructura de la pantalla

Última sincronizaçãoLast syncÚltima sincronización
Uma linha DataLoadInfo no topo, com a data da última sincronização dos dados do representante de vendas.A DataLoadInfo line at the top, with the last-sync date of the sales rep's data.Una línea DataLoadInfo arriba, con la fecha de última sincronización de los datos del representante de ventas.
CabeçalhoHeaderEncabezado
Ícone de engrenagem + título "Configurações".Gear icon + "Settings" title.Ícono de engranaje + título "Configuración".
Card de atualizaçãoUpdate cardTarjeta de actualización
Aparece só quando há uma atualização que exige aviso (Android). Mostra a versão nova; tocar abre o modal de atualização.Shows only when there's an update that requires a prompt (Android). Displays the new version; tapping opens the update modal.Aparece solo cuando hay una actualización que exige aviso (Android). Muestra la versión nueva; tocarla abre el modal de actualización.
Card da contaAccount cardTarjeta de cuenta
Versão do app, usuário, tipo de representante e "primário: sim/não".App version, username, rep type and "primary: yes/no".Versión de la app, usuario, tipo de representante y "primario: sí/no".
Card da placaPlate cardTarjeta de matrícula
Campo somente-leitura com ícone de lápis; aparece só onde o mercado habilita o campo. Tocar abre o modal de edição.Read-only field with a pencil icon; appears only where the market enables the field. Tapping opens the edit modal.Campo de solo lectura con ícono de lápiz; aparece solo donde el mercado habilita el campo. Tocarlo abre el modal de edición.
Card do sistemaSystem cardTarjeta del sistema
"Android" + fabricante, modelo, SDK e versão do sistema do aparelho."Android" + manufacturer, model, SDK and system version of the device."Android" + fabricante, modelo, SDK y versión del sistema del dispositivo.
04

Cartões e estadosCards & statesTarjetas y estados

A tela não tem "status" de negócio como um pedido. O que muda é quais cards aparecem, cada card decide sozinho se deve se mostrar:The screen has no business "status" like an order. What changes is which cards show up — each card decides on its own whether to render:La pantalla no tiene "estado" de negocio como un pedido. Lo que cambia es qué tarjetas aparecen — cada tarjeta decide por sí sola si debe mostrarse:

CardCardTarjetaAparece quandoShows whenAparece cuando
Aviso de atualizaçãoUpdate noticeAviso de actualizaciónAndroid e a severidade exige aviso e há URL de atualização. Senão, some.Android and the severity requires a prompt and there's an update URL. Otherwise, hidden.Android y la severidad exige aviso y hay URL de actualización. Si no, se oculta.
ContaAccountCuentaSempre.Always.Siempre.
Placa do veículoVehicle plateMatrículaO journeyConfig do mercado tem o campo car_license_plate visível para o tipo de representante. Hoje, só BR.The market's journeyConfig has the car_license_plate field visible for the rep type. Today, BR only.El journeyConfig del mercado tiene el campo car_license_plate visible para el tipo de representante. Hoy, solo BR.
SistemaSystemSistemaSempre.Always.Siempre.

Enquanto a tela carrega, um indicador de loading ocupa o centro; se a leitura falhar, uma tela de erro com "Tentar de novo" substitui todo o conteúdo.While the screen loads, a loading indicator fills the center; if the read fails, a full error view with "Retry" replaces all content.Mientras la pantalla carga, un indicador de carga ocupa el centro; si la lectura falla, una vista de error con "Reintentar" reemplaza todo el contenido.

05

Editar a placa do veículoEdit the vehicle plateEditar la matrícula

A placa é a única ação de escrita da tela, e só existe onde o mercado a habilita. O fluxo:The plate is the screen's only write action, and exists only where the market enables it. The flow:La matrícula es la única acción de escritura de la pantalla, y solo existe donde el mercado la habilita. El flujo:

  1. Toque no campo da placaTap the plate fieldToque el campo de la matrículaAbre um modal com um campo centralizado, em maiúsculas, limitado a 7 caracteres.Opens a modal with a centered, uppercase field, limited to 7 characters.Abre un modal con un campo centrado, en mayúsculas, limitado a 7 caracteres.
  2. Digite a placaType the plateEscriba la matrículaOnde o mercado exige validação (BR), a placa precisa ser válida (formato antigo AAA0000 ou Mercosul AAA0A00); senão o botão Salvar fica desabilitado e um erro aparece.Where the market requires validation (BR), the plate must be valid (legacy AAA0000 or Mercosul AAA0A00 format); otherwise Save stays disabled and an error shows.Donde el mercado exige validación (BR), la matrícula debe ser válida (formato antiguo AAA0000 o Mercosur AAA0A00); si no, Guardar queda deshabilitado y aparece un error.
  3. SalvarSaveGuardarA placa é normalizada, sobe pelo Dispatcher e — em sucesso — é gravada localmente. Um aviso verde confirma; um erro mostra a falha e mantém o modal aberto.The plate is normalized, uploaded via the Dispatcher and — on success — saved locally. A green notice confirms; an error shows the failure and keeps the modal open.La matrícula se normaliza, sube por el Dispatcher y — en éxito — se guarda localmente. Un aviso verde confirma; un error muestra el fallo y mantiene el modal abierto.

Sem mudança, sem envioNo change, no uploadSin cambio, sin envío Se a placa normalizada for igual à atual, nada é enviado — a operação retorna sucesso sem tocar o Dispatcher. If the normalized plate equals the current one, nothing is uploaded — the operation returns success without touching the Dispatcher. Si la matrícula normalizada es igual a la actual, no se envía nada — la operación retorna éxito sin tocar el Dispatcher.

06

Arquitetura e fluxo de dadosArchitecture & data flowArquitectura y flujo de datos

Clean Architecture + Riverpod + Freezed. A tela não tem proto próprio: ela compõe cinco fontes já existentes (nenhum RPC é disparado aqui) e tem uma única escrita — a placa, que vai pelo Dispatcher. Por isso há dois grafos distintos: leitura (composição) e escrita (transação).Clean Architecture + Riverpod + Freezed. The screen has no proto of its own: it composes five existing sources (no RPC is fired here) and has a single write — the plate, which goes through the Dispatcher. Hence two distinct graphs: read (composition) and write (transaction).Clean Architecture + Riverpod + Freezed. La pantalla no tiene proto propio: compone cinco fuentes existentes (no se dispara ningún RPC aquí) y tiene una única escritura — la matrícula, que va por el Dispatcher. De ahí dos grafos distintos: lectura (composición) y escritura (transacción).

Leitura — composição no build()Read — composition in build()Lectura — composición en build()

  • GetResourcesUseCaseresource · cache
    • DeviceInfoServicedevice_info_plus
      • PackageInfopackage_info_plus
        • marketConfigurationProviderEMC · journeyConfig
          • GetVehicleInfoUseCaseObjectBox local
            • await (paralelo)SettingsNotifier + State
              • → UISettingsPage

Escrita — salvar a placaWrite — saving the plateEscritura — guardar la matrícula

  • SettingsCarPlateEditModalContentonSave
    • saveCarLicensePlateSettingsNotifier
      • build(input)BuildCarLicensePlate…UseCaseDispatcherEnvelope
        • submit(envelope)SubmitCarLicensePlateUseCase→ DispatcherOrchestrator
          • on SuccessSaveVehicleInfoUseCaseObjectBox local
            • state.copyWithSettingsState

A escrita é remote-first (§36): dispara a transação primeiro, grava no cache local só depois do sucesso.The write is remote-first (§36): fires the transaction first, writes to local cache only after success.La escritura es remote-first (§36): dispara la transacción primero, graba en caché local solo tras el éxito.

07

Modelo de dadosData modelModelo de datos

Settings não tem uma entidade única nem um proto próprio: o SettingsState é uma composição de dados de cinco origens diferentes, montada no build() do Notifier. Só uma dessas origens — a placa (VehicleInfo) — atravessa camadas de dados (Entity ↔ Model, ObjectBox local); as demais chegam prontas de subsistemas já documentados (resource, EMC) ou de plugins de plataforma (device info, package info).Settings has no single entity and no proto of its own: SettingsState is a composition of data from five different sources, assembled in the Notifier's build(). Only one of those sources — the plate (VehicleInfo) — crosses data layers (Entity ↔ Model, local ObjectBox); the rest arrive ready from already-documented subsystems (resource, EMC) or platform plugins (device info, package info).Settings no tiene una entidad única ni un proto propio: SettingsState es una composición de datos de cinco orígenes distintos, armada en el build() del Notifier. Solo uno de esos orígenes — la matrícula (VehicleInfo) — atraviesa capas de datos (Entity ↔ Model, ObjectBox local); el resto llega listo de subsistemas ya documentados (resource, EMC) o de plugins de plataforma (device info, package info).

Fontes de dadosData sourcesFuentes de datos

Cada campo do SettingsState e de onde vem — não há RPC próprio da tela:Each SettingsState field and where it comes from — there's no screen-owned RPC:Cada campo del SettingsState y de dónde viene — no hay RPC propio de la pantalla:

Campo do StateState fieldCampo del StateTipoTypeTipoOrigemOriginOrigen
appVersionStringPackageInfo.fromPlatform() · package_info_plus
resourceResourceEntityGetResourcesUseCaseresources.resources.firstOrNull
deviceInfoDeviceInfoEntityDeviceInfoService.getDeviceInfo() · device_info_plus
carLicensePlateStringGetVehicleInfoUseCaseVehicleInfoEntity.carLicensePlate ("" se ausenteif absentsi ausente)
fieldsList<JourneyFieldConfig>MarketConfiguration.journeyConfig.visibleSettingsFieldsFor(repType)
lastSyncAtDateTime?resources.lastSyncAt

Estruturas de dadosData structuresEstructuras de datos

Um dropdown por estrutura. VehicleInfo é a única que persiste localmente (Entity ↔ Model, sem DTO nem proto); DeviceInfo e JourneyFieldConfig são só Entity (montadas de plugin/EMC). A ResourceEntity pertence ao subsistema de sessão — documentada à parte.One dropdown per structure. VehicleInfo is the only one that persists locally (Entity ↔ Model, no DTO or proto); DeviceInfo and JourneyFieldConfig are Entity-only (built from plugin/EMC). ResourceEntity belongs to the session subsystem — documented separately.Un dropdown por estructura. VehicleInfo es la única que persiste localmente (Entity ↔ Model, sin DTO ni proto); DeviceInfo y JourneyFieldConfig son solo Entity (armadas de plugin/EMC). La ResourceEntity pertenece al subsistema de sesión — documentada aparte.

  • VehicleInfo persistida (local)persisted (local)persistida (local) 1 campofieldcampo
    CampoModelEntity
    id@Id int
    carLicensePlateStringString

    Linha única no ObjectBox: o id existe só no Model (chave da box) e é reaproveitado a cada save. A Entity carrega apenas a placa.Single row in ObjectBox: id exists only in the Model (box key) and is reused on every save. The Entity carries just the plate.Fila única en ObjectBox: el id existe solo en el Model (clave de la box) y se reutiliza en cada save. La Entity lleva solo la matrícula.

  • DeviceInfo Entity-only 4 camposfieldscampos
    CampoEntityOrigem (plugin)Origin (plugin)Origen (plugin)
    manufacturerStringandroidInfo.manufacturer
    modelStringandroidInfo.model
    sdkIntintandroidInfo.version.sdkInt
    systemVersionStringandroidInfo.version.release
  • JourneyFieldConfig EMC 4 camposfieldscampos
    CampoEntitydefault
    fieldJourneyFieldTypeunknown
    isVisiblebooltrue
    requiresValidationboolfalse
    allowedResourceTypesList<ResourceTypeItem>[]

    Getter isEnabledFor(repType): isVisible e (allowedResourceTypes vazio ou contém o tipo). Filtra quais campos da jornada aparecem em Settings.Getter isEnabledFor(repType): isVisible and (allowedResourceTypes empty or contains the type). Filters which journey fields appear in Settings.Getter isEnabledFor(repType): isVisible y (allowedResourceTypes vacío o contiene el tipo). Filtra qué campos de la jornada aparecen en Settings.

  • CarLicensePlateDispatcherPayloadInput entrada de escritawrite inputentrada de escritura 4 camposfieldscampos
    CampoEntitydefault
    carLicensePlateString
    resourceResourceEntity
    submittedAtDateTime
    isTradePlateboolfalse

    Input cru (entities de domínio) — toda construção wire (normalizar placa, extrair resourceSfid/username, formatar data, isTradePlate) mora no build() do builder (§36). O Notifier injeta submittedAt: DateTimeUtils.now() e isTradePlate: true.A raw input (domain entities) — all wire construction (normalize the plate, extract resourceSfid/username, format the date, isTradePlate) lives in the builder's build() (§36). The Notifier injects submittedAt: DateTimeUtils.now() and isTradePlate: true.Input crudo (entities de dominio) — toda construcción wire (normalizar matrícula, extraer resourceSfid/username, formatear fecha, isTradePlate) vive en el build() del builder (§36). El Notifier inyecta submittedAt: DateTimeUtils.now() e isTradePlate: true.

Mappers

VehicleInfo tem mapper — duas direções (sem JSON/Proto/DTO, é local puro):Only VehicleInfo has a mapper — two directions (no JSON/Proto/DTO, it's local-only):Solo VehicleInfo tiene mapper — dos direcciones (sin JSON/Proto/DTO, es local puro):

DireçãoDirectionDirecciónMétodoMethodMétodo
Entity → ModeltoModel()
Model → EntitytoDomain()

Os únicos deltasThe only deltasLos únicos deltas

  • nenhum proto/DTO — Settings não faz gRPC de leiturano proto/DTO — Settings does no read gRPCsin proto/DTO — Settings no hace gRPC de lectura
  • VehicleInfoModel.id existe só no Model (chave ObjectBox), reaproveitado no saveexists only in the Model (ObjectBox key), reused on saveexiste solo en el Model (clave ObjectBox), reutilizado en el save
  • DeviceInfo / JourneyFieldConfig são Entity-only (sem Model)are Entity-only (no Model)son Entity-only (sin Model)
  • a escrita normaliza a placa (VehiclePlateUtils.normalize) antes de enviar e gravarthe write normalizes the plate (VehiclePlateUtils.normalize) before uploading and savingla escritura normaliza la matrícula (VehiclePlateUtils.normalize) antes de enviar y guardar
08

Repository

A tela consome vários repositórios, mas o único que ela possui é o VehicleInfoRepositoryImpl (implements VehicleInfoRepositoryInterface), que injeta só o datasource local — é local puro, sem rede. Os demais (resource, EMC, updater) são de subsistemas próprios. Método a método:The screen consumes several repositories, but the only one it owns is VehicleInfoRepositoryImpl (implements VehicleInfoRepositoryInterface), which injects only the local datasource — it's local-only, no network. The rest (resource, EMC, updater) belong to their own subsystems. Method by method:La pantalla consume varios repositorios, pero el único que posee es VehicleInfoRepositoryImpl (implements VehicleInfoRepositoryInterface), que inyecta solo el datasource local — es local puro, sin red. Los demás (resource, EMC, updater) son de subsistemas propios. Método a método:

getVehicleInfo() local

RetornaReturnsDevuelve Result<VehicleInfoEntity?, Failure>

Lê a linha única do ObjectBox (firstOrNull); null vira Success(null). Exceção de cache → Error(Failure) via FailureMapper.Reads the single ObjectBox row (firstOrNull); null becomes Success(null). Cache exception → Error(Failure) via FailureMapper.Lee la fila única del ObjectBox (firstOrNull); null es Success(null). Excepción de caché → Error(Failure) vía FailureMapper.

saveVehicleInfo({vehicleInfo}) local

RetornaReturnsDevuelve Result<void, Failure>

Grava a placa na box (regravando a mesma linha). Chamado depois do envio da transação (remote-first). Exceção → Error(Failure).Writes the plate to the box (rewriting the same row). Called after the transaction upload (remote-first). Exception → Error(Failure).Graba la matrícula en la box (regrabando la misma fila). Llamado después del envío de la transacción (remote-first). Excepción → Error(Failure).

09

Datasources

Um card por fonte. A tela usa um datasource ObjectBox próprio (placa) e dois serviços de plataforma (aparelho, versão) — sem datasource remoto de leitura.One card per source. The screen uses its own ObjectBox datasource (plate) and two platform services (device, version) — no remote read datasource.Un card por fuente. La pantalla usa un datasource ObjectBox propio (matrícula) y dos servicios de plataforma (dispositivo, versión) — sin datasource remoto de lectura.

Local VehicleInfoLocalDataSource ObjectBox

Envio / fluxo: persistência local via ObjectBox (box VehicleInfoModel), linha única — sem rede. Erro: falhas viram CacheException (propagada, não engolida).Sends / flow: local persistence via ObjectBox (VehicleInfoModel box), single row — no network. Error: failures become CacheException (propagated, not swallowed).Envío / flujo: persistencia local vía ObjectBox (box VehicleInfoModel), fila única — sin red. Error: fallos son CacheException (propagada, no tragada).

getVehicleInfo()
RetornoReturnRetorno
VehicleInfoEntity?
ComportamentoBehaviorComportamiento
_box.getAll().firstOrNull?.toDomain()
saveVehicleInfo({vehicleInfo})
RetornoReturnRetorno
void
ComportamentoBehaviorComportamiento
toModel(), reaproveita o id existente (ou 0) e faz _box.put(model) — sempre a mesma linha.toModel(), reuses the existing id (or 0) and _box.put(model) — always the same row.toModel(), reutiliza el id existente (o 0) y _box.put(model) — siempre la misma fila.
Service DeviceInfoService device_info_plus
getDeviceInfo()
RetornoReturnRetorno
Future<DeviceInfoEntity>
EnvioSendsEnvío
_deviceInfoPlugin.androidInfo e mapeia manufacturer/model/sdkInt/systemVersion.reads _deviceInfoPlugin.androidInfo and maps manufacturer/model/sdkInt/systemVersion.lee _deviceInfoPlugin.androidInfo y mapea manufacturer/model/sdkInt/systemVersion.
Tratamento de erroError handlingManejo de errores
Android-only — lê apenas androidInfo.Android-only — reads androidInfo only.Android-only — lee solo androidInfo.
Plugin PackageInfo package_info_plus
EnvioSendsEnvío
PackageInfo.fromPlatform()
RetornoReturnRetorno
o Notifier usa só .version (a versão do app).the Notifier uses only .version (the app version).el Notifier usa solo .version (la versión de la app).
10

Enums e labelsEnums & labelsEnums y labels

Um dropdown por enum, todos os valores. AppUpdateSeverity (usado pelo card de atualização) pertence ao subsistema de update — não listado aqui.One dropdown per enum, all values. AppUpdateSeverity (used by the update card) belongs to the update subsystem — not listed here.Un dropdown por enum, todos los valores. AppUpdateSeverity (usado por la tarjeta de actualización) pertenece al subsistema de actualización — no listado aquí.

JourneyFieldType 4 valoresvaluesvalores
casevalueavailableInSettingsavailableOnFinish
odometerodometerfalsetrue
carLicensePlatecar_license_platetruefalse
printerMacAddressprinter_mac_addresstruefalse
unknownunknownfalsefalse

fromString normaliza (lowercase, espaços/hífens → _) e loga valor não mapeado. Settings só considera os campos com availableInSettings == true.fromString normalizes (lowercase, spaces/hyphens → _) and logs unmapped values. Settings only considers fields with availableInSettings == true.fromString normaliza (minúsculas, espacios/guiones → _) y registra valores no mapeados. Settings solo considera los campos con availableInSettings == true.

ResourceTypeItem 8 valoresvaluesvalores
casevalue
preSalesRepPre-sales Rep
promptSalesRepPrompt-sales Rep
universalRepUniversal Rep
deliveryRepDelivery Rep
telesalesAnalystTelesales Analyst
webAgentDirectWeb Agent - Direct
tradeMarketingRepTrade Marketing Rep
unknownunknown

Derivado de resource.resourceType via fromString; usado para decidir a visibilidade dos campos da jornada por tipo de representante (allowedResourceTypes).Derived from resource.resourceType via fromString; used to decide journey-field visibility per rep type (allowedResourceTypes).Derivado de resource.resourceType vía fromString; usado para decidir la visibilidad de los campos de la jornada por tipo de representante (allowedResourceTypes).

DispatcherType.odometerCarPlate tipo de escritawrite typetipo de escritura
PropriedadePropertyPropiedadvalue
serviceNameCarLicensePlate
destinationDispatcherDestination.batchApi
enabledMarkets[EndMarket.BR]

É o DispatcherType que a placa usa. O serviceName discrimina a transação; enabledMarkets confirma que a escrita é só BR.It's the DispatcherType the plate uses. serviceName discriminates the transaction; enabledMarkets confirms the write is BR-only.Es el DispatcherType que usa la matrícula. serviceName discrimina la transacción; enabledMarkets confirma que la escritura es solo BR.

11

UseCases

Um dropdown por UseCase, com tipos de retorno exatos.One dropdown per UseCase, with exact return types.Un dropdown por UseCase, con tipos de retorno exactos.

GetResourcesUseCase sessãosessionsesión
MétodoRetornaUso
execute()Result<ResourcesEntity?, Failure>representante de vendas do cache; o Notifier usa resources.firstOrNull e lastSyncAt.the sales rep from cache; the Notifier uses resources.firstOrNull and lastSyncAt.el representante de ventas del caché; el Notifier usa resources.firstOrNull y lastSyncAt.
GetVehicleInfoUseCase
MétodoRetornaUso
execute()Result<VehicleInfoEntity?, Failure>lê a placa gravada; erro/null → placa vazia ("").reads the stored plate; error/null → empty plate ("").lee la matrícula guardada; error/null → matrícula vacía ("").
SaveVehicleInfoUseCase
MétodoRetornaUso
execute({carLicensePlate})Result<void, Failure>grava a placa (já normalizada) localmente, após o envio.writes the (already normalized) plate locally, after upload.graba la matrícula (ya normalizada) localmente, tras el envío.
BuildCarLicensePlateDispatcherPayloadUseCase builder
MétodoRetornaUso
build({input})DispatcherEnvelopeimplements DispatcherPayloadBuilder; monta o payload JSON e o envelope (type odometerCarPlate).implements DispatcherPayloadBuilder; builds the JSON payload and envelope (type odometerCarPlate).implements DispatcherPayloadBuilder; arma el payload JSON y el envelope (type odometerCarPlate).

Payload: CarLicensePlate (normalizado), resourceSfid, username, date (yyyy-MM-dd HH:mm:ss), isTradePlate. transactionReference = resource.sfid.Payload: CarLicensePlate (normalized), resourceSfid, username, date (yyyy-MM-dd HH:mm:ss), isTradePlate. transactionReference = resource.sfid.Payload: CarLicensePlate (normalizado), resourceSfid, username, date (yyyy-MM-dd HH:mm:ss), isTradePlate. transactionReference = resource.sfid.

SubmitCarLicensePlateUseCase
MétodoRetornaUso
submit({envelope})Result<DispatcherAck, Failure>delega ao DispatcherOrchestrator.dispatch (store/tracking/reenvio).delegates to DispatcherOrchestrator.dispatch (store/tracking/retry).delega al DispatcherOrchestrator.dispatch (store/tracking/reenvío).
12

Notifier & State

O SettingsNotifier (@riverpod, FutureOr<SettingsState> build()) monta a tela. O build() dispara as cinco leituras em paralelo (resource, device info, package info, market config, vehicle info) e faz await de todas; resolve o tipo de representante e filtra os campos da jornada visíveis em Settings. O State (SettingsState, Freezed) é a fonte única de verdade da page. Diferente das telas de lista, aqui não há refresh() de pull-to-refresh — a page não tem esse gesto; o erro é recuperado via ref.invalidate na tela de falha.The SettingsNotifier (@riverpod, FutureOr<SettingsState> build()) assembles the screen. build() fires the five reads in parallel (resource, device info, package info, market config, vehicle info) and awaits them all; resolves the rep type and filters journey fields visible in Settings. The State (SettingsState, Freezed) is the page's single source of truth. Unlike list screens, there's no pull-to-refresh refresh() here — the page has no such gesture; errors recover via ref.invalidate on the failure view.El SettingsNotifier (@riverpod, FutureOr<SettingsState> build()) arma la pantalla. El build() dispara las cinco lecturas en paralelo (resource, device info, package info, market config, vehicle info) y hace await de todas; resuelve el tipo de representante y filtra los campos de la jornada visibles en Settings. El State (SettingsState, Freezed) es la fuente única de verdad de la page. A diferencia de las pantallas de lista, aquí no hay refresh() de pull-to-refresh — la page no tiene ese gesto; el error se recupera vía ref.invalidate en la vista de fallo.

MétodosMethodsMétodos

build() async

RetornoReturnRetorno FutureOr<SettingsState>

Observa getResourcesUseCaseProvider; dispara as 5 leituras em paralelo e aguarda. Sem representante → throw BusinessFailure; resource nulo do cache → throw CacheFailure. Monta o State com appVersion, resource, deviceInfo, carLicensePlate, fields e lastSyncAt.Watches getResourcesUseCaseProvider; fires the 5 reads in parallel and awaits. No rep → throw BusinessFailure; null resource from cache → throw CacheFailure. Assembles the State with appVersion, resource, deviceInfo, carLicensePlate, fields and lastSyncAt.Observa getResourcesUseCaseProvider; dispara las 5 lecturas en paralelo y espera. Sin representante → throw BusinessFailure; resource nulo del caché → throw CacheFailure. Arma el State con appVersion, resource, deviceInfo, carLicensePlate, fields y lastSyncAt.

saveCarLicensePlate({carLicensePlate}) write

RetornoReturnRetorno Future<Failure?> (null = sucesso)(null = success)(null = éxito)

Normaliza a placa; se igual à atual, retorna null sem enviar. Senão: build(input) do envelope → submit(envelope) (Dispatcher); em erro retorna a Failure. Em sucesso: SaveVehicleInfoUseCase.execute local e state = AsyncValue.data(current.copyWith(carLicensePlate: normalized)).Normalizes the plate; if equal to current, returns null without uploading. Otherwise: envelope build(input)submit(envelope) (Dispatcher); on error returns the Failure. On success: local SaveVehicleInfoUseCase.execute and state = AsyncValue.data(current.copyWith(carLicensePlate: normalized)).Normaliza la matrícula; si es igual a la actual, retorna null sin enviar. Si no: build(input) del envelope → submit(envelope) (Dispatcher); en error retorna la Failure. En éxito: SaveVehicleInfoUseCase.execute local y state = AsyncValue.data(current.copyWith(carLicensePlate: normalized)).

State disponível para a PageState available to the PageState disponible para la Page

SettingsState campos + gettersfields + getterscampos + getters
campotipodefault
appVersionStringrequired
resourceResourceEntityrequired
deviceInfoDeviceInfoEntityrequired
carLicensePlateString""
fieldsList<JourneyFieldConfig>[]
lastSyncAtDateTime?null

Getters: showField(type)bool (o campo da jornada está na lista), fieldRequiresValidation(type)bool (exige validação de placa). O privado _fieldConfig(type) resolve o JourneyFieldConfig pelo tipo.Getters: showField(type)bool (the journey field is in the list), fieldRequiresValidation(type)bool (requires plate validation). Private _fieldConfig(type) resolves the JourneyFieldConfig by type.Getters: showField(type)bool (el campo de la jornada está en la lista), fieldRequiresValidation(type)bool (exige validación de matrícula). El privado _fieldConfig(type) resuelve el JourneyFieldConfig por tipo.

13

Page e widgetsPage & widgetsPage y widgets

A SettingsPage (ConsumerWidget) observa o settingsProvider. Loading e erro são globais (stateAsync.when); o conteúdo existe só no ramo data. Cada card decide sozinho se aparece (early-return SizedBox.shrink()). Todos os cards usam o container compartilhado SettingsCardWidget (raio xxl30). Árvore de composição:SettingsPage (ConsumerWidget) watches settingsProvider. Loading and error are global (stateAsync.when); content exists only in the data branch. Each card decides on its own whether to render (early-return SizedBox.shrink()). All cards use the shared SettingsCardWidget container (radius xxl30). Composition tree:La SettingsPage (ConsumerWidget) observa el settingsProvider. Loading y error son globales (stateAsync.when); el contenido existe solo en la rama data. Cada tarjeta decide por sí sola si aparece (early-return SizedBox.shrink()). Todas usan el container compartido SettingsCardWidget (radio xxl30). Árbol de composición:

  • SettingsPage
    • AppPageShell displayBackButton
      • CustomLoadingIndicator loading
      • FailureStateView error → invalidate
      • SingleChildScrollView data
        • DataLoadInfo lastSyncAt
        • SettingsHeaderWidget gear + título
        • SettingsUpdateAvailableCardWidget Android + severity.requiresPrompt → showAppUpdateModal
        • SettingsAccountCardWidget version · user · type · primary
        • SettingsCarPlateCardWidget showField(carLicensePlate) → CustomInput readOnly
          • SettingsCarPlateEditModalContent modal · input + validação → saveCarLicensePlate → ConectaNotice.success
        • SettingsSystemInfoCardWidget Android · manufacturer · model · SDK · versão

Notas por mercadoMarket notesMercados

A tela de Configurações é dirigida por configuração de mercado (End Market Configuration): o item aparece no menu lateral (menuItemType: settings) só onde o mercado o habilita. Está presente em três mercados:The Settings screen is driven by market configuration (End Market Configuration): the item appears in the drawer (menuItemType: settings) only where the market enables it. It's present in three markets:La pantalla de Configuración se rige por configuración de mercado (End Market Configuration): el ítem aparece en el menú lateral (menuItemType: settings) solo donde el mercado lo habilita. Está presente en tres mercados:

BRx CLx ZAx AR PY PE
disponívelavailabledisponible presente, desligadopresent, offpresente, apagado ausenteabsentausente

Dentro da tela, cada card tem a sua própria disponibilidade. A matriz completa (uma linha por card/ação):Inside the screen, each card has its own availability. The full matrix (one row per card/action):Dentro de la pantalla, cada tarjeta tiene su propia disponibilidad. La matriz completa (una fila por tarjeta/acción):

Card / açãoCard / actionTarjeta / acciónBRCLZAARPYPE
Tela (item do menu)Screen (drawer item)Pantalla (ítem del menú)xxx
Card da contaAccount cardTarjeta de cuentaxxx
Card de atualizaçãoUpdate cardTarjeta de actualizaciónxxx
Card do sistemaSystem cardTarjeta del sistemaxxx
Card da placa (journeyConfig)Plate card (journeyConfig)Tarjeta de matrícula (journeyConfig)x
Validação da placa (requiresValidation)Plate validation (requiresValidation)Validación de matrícula (requiresValidation)x
Escrita da placa (odometerCarPlate)Plate write (odometerCarPlate)Escritura de matrícula (odometerCarPlate)x
BR

Só no BrasilBrazil onlySolo Brasil O journeyConfig do BR inclui o campo car_license_plate com requiresValidation: true — só aqui o card da placa aparece, com validação de placa brasileira (formato antigo ou Mercosul), e a escrita sobe pela transação CarLicensePlate (odometerCarPlate, batchApi, BR-only). BR's journeyConfig includes the car_license_plate field with requiresValidation: true — only here does the plate card appear, with Brazilian plate validation (legacy or Mercosul), and the write uploads via the CarLicensePlate transaction (odometerCarPlate, batchApi, BR-only). El journeyConfig de BR incluye el campo car_license_plate con requiresValidation: true — solo aquí aparece la tarjeta de matrícula, con validación de matrícula brasileña (antigua o Mercosur), y la escritura sube por la transacción CarLicensePlate (odometerCarPlate, batchApi, solo BR).

CLZA

Chile · África do SulChile · South AfricaChile · Sudáfrica A tela existe e mostra conta, sistema e atualização, mas o journeyConfig desses mercados só tem odometer (que não é de Settings) — não há campo de placa, então o card não aparece. The screen exists and shows account, system and update, but these markets' journeyConfig only has odometer (not a Settings field) — no plate field, so the card doesn't appear. La pantalla existe y muestra cuenta, sistema y actualización, pero el journeyConfig de estos mercados solo tiene odometer (que no es de Settings) — no hay campo de matrícula, por lo que la tarjeta no aparece.

AR · PY · PE Existem como mercados do app (config PANGEA mínima), mas não têm o item settings no menu lateral — a tela não é acessível. They exist as app markets (minimal PANGEA config), but have no settings item in the drawer — the screen is not reachable. Existen como mercados de la app (config PANGEA mínima), pero no tienen el ítem settings en el menú lateral — la pantalla no es accesible.

Pendências / roadmapPending / roadmapPendientes / roadmap O JourneyFieldType.printerMacAddress já é marcado como availableInSettings: true no enum, mas nenhum mercado o habilita no journeyConfig e não há widget que o renderize em Settings hoje — é um campo previsto, ainda não implementado. Além disso, os cards de sistema e atualização são Android-only (o serviço lê só androidInfo; o card de update tem guard Platform.isAndroid). JourneyFieldType.printerMacAddress is already flagged availableInSettings: true in the enum, but no market enables it in journeyConfig and no widget renders it in Settings today — it's a planned, not-yet-implemented field. Also, the system and update cards are Android-only (the service reads only androidInfo; the update card has a Platform.isAndroid guard). JourneyFieldType.printerMacAddress ya está marcado como availableInSettings: true en el enum, pero ningún mercado lo habilita en journeyConfig y no hay widget que lo renderice en Settings hoy — es un campo previsto, aún no implementado. Además, las tarjetas de sistema y actualización son solo Android (el servicio lee solo androidInfo; la tarjeta de update tiene guard Platform.isAndroid).