👨💻 O que deverá ser desenvolvido
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, você vai construir um back-end dockerizado utilizando modelagem de dados através do Sequelize. Seu desenvolvimento deve respeitar regras de negócio providas no projeto e sua API deve ser 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 deverá implementar regras de negócio para popular adequadamente a tabela disponível no front-end que será exibida para a pessoa usuária do sistema.
Estrutura do projeto
O projeto é composto de 4 entidades importantes para sua estrutura:
1️⃣ 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 porta3002
dolocalhost
; - 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
.
2️⃣ 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 emapp/backend/packages.npm
.
3️⃣ 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 sitehttp://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.
4️⃣ 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 comandonpm run compose:up
ounpm run compose:up:dev
; - Você deve configurar as
Dockerfiles
corretamente nas raízes dofront-end
eback-end
, para conseguir inicializar a aplicação;
- Clone o repositório
Usar link SSH
-
Entre na pasta do repositório que você acabou de clonar:
cd pasta-do-repositório
- Instale as dependências [Caso existam]
*
npm install
⚠️ Configurações mínimas para execução do projeto
Na sua máquina você deve ter:
- Sistema Operacional Distribuição Unix
- Node versão 16
- Docker
- Docker-compose versão >=1.29.2
➡️ O node
deve ter versão igual ou superior à 16.14.0 LTS
:
- Para instalar o nvm, acesse esse link;
- Rode os comandos abaixo para instalar a versão correta de
node
e usá-la:nvm install 16.14 --lts
nvm use 16.14
nvm alias default 16.14
Esse projeto é composto de 4 seções principais:
- Users e Login
- Times
- Partidas
- Placar
Introdução
-
A rota utilizada deve ser (
/login
); -
A rota deve receber os campos
email
epassword
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 campo
-
O body da requisição deve conter o seguinte formato:
{ "email": "string", "password": "string" }
Requisitos
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;
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 metodologiaTDD
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.
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. }
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étodoTDD
, agora considerando o contrato do próximo 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" }
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étodoTDD
, agora considerando o contrato do próximo 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" }
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étodoTDD
, agora considerando o contrato do próximo 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" }
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étodoTDD
, agora considerando os contratos dos próximos dois requisitos.
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" }
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 umheader
com parâmetroauthorization
, 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" }
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
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étodoTDD
, considerando os contratos dos próximos dois requisitos. Nessa seção temos o diagrama de entidades.
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.
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 status200
e com umjson
contendo o retorno no seguinte modelo:
[
{
"id": 1,
"teamName": "Avaí/Kindermann"
},
{
"id": 2,
"teamName": "Bahia"
},
{
"id": 3,
"teamName": "Botafogo"
},
...
]
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 status200
e com umjson
contendo o retorno no seguinte modelo:
{
"id": 5,
"teamName": "Cruzeiro"
}
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étodoTDD
, agora considerando os contratos dos próximos três requisitos.
Introdução
- Para os requisitos de criação de partidas, será necessário implementar o model e algumas rotas relacionadas a entidade Match.
Requisitos
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.
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, "homeTeamId": 16, "homeTeamGoals": 1, "awayTeamId": 8, "awayTeamGoals": 1, "inProgress": false, "homeTeam": { "teamName": "São Paulo" }, "awayTeam": { "teamName": "Grêmio" } }, ... { "id": 41, "homeTeamId": 16, "homeTeamGoals": 2, "awayTeamId": 9, "awayTeamGoals": 0, "inProgress": true, "homeTeam": { "teamName": "São Paulo" }, "awayTeam": { "teamName": "Internacional" } } ]
-
OBS: Você deverá definir os relacionamentos para
homeTeam
eawayTeam
somente na model de partidas.
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,
"homeTeamId": 16,
"homeTeamGoals": 2,
"awayTeamId": 9,
"awayTeamGoals": 0,
"inProgress": true,
"homeTeam": {
"teamName": "São Paulo"
},
"awayTeam": {
"teamName": "Internacional"
}
},
{
"id": 42,
"homeTeamId": 6,
"homeTeamGoals": 1,
"awayTeamId": 1,
"awayTeamGoals": 0,
"inProgress": true,
"homeTeam": {
"teamName": "Ferroviária"
},
"awayTeam": {
"teamName": "Avaí/Kindermann"
}
}
]
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,
"homeTeamId": 16,
"homeTeamGoals": 1,
"awayTeamId": 8,
"awayTeamGoals": 1,
"inProgress": false,
"homeTeam": {
"teamName": "São Paulo"
},
"awayTeam": {
"teamName": "Grêmio"
}
},
{
"id": 2,
"homeTeamId": 9,
"homeTeamGoals": 1,
"awayTeamId": 14,
"awayTeamGoals": 1,
"inProgress": false,
"homeTeam": {
"teamName": "Internacional"
},
"awayTeam": {
"teamName": "Santos"
}
}
]
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étodoTDD
, agora considerando o contrato dos próximos requisitos.
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:
{
"homeTeamId": 16, // O valor deve ser o id do time
"awayTeamId": 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,
"homeTeamId": 16,
"homeTeamGoals": 2,
"awayTeamId": 8,
"awayTeamGoals": 2,
"inProgress": true,
}
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" }
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 em que o
homeTeam
e oawayTeam
sejam iguais, por exemplo: Barcelona x Barcelona; -
Caso isso ocorra, deve-se retornar, com um status
422
, a seguinte mensagem::
{ "message": "It is not possible to create a match with two equal teams" }
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!" }
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" }
-
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.
Introdução
- `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.
- O time
-
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.
- 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
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"
}
]
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"
}
]
31 - Desenvolva o endpoint /leaderboard/away
, de forma que seja possível filtrar as classificações dos times quando visitantes 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/away
, 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": "Palmeiras",
"totalPoints": 6,
"totalGames": 2,
"totalVictories": 2,
"totalDraws": 0,
"totalLosses": 0,
"goalsFavor": 7,
"goalsOwn": 0,
"goalsBalance": 7,
"efficiency": "100.00"
},
{
"name": "Corinthians",
"totalPoints": 6,
"totalGames": 3,
"totalVictories": 2,
"totalDraws": 0,
"totalLosses": 1,
"goalsFavor": 6,
"goalsOwn": 2,
"goalsBalance": 4,
"efficiency": "66.67"
},
{
"name": "Internacional",
"totalPoints": 6,
"totalGames": 2,
"totalVictories": 2,
"totalDraws": 0,
"totalLosses": 0,
"goalsFavor": 3,
"goalsOwn": 0,
"goalsBalance": 3,
"efficiency": "100.00"
},
{
"name": "São José-SP",
"totalPoints": 6,
"totalGames": 2,
"totalVictories": 2,
"totalDraws": 0,
"totalLosses": 0,
"goalsFavor": 3,
"goalsOwn": 1,
"goalsBalance": 2,
"efficiency": "100.00"
},
{
"name": "São Paulo",
"totalPoints": 4,
"totalGames": 3,
"totalVictories": 1,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 5,
"goalsOwn": 5,
"goalsBalance": 0,
"efficiency": "44.44"
},
{
"name": "Ferroviária",
"totalPoints": 4,
"totalGames": 3,
"totalVictories": 1,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 4,
"goalsOwn": 5,
"goalsBalance": -1,
"efficiency": "44.44"
},
{
"name": "Real Brasília",
"totalPoints": 4,
"totalGames": 3,
"totalVictories": 1,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 3,
"goalsOwn": 4,
"goalsBalance": -1,
"efficiency": "44.44"
},
{
"name": "Grêmio",
"totalPoints": 4,
"totalGames": 3,
"totalVictories": 1,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 5,
"goalsOwn": 7,
"goalsBalance": -2,
"efficiency": "44.44"
},
{
"name": "Flamengo",
"totalPoints": 4,
"totalGames": 3,
"totalVictories": 1,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 1,
"goalsOwn": 3,
"goalsBalance": -2,
"efficiency": "44.44"
},
{
"name": "Avaí/Kindermann",
"totalPoints": 3,
"totalGames": 2,
"totalVictories": 1,
"totalDraws": 0,
"totalLosses": 1,
"goalsFavor": 1,
"goalsOwn": 1,
"goalsBalance": 0,
"efficiency": "50.00"
},
{
"name": "Cruzeiro",
"totalPoints": 3,
"totalGames": 3,
"totalVictories": 1,
"totalDraws": 0,
"totalLosses": 2,
"goalsFavor": 6,
"goalsOwn": 7,
"goalsBalance": -1,
"efficiency": "33.33"
},
{
"name": "Santos",
"totalPoints": 2,
"totalGames": 2,
"totalVictories": 0,
"totalDraws": 2,
"totalLosses": 0,
"goalsFavor": 3,
"goalsOwn": 3,
"goalsBalance": 0,
"efficiency": "33.33"
},
{
"name": "Bahia",
"totalPoints": 2,
"totalGames": 2,
"totalVictories": 0,
"totalDraws": 2,
"totalLosses": 0,
"goalsFavor": 2,
"goalsOwn": 2,
"goalsBalance": 0,
"efficiency": "33.33"
},
{
"name": "Minas Brasília",
"totalPoints": 1,
"totalGames": 2,
"totalVictories": 0,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 1,
"goalsOwn": 3,
"goalsBalance": -2,
"efficiency": "16.67"
},
{
"name": "Botafogo",
"totalPoints": 0,
"totalGames": 2,
"totalVictories": 0,
"totalDraws": 0,
"totalLosses": 2,
"goalsFavor": 1,
"goalsOwn": 4,
"goalsBalance": -3,
"efficiency": "0.00"
},
{
"name": "Napoli-SC",
"totalPoints": 0,
"totalGames": 3,
"totalVictories": 0,
"totalDraws": 0,
"totalLosses": 3,
"goalsFavor": 1,
"goalsOwn": 10,
"goalsBalance": -9,
"efficiency": "0.00"
}
]
32 - Desenvolva o endpoint /leaderboard/away
de forma que seja possível filtrar as classificações dos times quando visitantes 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/away
, serão retornados os campos e valores corretos.
Retorno esperado:
[
{
"name": "Palmeiras",
"totalPoints": 6,
"totalGames": 2,
"totalVictories": 2,
"totalDraws": 0,
"totalLosses": 0,
"goalsFavor": 7,
"goalsOwn": 0,
"goalsBalance": 7,
"efficiency": "100.00"
},
{
"name": "Corinthians",
"totalPoints": 6,
"totalGames": 3,
"totalVictories": 2,
"totalDraws": 0,
"totalLosses": 1,
"goalsFavor": 6,
"goalsOwn": 2,
"goalsBalance": 4,
"efficiency": "66.67"
},
{
"name": "Internacional",
"totalPoints": 6,
"totalGames": 3,
"totalVictories": 2,
"totalDraws": 0,
"totalLosses": 1,
"goalsFavor": 4,
"goalsOwn": 2,
"goalsBalance": 2,
"efficiency": "66.67"
},
{
"name": "São José-SP",
"totalPoints": 6,
"totalGames": 2,
"totalVictories": 2,
"totalDraws": 0,
"totalLosses": 0,
"goalsFavor": 3,
"goalsOwn": 1,
"goalsBalance": 2,
"efficiency": "100.00"
},
{
"name": "São Paulo",
"totalPoints": 4,
"totalGames": 3,
"totalVictories": 1,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 5,
"goalsOwn": 5,
"goalsBalance": 0,
"efficiency": "44.44"
},
{
"name": "Ferroviária",
"totalPoints": 4,
"totalGames": 3,
"totalVictories": 1,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 4,
"goalsOwn": 5,
"goalsBalance": -1,
"efficiency": "44.44"
},
{
"name": "Real Brasília",
"totalPoints": 4,
"totalGames": 3,
"totalVictories": 1,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 3,
"goalsOwn": 4,
"goalsBalance": -1,
"efficiency": "44.44"
},
{
"name": "Grêmio",
"totalPoints": 4,
"totalGames": 3,
"totalVictories": 1,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 5,
"goalsOwn": 7,
"goalsBalance": -2,
"efficiency": "44.44"
},
{
"name": "Flamengo",
"totalPoints": 4,
"totalGames": 3,
"totalVictories": 1,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 1,
"goalsOwn": 3,
"goalsBalance": -2,
"efficiency": "44.44"
},
{
"name": "Avaí/Kindermann",
"totalPoints": 3,
"totalGames": 2,
"totalVictories": 1,
"totalDraws": 0,
"totalLosses": 1,
"goalsFavor": 1,
"goalsOwn": 1,
"goalsBalance": 0,
"efficiency": "50.00"
},
{
"name": "Cruzeiro",
"totalPoints": 3,
"totalGames": 3,
"totalVictories": 1,
"totalDraws": 0,
"totalLosses": 2,
"goalsFavor": 6,
"goalsOwn": 7,
"goalsBalance": -1,
"efficiency": "33.33"
},
{
"name": "Santos",
"totalPoints": 2,
"totalGames": 2,
"totalVictories": 0,
"totalDraws": 2,
"totalLosses": 0,
"goalsFavor": 3,
"goalsOwn": 3,
"goalsBalance": 0,
"efficiency": "33.33"
},
{
"name": "Bahia",
"totalPoints": 2,
"totalGames": 2,
"totalVictories": 0,
"totalDraws": 2,
"totalLosses": 0,
"goalsFavor": 2,
"goalsOwn": 2,
"goalsBalance": 0,
"efficiency": "33.33"
},
{
"name": "Minas Brasília",
"totalPoints": 1,
"totalGames": 2,
"totalVictories": 0,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 1,
"goalsOwn": 3,
"goalsBalance": -2,
"efficiency": "16.67"
},
{
"name": "Botafogo",
"totalPoints": 0,
"totalGames": 2,
"totalVictories": 0,
"totalDraws": 0,
"totalLosses": 2,
"goalsFavor": 1,
"goalsOwn": 4,
"goalsBalance": -3,
"efficiency": "0.00"
},
{
"name": "Napoli-SC",
"totalPoints": 0,
"totalGames": 3,
"totalVictories": 0,
"totalDraws": 0,
"totalLosses": 3,
"goalsFavor": 1,
"goalsOwn": 10,
"goalsBalance": -9,
"efficiency": "0.00"
}
]
33 - Desenvolva o endpoint /leaderboard
de forma que seja possível filtrar a classificação geral dos times 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
, 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": "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.00"
},
{
"name": "Santos",
"totalPoints": 11,
"totalGames": 5,
"totalVictories": 3,
"totalDraws": 2,
"totalLosses": 0,
"goalsFavor": 12,
"goalsOwn": 6,
"goalsBalance": 6,
"efficiency": "73.33"
},
{
"name": "Grêmio",
"totalPoints": 10,
"totalGames": 5,
"totalVictories": 3,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 9,
"goalsOwn": 8,
"goalsBalance": 1,
"efficiency": "66.67"
},
{
"name": "Internacional",
"totalPoints": 10,
"totalGames": 5,
"totalVictories": 3,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 7,
"goalsOwn": 6,
"goalsBalance": 1,
"efficiency": "66.67"
},
{
"name": "Real Brasília",
"totalPoints": 10,
"totalGames": 5,
"totalVictories": 3,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 5,
"goalsOwn": 4,
"goalsBalance": 1,
"efficiency": "66.67"
},
{
"name": "São Paulo",
"totalPoints": 8,
"totalGames": 5,
"totalVictories": 2,
"totalDraws": 2,
"totalLosses": 1,
"goalsFavor": 9,
"goalsOwn": 6,
"goalsBalance": 3,
"efficiency": "53.33"
},
{
"name": "Ferroviária",
"totalPoints": 7,
"totalGames": 5,
"totalVictories": 2,
"totalDraws": 1,
"totalLosses": 2,
"goalsFavor": 7,
"goalsOwn": 7,
"goalsBalance": 0,
"efficiency": "46.67"
},
{
"name": "São José-SP",
"totalPoints": 6,
"totalGames": 5,
"totalVictories": 2,
"totalDraws": 0,
"totalLosses": 3,
"goalsFavor": 5,
"goalsOwn": 6,
"goalsBalance": -1,
"efficiency": "40.00"
},
{
"name": "Flamengo",
"totalPoints": 5,
"totalGames": 5,
"totalVictories": 1,
"totalDraws": 2,
"totalLosses": 2,
"goalsFavor": 2,
"goalsOwn": 5,
"goalsBalance": -3,
"efficiency": "33.33"
},
{
"name": "Cruzeiro",
"totalPoints": 4,
"totalGames": 5,
"totalVictories": 1,
"totalDraws": 1,
"totalLosses": 3,
"goalsFavor": 8,
"goalsOwn": 10,
"goalsBalance": -2,
"efficiency": "26.67"
},
{
"name": "Avaí/Kindermann",
"totalPoints": 4,
"totalGames": 5,
"totalVictories": 1,
"totalDraws": 1,
"totalLosses": 3,
"goalsFavor": 4,
"goalsOwn": 8,
"goalsBalance": -4,
"efficiency": "26.67"
},
{
"name": "Botafogo",
"totalPoints": 4,
"totalGames": 5,
"totalVictories": 1,
"totalDraws": 1,
"totalLosses": 3,
"goalsFavor": 3,
"goalsOwn": 8,
"goalsBalance": -5,
"efficiency": "26.67"
},
{
"name": "Bahia",
"totalPoints": 2,
"totalGames": 5,
"totalVictories": 0,
"totalDraws": 2,
"totalLosses": 3,
"goalsFavor": 2,
"goalsOwn": 6,
"goalsBalance": -4,
"efficiency": "13.33"
},
{
"name": "Minas Brasília",
"totalPoints": 2,
"totalGames": 5,
"totalVictories": 0,
"totalDraws": 2,
"totalLosses": 3,
"goalsFavor": 4,
"goalsOwn": 9,
"goalsBalance": -5,
"efficiency": "13.33"
},
{
"name": "Napoli-SC",
"totalPoints": 2,
"totalGames": 5,
"totalVictories": 0,
"totalDraws": 2,
"totalLosses": 3,
"goalsFavor": 3,
"goalsOwn": 12,
"goalsBalance": -9,
"efficiency": "13.33"
}
]
34 - Desenvolva o endpoint /leaderboard de forma que seja possível filtrar a classificação geral dos times na tela de classificação do front-end e atualizar a tabela ao inserir a partida Flamengo 3 X 0 Napoli-SC
- Será avaliado que após acrescentar a partida Flamengo 3 X 0 Napoli-SC e fazer a requisição ao endpoint /leaderboard, serão retornados os campos e valores corretos.
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.00"
},
{
"name": "Santos",
"totalPoints": 11,
"totalGames": 5,
"totalVictories": 3,
"totalDraws": 2,
"totalLosses": 0,
"goalsFavor": 12,
"goalsOwn": 6,
"goalsBalance": 6,
"efficiency": "73.33"
},
{
"name": "Grêmio",
"totalPoints": 10,
"totalGames": 5,
"totalVictories": 3,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 9,
"goalsOwn": 8,
"goalsBalance": 1,
"efficiency": "66.67"
},
{
"name": "Internacional",
"totalPoints": 10,
"totalGames": 5,
"totalVictories": 3,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 7,
"goalsOwn": 6,
"goalsBalance": 1,
"efficiency": "66.67"
},
{
"name": "Real Brasília",
"totalPoints": 10,
"totalGames": 5,
"totalVictories": 3,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 5,
"goalsOwn": 4,
"goalsBalance": 1,
"efficiency": "66.67"
},
{
"name": "São Paulo",
"totalPoints": 8,
"totalGames": 5,
"totalVictories": 2,
"totalDraws": 2,
"totalLosses": 1,
"goalsFavor": 9,
"goalsOwn": 6,
"goalsBalance": 3,
"efficiency": "53.33"
},
{
"name": "Flamengo",
"totalPoints": 8,
"totalGames": 6,
"totalVictories": 2,
"totalDraws": 2,
"totalLosses": 2,
"goalsFavor": 5,
"goalsOwn": 5,
"goalsBalance": 0,
"efficiency": "44.44"
},
{
"name": "Ferroviária",
"totalPoints": 7,
"totalGames": 5,
"totalVictories": 2,
"totalDraws": 1,
"totalLosses": 2,
"goalsFavor": 7,
"goalsOwn": 7,
"goalsBalance": 0,
"efficiency": "46.67"
},
{
"name": "São José-SP",
"totalPoints": 6,
"totalGames": 5,
"totalVictories": 2,
"totalDraws": 0,
"totalLosses": 3,
"goalsFavor": 5,
"goalsOwn": 6,
"goalsBalance": -1,
"efficiency": "40.00"
},
{
"name": "Cruzeiro",
"totalPoints": 4,
"totalGames": 5,
"totalVictories": 1,
"totalDraws": 1,
"totalLosses": 3,
"goalsFavor": 8,
"goalsOwn": 10,
"goalsBalance": -2,
"efficiency": "26.67"
},
{
"name": "Avaí/Kindermann",
"totalPoints": 4,
"totalGames": 5,
"totalVictories": 1,
"totalDraws": 1,
"totalLosses": 3,
"goalsFavor": 4,
"goalsOwn": 8,
"goalsBalance": -4,
"efficiency": "26.67"
},
{
"name": "Botafogo",
"totalPoints": 4,
"totalGames": 5,
"totalVictories": 1,
"totalDraws": 1,
"totalLosses": 3,
"goalsFavor": 3,
"goalsOwn": 8,
"goalsBalance": -5,
"efficiency": "26.67"
},
{
"name": "Bahia",
"totalPoints": 2,
"totalGames": 5,
"totalVictories": 0,
"totalDraws": 2,
"totalLosses": 3,
"goalsFavor": 2,
"goalsOwn": 6,
"goalsBalance": -4,
"efficiency": "13.33"
},
{
"name": "Minas Brasília",
"totalPoints": 2,
"totalGames": 5,
"totalVictories": 0,
"totalDraws": 2,
"totalLosses": 3,
"goalsFavor": 4,
"goalsOwn": 9,
"goalsBalance": -5,
"efficiency": "13.33"
},
{
"name": "Napoli-SC",
"totalPoints": 2,
"totalGames": 6,
"totalVictories": 0,
"totalDraws": 2,
"totalLosses": 4,
"goalsFavor": 3,
"goalsOwn": 15,
"goalsBalance": -12,
"efficiency": "11.11"
}
]
35 - Desenvolva o endpoint /leaderboard de forma que seja possível filtrar a classificação geral dos times na tela de classificação do front-end e atualizar a tabela ao inserir a partida Minas Brasília 1 X 0 Ferroviária
- Será avaliado que após acrescentar a partida Minas Brasília 1 X 0 Ferroviária e fazer a requisição ao endpoint /leaderboard, serão retornados os campos e valores corretos.
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.00"
},
{
"name": "Santos",
"totalPoints": 11,
"totalGames": 5,
"totalVictories": 3,
"totalDraws": 2,
"totalLosses": 0,
"goalsFavor": 12,
"goalsOwn": 6,
"goalsBalance": 6,
"efficiency": "73.33"
},
{
"name": "Grêmio",
"totalPoints": 10,
"totalGames": 5,
"totalVictories": 3,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 9,
"goalsOwn": 8,
"goalsBalance": 1,
"efficiency": "66.67"
},
{
"name": "Internacional",
"totalPoints": 10,
"totalGames": 5,
"totalVictories": 3,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 7,
"goalsOwn": 6,
"goalsBalance": 1,
"efficiency": "66.67"
},
{
"name": "Real Brasília",
"totalPoints": 10,
"totalGames": 5,
"totalVictories": 3,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 5,
"goalsOwn": 4,
"goalsBalance": 1,
"efficiency": "66.67"
},
{
"name": "São Paulo",
"totalPoints": 8,
"totalGames": 5,
"totalVictories": 2,
"totalDraws": 2,
"totalLosses": 1,
"goalsFavor": 9,
"goalsOwn": 6,
"goalsBalance": 3,
"efficiency": "53.33"
},
{
"name": "Ferroviária",
"totalPoints": 7,
"totalGames": 6,
"totalVictories": 2,
"totalDraws": 1,
"totalLosses": 3,
"goalsFavor": 7,
"goalsOwn": 8,
"goalsBalance": -1,
"efficiency": "38.89"
},
{
"name": "São José-SP",
"totalPoints": 6,
"totalGames": 5,
"totalVictories": 2,
"totalDraws": 0,
"totalLosses": 3,
"goalsFavor": 5,
"goalsOwn": 6,
"goalsBalance": -1,
"efficiency": "40.00"
},
{
"name": "Flamengo",
"totalPoints": 5,
"totalGames": 5,
"totalVictories": 1,
"totalDraws": 2,
"totalLosses": 2,
"goalsFavor": 2,
"goalsOwn": 5,
"goalsBalance": -3,
"efficiency": "33.33"
},
{
"name": "Minas Brasília",
"totalPoints": 5,
"totalGames": 6,
"totalVictories": 1,
"totalDraws": 2,
"totalLosses": 3,
"goalsFavor": 5,
"goalsOwn": 9,
"goalsBalance": -4,
"efficiency": "27.78"
},
{
"name": "Cruzeiro",
"totalPoints": 4,
"totalGames": 5,
"totalVictories": 1,
"totalDraws": 1,
"totalLosses": 3,
"goalsFavor": 8,
"goalsOwn": 10,
"goalsBalance": -2,
"efficiency": "26.67"
},
{
"name": "Avaí/Kindermann",
"totalPoints": 4,
"totalGames": 5,
"totalVictories": 1,
"totalDraws": 1,
"totalLosses": 3,
"goalsFavor": 4,
"goalsOwn": 8,
"goalsBalance": -4,
"efficiency": "26.67"
},
{
"name": "Botafogo",
"totalPoints": 4,
"totalGames": 5,
"totalVictories": 1,
"totalDraws": 1,
"totalLosses": 3,
"goalsFavor": 3,
"goalsOwn": 8,
"goalsBalance": -5,
"efficiency": "26.67"
},
{
"name": "Bahia",
"totalPoints": 2,
"totalGames": 5,
"totalVictories": 0,
"totalDraws": 2,
"totalLosses": 3,
"goalsFavor": 2,
"goalsOwn": 6,
"goalsBalance": -4,
"efficiency": "13.33"
},
{
"name": "Napoli-SC",
"totalPoints": 2,
"totalGames": 5,
"totalVictories": 0,
"totalDraws": 2,
"totalLosses": 3,
"goalsFavor": 3,
"goalsOwn": 12,
"goalsBalance": -9,
"efficiency": "13.33"
}
]