Detalhe da visitaVisit detailDetalle de la visita
O cockpit da visita: reúne numa só tela o card do varejo, os indicadores de status, metas do mês e do dia, tarefas, painéis (boost plan, parceria, investimento inteligente, Conecta Prime), o último pedido e a grade de ferramentas que dá acesso a merchandising, pedido, financeiro, surveys e mais. É daqui que o representante de vendas faz o check-in (iniciar / finalizar). A leitura é só do cache — a Lista de visitas já baixou a visita. The visit cockpit: it gathers on one screen the retail card, status indicators, monthly and daily targets, tasks, dashboards (boost plan, partnership, smart investment, Conecta Prime), the last order and the tools grid that opens merchandising, order, financial, surveys and more. This is where the sales rep does the check-in (start / finish). The read is cache-only — the Visit list already downloaded the visit. El cockpit de la visita: reúne en una sola pantalla la tarjeta del punto de venta, los indicadores de estado, metas del mes y del día, tareas, paneles (boost plan, alianza, inversión inteligente, Conecta Prime), el último pedido y la grilla de herramientas que abre merchandising, pedido, financiero, surveys y más. Desde aquí el representante de ventas hace el check-in (iniciar / finalizar). La lectura es solo del caché — la Lista de visitas ya descargó la visita.
O que é e para que serveWhat it is and what it's forQué es y para qué sirve
O Detalhe da visita abre quando o representante de vendas toca num card da Lista de visitas. É o roteiro completo daquela visita: quem é o varejo, como ele está (status), o que precisa ser feito (tarefas), quais são as metas, e as ferramentas que ele pode usar durante o atendimento. É também o único lugar onde a visita é iniciada e finalizada (check-in). The Visit detail opens when the sales rep taps a card in the Visit list. It's the full playbook for that visit: who the retail is, how it's doing (status), what needs to be done (tasks), what the targets are, and the tools they can use during the call. It's also the only place where a visit is started and finished (check-in). El Detalle de la visita abre cuando el representante de ventas toca una tarjeta de la Lista de visitas. Es el guion completo de esa visita: quién es el punto de venta, cómo está (estado), qué hay que hacer (tareas), cuáles son las metas, y las herramientas que puede usar durante la atención. Es también el único lugar donde una visita se inicia y finaliza (check-in).
Quem é o varejo?Who is the retail?¿Quién es el punto de venta?
Card com nome, código, endereço, próxima/última visita e cinco indicadores de status.Card with name, code, address, next/previous visit and five status indicators.Tarjeta con nombre, código, dirección, próxima/última visita y cinco indicadores de estado.
O que fazer?What to do?¿Qué hacer?
Tarefas, metas do mês e do dia, painéis de performance — e a grade de ferramentas.Tasks, monthly and daily targets, performance dashboards — and the tools grid.Tareas, metas del mes y del día, paneles de desempeño — y la grilla de herramientas.
Iniciar / finalizarStart / finishIniciar / finalizar
Um botão faz o check-in. Antes de iniciar, ferramentas e tarefas pedem para começar a visita.A button does the check-in. Before starting, tools and tasks prompt to begin the visit.Un botón hace el check-in. Antes de iniciar, herramientas y tareas piden comenzar la visita.
Escopo desta telaScope of this screenAlcance de esta pantalla Esta doc cobre o que vive na tela do detalhe: card do varejo, status, metas, tarefas, painéis, último pedido, check-in e a grade de ferramentas. As ferramentas em si (pedido, merchandising, financeiro, price check, surveys, stock count, prime, calculadora de margem…) são telas próprias — o detalhe só navega até elas; cada uma tem sua própria doc. This doc covers what lives on the detail screen: retail card, status, targets, tasks, dashboards, last order, check-in and the tools grid. The tools themselves (order, merchandising, financial, price check, surveys, stock count, prime, margin calculator…) are their own screens — the detail only navigates to them; each has its own doc. Esta doc cubre lo que vive en la pantalla del detalle: tarjeta del punto de venta, estado, metas, tareas, paneles, último pedido, check-in y la grilla de herramientas. Las herramientas en sí (pedido, merchandising, financiero, price check, surveys, stock count, prime, calculadora de margen…) son pantallas propias — el detalle solo navega hacia ellas; cada una tiene su propia doc.
Como acessarHow to openCómo acceder
- Pela Lista de visitasFrom the Visit listDesde la Lista de visitasToque em qualquer card na aba Visitas, ou no botão flutuante da visita em andamento. É o caminho principal.Tap any card in the Visits tab, or the floating button of the in-progress visit. This is the main path.Toque cualquier tarjeta en la pestaña Visitas, o el botón flotante de la visita en curso. Es el camino principal.
- Por outros fluxosFrom other flowsDesde otros flujosVisitas do dia na Home e a visita ad hoc (criada a partir de Varejos) também abrem esta tela.Visits of the day on the Home and the ad hoc visit (created from Retails) also open this screen.Visitas del día en la Home y la visita ad hoc (creada desde Puntos de venta) también abren esta pantalla.
- A tela abreThe screen opensLa pantalla abreCom uma seta de voltar no topo, uma única coluna rolável e puxar para atualizar. Só recebe o
visitSfid— rebusca tudo do cache.With a back arrow at the top, a single scrollable column and pull to refresh. It only receives thevisitSfid— it re-fetches everything from cache.Con una flecha de volver arriba, una sola columna desplazable y deslizar para actualizar. Solo recibe elvisitSfid— re-obtiene todo del caché.
Estrutura da telaScreen structureEstructura de la pantalla
Uma coluna rolável, de cima para baixo. Cada bloco só aparece se o mercado o habilita (via End Market Configuration) e se há dado para mostrar — por isso a tela é bem diferente entre BR, CL e ZA (ver Mercados). A ordem é sempre a mesma:A single scrollable column, top to bottom. Each block appears only if the market enables it (via End Market Configuration) and there's data to show — that's why the screen looks quite different across BR, CL and ZA (see Markets). The order is always the same:Una columna desplazable, de arriba a abajo. Cada bloque aparece solo si el mercado lo habilita (vía End Market Configuration) y hay dato para mostrar — por eso la pantalla se ve bastante distinta entre BR, CL y ZA (ver Mercados). El orden es siempre el mismo:
- Última sincronizaçãoLast syncÚltima sincronización
- Faixa no topo com a data/hora do último sync — vem do container da Lista de visitas, não da visita individual.Top strip with the last sync date/time — comes from the Visit list container, not the individual visit.Franja superior con la fecha/hora del último sync — viene del contenedor de la Lista de visitas, no de la visita individual.
- Botão iniciar / finalizarStart / finish buttonBotón iniciar / finalizar
- Botão largo de check-in. Diz "Iniciar visita" (azul) ou "Finalizar visita" (laranja) conforme o status.Wide check-in button. Reads "Start visit" (blue) or "End visit" (orange) depending on status.Botón ancho de check-in. Dice "Iniciar visita" (azul) o "Finalizar visita" (naranja) según el estado.
- Card do varejoRetail cardTarjeta del punto de venta
- Código, nome, documento fiscal, endereço (com atalho Waze), datas da visita anterior/próxima e um botão que abre o Detalhe do varejo.Code, name, tax code, address (with Waze shortcut), previous/next visit dates and a button opening the Retail detail.Código, nombre, documento fiscal, dirección (con atajo Waze), fechas de visita anterior/próxima y un botón que abre el Detalle del punto de venta.
- Indicadores de statusStatus indicatorsIndicadores de estado
- Fila de ícones circulares (B2B, em dia/atrasado, concorrência, contrafação, ativo). Verde = ok, vermelho = atenção. Quais aparecem varia por mercado.Row of circular icons (B2B, compliant/overdue, competition, counterfeits, active). Green = ok, red = attention. Which ones show varies by market.Fila de íconos circulares (B2B, al día/atrasado, competencia, falsificación, activo). Verde = ok, rojo = atención. Cuáles aparecen varía por mercado.
- Pilares comerciaisCommercial pillarsPilares comerciales
- Grade de pilares comerciais do varejo (BR).Grid of the retail's commercial pillars (BR).Grilla de pilares comerciales del punto de venta (BR).
- Boost plan (roteiro)Boost plan (script)Boost plan (guion)
- Card com o texto do roteiro de abordagem do boost plan (BR).Card with the boost plan approach script text (BR).Tarjeta con el texto del guion de abordaje del boost plan (BR).
- Oportunidade de shareShare opportunityOportunidad de share
- Chips de KPI de investimento inteligente (BR).Smart investment KPI chips (BR).Chips de KPI de inversión inteligente (BR).
- TarefasTasksTareas
- Lista das tarefas do varejo (ícone + título + pílula de status), ordenadas por status e prazo. Tocar abre o detalhe da tarefa. Vazio = card "sem tarefas".List of the retail's tasks (icon + title + status pill), sorted by status and due date. Tapping opens the task detail. Empty = "no tasks" card.Lista de tareas del punto de venta (ícono + título + píldora de estado), ordenadas por estado y plazo. Tocar abre el detalle de la tarea. Vacío = tarjeta "sin tareas".
- Meta do diaTarget of the dayMeta del día
- Carrossel de metas do dia por categoria (realizado / meta / %).Carousel of daily targets by category (realized / target / %).Carrusel de metas del día por categoría (realizado / meta / %).
- Meta mensalMonthly targetMeta mensual
- Card por categoria com filtro (tipo) e barras por período (mês corrente / até hoje). Carrossel quando há mais de uma categoria (BR/ZA).Per-category card with a (type) filter and per-period bars (current month / month-to-date). Carousel when there's more than one category (BR/ZA).Tarjeta por categoría con filtro (tipo) y barras por período (mes corriente / hasta hoy). Carrusel cuando hay más de una categoría (BR/ZA).
- ParceriaPartnershipAlianza
- Painel de parceria: realizado × meta sugerida, parceiros sugeridos com barra de progresso e ticket médio (BR).Partnership dashboard: realized × suggested target, suggested partners with progress bar and average ticket (BR).Panel de alianza: realizado × meta sugerida, socios sugeridos con barra de progreso y ticket promedio (BR).
- Volume de entregaDelivery volumeVolumen de entrega
- Carrossel de acompanhamento de entrega por categoria (BR).Delivery tracking carousel by category (BR).Carrusel de seguimiento de entrega por categoría (BR).
- Último pedidoLast orderÚltimo pedido
- O último pedido do varejo (mesmo card da Lista de pedidos) + botão "ver últimos pedidos". Vazio = card "sem pedidos".The retail's last order (same card as the Order list) + "see latest orders" button. Empty = "no orders" card.El último pedido del punto de venta (misma tarjeta de la Lista de pedidos) + botón "ver últimos pedidos". Vacío = tarjeta "sin pedidos".
- Boost plan (painel)Boost plan (dashboard)Boost plan (panel)
- Barra de recompensa em degraus (compre mais / ganhe mais) + botão que abre o modal de bonificações (BR).Stepped reward bar (buy more / earn more) + button opening the bonuses modal (BR).Barra de recompensa escalonada (compre más / gane más) + botón que abre el modal de bonificaciones (BR).
- Conecta PrimeConecta PrimeConecta Prime
- Painel de fidelidade Prime: comprar & ganhar em degraus, bônus, ganho acumulado e um simulador (slider). Aparece só se o varejo é elegível (BR).Prime loyalty dashboard: stepped buy & earn, bonus, earned-so-far and a simulator (slider). Shows only if the retail is eligible (BR).Panel de fidelidad Prime: comprar & ganar escalonado, bono, ganancia acumulada y un simulador (slider). Aparece solo si el punto de venta es elegible (BR).
- Grade de ferramentasTools gridGrilla de herramientas
- Grade 4-colunas de atalhos (pedido, merchandising, financeiro, price check, surveys, stock, prime, calculadora de margem…). Cada ícone navega para outra tela. Quais aparecem é 100% definido pelo mercado.4-column grid of shortcuts (order, merchandising, financial, price check, surveys, stock, prime, margin calculator…). Each icon navigates to another screen. Which ones appear is 100% market-defined.Grilla de 4 columnas de atajos (pedido, merchandising, financiero, price check, surveys, stock, prime, calculadora de margen…). Cada ícono navega a otra pantalla. Cuáles aparecen es 100% definido por el mercado.
Indicador flutuanteFloating indicatorIndicador flotante Quando a visita está iniciada, uma pílula flutuante "em andamento" aparece no rodapé; tocá-la rola a tela até o botão de finalizar. When the visit is started, a floating "in progress" pill shows at the bottom; tapping it scrolls to the finish button. Cuando la visita está iniciada, una píldora flotante "en curso" aparece al pie; tocarla desplaza hasta el botón de finalizar.
Status e estadosStatus & statesEstado y estados
Dois tipos de "status" convivem na tela: o status da visita (controla o check-in) e os indicadores do varejo (a fila de ícones).Two kinds of "status" live on the screen: the visit status (drives check-in) and the retail indicators (the row of icons).Dos tipos de "estado" conviven en la pantalla: el estado de la visita (controla el check-in) y los indicadores del punto de venta (la fila de íconos).
Status da visitaVisit statusEstado de la visita
Visita precisa estar iniciadaVisit must be startedLa visita debe estar iniciada Tocar numa ferramenta ou tarefa com a visita ainda não iniciada abre um modal "iniciar visita?". Só depois de iniciar (ou confirmar) o app navega para o destino. É o guard de visita ativa. Tapping a tool or task while the visit is not yet started opens a "start visit?" modal. Only after starting (or confirming) does the app navigate to the destination. It's the active-visit guard. Tocar una herramienta o tarea con la visita aún no iniciada abre un modal "¿iniciar visita?". Solo después de iniciar (o confirmar) la app navega al destino. Es el guard de visita activa.
Indicadores do varejoRetail indicatorsIndicadores del punto de venta
- B2B
- Verde se o varejo é B2B.Green if the retail is B2B.Verde si el punto de venta es B2B.
- Em dia / atrasadoCompliant / overdueAl día / atrasado
- Verde "em dia" quando não está com pendência financeira; vermelho "atrasado" caso contrário.Green "compliant" when there's no overdue balance; red "overdue" otherwise.Verde "al día" cuando no hay pendencia financiera; rojo "atrasado" en caso contrario.
- ConcorrênciaCompetitorsCompetencia
- Sinaliza presença de concorrência (CL).Flags competitor presence (CL).Señala presencia de competencia (CL).
- ContrafaçãoCounterfeitsFalsificación
- Sinaliza produtos ilegais/contrafeitos (CL).Flags illegal/counterfeit products (CL).Señala productos ilegales/falsificados (CL).
- AtivoActiveActivo
- Verde com check quando a conta está ativa; vermelho com "X" quando inativa.Green check when the account is active; red "X" when inactive.Verde con check cuando la cuenta está activa; rojo con "X" cuando inactiva.
AçõesActionsAcciones
- Iniciar / finalizar (check-in)Start / finish (check-in)Iniciar / finalizar (check-in)
- O botão grande grava o novo status e envia pela transação
VisitUploadAPI, junto com a localização (GPS). Três desfechos: enviado (ok, silencioso), enfileirado (offline — aviso azul, reenvia depois) e falhou (aviso vermelho e o status volta).The big button saves the new status and uploads via theVisitUploadAPItransaction, along with the location (GPS). Three outcomes: sent (ok, silent), queued (offline — blue notice, resent later) and failed (red notice and the status reverts).El botón grande graba el nuevo estado y envía por la transacciónVisitUploadAPI, junto con la ubicación (GPS). Tres desenlaces: enviado (ok, silencioso), en cola (offline — aviso azul, reenvía luego) y falló (aviso rojo y el estado vuelve). - Abrir uma ferramentaOpen a toolAbrir una herramienta
- Tocar num item da grade passa pelo guard (visita iniciada) e então navega para a tela da ferramenta. Alguns itens abrem apps externos: Conecta Você e ShelfWatch (deep link).Tapping a grid item goes through the guard (started visit) and then navigates to the tool's screen. Some items open external apps: Conecta Você and ShelfWatch (deep link).Tocar un ítem de la grilla pasa por el guard (visita iniciada) y luego navega a la pantalla de la herramienta. Algunos ítems abren apps externas: Conecta Você y ShelfWatch (deep link).
- Abrir uma tarefaOpen a taskAbrir una tarea
- Tocar numa tarefa passa pelo guard e abre o detalhe da tarefa.Tapping a task goes through the guard and opens the task detail.Tocar una tarea pasa por el guard y abre el detalle de la tarea.
- Editar o varejoEdit the retailEditar el punto de venta
- O botão no card do varejo abre o Detalhe do varejo.The button on the retail card opens the Retail detail.El botón en la tarjeta del punto de venta abre el Detalle del punto de venta.
- Simular PrimeSimulate PrimeSimular Prime
- No painel Conecta Prime, arrastar o slider recalcula a recompensa na hora, sem sair da tela.On the Conecta Prime dashboard, dragging the slider recomputes the reward on the fly, without leaving the screen.En el panel Conecta Prime, arrastrar el slider recalcula la recompensa al instante, sin salir de la pantalla.
- Ver bonificações do boost planSee boost plan bonusesVer bonificaciones del boost plan
- Botão "Bonificações" abre um modal com o total a receber e o produto de bônus."Bonuses" button opens a modal with the total to receive and the bonus product.Botón "Bonificaciones" abre un modal con el total a recibir y el producto de bono.
- Ver últimos pedidosSee latest ordersVer últimos pedidos
- Botão sob o último pedido, passa pelo guard e abre a lista de pedidos do varejo.Button under the last order, goes through the guard and opens the retail's orders list.Botón bajo el último pedido, pasa por el guard y abre la lista de pedidos del punto de venta.
Arquitetura e fluxo de dadosArchitecture & data flowArquitectura y flujo de datos
Clean Architecture + Riverpod + Freezed + ObjectBox. Dois fluxos: a leitura (só cache, montando o State a partir da visita + dados do varejo) e a escrita (check-in, via Dispatcher).Clean Architecture + Riverpod + Freezed + ObjectBox. Two flows: the read (cache-only, assembling the State from the visit + account data) and the write (check-in, via the Dispatcher).Clean Architecture + Riverpod + Freezed + ObjectBox. Dos flujos: la lectura (solo caché, armando el State desde la visita + datos del punto de venta) y la escritura (check-in, vía Dispatcher).
Leitura · só cacheRead · cache-onlyLectura · solo caché
Nenhum RPC de visita é chamado. A visita sai do cache por sfid (via VisitContext); o Notifier ainda cruza tarefas, último pedido, dados Prime (todos cache-only, por conta do varejo) e a config de mercado (EMC) para decidir o que renderizar:No visit RPC is called. The visit comes from cache by sfid (via VisitContext); the Notifier also cross-references tasks, last order, Prime data (all cache-only, by account) and the market config (EMC) to decide what to render:Ningún RPC de visita se llama. La visita sale del caché por sfid (vía VisitContext); el Notifier además cruza tareas, último pedido, datos Prime (todos cache-only, por cuenta) y la config de mercado (EMC) para decidir qué renderizar:
- VisitModelObjectBox · cache
- getVisitBySfidVisitLocalDataSource
- toDomainVisitEntitydomain
- getCachedBySfidGetVisitsUseCase
- buildVisitContextprovider · family
- _load + tasks/orders/prime/EMCVisitDetailNotifier + State
- → UIVisitDetailPage
- _load + tasks/orders/prime/EMCVisitDetailNotifier + State
- buildVisitContextprovider · family
- getCachedBySfidGetVisitsUseCase
- toDomainVisitEntitydomain
- getVisitBySfidVisitLocalDataSource
Escrita · check-in via DispatcherWrite · check-in via DispatcherEscritura · check-in vía Dispatcher
Iniciar/finalizar atualiza o status na hora (otimista), persiste no cache e envia pelo Dispatcher (VisitUploadAPI). Se o remote falha por rede, fica enfileirado; se falha por outro motivo, o status é revertido:Start/finish updates the status right away (optimistic), persists to cache and uploads through the Dispatcher (VisitUploadAPI). If the remote fails on the network it stays queued; if it fails otherwise the status is reverted:Iniciar/finalizar actualiza el estado al instante (optimista), persiste en el caché y envía por el Dispatcher (VisitUploadAPI). Si el remote falla por red queda en cola; si falla por otro motivo el estado se revierte:
- VisitDetailStartButtonWidgetUI
- startVisit / endVisitVisitContextprovider
- saveVisitStatus (local)SaveVisitStatusUseCase
- build(input)BuildVisitUploadDispatcherPayloadUseCase→ DispatcherEnvelope
- submit(envelope)SubmitVisitUploadUseCase
- dispatchDispatcherOrchestratorgRPC · VisitUploadAPI
- submit(envelope)SubmitVisitUploadUseCase
- build(input)BuildVisitUploadDispatcherPayloadUseCase→ DispatcherEnvelope
- saveVisitStatus (local)SaveVisitStatusUseCase
- startVisit / endVisitVisitContextprovider
Notas de implementaçãoImplementation notesNotas de implementación
O VisitDetailNotifier é family por visitSfid e autoDispose. O check-in vive num provider compartilhado (VisitContext, também family) — o Notifier escuta esse provider e reflete a mudança de status no State sem re-buscar. O lastSyncAt exibido vem do container da lista (VisitsEntity.lastSyncAt via getCached()), nunca do Resource. refresh() força um fetch remoto da lista (execute(source: remote)), invalida o VisitContext e remonta o State via _load() — sem AsyncValue.loading (o pull-to-refresh tem indicador próprio).
VisitDetailNotifier is family by visitSfid and autoDispose. Check-in lives in a shared provider (VisitContext, also family) — the Notifier listens to it and reflects the status change into the State without re-fetching. The displayed lastSyncAt comes from the list container (VisitsEntity.lastSyncAt via getCached()), never from the Resource. refresh() forces a remote fetch of the list (execute(source: remote)), invalidates VisitContext and rebuilds the State via _load() — no AsyncValue.loading (pull-to-refresh has its own indicator).
VisitDetailNotifier es family por visitSfid y autoDispose. El check-in vive en un provider compartido (VisitContext, también family) — el Notifier lo escucha y refleja el cambio de estado en el State sin re-buscar. El lastSyncAt mostrado viene del contenedor de la lista (VisitsEntity.lastSyncAt vía getCached()), nunca del Resource. refresh() fuerza un fetch remoto de la lista (execute(source: remote)), invalida VisitContext y rearma el State vía _load() — sin AsyncValue.loading (el pull-to-refresh tiene su propio indicador).
Modelo de dadosData modelModelo de datos
O Detalhe reusa o mesmo modelo da Lista de visitas — a mesma VisitEntity, mesmo proto (VisitConectaRep), DTO, Model e mappers. Não há entity VisitDetail própria (§35). O dado existe em quatro representações — Proto (wire gRPC) → DTO (Freezed) → Model (ObjectBox) → Entity (domínio) — ligadas por mappers; enums só existem tipados na Entity, datas são parseadas no Model, e sub-mensagens viram relações ToOne/ToMany.Detail reuses the same model as the Visit list — the same VisitEntity, same proto (VisitConectaRep), DTO, Model and mappers. There's no dedicated VisitDetail entity (§35). The data exists in four representations — Proto (gRPC wire) → DTO (Freezed) → Model (ObjectBox) → Entity (domain) — linked by mappers; enums are only typed in the Entity, dates are parsed in the Model, and sub-messages become ToOne/ToMany relations.El Detalle reutiliza el mismo modelo que la Lista de visitas — la misma VisitEntity, mismo proto (VisitConectaRep), DTO, Model y mappers. No hay entity VisitDetail propia (§35). El dato existe en cuatro representaciones — Proto (wire gRPC) → DTO (Freezed) → Model (ObjectBox) → Entity (dominio) — unidas por mappers; los enums solo están tipados en la Entity, las fechas se parsean en el Model, y las sub-mensajes se vuelven relaciones ToOne/ToMany.
A raiz Visit (28 campos) e o AccountData (42 campos) já estão documentados campo-a-campo na Lista de visitas. Aqui detalhamos as sub-árvores que o Detalhe renderiza e a lista não: metas mensais, acompanhamento de entrega, os sete painéis (Dashboards), a equipe do varejo (Staff), ShelfWatch e checagens de concorrência. A leitura é cache-only; a escrita (check-in) sai pelo Dispatcher.The Visit root (28 fields) and AccountData (42 fields) are already documented field-by-field in the Visit list. Here we detail the sub-trees the Detail renders and the list doesn't: monthly targets, delivery tracking, the seven dashboards (Dashboards), the retail's team (Staff), ShelfWatch and competitor checks. The read is cache-only; the write (check-in) goes through the Dispatcher.La raíz Visit (28 campos) y AccountData (42 campos) ya están documentados campo a campo en la Lista de visitas. Aquí detallamos las sub-árboles que el Detalle renderiza y la lista no: metas mensuales, seguimiento de entrega, los siete paneles (Dashboards), el equipo del punto de venta (Staff), ShelfWatch y chequeos de competencia. La lectura es cache-only; la escritura (check-in) sale por el Dispatcher.
Proto
VisitConectaRep.proto · proto3 · package mn.bat.conectarep.streambridge. O Detalhe não chama este método; lê o resultado do cache. Um serviço, um método unário:Detail doesn't call this method; it reads the result from cache. One service, one unary method:El Detalle no llama este método; lee el resultado del caché. Un servicio, un método unario:
getVisitListunary · origem (cache)unary · origin (cache)unary · origen (caché)rpc getVisitList(VisitRequest) returns (VisitReply)
path /mn.bat.conectarep.streambridge.VisitConectaRepService/getVisitList
VisitRequestlocationHierarchySfidstring· #1 · hierarquia do representante de vendas (resolvida no repository)sales rep hierarchy (resolved in the repository)jerarquía del representante de ventas (resuelta en el repository)dateReferencestring· #2 · optionallastModifiedDatestring· #3 · optional (não usado hoje)optional (not used today)optional (no usado hoy)
VisitReplyrepeated Visit visitList — o Detalhe pega uma Visit por sfid do cache; as sub-árvores estão nas Estruturas de dados abaixo.Detail pulls one Visit by sfid from cache; the sub-trees are in Data structures below.el Detalle toma una Visit por sfid del caché; las sub-árboles están en Estructuras de datos abajo.
Estruturas de dadosData structuresEstructuras de datos
Sub-árvores que o Detalhe renderiza (a raiz Visit e AccountData ficam na Lista de visitas). Colunas Proto · DTO · Model · Entity, uma linha por campo. O delta (texto azul) marca onde o tipo primeiro muda: relação ToMany/ToOne no Model, parse de data no Model, enum na Entity. ¹ = optional no proto.Sub-trees the Detail renders (the Visit root and AccountData are in the Visit list). Columns Proto · DTO · Model · Entity, one row per field. The delta (blue text) marks where the type first changes: ToMany/ToOne relation in the Model, date parse in the Model, enum in the Entity. ¹ = optional in the proto.Sub-árboles que el Detalle renderiza (la raíz Visit y AccountData están en la Lista de visitas). Columnas Proto · DTO · Model · Entity, una fila por campo. El delta (texto azul) marca dónde primero cambia el tipo: relación ToMany/ToOne en el Model, parse de fecha en el Model, enum en la Entity. ¹ = optional en el proto.
MonthlyTarget Visit.monthlyTarget¹ 1 listalistlista
Campo Proto DTO Model Entity categoriesrepeated MonthlyTargetCategory List<…DTO> ToMany<…Model>List<…Entity> MonthlyTargetCategory MonthlyTarget.categories[] 2 camposfieldscampos
Campo Proto DTO Model Entity categorystring String String String itemsrepeated MonthlyTargetItem List<…DTO> ToMany<…Model>List<…Entity> MonthlyTargetItem MonthlyTargetCategory.items[] 2 camposfieldscampos
Campo Proto DTO Model Entity typestring String String String periodsrepeated MonthlyTargetPeriod List<…DTO> ToMany<…Model>List<…Entity> MonthlyTargetPeriod MonthlyTargetItem.periods[] 5 camposfieldscampos
Campo Proto DTO Model Entity periodstring String String String realizeddouble double double double targetdouble double double double differencedouble double double double percentagedouble double double double
DeliveryTracking Visit.deliveryTracking[] 5 camposfieldscampos
Campo Proto DTO Model Entity categorystring String String String realizeddouble double double double targetdouble double double double differencedouble double double double percentagedouble double double double
VisitDashboards Visit.dashboards 7 painéis opcionaisoptional dashboardspaneles opcionales
Campo Proto DTO Model Entity campaignCampaignDashboard¹ …DTO? ToOne<…Model>…Entity? partnershipPartnershipDashboard¹ …DTO? ToOne<…Model>…Entity? conectaVoceConectaVoceDashboard¹ …DTO? ToOne<…Model>…Entity? conectaNegociosConectaNegociosDashboard¹ …DTO? ToOne<…Model>…Entity? conectaAMPMConectaAMPMDashboard¹ …DTO? ToOne<…Model>…Entity? boostPlanBoostPlanDashboard¹ …DTO? ToOne<…Model>…Entity? smartInvestmentSmartInvestmentDashboard¹ …DTO? ToOne<…Model>…Entity? BoostPlanDashboard Dashboards.boostPlan 7 camposfieldscampos
Campo Proto DTO Model Entity targetPackagesdouble double double double maxTargetPackagesdouble double double double realizedPackagesdouble double double double percentagedouble double double double bonusAtTargetdouble¹ double? double? double? bonusAtMaxdouble¹ double? double? double? bonusProductstring¹ String? String? String? SmartInvestmentDashboard Dashboards.smartInvestment 2 camposfieldscampos
Campo Proto DTO Model Entity statusstring String String String kpisrepeated SmartInvestmentKpi List<…DTO> ToMany<…Model>List<…Entity> SmartInvestmentKpi SmartInvestmentDashboard.kpis[] 2 camposfieldscampos
Campo Proto DTO Model Entity idstring String String String kpiNamestring String String String
PartnershipDashboard Dashboards.partnership 4 camposfieldscampos
Campo Proto DTO Model Entity realizeddouble double double double suggestedTargetdouble double double double averageTicketdouble double double double suggestedPartnersrepeated SuggestedPartner List<…DTO> ToMany<…Model>List<…Entity> SuggestedPartner PartnershipDashboard.suggestedPartners[] 3 camposfieldscampos
Campo Proto DTO Model Entity partnerNamestring String String String realizeddouble double double double targetdouble double double double
CampaignDashboard Dashboards.campaign 5 camposfieldscampos
Campo Proto DTO Model Entity campaignNamestring String String String targetdouble double double double realizeddouble double double double percentagedouble double double double rewarddouble¹ double? double? double? ConectaVoceDashboard Dashboards.conectaVoce 4 camposfieldscampos
Campo Proto DTO Model Entity realizeddouble double double double targetdouble double double double percentagedouble double double double lastUpdatedstring String? String? String? ConectaNegociosDashboard Dashboards.conectaNegocios 5 camposfieldscampos
Campo Proto DTO Model Entity monthReferencestring String String String monthDescriptionstring¹ String String String realizeddouble double double double targetdouble double double double percentagedouble double double double ConectaAMPMDashboard Dashboards.conectaAMPM 5 camposfieldscampos
Campo Proto DTO Model Entity monthReferencestring String String String monthDescriptionstring¹ String String String realizeddouble double double double targetdouble double double double percentagedouble double double double
Staff AccountData.staff 3 camposfieldscampos
Campo Proto DTO Model Entity contactsrepeated Contact List<…DTO> ToMany<…Model>List<…Entity> clerksrepeated Clerk List<…DTO> ToMany<…Model>List<…Entity> isRegisteredInConectaVocebool bool bool bool Contact Staff.contacts[] 14 camposfieldscampos
Campo Proto DTO Model Entity idstring String String String namestring String String String rolestring String String ContactRole?phonestring String? String? String? emailstring String? String? String? birthdatestring String? DateTime?DateTime? taxIdstring String? String? String? isMainContactbool bool bool bool b2bPortalStatusstring String String B2bPortalStatus?statusstring String String String contactDesignationstring String String ContactDesignation?languagePreferencestring String String LanguagePreference?preferredMethodOfContactstring String String PreferredContactMethod?isRewardNominatedbool bool? bool? bool? Clerk Staff.clerks[] 9 camposfieldscampos
Campo Proto DTO Model Entity idstring String String String taxIdstring String? String? String? namestring String String String programLayerCodestring String String ClerkProgramLayerphonestring String? String? String? emailstring String? String? String? birthdaystring String? DateTime?DateTime? statusstring String String ClerkStatus?isEngagedbool bool? bool? bool?
ShelfWatch Visit.shelfWatch¹ 2 camposfieldscampos
Campo Proto DTO Model Entity deepLinkUrlstring¹ String? String? String? assetsrepeated ShelfWatchAsset List<…DTO> ToMany<…Model>List<…Entity> ShelfWatchAsset ShelfWatch.assets[] 3 camposfieldscampos
Campo Proto DTO Model Entity namestring String String String imageUrlstring¹ String? String? String? recordTypestring¹ String? String? String?
CompetitorCheck Visit.competitorChecks[] 4 camposfieldscampos
Campo Proto DTO Model Entity idstring String String String campaignstring String String String startDatestring¹ String? String? String? endDatestring¹ String? String? String?
Mappers
As sub-árvores acima seguem os mesmos 5 mappers da Lista de visitas — cada camada tem seu conversor, encadeado a partir de VisitMapper:The sub-trees above follow the same 5 mappers as the Visit list — each layer has its converter, chained from VisitMapper:Las sub-árboles arriba siguen los mismos 5 mappers que la Lista de visitas — cada capa tiene su conversor, encadenado desde VisitMapper:
| DireçãoDirectionDirección | MétodoMethodMétodo | Onde/quandoWhere/whenDónde/cuándo |
|---|---|---|
| JSON → DTO | fromMap | mock (dev)mock (dev)mock (dev) |
| Proto → DTO | toDTO | remote (a Lista já rodou)remote (list already ran it)remote (la Lista ya lo corrió) |
| DTO → Entity | toDomain | enums tipados, datas parseadastyped enums, parsed datesenums tipados, fechas parseadas |
| Entity → Model | toModel | grava relações ToOne/ToMany no ObjectBoxwrites ToOne/ToMany relations to ObjectBoxgraba relaciones ToOne/ToMany en ObjectBox |
| Model → Entity | toDomain | leitura do cache (Detalhe)cache read (Detail)lectura del caché (Detalle) |
Os únicos deltasThe only deltasLos únicos deltas
- Sub-mensagens repetidas (
categories,items,periods,kpis,suggestedPartners,contacts,clerks,assets) viramToManyno Model.Repeated sub-messages (categories,items,periods,kpis,suggestedPartners,contacts,clerks,assets) becomeToManyin the Model.Sub-mensajes repetidos (categories,items,periods,kpis,suggestedPartners,contacts,clerks,assets) se vuelvenToManyen el Model. - Os 7 painéis de
DashboardsviramToOneno Model (sub-mensagens opcionais).The 7Dashboardspanels becomeToOnein the Model (optional sub-messages).Los 7 paneles deDashboardsse vuelvenToOneen el Model (sub-mensajes opcionales). Contact.birthdateeClerk.birthday: parseString → DateTime?no Model.Contact.birthdateandClerk.birthday:String → DateTime?parse in the Model.Contact.birthdateyClerk.birthday: parseString → DateTime?en el Model.- Enums só na Entity:
Contact.role/b2bPortalStatus/contactDesignation/languagePreference/preferredMethodOfContacteClerk.programLayer/status(labels de wire exibidos crus — decisão de produto).Enums only in the Entity:Contact.role/b2bPortalStatus/contactDesignation/languagePreference/preferredMethodOfContactandClerk.programLayer/status(wire labels shown as-is — product decision).Enums solo en la Entity:Contact.role/b2bPortalStatus/contactDesignation/languagePreference/preferredMethodOfContactyClerk.programLayer/status(labels de wire mostrados crudos — decisión de producto).
Repository
O Detalhe usa o mesmo VisitRepository da Lista — sem repository próprio. Para a leitura, importam só os métodos cache-only (§28 categoria A: lookup single-item por sfid nunca dispara remote). Os demais métodos (fetch remoto, mock) estão na Lista de visitas.Detail uses the same VisitRepository as the list — no dedicated repository. For the read, only the cache-only methods matter (§28 category A: a single-item sfid lookup never triggers remote). The remaining methods (remote fetch, mock) are in the Visit list.El Detalle usa el mismo VisitRepository que la lista — sin repository propio. Para la lectura, solo importan los métodos cache-only (§28 categoría A: un lookup single-item por sfid nunca dispara remote). Los demás métodos (fetch remoto, mock) están en la Lista de visitas.
getCachedVisitBySfid({visitSfid}) local
- Retorno
Future<Result<VisitEntity, Failure>>- ComportamentoBehaviorComportamiento
- Lê uma visita do ObjectBox por
sfid. Nunca vai à rede. É o método que oVisitContextchama nobuild(). Falha se osfidnão existe no cache.Reads one visit from ObjectBox bysfid. Never hits the network. It's whatVisitContextcalls inbuild(). Fails if thesfidisn't in cache.Lee una visita del ObjectBox porsfid. Nunca va a la red. Es lo queVisitContextllama enbuild(). Falla si elsfidno está en caché.
getCachedVisits() local
- Retorno
Future<Result<VisitsEntity?, Failure>>- ComportamentoBehaviorComportamiento
- Container da lista. O Detalhe usa só para pegar o
lastSyncAtexibido no topo.The list container. Detail uses it only to read thelastSyncAtshown at the top.Contenedor de la lista. El Detalle lo usa solo para leer ellastSyncAtmostrado arriba.
saveVisitStatus({visitSfid, status, startedAt?, endedAt?}) local · check-inlocal · check-inlocal · check-in
- Retorno
Future<void>- ComportamentoBehaviorComportamiento
- Atualiza o status/datas da visita no cache (sem rede) — a parte local do check-in. O envio remoto sai pelo Dispatcher (
VisitUploadAPI).Updates the visit's status/dates in cache (no network) — the local part of check-in. The remote upload goes through the Dispatcher (VisitUploadAPI).Actualiza el estado/fechas de la visita en el caché (sin red) — la parte local del check-in. El envío remoto sale por el Dispatcher (VisitUploadAPI).
Datasources
Na leitura do Detalhe só o datasource local (ObjectBox) atua — não há Remote nem Mock aqui. Ambos vivem na Lista de visitas.On the Detail read only the local datasource (ObjectBox) acts — there's no Remote nor Mock here. Both live in the Visit list.En la lectura del Detalle solo actúa el datasource local (ObjectBox) — no hay Remote ni Mock aquí. Ambos viven en la Lista de visitas.
Local VisitLocalDataSource ObjectBox
- EnvioSendEnvío
- Nenhum — leitura pura do banco.None — pure DB read.Ninguno — lectura pura de la BD.
- ErroErrorError
- Sem registro → falha "não encontrado", tratada pela page (retry via
ref.invalidate).No record → "not found" failure, handled by the page (retry viaref.invalidate).Sin registro → falla "no encontrado", manejada por la page (retry víaref.invalidate).
getVisitBySfid({visitSfid})
- Retorno
VisitModel?- UsoUseUso
- Busca a visita por
sfid; o repository mapeia para Entity.Fetches the visit bysfid; the repository maps to Entity.Busca la visita porsfid; el repository mapea a Entity.
getVisits()
- Retorno
VisitsModel?- UsoUseUso
- Container da lista — o Detalhe só lê o
lastSyncAt.List container — Detail only readslastSyncAt.Contenedor de la lista — el Detalle solo leelastSyncAt.
updateVisitStatusInVisit({visitSfid, status, startedAt?, endedAt?})
- Retorno
Future<void>- UsoUseUso
- Escreve o novo status/datas no registro da visita — a persistência local do check-in.Writes the new status/dates onto the visit record — the local persistence of check-in.Escribe el nuevo estado/fechas en el registro de la visita — la persistencia local del check-in.
Enums e labelsEnums & labelsEnums y labels
Os enums que dirigem o comportamento da tela. ModuleType e ModuleDetailType são enums compartilhados entre features — abaixo só a fatia do detalhe da visita (um valor por linha).The enums that drive the screen. ModuleType and ModuleDetailType are shared across features — below, only the visit detail slice (one value per line).Los enums que dirigen la pantalla. ModuleType y ModuleDetailType son enums compartidos entre features — abajo, solo la porción del detalle de la visita (un valor por línea).
VisitStatus 6 · botão + guardbutton + guardbotón + guard
| case | value | Efeito no DetalheEffect on DetailEfecto en el Detalle |
|---|---|---|
scheduled | scheduled | não iniciada → botão "Iniciar"not started → "Start" buttonno iniciada → botón "Iniciar" |
notStarted | not_started | não iniciada → botão "Iniciar"not started → "Start" buttonno iniciada → botón "Iniciar" |
started | started | iniciada → botão "Finalizar" + pílula flutuante; guard liberadostarted → "Finish" button + floating pill; guard passesiniciada → botón "Finalizar" + píldora flotante; guard liberado |
completed | completed | finalizada (destino do "Finalizar")finished (target of "Finish")finalizada (destino de "Finalizar") |
cancelled | cancelled | canceladacancelledcancelada |
unknown | unknown | fallbackfallbackfallback |
VisitStatusUpdateOutcome 3 · resultado do check-in3 · check-in result3 · resultado del check-in
| case | AvisoNoticeAviso |
|---|---|
sent | enviado (silencioso)sent (silent)enviado (silencioso) |
queued | offline → aviso azul, reenvia depoisoffline → blue notice, resent lateroffline → aviso azul, reenvía luego |
failed | aviso vermelho + status revertidored notice + status revertedaviso rojo + estado revertido |
ModuleType fatia visit detailvisit detail sliceporción visit detail 15
| case | value |
|---|---|
visitDetailStartButton | visit_detail_start_button |
visitDetailClientCard | visit_detail_client_card |
visitDetailStatusIndicators | visit_detail_status_indicators |
visitDetailCommercialPillars | visit_detail_commercial_pillars |
visitDetailTasks | visit_detail_tasks |
visitDetailTargetOfTheDay | visit_detail_target_of_the_day |
visitDetailMonthlyTarget | visit_detail_monthly_target |
visitDetailLastOrder | visit_detail_last_order |
visitDetailConectaPrime | visit_detail_conecta_prime |
visitDetailBoostPlanScript | visit_detail_boost_plan_script |
visitDetailBoostPlanDashboard | visit_detail_boost_plan_dashboard |
visitDetailShareOpportunity | visit_detail_share_opportunity |
visitDetailDeliveryVolume | visit_detail_delivery_volume |
visitDetailPartnership | visit_detail_partnership |
visitDetailToolsGrid | visit_detail_tools_grid |
ModuleDetailType ferramentas + statustools + statusherramientas + estado 17 + 5
| case | value | Navega paraNavigates toNavega a |
|---|---|---|
visitDetailToolPlaceOrder | place_order | ProductShowcase |
visitDetailToolReturns | returns | BuybackMenu |
visitDetailToolConectaVoce | visit_conecta_voce | app externo (gate: participante)external app (gate: participant)app externa (gate: participante) |
visitDetailToolMerchandising | merchandising | OsMerchandising |
visitDetailToolFinancialManagement | financial_management | FinancialManagement |
visitDetailToolStockHistory | stock_history | StockCount |
visitDetailToolPerformance | performance | — (no-op hoje)— (no-op today)— (no-op hoy) |
visitDetailToolPosAudit | pos_audit | — (no-op hoje)— (no-op today)— (no-op hoy) |
visitDetailToolCompetitorInsights | competitor_insights | CompetitorInsights |
visitDetailToolSurveys | surveys | Surveys (survey) |
visitDetailToolPrimeManagement | prime_management | PrimeManagement (gate: elegível)PrimeManagement (gate: eligible)PrimeManagement (gate: elegible) |
visitDetailToolCompetitorActions | competitor_actions | Surveys (competitor actions) |
visitDetailToolDeliveries | deliveries | — (no-op hoje)— (no-op today)— (no-op hoy) |
visitDetailToolCounterfeits | counterfeits | — (no-op hoje)— (no-op today)— (no-op hoy) |
visitDetailToolShelfWatch | shelf_watch | deep link externoexternal deep linkdeep link externo |
visitDetailToolPriceCheck | price_check | PriceCheck |
visitDetailToolMarginCalculator | margin_calculator | MarginCalculator |
visitDetailStatusB2b | status_b2b | indicadorindicatorindicador |
visitDetailStatusCompliant | status_compliant | indicadorindicatorindicador |
visitDetailStatusCompetitors | status_competitors | indicadorindicatorindicador |
visitDetailStatusCounterfeits | status_counterfeits | indicadorindicatorindicador |
visitDetailStatusActive | status_active | indicadorindicatorindicador |
KpiTargetType 2 · filtro da meta mensalmonthly target filterfiltro de meta mensual
| case | value |
|---|---|
all | all |
delivered | delivered |
KpiPeriod 3 · períodos da metatarget periodsperíodos de meta
| case | value |
|---|---|
monthToDate | mtd |
month | month |
unknown | "" |
AccountStatus 5 · indicador "ativo""active" indicatorindicador "activo"
| case | value |
|---|---|
active | active |
temporarilyDeactivated | temporarily_deactivated |
permanentDeactivationRequest | permanent_deactivation_request |
disablePermanent | disable_permanent |
unknown | unknown |
Enums da equipe (Staff)Team enums (Staff)Enums del equipo (Staff)
Os enums de Contact/Clerk (ContactRole, B2bPortalStatus, ContactDesignation, LanguagePreference, PreferredContactMethod, ClerkProgramLayer, ClerkStatus) são labels de wire exibidos crus (decisão de produto). O Detalhe só lê staff.isRegisteredInConectaVoce; as listas de contatos/balconistas são renderizadas em Gerenciar equipe — os enums completos vivem naquele doc.
Contact/Clerk enums (ContactRole, B2bPortalStatus, ContactDesignation, LanguagePreference, PreferredContactMethod, ClerkProgramLayer, ClerkStatus) are wire labels shown as-is (product decision). Detail only reads staff.isRegisteredInConectaVoce; the contact/clerk lists render in Manage staff — the full enums live in that doc.
Los enums de Contact/Clerk (ContactRole, B2bPortalStatus, ContactDesignation, LanguagePreference, PreferredContactMethod, ClerkProgramLayer, ClerkStatus) son labels de wire mostrados crudos (decisión de producto). El Detalle solo lee staff.isRegisteredInConectaVoce; las listas de contactos/dependientes se renderizan en Gestionar equipo — los enums completos viven en ese doc.
UseCases
O Notifier compõe várias fontes cache-only por conta do varejo + a config de mercado. O check-in usa três usecases do Dispatcher.The Notifier composes several cache-only sources by account + the market config. Check-in uses three Dispatcher usecases.El Notifier compone varias fuentes cache-only por cuenta + la config de mercado. El check-in usa tres usecases del Dispatcher.
GetVisitsUseCase a visita + lastSyncthe visit + lastSyncla visita + lastSync
| MétodoMethodMétodo | RetornaReturnsRetorna | Uso no DetalheUse in DetailUso en el Detalle |
|---|---|---|
getCachedBySfid({visitSfid}) | Result<VisitEntity, Failure> | a visita (via VisitContext)the visit (via VisitContext)la visita (vía VisitContext) |
getCached() | Result<VisitsEntity?, Failure> | só o lastSyncAtonly lastSyncAtsolo el lastSyncAt |
execute({source: remote}) | Result<VisitsEntity?, Failure> | no refresh() (pull-to-refresh)on refresh() (pull-to-refresh)en refresh() (pull-to-refresh) |
GetTasksForAccountUseCase tarefas do varejoretail taskstareas del PDV
| MétodoMethodMétodo | RetornaReturnsRetorna | UsoUseUso |
|---|---|---|
execute({accountSfid}) | Result<List<TaskEntity>, Failure> | lista de tarefas; o Notifier ordena por status e prazotask list; the Notifier sorts by status and due datelista de tareas; el Notifier ordena por estado y plazo |
GetOrdersForAccountUseCase último pedidolast orderúltimo pedido
| MétodoMethodMétodo | RetornaReturnsRetorna | UsoUseUso |
|---|---|---|
execute({accountSfid}) | Result<List<OrderEntity>, Failure> | o Notifier pega o primeiro (o mais recente)the Notifier takes the first (most recent)el Notifier toma el primero (el más reciente) |
GetPrimeManagementUseCase painel PrimePrime dashboardpanel Prime
| MétodoMethodMétodo | RetornaReturnsRetorna | UsoUseUso |
|---|---|---|
getCachedByAccountSfid({accountSfid}) | Result<PrimeAccountDataEntity?, Failure> | dados do painel Conecta Prime + flags de elegibilidade (gate do tool Prime). Modelo completo em Prime.Conecta Prime dashboard data + eligibility flags (Prime tool gate). Full model in Prime.datos del panel Conecta Prime + flags de elegibilidad (gate del tool Prime). Modelo completo en Prime. |
GetEndMarketConfigurationUseCase config do mercadomarket configconfig del mercado
| MétodoMethodMétodo | RetornaReturnsRetorna | UsoUseUso |
|---|---|---|
execute() | Result<MarketConfiguration, Failure> | visitDetailConfig.modules visíveis → decide o que renderiza (ver Mercados)visible visitDetailConfig.modules → decides what renders (see Markets)módulos visibles de visitDetailConfig.modules → decide qué renderiza (ver Mercados) |
Check-in VisitUploadAPI 3 useCases
| UseCase | Método → RetornaMethod → ReturnsMétodo → Retorna |
|---|---|
SaveVisitStatusUseCase | execute({visitSfid, status, startedAt?, endedAt?}) → Future<void> (persistência local)(local persist)(persistencia local) |
BuildVisitUploadDispatcherPayloadUseCase | build({input: VisitUploadDispatcherPayloadInput}) → DispatcherEnvelope |
SubmitVisitUploadUseCase | submit({envelope}) → Result<DispatcherAck, Failure> |
Notifier & State
Dois providers: o VisitDetailNotifier (state da page, family por visitSfid, autoDispose) e o VisitContext (provider compartilhado que detém a visita e o check-in, também family). O Notifier escuta o VisitContext e reflete a mudança de status no State — a única fonte da verdade é o cache/remote, lido por ambos (§17).Two providers: VisitDetailNotifier (page state, family by visitSfid, autoDispose) and VisitContext (shared provider owning the visit and the check-in, also family). The Notifier listens to VisitContext and reflects the status change into the State — the single source of truth is cache/remote, read by both (§17).Dos providers: VisitDetailNotifier (state de la page, family por visitSfid, autoDispose) y VisitContext (provider compartido que posee la visita y el check-in, también family). El Notifier escucha a VisitContext y refleja el cambio de estado en el State — la única fuente de verdad es el caché/remote, leído por ambos (§17).
MétodosMethodsMétodos
build({visitSfid}) VisitDetailNotifier
Resolve os useCases, registra o ref.listen no VisitContext (para refletir o check-in no State) e retorna _load() via AsyncGuard.Resolves the useCases, registers the ref.listen on VisitContext (to reflect check-in into the State) and returns _load() via AsyncGuard.Resuelve los useCases, registra el ref.listen en VisitContext (para reflejar el check-in en el State) y retorna _load() vía AsyncGuard.
_load() private
Monta o State: busca a visita (VisitContext), o lastSyncAt do container, a config de mercado, e em paralelo tarefas/último pedido/dados Prime por conta. Aplica a config para expandir metas mensais, metas do dia e volume de entrega para as categorias esperadas (preenchendo zeros quando faltam).Assembles the State: fetches the visit (VisitContext), the container's lastSyncAt, the market config, and in parallel tasks/last order/Prime data by account. Applies the config to expand monthly targets, daily targets and delivery volume to the expected categories (filling zeros when missing).Arma el State: obtiene la visita (VisitContext), el lastSyncAt del contenedor, la config de mercado, y en paralelo tareas/último pedido/datos Prime por cuenta. Aplica la config para expandir metas mensuales, metas del día y volumen de entrega a las categorías esperadas (rellenando ceros cuando faltan).
refresh() pull-to-refresh
Null-guard no State atual; força fetch remoto da lista (execute(source: remote)), invalida o VisitContext e remonta via _load(). Não usa AsyncValue.loading.Null-guard on current State; forces a remote list fetch (execute(source: remote)), invalidates VisitContext and rebuilds via _load(). Doesn't use AsyncValue.loading.Null-guard en el State actual; fuerza fetch remoto de la lista (execute(source: remote)), invalida VisitContext y rearma vía _load(). No usa AsyncValue.loading.
startVisit() / endVisit() VisitContext
Atualiza o status otimista, persiste local (SaveVisitStatusUseCase), monta o envelope (Build…) com resource + GPS + status e envia (Submit…). Retorna VisitStatusUpdateResult (sent/queued/failed); em falha não-rede, reverte o status.Updates status optimistically, persists locally (SaveVisitStatusUseCase), builds the envelope (Build…) with resource + GPS + status and uploads (Submit…). Returns VisitStatusUpdateResult (sent/queued/failed); on non-network failure it reverts the status.Actualiza el estado optimista, persiste local (SaveVisitStatusUseCase), arma el sobre (Build…) con resource + GPS + estado y envía (Submit…). Retorna VisitStatusUpdateResult (sent/queued/failed); en falla no-red revierte el estado.
State disponível para a PageState available to the PageState disponible para la Page
VisitDetailState campos + gettersfields + getterscampos + getters
| Campo / getterField / getterCampo / getter | TipoTypeTipo | Para quêWhat forPara qué |
|---|---|---|
visit | VisitEntity | a visita inteirathe whole visitla visita entera |
lastSyncAt | DateTime? | DataLoadInfo |
visibleModules | List<ModuleConfig> | módulos visíveis (EMC)visible modules (EMC)módulos visibles (EMC) |
accountTasks | List<TaskEntity> | tarefas ordenadassorted taskstareas ordenadas |
accountLastOrder | OrderEntity? | último pedidolast orderúltimo pedido |
monthlyTarget | MonthlyTargetEntity | meta mensal expandidaexpanded monthly targetmeta mensual expandida |
targetsOfTheDay | List<TargetOfTheDayEntity> | metas do diadaily targetsmetas del día |
deliveryVolume | List<DeliveryTrackingEntity> | volume de entregadelivery volumevolumen de entrega |
primeAccountData | PrimeAccountDataEntity? | painel PrimePrime dashboardpanel Prime |
displayPrimePayment / displayPrimeSimulator | bool | gate do tool PrimePrime tool gategate del tool Prime |
getModule(type) | ModuleConfig? | cada widget checa se seu módulo está visíveleach widget checks if its module is visiblecada widget verifica si su módulo está visible |
visibleVisitDetailTools | List<ModuleDetailType> | itens da grade (com gates Prime/Conecta Você)grid items (with Prime/Conecta Você gates)ítems de la grilla (con gates Prime/Conecta Você) |
visibleVisitDetailStatusIndicators | List<ModuleDetailType> | quais indicadores mostrarwhich indicators to showqué indicadores mostrar |
isB2B / isOverdue / hasCompetition / hasIllegalProducts / isAccountActive | bool | estados dos indicadoresindicator statesestados de los indicadores |
isVisitStarted | bool | botão iniciar/finalizarstart/finish buttonbotón iniciar/finalizar |
showsInProgressIndicator | bool | pílula flutuante "em andamento""in progress" floating pillpíldora flotante "en curso" |
isConectaVoceParticipant | bool | gate do tool Conecta VocêConecta Você tool gategate del tool Conecta Você |
Page e widgetsPage & widgetsPage y widgets
A VisitDetailPage recebe só o visitSfid e observa o provider. No data, o corpo é um Column rolável (pull-to-refresh) que lista os widgets — cada um decide sozinho se aparece (early-return, §27). A pílula flutuante "em andamento" fica num Stack por cima. Os itens do tools grid e das tarefas passam pelo VisitStartGuard antes de navegar.The VisitDetailPage receives only the visitSfid and watches the provider. On data, the body is a scrollable Column (pull-to-refresh) that lists the widgets — each decides on its own whether to show (early-return, §27). The floating "in progress" pill sits in a Stack on top. Tools grid and task items pass through the VisitStartGuard before navigating.La VisitDetailPage recibe solo el visitSfid y observa el provider. En data, el cuerpo es una Column desplazable (pull-to-refresh) que lista los widgets — cada uno decide solo si aparece (early-return, §27). La píldora flotante "en curso" está en un Stack encima. Los ítems del tools grid y de las tareas pasan por el VisitStartGuard antes de navegar.
- VisitDetailPage ConsumerWidget · AppPageShell
- DataLoadInfo lastSyncAt
- VisitDetailStartButtonWidget iniciar/finalizar (VisitContext)start/finish (VisitContext)iniciar/finalizar (VisitContext)
- VisitDetailClientCardWidget card do varejo → Detalhe do varejoretail card → Retail detailtarjeta del PDV → Detalle del PDV
- VisitDetailStatusIndicatorsWidget fila de íconesicon rowfila de íconos
- VisitDetailCommercialPillarsWidget CommercialPillarsGrid
- VisitDetailBoostPlanScriptWidget roteiro (texto)script (text)guion (texto)
- VisitDetailShareOpportunityWidget chips de KPI (smart investment)KPI chips (smart investment)chips de KPI (smart investment)
- VisitDetailTasksWidget lista de tarefas → detalhe (via guard)task list → detail (via guard)lista de tareas → detalle (vía guard)
- CustomEmptyState sem tarefasno taskssin tareas
- VisitStartGuard modal "iniciar visita?" se não iniciada"start visit?" modal if not startedmodal "¿iniciar visita?" si no iniciada
- VisitDetailGoalsCarouselWidget meta do dia (KpiCategoryCarousel)target of the day (KpiCategoryCarousel)meta del día (KpiCategoryCarousel)
- VisitDetailMonthlyTargetWidget carrossel por categoria + filtro + períodoscarousel by category + filter + periodscarrusel por categoría + filtro + períodos
- VisitDetailPartnershipWidget parceria (parceiros + ticket)partnership (partners + ticket)alianza (socios + ticket)
- VisitDetailDeliveryVolumeWidget KpiCategoryCarousel
- VisitDetailLastOrderWidget OrderCardWidget + "ver últimos" (via guard)OrderCardWidget + "see latest" (via guard)OrderCardWidget + "ver últimos" (vía guard)
- VisitDetailBoostPlanDashboardWidget SteppedRewardBar
- VisitDetailBoostPlanBonusesModalContent modal · total + produto de bônusmodal · total + bonus productmodal · total + producto de bono
- VisitDetailConectaPrimeWidget buy&earn + slider (simulador in-place)buy&earn + slider (in-place simulator)buy&earn + slider (simulador in-place)
- VisitDetailToolsGridWidget grade 4-col → navega p/ outras telas (via guard)4-col grid → navigates to other screens (via guard)grilla 4-col → navega a otras pantallas (vía guard)
- CustomToolTile um por ferramenta habilitadaone per enabled tooluno por herramienta habilitada
- VisitStartGuard modal "iniciar visita?" antes de navegar"start visit?" modal before navigatingmodal "¿iniciar visita?" antes de navegar
- InProgressIndicatorWidget pílula flutuante (Stack)floating pill (Stack)píldora flotante (Stack)
Destinos da grade (cada um é doc própria): place_order→ProductShowcase · returns→Buyback · merchandising→OsMerchandising · financial_management→Financeiro · stock_history→StockCount · price_check→PriceCheck · surveys/competitor_actions→Surveys · competitor_insights→CompetitorInsights · margin_calculator→MarginCalculator · prime_management→Prime · shelf_watch/visit_conecta_voce→apps externos.Grid destinations (each its own doc): place_order→ProductShowcase · returns→Buyback · merchandising→OsMerchandising · financial_management→Financial · stock_history→StockCount · price_check→PriceCheck · surveys/competitor_actions→Surveys · competitor_insights→CompetitorInsights · margin_calculator→MarginCalculator · prime_management→Prime · shelf_watch/visit_conecta_voce→external apps.Destinos de la grilla (cada uno su propia doc): place_order→ProductShowcase · returns→Buyback · merchandising→OsMerchandising · financial_management→Financiero · stock_history→StockCount · price_check→PriceCheck · surveys/competitor_actions→Surveys · competitor_insights→CompetitorInsights · margin_calculator→MarginCalculator · prime_management→Prime · shelf_watch/visit_conecta_voce→apps externas.
Notas por mercadoMarket notesNotas por mercado
O Detalhe da visita é 100% dirigido pelo End Market Configuration: a presença de visitDetailConfig habilita a tela, e cada módulo e cada ferramenta da grade é declarado por mercado. Está habilitado nos mesmos três mercados da Lista de visitas e do check-in (VisitUploadAPI):Visit detail is 100% driven by End Market Configuration: the presence of visitDetailConfig enables the screen, and each module and each grid tool is declared per market. Enabled in the same three markets as the Visit list and the check-in (VisitUploadAPI):El Detalle de la visita es 100% dirigido por End Market Configuration: la presencia de visitDetailConfig habilita la pantalla, y cada módulo y cada herramienta de la grilla se declara por mercado. Habilitado en los mismos tres mercados que la Lista de visitas y el check-in (VisitUploadAPI):
Módulos da tela por mercadoScreen modules by marketMódulos de la pantalla por mercado
| MóduloModuleMódulo | BR | CL | ZA |
|---|---|---|---|
visit_detail_start_button | x | x | x |
visit_detail_client_card | x | x | x |
visit_detail_status_indicators | x | x | x |
visit_detail_commercial_pillars | x | — | — |
visit_detail_tasks | x | x | x |
visit_detail_target_of_the_day | x | x | x |
visit_detail_monthly_target | x | — | x |
visit_detail_last_order | x | x | x |
visit_detail_conecta_prime | x | — | — |
visit_detail_boost_plan_script | x | — | — |
visit_detail_boost_plan_dashboard | x | — | — |
visit_detail_share_opportunity | x | — | — |
visit_detail_delivery_volume | x | — | — |
visit_detail_partnership | x | — | — |
visit_detail_tools_grid | x | x | x |
Indicadores de status por mercadoStatus indicators by marketIndicadores de estado por mercado
| IndicadorIndicatorIndicador | BR | CL | ZA |
|---|---|---|---|
status_b2b | x | x | x |
status_compliant | x | x | x |
status_competitors | false | x | — |
status_counterfeits | false | x | — |
status_active | x | x | x |
Ferramentas da grade por mercadoGrid tools by marketHerramientas de la grilla por mercado
| FerramentaToolHerramienta | BR | CL | ZA |
|---|---|---|---|
place_order | x | x | x |
merchandising | x | x | x |
financial_management | x | x | x |
stock_history | x | x | x |
surveys | x | x | x |
returns | x | x | — |
visit_conecta_voce | x | — | — |
prime_management | x | — | — |
competitor_actions | x | — | — |
performance | — | x | — |
deliveries | — | x | — |
shelf_watch | — | x | x |
price_check | — | — | x |
competitor_insights | — | — | x |
margin_calculator | — | — | x |
A tela mais ricaThe richest screenLa pantalla más rica BR é o único com os painéis de pilares comerciais, boost plan (roteiro + painel), oportunidade de share, parceria, volume de entrega e Conecta Prime. Na grade, exclusivos de BR: Conecta Você, Prime e ações de concorrência. BR is the only one with the commercial pillars, boost plan (script + dashboard), share opportunity, partnership, delivery volume and Conecta Prime panels. In the grid, BR-exclusive: Conecta Você, Prime and competitor actions. BR es el único con los paneles de pilares comerciales, boost plan (guion + panel), oportunidad de share, alianza, volumen de entrega y Conecta Prime. En la grilla, exclusivos de BR: Conecta Você, Prime y acciones de competencia.
EnxutoLeanReducido CL não tem meta mensal nem os painéis de BR — foca em card, status, tarefas, meta do dia, último pedido e a grade. Exclusivos de CL na grade: performance e deliveries. CL has no monthly target nor BR's panels — it focuses on card, status, tasks, target of the day, last order and the grid. CL-exclusive in the grid: performance and deliveries. CL no tiene meta mensual ni los paneles de BR — se enfoca en tarjeta, estado, tareas, meta del día, último pedido y la grilla. Exclusivos de CL en la grilla: performance y deliveries.
Base estruturalStructural baseBase estructural ZA tem meta mensal (como BR) mas não os painéis de BR. Só 3 indicadores de status (sem concorrência/contrafação). Exclusivos de ZA na grade: price check, competitor insights e margin calculator. ZA has monthly target (like BR) but not BR's panels. Only 3 status indicators (no competitors/counterfeits). ZA-exclusive in the grid: price check, competitor insights and margin calculator. ZA tiene meta mensual (como BR) pero no los paneles de BR. Solo 3 indicadores de estado (sin competencia/falsificación). Exclusivos de ZA en la grilla: price check, competitor insights y margin calculator.
AR · PY · PE
Existem como mercados do app, mas não têm visitDetailConfig no End Market Configuration — a tela não é renderizada (config PANGEA mínima). Também não estão em DispatcherType.visit.enabledMarkets.
They exist as app markets, but have no visitDetailConfig in End Market Configuration — the screen isn't rendered (minimal PANGEA config). They're also not in DispatcherType.visit.enabledMarkets.
Existen como mercados de la app, pero no tienen visitDetailConfig en End Market Configuration — la pantalla no se renderiza (config PANGEA mínima). Tampoco están en DispatcherType.visit.enabledMarkets.
Pendências / roadmapPending / roadmapPendencias / roadmap
Quatro ferramentas aparecem na grade mas ainda não navegam (no-op hoje): performance, pos_audit, deliveries e counterfeits. O botão "adicionar tarefa" existe no código mas está oculto (Visibility(visible: false)).
Four grid tools show but don't navigate yet (no-op today): performance, pos_audit, deliveries and counterfeits. The "add task" button exists in code but is hidden (Visibility(visible: false)).
Cuatro herramientas de la grilla aparecen pero aún no navegan (no-op hoy): performance, pos_audit, deliveries y counterfeits. El botón "agregar tarea" existe en el código pero está oculto (Visibility(visible: false)).