0006 — Painel colaborador: dashboard e detalhe abertos para o usuário Maxsul¶
Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-09-08 · Decidido em: 2026-07-14
Contexto¶
A home (/) era um painel de cards de contagem por tabela — útil para diagnóstico, impróprio para o
usuário final da Maxsul, que precisa acompanhar seus pedidos e onde cada um está rumo ao X-Adm,
sem jargão de integração e sem login. Além disso, o alerta de erro terminal
(decisão 0005) já linka o e-mail para o detalhe do pedido, que não
existia.
Decisão¶
Duas telas abertas (sem auth, atrás da rede — postura atual do app) num chrome limpo da marca
XADM (layout-painel, sem os menus de operador), no pacote painel/:
GET /— dashboard: tiles de resumo por status + lista de pedidos (nº, cliente via joinpied_cliente, data, badge), linha clicável →/pedidos/{code}, filtro?status=<slug>.GET /pedidos/{code}— detalhe: timeline do status + dados (nº, cliente, documento, datas) + itens (payload.products[]).codeinexistente → 404 amigável. Pedido Falhou → mensagem amigável, semcodRetorno/de-para.
Vocabulário de status (4 buckets) — tradução única (painel/StatusBucket) do status técnico:
Recebido (CAPTURADO,NA_FILA) · Em processamento (ENVIANDO,ENVIADO) · Importado (CONFIRMADO)
· Falhou (ERRO,ERRO_XADM); desconhecido→Recebido. Nenhum segundo campo de estado — a fonte segue
sendo pied_pedido.status.
Revisão (spec
.ia/003, 2026-08-07). O vocabulário dos 4 buckets foi reescrito para refletir a esteira real: Pedidos em aberto (CAPTURADO) · Enviando ao X-Adm (NA_FILA, ENVIANDO, ENVIADO, ERRO) · Importado no X-Adm (CONFIRMADO) · Erro (ERRO_XADM); desconhecido→Pedidos em aberto.ERRO(transporte, transitório) passou de "Falhou" para Enviando ao X-Adm; sóERRO_XADM(rejeição final do X-Adm) fica em Erro. A decisão estrutural (duas telas abertas, chrome limpo, fonte únicaStatusBucket) permanece — mudou só o rótulo/agrupamento. Título da home: "Importação de Pedidos PIED → X-Adm"; lista paginada porlast_update.Revisão (prontidão, 2026-09-04).
NA_FILAdeixou de ser traduzido só pelo nome: sem oinvoiceno payload oPushServicesegura o pedido na fila (pode ser horas, até o poll REST passar), então ele volta para Pedidos em aberto — anunciar "Enviando ao X-Adm" enquanto nada sai era mentira visível ao cliente. Cominvoice, segue Enviando ao X-Adm. A fonte única continua oStatusBucket, que agora recebe a prontidão como 2º insumo (de(status, pronto)+sqlFiltro()para tiles/lista/filtro lerem a mesma regra). A outra metade do mesmo incidente — encurtar a espera — está na decisão 0017, que também guarda o diagnóstico.Revisão (2026-09-04) — dois eixos de status na lista (integração × PIED). A coluna única "Status" confundia dois conceitos: "Pedidos em aberto" é o nosso estado de integração, mas na PIED o mesmo pedido já pode constar pago. A lista do dashboard passa a ter duas colunas ortogonais: Status Integração (o bucket do
StatusBucket, nosso lado) e Pagamento PIED (pagamento traduzido pelo novopainel/PagamentoPied+deal_statuscru). Segue "nenhum segundo campo de estado" no sentido de fonte —PagamentoPiedsó traduzpied_pedido.payment_status, não é estado novo. Vocabulário dos dois eixos no glossário.
Reorganização: a home de diagnóstico (cards) migra de / para /homedev (o navbar de operador
aponta para lá). As demais telas internas (/console, /dados, /captura, /health,
/destinatarios) ficam inalteradas.
Reconciliação: o link do e-mail de alerta (0005) passou de /pedido/{code} para /pedidos/{code}.
Consequências¶
- Duas superfícies de UI: painel do usuário (chrome limpo) × telas de operador (navbar cheio) — separadas por layout, sem misturar menus.
- Read-only: o painel não tem ações de escrita; reenviar/enfileirar seguem só no
/console. - Aberto, sem auth: mantém a postura atual (dívida de login deferida, como
/consolee/dados). - Vocabulário amigável durável: registrado no glossário; o
StatusBucketé a fonte única (tiles, lista e timeline consomem dele). - Dependência do link:
/pedidos/{code}agora resolve — fecha a promessa do e-mail da 0005.
Revisão (2026-08-14) — painel expõe o motivo do erro terminal e deixa de ser read-only. Duas afirmações acima estão superadas: (a) "detalhe … sem
codRetorno/de-para" — o detalhe agora mostra omsgRetornodo X-Adm no erro terminal (1XX), limpo do traço de prefixo, com orientação de corrigir e reimportar; 9XX/transporte mantêm o aviso genérico. (b) "read-only … sem ações de escrita; reenviar/enfileirar seguem só no /console" — o painel já ganhara Importar/Dispensar (pedido em aberto pago) e agora Re-Importar no detalhe de qualquer pedido em Erro (reenfileira + envia na hora, espelhando o/console). A distinção 1XX×9XX e a regra de não re-tentar o 1XX automaticamente vivem na 0005.Revisão (2026-09-08) — o Re-Importar re-arma o espelho, e o flash conta a verdade. "Reenfileira + envia na hora" era insuficiente: sem re-armar o
cod_retornoda linha no espelho o X-Adm nunca reprocessava, e o painel dizia "ENFILEIRADO" mesmo assim. O botão agora chamaPOST /api/v1/xadm/retorno/pedido/reenfileirardepois do push (ver api-integrador §6) e o flash reporta o desfecho real — N linhas reabertas · nada a reabrir · falha explícita. Nunca dizer "reenviado" quando a chamada falhou é requisito de produto, não detalhe: foi o que fez o operador clicar três vezes no mesmo pedido.Revisão (2026-09-10) — a Falha diz o que falta e pode ser fechada à mão. Incidente dos 15 kits: o contrato gravava no X-Adm e o produto-kit, a composição ou o item não — e o detalhe só dizia "Remessa travada". Duas mudanças: (a) o detalhe em Falha ganha um diagnóstico ao vivo (tipo do pedido, Gravado no X-Adm × NÃO gravado — lance manualmente com os dados do envio, avisos "Possível" tirados do texto do X-Adm), consultando o Integrador na abertura — decidido ao vivo, sem persistir (sem migração, sempre fresco; Integrador fora → aviso no lugar); (b) botão Importado manualmente ao lado do Re-Importar (e na home, nas linhas em Falha), que leva
ERRO_XADM → IMPORTADO_MANUAL— o mesmo status do Dispensar, em vez de um novo — com observação obrigatória (importacao_manual_obs, V12), porque o painel não tem login e ela é o único rastro de o que foi lançado e por quem. A reconciliação passa a ignorarIMPORTADO_MANUAL(senão a remessa, que segueTRAVADAno Integrador, devolvia o pedido à Falha a cada minuto). Rotas e texto em configuração.Revisão (2026-09-10, mesma data) — o botão fecha também a remessa no Integrador. O dono ganhou o
resolver-manual(TRAVADA → RESOLVIDA_MANUAL, decisão 0025 dele), e o clique passa a chamá-lo antes de marcar o pedido aqui: só o200fecha o pedido;409(parte do pedido ainda pendente de entrega — remessaABERTA, ouTRAVADAcom filho000bloqueado, que fechar soltaria para o ERP) e falha de transporte o deixam em Falha, com o motivo. Decidido Integrador primeiro — na ordem inversa, uma falha do comando deixaria a remessa travada lá para sempre, sem reconciliação que a revisite; e sem retry em fila (M2M), porque o operador está na tela e pode clicar de novo. Ganha também um campo operador, opcional (o dono o aceita no corpo; o painel segue sem login), gravado localmente no fim da observação — sem migração nova. Detalhe em API do Integrador §5.Revisão (2026-09-10, terceira) — a Falha tem um caminho só: lançar à mão. O X-Adm é caminho só de ida: o que ele gravou (
006) é definitivo e a integração nunca reenvia, e o re-arme só reabre1XX— reimportar serve, no máximo, para a parte que falhou, e nos 16 pedidos-kit do incidente nem isso resolvia (defeitos do lado ZIM,integrador-clientdocs/dev/contrato-pabast.md§8). Decidido: (a) o caminho padrão de toda Falha é conferir no X-Adm → lançar à mão o que falta → Importado manualmente, num "O que fazer" único, com o aviso de não excluir no X-Adm o que está em Gravado; (b) o Re-Importar só aparece com parte do pedido pendente (linha no espelho que não é006nem1XX— o filho que espera um pai rejeitado, ex. cliente não cadastrado): aí oresolver-manualresponde409por desenho e o caminho é corrigir e reimportar. O409também o põe à mostra (?pendente=1), cobrindoformulas, que o diagnóstico não consulta; (c) o reenvio automático por dado novo da PIED deixa de tocarERRO_XADM(ver 0005) — reenviar sozinho re-armaria o1XXenquanto o operador lança o mesmo à mão; (d) o diagnóstico completa os dados de lançamento: nome de cada componente, produto do item do kit, venda a prazo e, na duplicidade de contrato, os dois códigos e a ordem de escolher qual fica antes de lançar. Rejeitado: excluir no X-Adm e reimportar — esbarra na mão única e exigiria no Integrador um re-arme de006, com risco de duplicar pedido no ERP.
Alternativas consideradas¶
- Reusar o layout/navbar de operador nas telas do usuário: rejeitada — vaza ferramenta interna e foge do "limpo e elegante".
- Mostrar o estado técnico cru (CAPTURADO/ENVIADO/…): rejeitada — jargão de integração para o usuário final; os 4 buckets comunicam "onde meu pedido está".
- Manter a home de cards em
/e pôr o painel em outra rota: rejeitada — o usuário final é o público primário da raiz; o diagnóstico é secundário (vai para/homedev). - Valor monetário e busca no dashboard, ações no detalhe: fora de escopo do MVP (mantém enxuto).