DEV Community

Celso Costa
Celso Costa

Posted on • Edited on

[Projeto] - Desenvolvimento de um Marketplace

Descrição do Projeto

Desenvolvendo um marketplace. Como único desenvolvedor, fiquei responsável por desenvolver tanto o frontend quanto o backend, além de gerenciar a infraestrutura em uma VPS para colocar o sistema em produção. Estamos utilizando o padrão REST para a comunicação entre o frontend e o backend, bem como entre os serviços internos. Nosso objetivo é que esta primeira versão tenha funcionalidades essenciais, como registro e autenticação de usuários, listagem e gerenciamento de produtos, carrinho de compras, checkout e integração com um gateway de pagamento.

O intuito deste post é mostrar como o projeto foi pensado e desenvolvido, apontar as dificuldades enfrentadas e, por fim, sugerir melhorias para as próximas versões. Caso você esteja pensando em construir um marketplace ou e-commerce, leve em consideração as informações contidas neste post, mas use o bom senso, pois nem tudo o que está aqui pode se aplicar ao seu caso.

Observação: Esse post não irá detalhar como foi desenvolvido o frontend.

Requisitos

Definição: Definem o que um sistema deve fazer e sob quais restrições. Requisitos relacionados com a primeira parte dessa definição - "o que um sistema deve fazer", ou seja, suas funcionalidades - são chamados de Requisitos Funcionais. Já os requisitos relacionados a segunda parte - "sob que restrições" - são chamados de Requisitos Não Funcionais.[1]

Requisitos Funcionais(RF)

Lojista

[RF01]: O sistema deve permitir que os lojistas se registrem sendo do tipo pessoa física ou jurídica.
[RF02]: O sistema deve permitir que o administrador possa autorizar ou desautorizar o lojistas caso não esteja em conformidades com as informações verdadeiras informadas no cadastro.
[RF03]: O sistema deve permitir que o lojista vincule o seu perfil a uma comunidade
[RF04]: O sistema deve permitir que o lojista possa cria sua loja com foto da loja, descrição e contato.
[RF05]: O sistema deve permitir que o lojista cadastre produtos
[RF06]: O sistema deve permitir que o lojista possa alterar o preço do produto, quantidade e excluir produto.
[RF08]: O sistema deve permitir que o lojista possa

Cliente

[RF01]: O sistema deve permitir que o cliente se registrem sendo do tipo pessoa física ou jurídica.
[RF02]: O sistema deve permitir que o cliente cadastre endereços, cartões para pagamentos e informações básicas de contato como email e telefone.
[RF03]: O sistema deve permitir que o cliente adicione ao carrinho o item desejado
[RF04]: O sistema deve permitir o pagamento de cartão de crédito ou pix
[RF05]: O sistema deve permitir que o cliente escolha se prefere retirar na loja ou entrega(via transportadora).
[RF06]: O sistema deve permitir que o cliente acompanhe o status do pedido, como: pedido feito, pedido autorizado, pedido em transporte e pedido entregue
[RF07]: O sistema deve permitir que o cliente receba um email informando os itens comprados

Comunidades

[RF01]: O sistema deve permitir que o um líder de comunidade se registre com informações do tipo quem são os líderes da comunidade CPF, CNPJ, informações de contato e endereço.
[RF02]: O sistema deve permitir que o líder da comunidade liste todos os lojistas vinculada a essa comunidade.

Administrador

[RF01]: O sistema deve permitir o administrador listar todos os clientes cadastrados.
[RF02]: O sistema deve permitir que o administrador liste todos os lojistas e consiga desautorizar o lojista que não esteja em conformidades com a regras da plataforma.
[RF03]: O sistema deve permitir que o administrador liste todas as comunidades, tenha informações sobre os responsáveis delas e possa autorizar ou desautorizar as comunidades.

Requisitos não funcionais(RNF)

Segurança

[RNF01]: O armazenamento dos tokens de acesso e de renovação deve ser seguro, preferencialmente em armazenamento seguro do navegador (por exemplo, localStorage ou cookies com flags Secure e HttpOnly).

[RNF02]: O sistema deve implementar a renovação de tokens (refresh tokens) de forma segura para permitir sessões prolongadas sem comprometer a segurança.

