Desafio frontend público da Stone: praticar estados, permissões e auditoria em React

Pratique o desafio frontend público da Stone com estados, papéis e falha de auditoria em React. Veja testes originais e limites da autorização na tela.

Author: PracHub

Published: 10/11/2026

Desafio frontend público da Stone: praticar estados, permissões e auditoria em React

October 11, 2026

Quick Overview

Guia em português do Brasil sobre a versão pública template-desafio-admin da Stone, com commit consultado identificado e sem inferir o processo atual de contratação. Um laboratório React original mostra uma decisão salva seguida de falha na auditoria, recuperação apenas da etapa pendente e preservação do operador original. Matriz de papéis, testes do modelo e do navegador separam projeção da interface de autorização real no servidor. Não é uma entrega completa da API oficial.

Software EngineerFree

Uma tela pode mostrar “aprovado” corretamente e ainda deixar o trabalho incompleto: a atualização foi salva, mas a auditoria falhou. No desafio frontend público da Stone, estudar estados e permissões fica mais produtivo quando você consegue explicar esse tipo de resultado parcial, em vez de tratar todo erro como se nada tivesse acontecido.

Fato oficial: o repositório stone-payments/template-desafio-admin publica um exercício admin-web. Consultamos o main em 11 de outubro de 2026, no commit 627a67884e4855c1acf0691e86a5da8dc4191dc1. O artefato existe; isso não confirma que toda vaga atual da Stone utilize essa versão. Verifique o repositório e as instruções da sua convocação. Ele é diferente do card-interview em Go.

O laboratório deste artigo é original: uma solicitação fictícia de acesso, um componente React e promessas controladas em memória. Não implementa a API oficial nem serve como entrega completa do desafio. Não usamos relatos de candidatos para prever prazo, etapas ou aprovação. Regras documentadas, resultados executados e sugestões de arquitetura aparecem separados.

Uma decisão já salva permanece aprovada quando a auditoria falha; a recuperação repete apenas a auditoria.

Depois do caso, pratique Implement list, form, and API rendering with pitfalls. Além de renderizar dados, explique qual operação cada mensagem da interface confirma.

Confirme o contrato do admin-web antes de escolher componentes

Resumo oficial desta versão: o exercício usa React e TypeScript, uma API fornecida e contextos de usuários, cartões, analistas e auditoria. Pedidos começam como requested e podem virar approved ou rejected, sem uma segunda mudança de status. Ações devem produzir auditoria. Há restrições para n1 visualizar auditoria, salário e limite, além de excluir pedidos; n2, inclusive combinado com n1, possui acesso ampliado. O texto também pede criação condicionada à feature e sessão simples no cliente. Consulte o README fixado para rotas e campos exatos.

Esse resumo não resolve como duas gravações devem se comportar quando apenas uma funciona. Registre a dúvida e explicite a decisão adotada no exercício. “A API fornecida existe” também não demonstra que ela ofereça transação atômica, idempotência ou controle de versão.

Nosso laboratório usa JSX e uma solicitação de acesso ao laboratório, não cartões. Seu objetivo é isolar decisão, projeção de permissões e recuperação da auditoria. Não cobre login, cadastro, exclusão, todas as rotas ou o requisito TypeScript de uma entrega oficial completa.

Modele estado de negócio e estado da operação separadamente

A solicitação fictícia LAB-7 começa como requested. Pode ser aprovada ou rejeitada uma vez. Ao mesmo tempo, a interface precisa representar se está salvando a decisão, gravando a auditoria ou aguardando repetição desta última. O status responde o que aconteceu com o recurso; a fase responde qual etapa da operação ainda está pendente.

Orientação oficial do React: evite estados contraditórios e informações duplicadas que precisam ser sincronizadas. A documentação de estrutura de estado apresenta esse princípio. Aplicamos a orientação mantendo o status do recurso separado de uma fase explícita da operação; não criamos cinco booleanos independentes para cada mensagem.

Fase da interfaceStatus do recursoO que já sabemosPróxima ação permitida no laboratório
idlerequestedNenhuma decisão enviadaAprovar ou rejeitar
savingrequestedGravação ainda pendenteAguardar resposta
auditSavingapproved ou rejectedDecisão salva; auditoria pendenteAguardar auditoria
auditPendingapproved ou rejectedDecisão salva; auditoria falhouRepetir somente auditoria
doneapproved ou rejectedAs duas operações confirmadasNão decidir novamente
errorrequestedGravação da decisão falhou neste simuladorTentar a decisão novamente

