jsfoliveira / Project-Trybe-Futebol-Clube

Projeto proposto e desenvolvido no curso de desenvolvimento web da Trybe

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

👩‍💻 Project Trybe Futebol Clube

Esse projeto contém uma série de informações sobre o que eu aprendi aqui na Trybe ao longo do curso de desenvolvimento web da Trybe.
O TFC é um site informativo sobre partidas e classificações de futebol! ⚽️

No time de desenvolvimento do TFC, seu squad ficou responsável por desenvolver uma API (utilizando o método TDD) e também integrar - através do docker-compose - as aplicações para que elas funcionem consumindo um banco de dados.

Nesse projeto, pude construir um back-end dockerizado utilizando modelagem de dados através do Sequelize. O desenvolvimento respeita regras de negócio providas no projeto e sua API foi capaz de ser consumida por um front-end já provido nesse projeto.

Para adicionar uma partida é necessário ter um token, portanto a pessoa deverá estar logada para fazer as alterações. Teremos um relacionamento entre as tabelas teams e matches para fazer as atualizações das partidas.

O seu back-end implementou regras de negócio para popular adequadamente a tabela disponível no front-end que é exibida para a pessoa usuária do sistema.

🚀Começando

Esse projeto foi proposto pelo curso de desenvolvimento web da Trybe.

Desenvolvimento

Esse projeto foi desenvolvido no bloco de back-end e foi possível treinar a linguagem TypeScript, através do MySQL, sendo usados os princípios SOLID e POO.

Commits

Os commits foram feitos de acordo com os requisitos finalizados.

Branch

Todo o projeto foi feita na branch 'juliana-oliveira-project-tfc', isso por conta da exigência do curso.

Instalação

Precisa utilizar o comando $npm install, a fim de instalar as dependências do projeto.

Testes

O teste acontece de cada desafio, através do comando $npm test.

Banco de dados

  • Será um container docker MySQL já configurado no docker-compose através de um serviço definido como db.
  • Tem o papel de fornecer dados para o serviço de backend.
  • Durante a execução dos testes sempre vai ser acessado pelo sequelize e via porta 3002 do localhost;
  • Você também pode conectar a um Cliente MySQL (Workbench, Beekeeper, DBeaver e etc), colocando as credenciais configuradas no docker-compose no serviço db.

Back-end

  • Será o ambiente que você realizará a maior parte das implementações exigidas.
  • Deve rodar na porta 3001, pois o front-end faz requisições para ele nessa porta por padrão;
  • Sua aplicação deve ser inicializada a partir do arquivo app/backend/src/server.ts;
  • Garanta que o express é executado e a aplicação ouve a porta que vem das variáveis de ambiente;
  • Todas as dependências extras (tal como joi, boom, express-async-errors...) devem ser listadas em app/backend/packages.npm.

Front-end

  • O front já está concluído, não é necessário realizar modificações no mesmo. A única exceção será seu Dockerfile que precisará ser configurado.
  • Todos os testes a partir do requisito de login usam o puppeteer para simular uma pessoa acessando o site http://localhost:3000/;
  • O front se comunica com serviço de back-end pela url http://localhost:3001 através dos endpoints que você deve construir nos requisitos.
  • Recomendamos que sempre que implementar um requisito no back-end acesse a página no front-end que consome a implementação para validar se está funcionando como esperado.

Docker

  • O docker-compose tem a responsabilidade de unir todos os serviços conteinerizados (backend, frontend e db) e subir o projeto completo com o comando npm run compose:up ou npm run compose:up:dev;
  • Você deve configurar as Dockerfiles corretamente nas raízes do front-end e back-end, para conseguir inicializar a aplicação;

Na sua máquina você deve ter

  • Sistema Operacional Distribuição Unix
  • Node versão 16
  • Docker
  • Docker-compose versão >=1.29.2

Variáveis de ambiente

No diretório app/backend/, contém o arquivo .env. Nele, você precisa alterar os valores de acordo com o cenário do seu ambiente (credenciais de banco de dados, secrets desejadas e etc). Isso vai permitir que você inicialize a aplicação fora do container e ela se conecte com seu banco local caso deseje.

⚠️ Variáveis de ambiente além das especificadas acima não são suportadas, pois não são esperadas pelo avaliador do projeto. ⚠️

⚠️ Não defina variável de ambiente para o nome do banco, o mesmo deve se manter com o nome TRYBE_FUTEBOL_CLUBE. ⚠️

Autores