Stack

  • NextJS/ReactJS
  • NodeJS
  • PostgreSQL
  • Nginx
  • minIO
  • Docker
  • RabbitMQ

System Design

Image description

Explicando o Fluxo

  • public-gateway

Tecnologia: NodeJS, Typescript

Descrição: Atua como ponto de entrada para gerenciar e rotear. Redireciona o tráfego de entrada e saída entre a rede interna e externa.

  • auth

Tecnologia: NodeJS, Typescript

Descrição: O Serviço de Autenticação recebe as requisições de autenticação do public-gateway, valida essas requisições, e faz chamadas apropriadas para o serviço de identity para verificar as credenciais e gerenciar o registro dos usuários.

  • identity

Tecnologia: NodeJS, Typescript

Descrição: O Serviço de Identity gerencia as operações relacionadas aos usuários e contas, incluindo autenticação, registro, atualização de perfis.

  • community

Tecnologia: NodeJS, Typescript

Descrição: O Serviço de Community gerencia a criação, atualização e manutenção de dados de comunidades e seus respectivos responsáveis, incluindo endereços, e-mails e telefones.

  • customer

Tecnologia: NodeJS, Typescript

Descrição: O Serviço de Customer gerencia a criação, atualização e manutenção de dados de comunidades e seus respectivos responsáveis, incluindo endereços, e-mails e telefones.

  • marketplace

Tecnologia: NodeJS, Typescript

Descrição: O Serviço de marketplace é responsável por gerenciar as operações essenciais de um marketplace, incluindo carrinho de compras, categorias de produtos, inventário e pedidos. Ele utiliza diversos modelos, como Cart, que representa um carrinho de compras; CartSessionCartItem, que gerencia a associação entre uma sessão de carrinho e itens; Category, que classifica os itens em categorias; e Department, que organiza os produtos por departamentos. Além disso, inclui Item, que representa os produtos disponíveis; ItemMedia, para gerenciar as fotos dos itens; ItemNumbering, que lida com a numeração dos itens; e ItemSize, que define os tamanhos dos itens (P, M, G, etc.). O serviço também abrange OrderItem, que representa itens dentro de um pedido; OrderStatus, que gerencia o status dos pedidos; OrderShipping, que lida com as informações de envio dos pedidos; e OrderItemShipping, que gerencia o envio de itens específicos dentro de um pedido. Outros modelos incluem ShippingToken, que representa tokens de envio para rastreamento; ShippingService, que gerencia os serviços de envio disponíveis; e StoreStoreAddress, que representa o endereço das lojas. O serviço permite a adição e remoção de itens do carrinho, a categorização e organização dos produtos, e o processamento completo dos pedidos, desde a criação até o envio.

  • media

Tecnologia: NodeJS, Typescript, minIO

Descrição: O Serviço de media é responsável pelo gerenciamento e armazenamento de arquivos de mídia, incluindo fotos das lojas, fotos de perfil e fotos dos itens (produtos). Organiza por buckets do MinIO para armazenar essas mídias.

  • supplier

Tecnologia: NodeJS, Typescript

Descrição: O Serviço de supplier gerencia a criação, atualização e manutenção de dados do lojista incluindo endereços, e-mails e telefones.

  • marketplace-cart-session-cron

Tecnologia: NodeJS, Typescript

Descrição: O Serviço de marketplace-cart-session-cron é responsável por gerenciar e limpar carrinhos de compras abandonados. Este serviço executa uma tarefa programada que verifica e remove carrinhos inativos no banco de dados. Para carrinhos de usuários não autenticados, ou seja, aqueles que não fizeram login, o serviço mantém o carrinho ativo por um período de 24 horas antes de removê-lo. Para carrinhos de usuários autenticados, o carrinho permanece ativo por 7 dias.

  • marketplace-order-cron

Tecnologia: NodeJS, Typescript

Descrição: A crontab marketplace-order-cron é responsável pela automação do processo de verificação e atualização dos pedidos com status de pagamento pendente. O serviço opera em intervalos regulares para consultar todos os pedidos que estão com o status "pendente de pagamento". Para cada pedido identificado, o serviço realiza uma solicitação à API de pagamento para processar o pagamento. Se o pagamento for bem-sucedido, o serviço atualiza o status do pedido no banco de dados para refletir a nova condição.

  • shipping-cron