A última linha tem uma precondição importante: nossa API em memória sinaliza falha antes de aplicar a decisão. Um timeout de rede real poderia ocorrer depois de o servidor gravar. Nesse caso, inferir que o recurso continua requested seria incorreto sem consulta ou contrato adicional.

O estado local também guarda o evento de auditoria pendente: recurso, valor anterior, valor posterior e identificador do operador que decidiu. O evento acompanha a operação original; não é reconstruído usando o operador selecionado na tela no momento da repetição.

A falha da auditoria não desfaz uma decisão já gravada

Acompanhe três eventos: o operador A aprova, a gravação confirma sucesso e a auditoria falha. No componente real, o status exibido permanece approved, a fase vira auditPending e aparece uma mensagem específica de pendência.

A transição executada no modelo é:

case 'auditFailed':
  return state.phase === 'auditSaving'
    ? { ...state, phase: 'auditPending',
        error: 'Decisão gravada; auditoria pendente.' }
    : state;

O campo card.status não é restaurado para requested. Fazer isso deixaria a tela diferente do servidor simulado e poderia habilitar outra decisão indevida. Um teste de regressão introduziu exatamente esse rollback falso numa cópia do modelo; a verificação do status após falha de auditoria rejeitou a variante.

Essa política de recuperação é nossa escolha de estudo, não uma garantia dada pelo README. Uma aplicação real pode precisar que o backend faça a mudança e registre o evento numa única unidade confiável. O frontend, sozinho, não torna duas operações remotas atômicas.

Também diferencie esconder o erro de recuperar a operação. Mostrar apenas um toast “tente novamente” não informa qual etapa falhou nem qual resultado foi confirmado. A mensagem deve permitir ao operador entender por que o status mudou e por que ainda existe trabalho pendente.

A repetição deve preservar o ator e evitar a primeira gravação

Na primeira tentativa, o componente envia uma operação save e depois uma audit. Após a falha da auditoria, o botão “Repetir somente auditoria” envia apenas audit. A sequência observada foi:

save  → sucesso
audit → falha
audit → sucesso

Houve uma chamada de atualização e duas tentativas de auditoria. Ao final, o servidor em memória continha um evento confirmado, com requestedBy: "operator-A". Não houve segunda atualização de status.

Para testar a identidade, mudamos o papel de demonstração de n1 para n2 depois da falha e antes da repetição. O operador atual passou a B, mas o evento reenviado continuou atribuído a A. Registrar B como autor atribuiria a decisão à pessoa que repetiu a auditoria, não à pessoa que aprovou o pedido. Em um sistema real, quem repetiu a recuperação pode merecer um campo separado; isso não deve substituir quem realizou a ação original.

O laboratório conserva o mesmo ID de evento, mas não implementa deduplicação durável. A falha simulada não gravou a primeira auditoria. Se um servidor real gravar e a resposta se perder, repetir sem idempotência pode duplicar eventos. Portanto, “um evento no nosso teste” não equivale a “exactly once em rede”.

Se pedirem como evoluir, proponha um identificador de operação estável e uma regra de deduplicação no servidor, ou um comando backend que registre decisão e auditoria de forma consistente. São propostas arquiteturais, não recursos implementados no componente.

Transforme papéis em uma matriz verificável

No laboratório, o papel selecionado serve apenas para exercitar a projeção da interface. n1 pode decidir, mas não vê painel de auditoria nem o orçamento fictício. n2 vê ambos. A combinação n1 + n2 mantém as permissões ampliadas. Um papel desconhecido não recebe permissão por padrão.

Papéis de demonstraçãoDecidirVer auditoriaVer dado restrito
n1SimNãoNão
n2SimSimSim
n1 e n2SimSimSim
Nenhum reconhecidoNãoNãoNão

Essa tabela é a projeção original para o recurso fictício. “Orçamento” não é um campo do contrato oficial de cartões. Reaproveitamos a distinção entre grupos para tornar o comportamento observável sem usar dados financeiros reais.

Referência de segurança: a OWASP recomenda verificar autorização no servidor e em cada operação. Ocultar um botão ou uma seção no React não impede uma chamada direta à API. A sessão simplificada de um exercício não deve ser apresentada como uma arquitetura de autenticação segura para produção.

A matriz de papéis controla a projeção visual; a autorização real precisa ser validada no servidor.

Ao explicar seu trabalho, diga qual parte foi demonstrada: o DOM omite os campos e ações fora da projeção permitida. Não diga que isso prova proteção dos dados na resposta HTTP. Nosso laboratório não faz HTTP e não possui um backend autorizado; essa verificação continua fora do escopo.

