Cashback é um SPA desenvolvido em React como desafio do Grupo Boticário
👀 https://cashback-boticario.netlify.app/
A aplicação foi desenvolvida com o
create-react-app
, porém, como existe o fluxo de autenticação emJWT
e consumo deAPI
eu utilizei a solução daNetlify
para executar a arquitetura do projeto.
- Para executar o projeto em ambiente local é necessário instalar o
netlify-cli
:
npm install -g netlify-cli@2.63.3
- Instale as dependências do projeto com o comando
yarn install
- No diretório do projeto execute o comando
netlify dev
para subir a aplicação, oidentity
(serviço de autenticação em JWT) e aslambda-functions
onde estão contidas as regras de negócio da aplicação, regras deproxy
eparsing
esanitização dos dados
para a mock api. Na conclusão do processo o projeto estará disponível emhttp://localhost:8888/
Testes:
yarn test
Coverage:
yarn test:coverage
Abrir relatório de cobertura de testes:
open coverage/lcov-report/index.html
- React
- React Hooks
- Redux
- Redux-Sagas
- React-testing-library
- Emotion CSS (Styled Components)
Para evitar que as regras de negócio estivessem contidas no front-end, elas foram alocadas na pasta functions
, que é utilizada pelo netlify
como lambda-functions
.
Compras até
R$ 50,00
não geram cashback e o statusREPROVADO
é aplicado automaticamente. Compras entreR$ 50,01
eR$ 500,00
recebem o statusAPROVADO
automaticamente e as seguintes regras de cashback são aplicadas:
3%
de cashback em compras de atéR$ 250,00
.5%
de cashback em compras de atéR$ 250,00
eR$ 500,00
.
Compras acima de
R$ 500,00
geram8%
de cashback, porém o statusEM VALIDAÇÃO
é aplicado.
Minha intenção foi apresentar qual abordagem eu teria em construir uma aplicação restful escalável.
👉 Em uma situação real, eu levaria outros fatores em consideração na escolha da arquitetura, como objetivo de negócio (é um MVP que precisa validar uma hipótese, é para ser lançado rápido?, todos no time estão familiarizados com as tecnologias?)... 👉 Em aplicações menores eu utilizaria soluções
built-in
do React para genreciamento de estado comocontext-api
combinado comuseReducers
.
Eu escolhi essa combinação de tecnologias, pois ainda são boas opções para APIs Rest e entre as opções de controle de estado, proporcionam as melhores opções de debugging
e integradas ao redux dev tools
e o redux-logger
(utilizadas nesse projeto) garantem:
Arquitetura Event-driven
-> através da abordagem declarativa do fluxo unidirecional do Flux/Redux, que me obriga a separar as "etapas" do fluxo do de dadosPrevisibilidade
-> através das soluções de logs, que podem ser integradas a ferramentas de monitoramento de erros como oSentry
, permitindo que o fluxo de actions disparadas sejam empilhadas na forma debreadcrumb
, o que facilita entender o fluxo do usuário até que o erro seja disparado.
Eu escolhi a abordagem conhecida como Rails-Style Structure + Module Index
, que é mais verbosa (muitas pastas e arquivos index), porém é eficiente quando a aplicação escala e é necessária a segmentação do estrutura do projeto em múltiplos domínios e posteriormente, se necessário, a uma abordagem de micro-frontends
.
- Os componentes foram organizados em
presentational components
econtainer components
onde apenas oscontainers
se comunicam com a store global.
- Cada
Componente
,Container
,Route/Page
possui o seu próprioJSX
,estilos .styled.js
e seus próprios arquivos de testes.spec.js
, o que facilita o compartilhamento de componentes, entre domínios, micro-frontends ou publicação deshared-components
em soluções entre times, como obit.dev
.
Todo o CSS do projeto foi criado do zero por se tratar de um desafio de Front-end. Também criei os
design-tokens
para utilizar nos estilos globais e garantir uma maior padronização do projeto. Utilizei a convenção detamanho de camisetas
(S
,M
,X
,XXL
) e pode ser encontrado emsrc/style/theme.js
e é importada peloThemeProvider
.
Joguei toda a responsabilidade de controle de side-effects para Redux-Sagas
, onde através do Redux eu controlo os estados das race conditions
e resposta da UI com a abordagem de máquina finita de estados
, por isso na minha global store poderá ser observado que todas as requests possuem uma entrada com estado inicial idle
que imediatamente muda para running
e que pode retornar success
ou failure
e a partir daí os reducers podem abrigar algumas lógicas de exibição de estados.
- Utilize um destes frameworks: Angular,
React
ou Vue.js - Você
pode utilizar
um framework de UI. Exemplo: Bootstrap, Material-UI, Bulma, etc. - Design Responsivo (manter a integridade das informações e layout nos principais breakpoints; Mobile e Desktop).
- Integração com uma API 'fake' (mockado ou remoto).
- Respeitar boas práticas de código e arquitetura.
- Teste Unitário (Jasmine, Jest).
- Testes Automatizados (E2E).
- Utilização de boas práticas do Git.
- State Management (
Redux
, NGRX, MobX, etc). - Webcomponents cross-platform.
- Offline Cache com Service Worker.
- Autenticação JWT
- Nome completo
- CPF
- Senha
- Senha
- Código
- Valor da compra
- Data da compra
-
Código
-
Valor
-
% de cashback aplicado
-
Valor do cashback
-
Status do cadastro
-
EM VALIDAÇÃO
-
REPROVADO
-
APROVADO
-
-
Exibição de Cashback