Esse foi um projeto individual,que desenvolvido somente por Juliana Oliveira.

Ferramentas usadas

Foi usado Visual Studio Code, além do Trello que auxiliou na organização das tarefas.

Framework usado

Nenhum.

👣Requisitos

Metodologia usada

No trabalho do desenvolvimento de software a gente sempre tem prazos, muitas vezes os prazos são apertados.
Por outro lado, eu não quero criar algo que não entendo perfeitamente, como também fazer códigos rápidos pode levar a erros que podem demorar muito pra corrigir.
Por isso, usei e sempre uso o método Baby Steps, que é uma estratégia de abordar o desafio passo à passo, defensivamente.
Baby steps é um termo em inglês que quer dizer passos de bebê. Refere-se a fazer as coisas, quaisquer que sejam, devagar, com calma, passo a passo.

Sobre os Requisitos

Esse projeto é composto de 4 seções principais:

  1. Users e Login
  2. Times
  3. Partidas
  4. Placar

Database

  • Comece rodando o comando npm run build na pasta do back-end para fazer o build da aplicação;
  • Nessa seção temos o diagrama de entidades;
  • Mantenha o arquivo /app/backend/src/database/migrations/99999999999999-create-z.js, pois ele é necessário para a avaliação dos requisitos dessa seção;
  • A leitura da seção Bônus: Model com Sequelize no conteúdo de TypeScript: Tipagem Estática e Generics, contido nesse link, é recomendável!

Seção 1: Users e Login

Introdução
  • A rota utilizada deve ser (/login);

  • A rota deve receber os campos email e password e esses campos devem ser validados no banco de dados:

    • O campo email deve receber um email válido;
    • O Campo password deve ter mais de 6 caracteres.
  • O body da requisição deve conter o seguinte formato:

    {
      "email": "string",
      "password": "string"
    }
Requisitos

👣Requisito 1 - Desenvolva em /app/backend/src/database nas pastas correspondentes, uma migration e um model para a tabela users

  • O avaliador consultará os dados da tabela users, verificando se ela contém os dados iniciais corretos. Nessa seção temos o diagrama de entidades;

👣Requisito 2 - (TDD) Desenvolva testes que cubram no mínimo 5% dos arquivos back-end em /src, com um mínimo de 7 linhas cobertas

Sugestões:

  • Baseando-se no contrato do endpoint /login do próximo requisito, inicie um teste de integração utilizando a metodologia TDD com a implementação do requisito seguinte;
  • Nesse primeiro momento, foque em desenvolver o que pede o requisito, progredindo gradualmente a partir disso;
  • Para tanto, utilize/altere o arquivo de referência app/backend/src/tests/change.me.test.ts;
  • Veja a seção de Testes de cobertura para mais detalhes.

👣Requisito 3 - Desenvolva o endpoint /login no back-end de maneira que ele permita o acesso com dados válidos no front-end

  • A rota de ser do tipo POST;

  • O avaliador verificará se é possível fazer o login com dados corretos e que, após o acesso, será redirecionado para a tela de jogos.

  • As senhas que existem no banco de dados estão encriptadas. Veja a seção de Criptografia de Senhas para mais detalhes de como comparar a senha do banco com a senha do corpo da requisição.

  • Se o login foi feito com sucesso, o resultado retornado deverá ser similar ao exibido abaixo, com um status http 200:

    {
      "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6ImFkbWluIiwiaWF0IjoxNjU0NTI3MTg5fQ.XS_9AA82iNoiVaASi0NtJpqOQ_gHSHhxrpIdigiT-fc" // Aqui deve ser o token gerado pelo backend.
    }

👣Requisito 4 - (TDD) Desenvolva testes que cubram no mínimo 10% dos arquivos back-end em /src, com um mínimo de 19 linhas cobertas

Sugestão:

  • Evolua os testes de integração da sua rota /login, utilizando o método TDD, agora considerando o contrato do próximo requisito.

👣Requisito 5 - Desenvolva o endpoint /login no back-end de maneira que ele não permita o acesso sem informar um email no front-end

  • O avaliador verificará se fazer o login sem um email, haverá o retorno de status bad request.

  • Se o login não tiver o campo "email", o resultado retornado deverá ser a mensagem abaixo, com um status http 400:

  { "message": "All fields must be filled" }

👣Requisito 6 - (TDD) Desenvolva testes que cubram no mínimo 15% dos arquivos back-end em /src, com um mínimo de 25 linhas cobertas