Uma regra com precedência de negação também seria outro contrato. A combinação n1 + n2 deste estudo segue a política de acesso ampliado descrita para esta versão, sem inventar que toda união de papéis em qualquer sistema se comporta assim.

Inicie mutações no evento do usuário, com guarda de execução

Orientação oficial do React: lógica causada por uma interação específica costuma pertencer ao respectivo event handler, em vez de um Effect que infere a intenção a partir de outro estado. Veja You Might Not Need an Effect. O laboratório inicia a gravação no clique e usa o resultado das promessas para avançar as fases.

Enquanto salva, os botões de decisão ficam desabilitados. A guarda busy.current em useRef também recusa nova execução imediatamente, antes de a próxima renderização desabilitar os botões. O modelo recusa outra decisão quando já está salvando ou quando o recurso chegou a um estado terminal.

Essas proteções locais atendem problemas diferentes: desabilitar comunica indisponibilidade; a guarda protege a execução imediata; a transição evita estados locais inválidos. Nenhuma delas substitui proteção do servidor contra outra aba, outro cliente ou repetição de requisição.

O teste de navegador verificou que, após um clique, o botão ficava desabilitado e havia uma única chamada save. Não executamos um teste de múltiplas abas nem alegamos eliminar toda concorrência possível. A presença da guarda no código e a observação do fluxo cobrem o caso local demonstrado.

Também não grave auditoria durante o render. Renderizar a mesma tela não significa que o usuário realizou outra ação. E não deduza “preciso salvar” apenas porque card.status mudou: uma consulta, uma recuperação ou uma atualização externa pode alterar esse estado sem representar uma nova intenção do operador.

Teste resultados parciais antes de revisar o acabamento

As promessas ficam pendentes até os controles do experimento responderem com sucesso ou falha. Isso permite escolher o resultado de cada etapa, sem rede, sleep ou dependência de velocidade. Os controles pertencem ao runner de testes, não à interface de produto que seria entregue a um usuário.

O relatório do modelo registra 24 verificações em Node; o relatório de navegador registra 23 verificações de DOM no Chrome com React e react-dom 19.3, usando promessas controladas em memória. Os testes observaram permissões, bloqueio durante gravação, falha de auditoria, repetição isolada, identidade original, papéis combinados, papel desconhecido e caminho de rejeição.

No caminho em que a gravação falha, o recurso permaneceu requested, nenhuma auditoria foi chamada e os botões de decisão voltaram a permitir tentativa. Em seguida, uma rejeição completa terminou como rejected, com um evento confirmado. No caminho de falha parcial, approved foi preservado até a recuperação concluir.

O teste de mutação confirma que ao menos uma implementação errada importante é distinguida da correta. Ele não cobre toda a aplicação oficial. Persistência após recarregar, login real, conflito entre operadores, resposta perdida, acessibilidade completa e API fornecida não foram implementados ou validados aqui.

Para revisar uma entrega própria, apresente o cenário, a sequência de chamadas, o estado final e a limitação. Você pode apoiar a explicação nesses quatro elementos, mesmo quando ainda há partes não implementadas: eles mostram o que foi observado e onde falta trabalho.

Conecte a preparação a cinco exercícios específicos

Os destinos abaixo foram verificados como prática complementar. Não são apresentados como perguntas da Stone nem como uma previsão da sua avaliação.

Pergunta completa no PracHubO que levar deste estudo
Implement list, form, and API rendering with pitfallsDistinguir estado do recurso, operação pendente e mensagem exibida.
Design an RBAC Relational SchemaSeparar identidade, papel, recurso e permissão verificável.
Evaluate Role-Based Access with Deny PrecedenceLer a política concreta sem presumir como papéis combinados se resolvem.
Design an Audit Logs ServicePreservar ator, antes/depois, identificador e comportamento de repetição.
Design a Fixed-Position Payment Command State MachineExplicar transições permitidas e efeitos de repetir um comando terminal.

Comece pelo exercício de lista, formulário e API. Num simulador com dados fictícios, faça a auditoria falhar depois de confirmar a gravação e escreva a mensagem que mostraria ao operador. Em seguida, prove que a recuperação chama somente a etapa pendente. Antes de usar esse raciocínio na sua convocação, volte ao README recebido e diferencie o que ele exige, o que você decidiu e o que conseguiu testar.

Sources and Further Reading


Comments (0)