Tecnologia: NodeJS, Typescript

Descrição: O Serviço shipping-cron é responsável por manter a validade dos tokens da API da transportadora. Este serviço é executado periodicamente para atualizar o token de autenticação, que é necessário para realizar chamadas à API da transportadora. Como os tokens fornecidos pela transportadora têm um período de expiração, o shipping-cron garante que um novo token seja obtido e registrado antes que o token atual expire, assegurando que as operações de envio e rastreamento continuem a funcionar sem interrupções.

  • customer-external-consumer

Tecnologia: NodeJS, Typescript

Descrição:
O customer-external-consumer é um serviço que consome mensagens de uma fila no RabbitMQ. Sua principal função é cadastrar clientes na API de pagamento e obter o identificador exclusivo do cliente fornecido pela API de pagamento. Esse identificador é então armazenado no banco de dados. Isso permite que, ao fazer pedidos de itens, o serviço envie à API de pagamento o identificador do cliente, facilitando a associação dos pagamentos com os clientes corretos.

  • supplier-external-consumer

Tecnologia: NodeJS, Typescript

Descrição: O supplier-external-consumer é um serviço que consome mensagens de uma fila no RabbitMQ. Sua principal função é cadastrar (lojistas) fornecedores na API de pagamento e obter o identificador exclusivo do fornecedor fornecido pela API de pagamento. Esse identificador é então armazenado no banco de dados local. Isso permite que, ao processar transações relacionadas aos fornecedores, o serviço envie à API de pagamento o identificador do fornecedor, garantindo a correta associação dos pagamentos com os fornecedores registrados.

  • email-consumer

Tecnologia: NodeJS, Typescript

Descrição: O email-consumer é um serviço que consome mensagens de email de uma fila no RabbitMQ. Ao receber uma mensagem, o serviço monta o template de email utilizando os atributos fornecidos no payload da mensagem. Após a montagem do email, o serviço envia o email formatado para o servidor SMTP para ser entregue ao destinatário.

Dificuldades enfrentadas

  1. Inicialmente, eu não quis trabalhar com nenhum ORM, o que foi um grande erro, porque no início, quando eu desenvolvia uma feature e o cliente pedia para adicionar ou remover uma nova informação, a manutenção das queries ficava bastante custosa. Então, tive que refatorar e adotei o ORM, facilitando a manutenção do sistema.

  2. Inicialmente, não tínhamos um(a) designer para o projeto, então precisei dedicar muito tempo à construção dos layouts das telas, e o cliente acabou achando-os muito simples. No final do projeto, uma UX/UI foi integrada à equipe e conseguiu criar, no Figma, os layouts da maneira que o cliente desejava. Minha observação: ter um(a) UX/UI facilitará e agregará valor ao seu projeto.

  3. Como as especificações não estavam definidas desde o primeiro dia, a primeira versão foi desenvolvida de forma iterativa e contínua. Decidi aplicar os conceitos de Domain-Driven Design (DDD), mas, ao precisar refatorar, era necessário modificar muitos arquivos, como interfaces de repositório e validações. Então, para a versão 1 e considerando que o cliente ainda não tinha clareza sobre o que precisava ser implementado, eu optaria por uma arquitetura mais simples para facilitar o desenvolvimento. Acredito que isso tenha sido um exemplo de overengineering no projeto, o que custou tempo de desenvolvimento.

Melhorias futuras

  1. Adicionar um BFF (Backend For Frontend) com GraphQL, isso vai agregar bastante ao front-end ao consumir os dados da API.

  2. Adicionar testes, já que temos vários serviços e, ao alterar um, é necessário que todos estejam consistentes.

  3. Adicionar CI/CD para automatizar a integração e deploy conforme as equipes forem contratadas para gerenciar o projeto.

  4. Adicionar observabilidade dos serviços. [OpenTelemetry, Grafana]

  5. Adicionar CDN para imagens dos produtos.

Referência

  1. https://engsoftmoderna.info/cap3.html

Top comments (0)