Sugestão:

  • Evolua os testes de integração da sua rota /login, utilizando o método TDD, agora considerando o contrato do próximo requisito.

👣Requisito 7 - Desenvolva o endpoint /login no back-end de maneira que ele não permita o acesso sem informar uma senha no front-end

  • O avaliador verificará se fazer login sem senha, o retorno será status bad request.

  • Se o login não tiver o campo "password", o resultado retornado deverá ser conforme exibido abaixo, com um status http 400:

  { "message": "All fields must be filled" }

👣Requisito 8 - (TDD) Desenvolva testes que cubram no mínimo 20% dos arquivos back-end em /src, com um mínimo de 35 linhas cobertas

Sugestão:

  • Evolua os testes de integração da sua rota /login, utilizando o método TDD, agora considerando o contrato do próximo requisito.

👣Requisito 9 - Desenvolva o endpoint /login no back-end de maneira que ele não permita o acesso com um email inválido no front-end

  • O avaliador verificará se fazer o login com um email incorreto retornará status não-autorizado.

  • Se o login tiver o "email" inválido, o resultado retornado será similar ao exibido abaixo, com um status http 401:

  { "message": "Incorrect email or password" }

👣Requisito 10 - (TDD) Desenvolva testes que cubram no mínimo 30% dos arquivos back-end em /src, com um mínimo de 45 linhas cobertas

Sugestão:

  • Evolua os testes de integração da sua rota /login, utilizando o método TDD, agora considerando os contratos dos próximos dois requisitos.

👣Requisito 11 - Desenvolva o endpoint /login no back-end de maneira que ele não permita o acesso com uma senha inválida no front-end

  • O avaliador verificará se fazer o login com uma senha incorreta retornará status não-autorizado.

  • Se o login tiver a "senha" inválida, o resultado retornado deverá ser conforme exibido abaixo, com um status http 401:

  { "message": "Incorrect email or password" }

👣Requisito 12 - Desenvolva o endpoint /login/validate no back-end de maneira que ele retorne os dados corretamente no front-end

  • Deve ser uma rota GET que receba um header com parâmetro authorization, onde ficará armazenado o token gerado no login;

  • O avaliador verificará se ao tentar bater na rota com um token válido, o mesmo retornará o tipo de usuário.

A resposta deve ser de status 200 com um objeto contendo a role do user:

  { "role": "admin" }

Seção 2: Times

Introdução
  • Os requisitos a seguir consideram o consumo da rota /teams para retornar os nomes dos times associados à partida na renderização do front-end
Requisitos

👣Requisito 13 - (TDD) Desenvolva testes que cubram no mínimo 45% dos arquivos back-end em /src, com um mínimo de 70 linhas cobertas

Sugestão:

  • Crie um novo teste de integração, agora da sua rota /teams, utilizando o método TDD, considerando os contratos dos próximos dois requisitos. Nessa seção temos o diagrama de entidades.

👣Requisito 14 - Desenvolva em /app/backend/src/database nas pastas correspondentes, uma migration e um model para a tabela de teams

  • O avaliador consultará os dados da tabela teams, verificando se ela contém os dados iniciais corretos. Nessa seção temos o diagrama de entidades.

👣Requisito 15 - Desenvolva o endpoint /teams no back-end de forma que ele possa retornar todos os times corretamente

  • Deve ser uma rota GET com resposta com status 200 e com um json contendo o retorno no seguinte modelo:
[
  {
    "id": 1,
    "teamName": "Avaí/Kindermann"
  },
  {
    "id": 2,
    "teamName": "Bahia"
  },
  {
    "id": 3,
    "teamName": "Botafogo"
  },
  ...
]

👣Requisito 16 - Desenvolva o endpoint /teams/:id no back-end de forma que ele possa retornar dados de um time específico

  • Deve ser uma rota GET com resposta com status 200 e com um json contendo o retorno no seguinte modelo:
{
  "id": 5,
  "teamName": "Cruzeiro"
}

👣Requisito 17 - (TDD) Desenvolva testes que cubram no mínimo 60% dos arquivos back-end em /src, com um mínimo de 80 linhas cobertas

Sugestão:

  • Crie um novo teste de integração, agora da sua rota /matches, utilizando o método TDD, agora considerando os contratos dos próximos três requisitos.

Seção 3: Partidas

Introdução
  • Para os requisitos de criação de partidas, será necessário implementar o model e algumas rotas relacionadas a entidade Match.
Requisitos

