Skip to content

Backend challenge: developing an API to handle growers, properties, and crop resources

License

Notifications You must be signed in to change notification settings

LucasPereiraMiranda/serasa-brain-ag-challenge

 
 

Repository files navigation

Serasa Brain AG Challenge

GitHub language count Repository size GitHub last commit Repository issues GitHub license

Descrição do desafio

O desafio consiste em desenvolver uma aplicação backend para atender aos requisitos descritos no documento oficial.

Techs

A implementação do desafio está utilizando as seguintes tecnologias:

Diagrama de Entidade-Relacionamento

O diagrama de entidade-relacionamento (DER) a seguir foi modelado para representar a estrutura do banco de dados no contexto do desafio. Ele ilustra as entidades principais e seus relacionamentos, fornecendo uma visão ilustrativa do fluxo de dados.

Diagrama entidade relacionamento modelado para o desafio

Execução do projeto

Docker-compose

Para executarmos o projeto com o docker-compose:

  1. Inicialmente, podemos conferir se existem processos executando nas portas 3000 e 5432.

Caso houver, precisamos desligá-los temporariamente para a execução do projeto a partir do docker-compose.

  1. Podemos copiar o .env.example existente na raiz do projeto, e duplicá-lo com o nome .env:
$ cp .env.example .env # em ambiente linux
  1. Podemos executar a instrução:
$ docker-compose up --build

Visando que o docker-compose do projeto levante 2 containers usando as variáveis de ambiente contidas no .env:

  • 1 associado a aplicação nest: serasa-brain-ag-challenge-app
  • 1 associado ao database postgres: serasa-brain-ag-challenge-db

Ocorrendo assim este preview de execução:

Preview de execução com o docker-compose

Modo local (sem containers)

Para executarmos o projeto com o modo local

  1. Podemos copiar o .env.example existente na raiz do projeto, e duplicá-lo com o nome .env:
$ cp .env.example .env # em ambiente linux
  1. Podemos instalar as dependencias:
$ npm install
  1. Podemos criar o banco de dados, levando em consideração os valores contidos no .env

  2. Podemos executar o projeto em modo de desenvolvimento:

$ npm run start:dev

Execução dos testes

Para executar os testes automatizados, podemos invocar o comando:

$ npm run test

O qual executará os testes unitários trazendo a seguinte previsão:

Preview de execução dos testes

Execução das migrations

Para executar as migrations existentes, podemos invocar o comando:

$ npm run migration:run

Para gerar uma nova migration a partir de uma nova entidade, podemos executar:

$ npm run migration:generate

Observação: Para executar estes processos, precisamos que o container associado ao postgres esteja ativo. Para executar as migrations via terminal, precisamos apontar para o container (no redirecionamento para o localhost) durante a execução da migration.

Swagger

A aplicação contém um Swagger, que inclui os contratos e especificações para comunicação com a API. Ao executar a aplicação localmente, o Swagger pode ser acessado por meio da seguinte URI:

$ http://localhost:3000/api#/

O preview do swagger esta presente na imagem abaixo:

Preview de execução do swagger

Considerações feitas durante o desenvolvimento

Estratégias para escalabilidade e confiabilidade em situações de grande carga

Para garantir que o sistema seja capaz de suportar um grande número de usuários simultâneos, foram implementadas as seguintes soluções:

  • Adição de Índices: Índices foram adicionados nas colunas frequentemente acessadas, como nativamente nas chaves primárias e em colunas usadas em filtros e buscas (crop.name), para melhorar o desempenho geral das consultas.

  • Adição de Cache: A utilização de cache foi implementada por meio da estratégia de armazenar resultados de consultas frequentes, reduzindo a carga nas tabelas que crescerão em densidade de dados com o intuito de manter um tempo saudável de resposta para os usuários e reduzir cargas no banco. A estratégia utilizada está contida no presente link.

  • Adição de Paginação: Foi implementada a paginação nos endpoints que retornam muitos registros (associados a findAll). Isso foi feito para evitar consultas que retornem grandes volumes de dados de uma só vez, ajudando a reduzir o tráfego de dados e melhorando a performance ao acessar as informações de forma mais controlada.

Estratégias para observabilidade

A observabilidade é um fator importante para garantir o bom funcionamento do sistema produtivo. Para isso, foram implementadas as seguintes estratégias no desafio:

  • Colunas para histórico de comportamento das entidades: Embora as colunas created_at e updated_at não sejam diretamente responsáveis pela monitoração do sistema em tempo real, elas fornecem informações importantes sobre o histórico e o comportamento dos registros ao longo do tempo. Esses dados podem ser utilizados para auditoria no decorrer do tempo.

  • Criação de Fluxo de Health Check: Foi implementado um fluxo de health check para observar o status das partes críticas do sistema, como banco de dados.

{
  "uptime": 538.826759168,
  "healthMessage": "OK",
  "checks": [
    {
      "name": "Database",
      "status": true,
      "details": "Connected"
    }
  ]
}

Estratégias que podem ser propostas:

  • APM: Como passo futuro, pode ser sugerido a adição de um APM como Elastic ou Datadog para ajudar na observabilidade geral da aplicação.

License

MIT

About

Backend challenge: developing an API to handle growers, properties, and crop resources

Topics

Resources

License

Stars

Watchers

Forks

Languages

  • TypeScript 98.8%
  • JavaScript 1.1%
  • Dockerfile 0.1%