👣Requisito 18 - Desenvolva em /app/backend/src/database nas pastas correspondentes, uma migration e um model para a tabela de matches

  • O avaliador consultará os dados da tabela matches, verificando se ela contém os dados iniciais corretos. Nessa seção temos o diagrama de entidades.

👣Requisito 19 - Desenvolva o endpoint /matches de forma que os dados apareçam corretamente na tela de partidas no front-end.

  • A rota deve ser um GET e retorna uma lista de partidas;

  • Será validado que a página apresentará todos os dados de partidas sem nenhum filtro.

    Exemplo de retorno:

    [
      {
        "id": 1,
        "homeTeam": 16,
        "homeTeamGoals": 1,
        "awayTeam": 8,
        "awayTeamGoals": 1,
        "inProgress": false,
        "teamHome": {
          "teamName": "São Paulo"
        },
        "teamAway": {
          "teamName": "Grêmio"
        }
      },
      ...
      {
        "id": 41,
        "homeTeam": 16,
        "homeTeamGoals": 2,
        "awayTeam": 9,
        "awayTeamGoals": 0,
        "inProgress": true,
        "teamHome": {
          "teamName": "São Paulo"
        },
        "teamAway": {
          "teamName": "Internacional"
        }
      }
    ]
  • OBS: Você deverá definir os relacionamentos para teamHome e teamAway somente na model de partidas.

👣Requisito 20 - Desenvolva o endpoint /matches de forma que seja possível filtrar as partidas em andamento na tela de partidas do front-end

  • A rota deverá ser do tipo GET e retornar uma lista de partidas filtradas;

  • Será validado que, ao escolher a opção de partidas em andamento, serão filtradas todas as partidas em andamento;

  • Essa requisição deverá usar query string para definir o parâmetro: ex: matches?inProgress=true

Exemplo de retorno da requisição:

[
  {
    "id": 41,
    "homeTeam": 16,
    "homeTeamGoals": 2,
    "awayTeam": 9,
    "awayTeamGoals": 0,
    "inProgress": true,
    "teamHome": {
      "teamName": "São Paulo"
    },
    "teamAway": {
      "teamName": "Internacional"
    }
  },
  {
    "id": 42,
    "homeTeam": 6,
    "homeTeamGoals": 1,
    "awayTeam": 1,
    "awayTeamGoals": 0,
    "inProgress": true,
    "teamHome": {
      "teamName": "Ferroviária"
    },
    "teamAway": {
      "teamName": "Avaí/Kindermann"
    }
  }
]

👣Requisito 21 - Desenvolva o endpoint /matches de forma que seja possível filtrar as partidas finalizadas na tela de partidas do front-end

  • A rota deverá ser do tipo GET e retornar uma lista de partidas filtradas;

  • Será validado que,ao escolher a opção de partidas finalizadas, serão filtradas todas as partidas finalizadas;

  • Essa requisição deverá usar query string para definir o parâmetro. ex: matches?inProgress=false

Exemplo de retorno da requisição:

[
  {
    "id": 1,
    "homeTeam": 16,
    "homeTeamGoals": 1,
    "awayTeam": 8,
    "awayTeamGoals": 1,
    "inProgress": false,
    "teamHome": {
      "teamName": "São Paulo"
    },
    "teamAway": {
      "teamName": "Grêmio"
    }
  },
  {
    "id": 2,
    "homeTeam": 9,
    "homeTeamGoals": 1,
    "awayTeam": 14,
    "awayTeamGoals": 1,
    "inProgress": false,
    "teamHome": {
      "teamName": "Internacional"
    },
    "teamAway": {
      "teamName": "Santos"
    }
  }
]

👣Requisito 22 - (Bônus; TDD) Desenvolva testes que cubram no mínimo 80% dos arquivos back-end em /src, com um mínimo de 100 linhas cobertas

Sugestão:

  • Evolua os testes de integração da sua rota /matches, utilizando o método TDD, agora considerando o contrato dos próximos requisitos.

👣Requisito 23 - Desenvolva o endpoint /matches de modo que seja possível salvar uma partida com o status de inProgress como true no banco de dados

  • A rota deverá ser do tipo POST e retornar a partida inserida no banco de dados;

  • Será validado que é possível salvar um jogo no banco de dados e ver o jogo na página de jogos;

  • A partida só pode ser criada com token JWT validado;

  • O corpo da requisição terá o seguinte formato:

{
  "homeTeam": 16, // O valor deve ser o id do time
  "awayTeam": 8, // O valor deve ser o id do time
  "homeTeamGoals": 2,
  "awayTeamGoals": 2
}
  • Caso a partida seja inserida com sucesso, deve-se retornar os dados da partida, com status 201:
{
  "id": 1,
  "homeTeam": 16,
  "homeTeamGoals": 2,
  "awayTeam": 8,
  "awayTeamGoals": 2,
  "inProgress": true,
}

👣Requisito 24 - Desenvolva o endpoint /matches/:id/finish de modo que seja possível alterar o status inProgress de uma partida para false no banco de dados

  • A rota deve ser do tipo PATCH;

  • Será recebido o id pelo parâmetro da URL;

  • Será validado que, ao finalizar uma partida, a alteração é feita no banco de dados e na página.

  • Deve-se retornar, com um status 200, a seguinte mensagem:

{ "message": "Finished" }

👣Requisito 25 - Desenvolva o endpoint /matches de forma que não seja possível inserir uma partida com times iguais

  • Será validado que não é possível inserir uma partida com times iguais;

  • Não deve ser possível criar uma partida com o mesmo time, por exemplo: Barcelona x Barcelona. Caso isso ocorra, deve-se retornar, com um status 401, a seguinte mensagem::

{ "message": "It is not possible to create a match with two equal teams" }

👣Requisito 26 - Desenvolva o endpoint /matches de forma que não seja possível inserir uma partida com um time que não existe na tabela teams

  • Será validado que não é possível inserir uma partida com um time que não existe na tabela teams;

  • Caso algum dos times não esteja cadastrado no banco de dados, deve-se retornar, com um status 404, a seguinte mensagem:

{ "message": "There is no team with such id!" }

👣Requisito 27 - Desenvolva o endpoint /matches de forma que não seja possível inserir uma partida sem um token válido

  • Será validado que não é possível inserir uma partida com um token inválido;

  • Caso o token informado não seja válido, deve-se retornar, com um status 401, a seguinte mensagem:

{ "message": "Token must be a valid token" }

👣Requisito 28 - Desenvolva o endpoint /matches/:id de forma que seja possível atualizar partidas em andamento

  • O endpoint deve ser do tipo PATCH;

  • Será recebido o id pelo parâmetro da URL;

  • Será avaliado que é possível alterar o resultado de uma partida.

  • O corpo da requisição terá o seguinte formato:

{
  "homeTeamGoals": 3,
  "awayTeamGoals": 1
}
  • Será avaliado que é o endpoint responde à requisição com um status 200 e qualquer corpo.

Seção 4: Leaderboards (placares)

Introdução

▶️ Para construir a classificação dos times, devem ser seguidas as seguintes regras de negócios:

- `Classificação`: Posição na classificação;
- `Time`: Nome do time;
- `P`: Total de Pontos;
- `J`: Total de Jogos;
- `V`: Total de Vitórias;
- `E`: Total de Empates;
- `D`: Total de Derrotas;
- `GP`: Gols marcados a favor;
- `GC`: Gols sofridos;
- `SG`: Saldo total de gols;
- `%`: Aproveitamento do time.

<br/>
  • Todas as regras de negócio e cálculos necessários deverão ser realizados no seu back-end. A aplicação front-end apenas renderizará essas informações.

  • Para calcular o Total de Pontos, você deve levar em consideração que:

    • O time vitorioso: marcará +3 pontos;
    • O time perdedor: marcará 0 pontos;
    • Em caso de empate: ambos os times marcam +1 ponto.
  • Para o campo Aproveitamento do time (%), que é a porcentagem de jogos ganhos, use a seguinte fórmula: P/(J*3)*100, onde:

    • P: Total de Pontos;
    • J: Total de Jogos.

    Obs.: O seu resultado deverá ser limitado a duas casas decimais.

  • Para calcular Saldo de Gols use a seguinte fórmula: GP - GC, onde:

    • GP: Gols marcados a favor;
    • GC: Gols sofridos.
  • O resultado deverá ser ordenado sempre de forma decrescente, levando em consideração a quantidade de pontos que o time acumulou. Em caso de empate no Total de Pontos, você deve levar em consideração os seguintes critérios para desempate:

Ordem para desempate

1º Total de Vitórias; 2º Saldo de gols; 3º Gols a favor; 4º Gols sofridos.

⚠️ Atenção: ⚠️

  • Por padrão, as respostas de todos os seus endpoints deverão estar em inglês, mesmo que a renderização no front-end seja em português.
  • A sua tabela deverá renderizar somente as PARTIDAS que já foram FINALIZADAS! Os seguintes pontos serão avaliados:
- Se a lista de classificação está correta;
- Se a regra de classificação se mantém mesmo com mudanças na classificação;
- Se a tabela de classificação tem 10 colunas;
- Se a tabela tem uma linha para cada time.

Exemplo de retorno esperado:

[
  {
    "name": "Palmeiras",
    "totalPoints": 13,
    "totalGames": 5,
    "totalVictories": 4,
    "totalDraws": 1,
    "totalLosses": 0,
    "goalsFavor": 17,
    "goalsOwn": 5,
    "goalsBalance": 12,
    "efficiency": 86.67
  },
  {
    "name": "Corinthians",
    "totalPoints": 12,
    "totalGames": 5,
    "totalVictories": 4,
    "totalDraws": 0,
    "totalLosses": 1,
    "goalsFavor": 12,
    "goalsOwn": 3,
    "goalsBalance": 9,
    "efficiency": 80
  },
  {
    "name": "Santos",
    "totalPoints": 11,
    "totalGames": 5,
    "totalVictories": 3,
    "totalDraws": 2,
    "totalLosses": 0,
    "goalsFavor": 12,
    "goalsOwn": 6,
    "goalsBalance": 6,
    "efficiency": 73.33
  },
  ...
]
  • Os endpoints dessa seção, irão alimentar uma tabela idêntica ao exemplo abaixo no front-end:

    Classificação Time P J V E D GP GC SG %
    1 Ferroviária 38 15 12 2 1 44 13 31 84.4
Requisitos

Leaderboard Home

👣Requisito 29 - Desenvolva o endpoint /leaderboard/home de forma que seja possível filtrar as classificações dos times da casa na tela de classificação do front-end com os dados iniciais do banco de dados

  • O endpoint deverá ser do tipo GET;

  • Será avaliado que ao fazer a requisição ao endpoint /leaderboard/home serão retornados os campos e valores corretos, considerando os dados iniciais do banco de dados;

  • Partidas que estiverem em andamento (não foram finalizadas) não devem ser consideradas.

Retorno esperado:
[
  {
    "name": "Santos",
    "totalPoints": 9,
    "totalGames": 3,
    "totalVictories": 3,
    "totalDraws": 0,
    "totalLosses": 0,
    "goalsFavor": 9,
    "goalsOwn": 3,
    "goalsBalance": 6,
    "efficiency": "100.00"
  },
  {
    "name": "Palmeiras",
    "totalPoints": 7,
    "totalGames": 3,
    "totalVictories": 2,
    "totalDraws": 1,
    "totalLosses": 0,
    "goalsFavor": 10,
    "goalsOwn": 5,
    "goalsBalance": 5,
    "efficiency": "77.78"
  },
  {
    "name": "Corinthians",
    "totalPoints": 6,
    "totalGames": 2,
    "totalVictories": 2,
    "totalDraws": 0,
    "totalLosses": 0,
    "goalsFavor": 6,
    "goalsOwn": 1,
    "goalsBalance": 5,
    "efficiency": "100.00"
  },
  {
    "name": "Grêmio",
    "totalPoints": 6,
    "totalGames": 2,
    "totalVictories": 2,
    "totalDraws": 0,
    "totalLosses": 0,
    "goalsFavor": 4,
    "goalsOwn": 1,
    "goalsBalance": 3,
    "efficiency": "100.00"
  },
  {
    "name": "Real Brasília",
    "totalPoints": 6,
    "totalGames": 2,
    "totalVictories": 2,
    "totalDraws": 0,
    "totalLosses": 0,
    "goalsFavor": 2,
    "goalsOwn": 0,
    "goalsBalance": 2,
    "efficiency": "100.00"
  },
  {
    "name": "São Paulo",
    "totalPoints": 4,
    "totalGames": 2,
    "totalVictories": 1,
    "totalDraws": 1,
    "totalLosses": 0,
    "goalsFavor": 4,
    "goalsOwn": 1,
    "goalsBalance": 3,
    "efficiency": "66.67"
  },
  {
    "name": "Internacional",
    "totalPoints": 4,
    "totalGames": 3,
    "totalVictories": 1,
    "totalDraws": 1,
    "totalLosses": 1,
    "goalsFavor": 4,
    "goalsOwn": 6,
    "goalsBalance": -2,
    "efficiency": "44.44"
  },
  {
    "name": "Botafogo",
    "totalPoints": 4,
    "totalGames": 3,
    "totalVictories": 1,
    "totalDraws": 1,
    "totalLosses": 1,
    "goalsFavor": 2,
    "goalsOwn": 4,
    "goalsBalance": -2,
    "efficiency": "44.44"
  },
  {
    "name": "Ferroviária",
    "totalPoints": 3,
    "totalGames": 2,
    "totalVictories": 1,
    "totalDraws": 0,
    "totalLosses": 1,
    "goalsFavor": 3,
    "goalsOwn": 2,
    "goalsBalance": 1,
    "efficiency": "50.00"
  },
  {
    "name": "Napoli-SC",
    "totalPoints": 2,
    "totalGames": 2,
    "totalVictories": 0,
    "totalDraws": 2,
    "totalLosses": 0,
    "goalsFavor": 2,
    "goalsOwn": 2,
    "goalsBalance": 0,
    "efficiency": "33.33"
  },
  {
    "name": "Cruzeiro",
    "totalPoints": 1,
    "totalGames": 2,
    "totalVictories": 0,
    "totalDraws": 1,
    "totalLosses": 1,
    "goalsFavor": 2,
    "goalsOwn": 3,
    "goalsBalance": -1,
    "efficiency": "16.67"
  },
  {
    "name": "Flamengo",
    "totalPoints": 1,
    "totalGames": 2,
    "totalVictories": 0,
    "totalDraws": 1,
    "totalLosses": 1,
    "goalsFavor": 1,
    "goalsOwn": 2,
    "goalsBalance": -1,
    "efficiency": "16.67"
  },
  {
    "name": "Minas Brasília",
    "totalPoints": 1,
    "totalGames": 3,
    "totalVictories": 0,
    "totalDraws": 1,
    "totalLosses": 2,
    "goalsFavor": 3,
    "goalsOwn": 6,
    "goalsBalance": -3,
    "efficiency": "11.11"
  },
  {
    "name": "Avaí/Kindermann",
    "totalPoints": 1,
    "totalGames": 3,
    "totalVictories": 0,
    "totalDraws": 1,
    "totalLosses": 2,
    "goalsFavor": 3,
    "goalsOwn": 7,
    "goalsBalance": -4,
    "efficiency": "11.11"
  },
  {
    "name": "São José-SP",
    "totalPoints": 0,
    "totalGames": 3,
    "totalVictories": 0,
    "totalDraws": 0,
    "totalLosses": 3,
    "goalsFavor": 2,
    "goalsOwn": 5,
    "goalsBalance": -3,
    "efficiency": "0.00"
  },
  {
    "name": "Bahia",
    "totalPoints": 0,
    "totalGames": 3,
    "totalVictories": 0,
    "totalDraws": 0,
    "totalLosses": 3,
    "goalsFavor": 0,
    "goalsOwn": 4,
    "goalsBalance": -4,
    "efficiency": "0.00"
  }
]

👣Requisito 30 - Desenvolva o endpoint /leaderboard/home de forma que seja possível filtrar as classificações dos times da casa na tela de classificação do front-end, e atualizar a tabela ao inserir a partida Corinthians 2 X 1 Internacional

  • Será avaliado que após acrescentar a partida Corinthians 2 X 1 Internacional e fazer a requisição ao endpoint /leaderboard/home, serão retornados os campos e valores corretos.
Retorno esperado:
[
  {
    "name": "Santos",
    "totalPoints": 9,
    "totalGames": 3,
    "totalVictories": 3,
    "totalDraws": 0,
    "totalLosses": 0,
    "goalsFavor": 9,
    "goalsOwn": 3,
    "goalsBalance": 6,
    "efficiency": "100.00"
  },
  {
    "name": "Corinthians",
    "totalPoints": 9,
    "totalGames": 3,
    "totalVictories": 3,
    "totalDraws": 0,
    "totalLosses": 0,
    "goalsFavor": 8,
    "goalsOwn": 2,
    "goalsBalance": 6,
    "efficiency": "100.00"
  },
  {
    "name": "Palmeiras",
    "totalPoints": 7,
    "totalGames": 3,
    "totalVictories": 2,
    "totalDraws": 1,
    "totalLosses": 0,
    "goalsFavor": 10,
    "goalsOwn": 5,
    "goalsBalance": 5,
    "efficiency": "77.78"
  },
  {
    "name": "Grêmio",
    "totalPoints": 6,
    "totalGames": 2,
    "totalVictories": 2,
    "totalDraws": 0,
    "totalLosses": 0,
    "goalsFavor": 4,
    "goalsOwn": 1,
    "goalsBalance": 3,
    "efficiency": "100.00"
  },
  {
    "name": "Real Brasília",
    "totalPoints": 6,
    "totalGames": 2,
    "totalVictories": 2,
    "totalDraws": 0,
    "totalLosses": 0,
    "goalsFavor": 2,
    "goalsOwn": 0,
    "goalsBalance": 2,
    "efficiency": "100.00"
  },
  {
    "name": "São Paulo",
    "totalPoints": 4,
    "totalGames": 2,
    "totalVictories": 1,
    "totalDraws": 1,
    "totalLosses": 0,
    "goalsFavor": 4,
    "goalsOwn": 1,
    "goalsBalance": 3,
    "efficiency": "66.67"
  },
  {
    "name": "Internacional",
    "totalPoints": 4,
    "totalGames": 3,
    "totalVictories": 1,
    "totalDraws": 1,
    "totalLosses": 1,
    "goalsFavor": 4,
    "goalsOwn": 6,
    "goalsBalance": -2,
    "efficiency": "44.44"
  },
  {
    "name": "Botafogo",
    "totalPoints": 4,
    "totalGames": 3,
    "totalVictories": 1,
    "totalDraws": 1,
    "totalLosses": 1,
    "goalsFavor": 2,
    "goalsOwn": 4,
    "goalsBalance": -2,
    "efficiency": "44.44"
  },
  {
    "name": "Ferroviária",
    "totalPoints": 3,
    "totalGames": 2,
    "totalVictories": 1,
    "totalDraws": 0,
    "totalLosses": 1,
    "goalsFavor": 3,
    "goalsOwn": 2,
    "goalsBalance": 1,
    "efficiency": "50.00"
  },
  {
    "name": "Napoli-SC",
    "totalPoints": 2,
    "totalGames": 2,
    "totalVictories": 0,
    "totalDraws": 2,
    "totalLosses": 0,
    "goalsFavor": 2,
    "goalsOwn": 2,
    "goalsBalance": 0,
    "efficiency": "33.33"
  },
  {
    "name": "Cruzeiro",
    "totalPoints": 1,
    "totalGames": 2,
    "totalVictories": 0,
    "totalDraws": 1,
    "totalLosses": 1,
    "goalsFavor": 2,
    "goalsOwn": 3,
    "goalsBalance": -1,
    "efficiency": "16.67"
  },
  {
    "name": "Flamengo",
    "totalPoints": 1,
    "totalGames": 2,
    "totalVictories": 0,
    "totalDraws": 1,
    "totalLosses": 1,
    "goalsFavor": 1,
    "goalsOwn": 2,
    "goalsBalance": -1,
    "efficiency": "16.67"
  },
  {
    "name": "Minas Brasília",
    "totalPoints": 1,
    "totalGames": 3,
    "totalVictories": 0,
    "totalDraws": 1,
    "totalLosses": 2,
    "goalsFavor": 3,
    "goalsOwn": 6,
    "goalsBalance": -3,
    "efficiency": "11.11"
  },
  {
    "name": "Avaí/Kindermann",
    "totalPoints": 1,
    "totalGames": 3,
    "totalVictories": 0,
    "totalDraws": 1,
    "totalLosses": 2,
    "goalsFavor": 3,
    "goalsOwn": 7,
    "goalsBalance": -4,
    "efficiency": "11.11"
  },
  {
    "name": "São José-SP",
    "totalPoints": 0,
    "totalGames": 3,
    "totalVictories": 0,
    "totalDraws": 0,
    "totalLosses": 3,
    "goalsFavor": 2,
    "goalsOwn": 5,
    "goalsBalance": -3,
    "efficiency": "0.00"
  },
  {
    "name": "Bahia",
    "totalPoints": 0,
    "totalGames": 3,
    "totalVictories": 0,
    "totalDraws": 0,
    "totalLosses": 3,
    "goalsFavor": 0,
    "goalsOwn": 4,
    "goalsBalance": -4,
    "efficiency": "0.00"
  }
]

About

Projeto proposto e desenvolvido no curso de desenvolvimento web da Trybe


Languages

Language:JavaScript 88.9%Language:CSS 7.3%Language:TypeScript 1.9%Language:Shell 1.0%Language:HTML 0.9%Language:Dockerfile 0.1%