Para realizar o projeto, atente-se a cada passo descrito a seguir, e se tiver qualquer dúvida, nos envie por Slack! #vqv 🚀
Aqui você vai encontrar os detalhes de como estruturar o desenvolvimento do seu projeto a partir deste repositório, utilizando uma branch específica e um Pull Request para colocar seus códigos.
Ao iniciar este projeto, você concorda com as diretrizes do Código de Conduta e do Manual da Pessoa Estudante da Trybe.
🤷🏽♀️ Como entregar
Para entregar o seu projeto você deverá criar um Pull Request neste repositório.
Lembre-se que você pode consultar nosso conteúdo sobre Git & GitHub e nosso Blog - Git & GitHub sempre que precisar!
👨💻 O que deverá ser desenvolvido
Para este projeto, você deverá aplicar os princípios de Programação Orientada a Objetos (POO
) para a construção de uma API com CRUD
para gerenciar uma concessionária de veículos. Isso será feito utilizando o banco de dados MongoDB
.
🗓 Data de Entrega
- Este projeto é individual;
- São
X
dias de projeto; - Data de entrega para avaliação final do projeto:
06/06/2022 14:00
.
!! Antes de começar a desenvolver
- Clone o repositório
- Use o comando:
git clone https://github.com/tryber/sd-015-b-project-car-shop.git
. - Entre na pasta do repositório que você acabou de clonar:
cd sd-015-b-project-car-shop
- Instale as dependências
npm install
- Crie uma branch a partir da branch
main
-
Verifique se você está na branch
main
- Exemplo:
git branch
- Exemplo:
-
Se não estiver, mude para a branch
main
- Exemplo:
git checkout main
- Exemplo:
-
Agora crie uma branch onde você vai submeter os
commits
do seu projeto- Você deve criar uma branch no seguinte formato:
nome-de-usuario-nome-do-projeto
- Exemplo:
git checkout -b joaozinho-sd-0X-project-car-shop
- Você deve criar uma branch no seguinte formato:
- Adicione as mudanças ao stage do Git e faça um
commit
-
Verifique que as mudanças ainda não estão no stage
- Exemplo:
git status
(deve aparecer listada a pasta joaozinho em vermelho)
- Exemplo:
-
Adicione o novo arquivo ao stage do Git
- Exemplo:
git add .
(adicionando todas as mudanças - que estavam em vermelho - ao stage do Git)git status
(deve aparecer listado o arquivo joaozinho/README.md em verde)
- Exemplo:
-
Faça o
commit
inicial- Exemplo:
git commit -m 'iniciando o projeto x'
(fazendo o primeiro commit)git status
(deve aparecer uma mensagem tipo nothing to commit )
- Exemplo:
- Adicione a sua branch com o novo
commit
ao repositório remoto
- Usando o exemplo anterior:
git push -u origin joaozinho-sd-0X-project-car-shop
- Crie um novo
Pull Request
(PR)
- Vá até a página de Pull Requests do repositório no GitHub
- Clique no botão verde "New pull request"
- Clique na caixa de seleção "Compare" e escolha a sua branch com atenção
- Coloque um título para a sua Pull Request
- Exemplo: "Cria tela de busca"
- Clique no botão verde "Create pull request"
- Adicione uma descrição para o Pull Request e clique no botão verde "Create pull request"
- Não se preocupe em preencher mais nada por enquanto!
- Volte até a página de Pull Requests do repositório e confira que o seu Pull Request está criado
⌨️ Durante o desenvolvimento
-
Faça
commits
das alterações que você fizer no código regularmente. -
Lembre-se de sempre após um (ou alguns)
commits
atualizar o repositório remoto. -
Os comandos que você utilizará com mais frequência são:
git status
(para verificar o que está em vermelho - fora do stage - e o que está em verde - no stage)git add
(para adicionar arquivos ao stage do Git)git commit
(para criar um commit com os arquivos que estão no stage do Git)git push -u nome-da-branch
(para enviar o commit para o repositório remoto na primeira vez que fizer opush
de uma nova branch)git push
(para enviar o commit para o repositório remoto após o passo anterior)
🤝 Depois de terminar o desenvolvimento (opcional)
Para sinalizar que o seu projeto está pronto para o "Code Review", faça o seguinte:
-
Vá até a página DO SEU Pull Request, adicione a label de "code-review" e marque seus colegas:
-
No menu à direita, clique no link "Labels" e escolha a label code-review;
-
No menu à direita, clique no link "Assignees" e escolha o seu usuário;
-
No menu à direita, clique no link "Reviewers" e digite
students
, selecione o timetryber/students-sd-00
.
-
Caso tenha alguma dúvida, aqui tem um video explicativo.
🕵🏿 Revisando um pull request
Use o conteúdo sobre Code Review para te ajudar a revisar os Pull Requests.
🎛 Linter
Para fazer a análise estática do seu código neste projeto, vamos utilizar o linter ESLint. Assim o código estará alinhado com as boas práticas de desenvolvimento, sendo mais legível e de fácil manutenção!
- Este projeto já vem com as dependências relacionadas ao linter configuradas no arquivo
package.json
- Para poder rodar o
ESLint
basta executar o comandonpm install
dentro do projeto e depoisnpm run lint
. - Se a análise do
ESLint
encontrar problemas no seu código, eles serão mostrados no seu terminal. - Se não houver problema no seu código, nada será impresso no seu terminal.
- Você pode também instalar o plugin do
ESLint
noVSCode
. Para isso, bastar ir em extensions e baixar o pluginESLint
.
🛠 Testes
Para executar os testes localmente, digite no terminal o comando npm test
.
👀De olho na dica: especialmente no início, quando a maioria dos testes está falhando, a saída após executar os testes é bastante poluída. Você pode desabilitar temporariamente um teste utilizando a função skip
junto à função describe
. Como o nome indica, a função a seguir "pula" um teste:
describe.skip('...', () => {})
🐳 Como subir o banco do MongoDB usando Docker
Caso não tenha o MongoDB instalado em sua máquina e deseje usar o Docker, é só seguir os passos a seguir:
- Baixe a imagem do MongoDB:
docker pull mongo
- Crie o contêiner do MongoDB:
docker run --name <nome-do-conteiner> -p 27017:27017 -d mongo
- Confira se o contêiner está rodando:
docker ps
🐳 Rodando no Docker vs Localmente
Rode os serviços
node
emongodb
com o comandodocker-compose up -d
.
- Lembre-se de parar o
mongo
se estiver usando localmente na porta padrão (27017
), ou adapte, caso queria fazer uso da aplicação em containers - Esses serviços irão inicializar um container chamado
car_shop
e outro chamadocar_shop_db
. - A partir daqui você pode rodar o container
car_shop
via CLI ou abri-lo no VS Code.
Use o comando
docker exec -it car_shop bash
.
- Ele te dará acesso ao terminal interativo do container criado pelo compose, que está rodando em segundo plano.
Instale as dependências [Caso existam] com
npm install
⚠ Atenção ⚠ Caso opte por utilizar o Docker, TODOS os comandos disponíveis no package.json
(npm start, npm test, npm run dev, ...) devem ser executados DENTRO do container, ou seja, no terminal que aparece após a execução do comando docker exec
citado acima.
⚠ Atenção ⚠ O git dentro do container não vem configurado com suas credenciais. Ou faça os commits fora do container, ou configure as suas credenciais do git dentro do container.
⚠ Atenção ⚠ Não rode o comando npm audit fix! Ele atualiza várias dependências do projeto, e essa atualização gera conflitos com o avaliador.
✨ Dica: A extensão Remote - Containers
(que estará na seção de extensões recomendadas do VS Code) é indicada para que você possa desenvolver sua aplicação no container Docker direto no VS Code, como você faz com seus arquivos locais.
Instale as dependências [Caso existam] com
npm install
⚠ Atenção ⚠ Não rode o comando npm audit fix! Ele atualiza várias dependências do projeto, e essa atualização gera conflitos com o avaliador.
✨ Dica: Para rodar o projeto desta forma, obrigatoriamente você deve ter o node
instalado em seu computador.
✨ Dica: O avaliador espera que a versão do node
utilizada seja a 16.
👷 Estruturação do projeto
Dentro da pasta src
foram deixados alguns arquivos de exemplo sendo eles:
src/controllers/controller.example.ts
src/index.example.ts
src/server.example.ts
server.example.ts
seja renomeado para server.ts
para que os testes funcionem.
✅ Arquivos prontos para uso
- O arquivo
src/connection.ts
possui o código necessário para realizar a conexão com o banco de dados:
import mongoose from 'mongoose';
const MONGO_DB_URL = 'mongodb://localhost:27017/CarShop';
const MONGO_DB_URL = 'mongodb://mongodb:27017/CarShop';
const connectToDatabase = (
mongoDatabaseURI = process.env.MONGO_URI
|| MONGO_DB_URL,
) => mongoose.connect(mongoDatabaseURI);
export default connectToDatabase;
- O arquivo
src/app.ts
contém o código necessário para subir o servidor:
public startServer(PORT: string | number = 3001): void {
connectToDatabase();
this.app.listen(
PORT,
() => console.log(`Server running here 👉 http://localhost:${PORT}`),
);
}
🔥⚠️ Tenha atenção para os seguintes pontos: ⚠️ 🔥
➡️ A conexão do banco local contida no arquivo src/connection.ts
deverá conter o seguinte parâmetro:
const MONGO_DB_URL = 'mongodb://localhost:27017/CarShop';
- Para o avaliador funcionar altere a conexão do banco contida no arquivo
src/connection.ts
para:
const MONGO_DB_URL = 'mongodb://mongodb:27017/CarShop';
➡️ Lembre-se de não entregar o projeto com nenhum teste ignorado. Testes ignorados serão tratados como testes falhando!
➡️ Não apague, em hipótese alguma, qualquer teste ou arquivo deste repositório.
➡️ src/models
, src/services
, src/controllers
, src/interfaces
e seus respectivos arquivos criados durante a execução do projeto, devem seguir à risca os nomes informados no README.
➡️ Não altere ou instale novas dependências no arquivo packages.json
, pois o mesmo está travado para essa avaliação.
🗣 Nos dê feedbacks sobre o projeto!
Ao finalizar e submeter o projeto, não se esqueça de avaliar sua experiência preenchendo o formulário. Leva menos de 3 minutos!
🗂 Compartilhe seu portfólio!
Você sabia que o LinkedIn é a principal rede social profissional e compartilhar o seu aprendizado lá é muito importante para quem deseja construir uma carreira de sucesso? Compartilhe esse projeto no seu LinkedIn, marque o perfil da Trybe (@trybe) e mostre para a sua rede toda a sua evolução.
Crie a interface Model
, que será usada para a conexão com o banco de dados. Ela deverá ter, pelo menos, as funções create()
, read()
, readOne()
, update()
e delete()
.
Por ser genérica, nossa interface deverá receber um tipo T
qualquer, e ela deve esperar, em cada função, as seguintes especificações:
create()
: deve receber um objeto do tipoT
e retornar uma Promise do tipoT
.read()
: deve retornar uma Promise contendo um array de objetos do tipoT
.readOne()
: deve receber uma string e retornar uma Promise do tipoT
ou nula.update()
: deve receber uma string e um objeto do tipoT
e retornar uma Promise do tipoT
ou nula.delete()
: deve receber uma string e retornar uma Promise do tipoT
ou nula.- O arquivo deve ficar no diretório
/src/interfaces/
e ter o nome deModelInterface.ts
. - A interface deve ser exportada com o nome de
Model
e não deve ser exportada de forma padrão.
Será verificado se:
- Existe a interface Model;
- A interface Model possui todas as funções solicitadas;
- A interface Model pode ser implementada com qualquer tipo;
- A interface está no local correto, com o nome correto e com a forma de exportação correta;
Crie a interface Vehicle
, que será usada para criarmos nossos tipos de carro, moto e caminhão.
Ela deverá ter todos os atributos comuns de todos os veículos que listaremos aqui. São eles:
Atributo | Descrição |
---|---|
model |
Marca e/ou modelo do veículo. Deve ser uma string com, pelo menos, 3 caracteres |
year |
Ano de fabricação do veículo. Deve ser maior ou igual a 1900, porém menor ou igual a 2022 |
color |
Cor principal do veículo. Deve ser uma string com, pelo menos, 3 caracteres |
status |
Status que define se um veículo pode ou não ser comprado. Deve receber valores booleanos e deve ser opcional |
buyValue |
Valor de compra do veículo. Deve receber apenas números inteiros |
- O arquivo deve ficar no diretório
/src/interfaces/
e ter o nome deVehicleInterface.ts
. - A interface deve ser exportada com o nome de
Vehicle
e não deve ser exportada de forma padrão.
Será verificado se:
- A interface Vehicle existe;
- A interface possui os atributos solicitados;
- A interface está no local correto, com o nome correto e com a forma de exportação correta.
Crie a interface Car
, de modo que ela possua todos os atributos da interface Vehicle
e, também, os atributos:
Atributo | Descrição |
---|---|
doorsQty |
Quantidade de portas de um carro. Deve ser maior ou igual a 2 e menor ou igual a 4 |
seatsQty |
Quantidade de assentos disponíveis no carro. Deve ser maior ou igual a 2 e menor ou igual a 7 |
- O arquivo deve ficar no diretório
/src/interfaces/
e ter o nome deCarInterface.ts
. - A interface deve ser exportada com o nome de
Car
e não deve ser exportada de forma padrão.
Será verificado se:
- A interface
Car
estende a interfaceVehicle
; - É possível criar um objeto do tipo
Car
; - A interface
Car
possui as propriedadesdoorsQty
eseatsQty
; - A interface está com local, nome e forma de exportação correta.
Crie uma rota que receba uma requisição POST
para cadastrar um veículo do tipo carro.
Será verificado se:
- A rota retorna erro
400
caso a requisição receba um objeto vazio; - A rota retorna erro
400
ao tentar criar um carro com quantidade de assentos inferior a 2; - A rota retorna erro
400
ao tentar criar um carro com quantidade de portas inferior a 2; - A rota retorna erro
400
ao tentar criar um carro semmodel
,year
,color
ebuyValue
; - A rota retorna erro
400
ao tentar criar um carro semdoorsQty
eseatsQty
; - Não é possível criar um carro se os atributos
model
,year
,color
,buyValue
,doorsQty
eseatsQty
estiverem com tipos errados; - É possível criar um carro se todos os parâmetros forem passados corretamente;
- Sua API deve responder com status http
201
e o seguinte body:
_id: "4edd40c86762e0fb12000003",
model: "Ferrari Maranello",
year: 1963,
color: "red",
buyValue: 3500000,
seatsQty: 2,
doorsQty: 2
Escreva testes que cubram, pelo menos, 15% da camada Model. Seus arquivos de teste deverão estar na pasta src/tests/unit/model
.
Será verificado se:
- A cobertura total das linhas dos arquivos na pasta
models
é maior ou igual a 15%.
Escreva testes que cubram, pelo menos, 15% da camada Service. Seus arquivos de teste deverão estar na pasta src/tests/unit/services
.
Será verificado se:
- A cobertura total das linhas dos arquivos na pasta
services
é maior ou igual a 15%.
Escreva testes que cubram, pelo menos, 15% da camada Controller. Seus arquivos de teste deverão estar na pasta src/tests/unit/controllers
.
Será verificado se:
- A cobertura total das linhas dos arquivos na pasta
controllers
é maior ou igual a 15%.
Crie uma rota que receba uma requisição GET
para receber todos os veículos do tipo carro registrados no banco de dados.
Será verificado se:
- É possível listar os carros com sucesso;
- Haverá retorno de uma lista vazia se não houver carros;
- Sua API responderá com status http
200
em caso de sucesso.
09 - Crie uma rota para o endpoint /cars/id
onde seja possível listar um único carro através do seu id
Crie uma rota que receba uma requisição GET
para receber determinado veículo do tipo carro que possua o id
passado como parâmetro na rota.
Será verificado se:
- É possível listar um carro com sucesso através do id;
- Sua API responderá com status http
200
em caso de sucesso; - É disparado o erro
400
Id must have 24 hexadecimal characters
caso o id possua menos que 24 caracteres; - É disparado o erro
404
Object not found
caso o id possua 24 caracteres, mas seja inválido;
Escreva testes que cubram, pelo menos, 30% da camada Model. Seus arquivos de teste deverão estar na pasta src/tests/unit/model
.
Será verificado se:
- A cobertura total das linhas dos arquivos na pasta
models
é maior ou igual a 30%.
Escreva testes que cubram, pelo menos, 30% da camada Service. Seus arquivos de teste deverão estar na pasta src/tests/unit/services
.
Será verificado se:
- A cobertura total das linhas dos arquivos na pasta
services
é maior ou igual a 30%.
Escreva testes que cubram, pelo menos, 30% da camada Controller. Seus arquivos de teste deverão estar na pasta src/tests/unit/controllers
.
Será verificado se:
- A cobertura total das linhas dos arquivos na pasta
controllers
é maior ou igual a 30%.
13 - Crie uma rota para o endpoint /cars/id
, onde é possível atualizar o registro de um carro através do seu id
Crie uma rota que receba uma requisição PUT
para atualizar determinado veículo do tipo carro que possua o id
passado como parâmetro na rota.
Será verificado se:
- É disparado o erro
404
Object not found
caso o id possua 24 caracteres, mas seja inválido; - É disparado o erro
400
Id must have 24 hexadecimal characters
caso o id possua menos que 24 caracteres; - É disparado o erro
400
caso obody
esteja vazio; - Um carro é atualizado com sucesso;
- Sua API responderá com status http
200
e o seguinte body, em caso de sucesso:
_id: "4edd40c86762e0fb12000003",
model: "Fiat Uno",
year: 1963,
color: "blue",
buyValue: 3500,
seatsQty: 4,
doorsQty: 4
Escreva testes que cubram, pelo menos, 60% da camada Model. Seus arquivos de teste deverão estar na pasta src/tests/unit/model
.
Será verificado se:
- A cobertura total das linhas dos arquivos na pasta
models
é maior ou igual a 60%.
Escreva testes que cubram, pelo menos, 60% da camada Service. Seus arquivos de teste deverão estar na pasta src/tests/unit/services
.
Será verificado se:
- A cobertura total das linhas dos arquivos na pasta
services
é maior ou igual a 60%.
Escreva testes que cubram, pelo menos, 60% da camada Controller. Seus arquivos de teste deverão estar na pasta src/tests/unit/controllers
.
Será verificado se:
- A cobertura total das linhas dos arquivos na pasta
controllers
é maior ou igual a 60%.
Crie uma rota que receba uma requisição DELETE
para excluir determinado veículo do tipo carro que possua o id
passado como parâmetro na rota.
Será verificado se:
- É disparado o erro
404
Object not found
caso o id possua 24 caracteres, mas seja inválido; - É disparado o erro
400
Id must have 24 hexadecimal characters
caso o id possua menos que 24 caracteres; - Um carro é removido com sucesso;
- Sua API deve responder com status http
204
sem body;
Crie a interface Motorcycle
, de modo que ela possua todos os atributos da interface Vehicle
e, também, os atributos:
Atributos | Descrição |
---|---|
category |
Categoria da moto. Deve poder ser apenas Street , Custom ou Trail |
engineCapacity |
A capacidade do motor. Deve ser um valor inteiro positivo menor ou igual a 2500 |
- O arquivo deve ficar no diretório
/src/interfaces/
e ter o nome deMotorcycleInterface.ts
. - A interface deve ser exportada com o nome de
Motorcycle
e não deve ser exportada de forma padrão.
Será verificado se:
- A interface
Motorcycle
estende a interfaceVehicle
; - É possível criar um objeto do tipo
Motorcycle
; - A interface
Motorcycle
possui as propriedadescategory
eengineCapacity
; - Não é possível criar um objeto do tipo
Motorcycle
com uma categoria errada; - A interface está com local, nome e forma de exportação correta.
Crie uma rota que receba uma requisição POST
para cadastrar um veículo do tipo moto.
Será verificado se:
- A rota retorna erro
400
caso a requisição receba um objeto vazio; - A rota retorna erro
400
ao tentar criar uma moto comcategory
diferente deStreet
,Custom
ouTrail
; - A rota retorna erro
400
ao tentar criar uma moto comcategory
diferente destring
; - A rota retorna erro
400
ao tentar criar uma moto comengineCapacity
menor ou igual a zero; - A rota retorna erro
400
ao tentar criar uma moto comengineCapacity
maior que 2500; - A rota retorna erro
400
ao tentar criar um moto semmodel
,year
,color
ebuyValue
; - A rota retorna erro
400
ao tentar criar um moto semcategory
eengineCapacity
; - Não é possível criar uma moto se os atributos
model
,year
,color
,buyValue
,category
eengineCapacity
estiverem com tipos errados; - É possível criar uma moto se todos os parâmetros forem passados corretamente;
- Sua API responderá com status http
201
e o seguinte body:
_id: "4edd40c86762e0fb12000003",
model: "Honda CG Titan 125",
year: 1963,
color: "red",
buyValue: 3500,
category: "Street",
engineCapacity: 125
20 - Crie uma rota para o endpoint /motorcycles
onde seja possível listar todas as motos registradas
Crie uma rota que receba uma requisição GET
para receber todos os veículos do tipo moto registrados no banco de dados.
Será verificado se:
- É possível listar as motos com sucesso;
- Haverá retorno de uma lista vazia se não houver motos;
- Sua API responderá com status http
200
.
21 - Crie uma rota para o endpoint /motorcycles/id
onde seja possível listar uma única moto através do seu id
Crie uma rota que receba uma requisição GET
para receber determinado veículo do tipo moto que possua o id
passado como parâmetro na rota.
Será verificado se:
- É possível listar uma moto com sucesso através do id;
- Sua API responderá com status http
200
em caso de sucesso; - É disparado o erro
400
Id must have 24 hexadecimal characters
caso o id possua menos que 24 caracteres; - É disparado o erro
404
Object not found
caso o id possua 24 caracteres, mas seja inválido;
22 - Crie uma rota para o endpoint /motorcycles/id
onde é possível atualizar o registro de uma moto através do seu id
Crie uma rota que receba uma requisição PUT
para atualizar determinado veículo do tipo moto que possua o id
passado como parâmetro na rota.
Será verificado se:
- É disparado o erro
404
Object not found
caso o id possua 24 caracteres, mas seja inválido; - É disparado o erro
400
Id must have 24 hexadecimal characters
caso o id possua menos que 24 caracteres; - É disparado o erro
400
caso obody
esteja vazio; - Una moto é atualizada com sucesso;
- Sua API responderá com status http
200
e o seguinte body, em caso de sucesso:
_id: "4edd40c86762e0fb12000003",
model: "Honda CG Titan 125",
year: 1963,
color: "black",
buyValue: 3500,
category: "Street",
engineCapacity: 125
Crie uma rota que receba uma requisição DELETE
para excluir determinado veículo do tipo moto que possua o id
passado como parâmetro na rota.
Será verificado se:
- É disparado o erro
404
Object not found
caso o id possua 24 caracteres, mas seja inválido; - É disparado o erro
400
Id must have 24 hexadecimal characters
caso o id possua menos que 24 caracteres; - Uma moto é removida com sucesso;
- Sua API responderá com status http
204
sem body, em caso de sucesso;
Escreva testes que cubram 90% da camada Model. Seus arquivos de teste deverão estar na pasta src/tests/unit/models
.
Será verificado se:
- A cobertura total das linhas dos arquivos na pasta
models
é igual a 90%.
Escreva testes que cubram 90% da camada Service. Seus arquivos de teste deverão estar na pasta src/tests/unit/services
.
Será verificado se:
- A cobertura total das linhas dos arquivos na pasta
services
é igual a 90%.
Escreva testes que cubram 90% da camada Controller. Seus arquivos de teste deverão estar na pasta src/tests/unit/controllers
.
Será verificado se:
- A cobertura total das linhas dos arquivos na pasta
controllers
é igual a 90%.
Escreva testes que cubram 100% da camada Model. Seus arquivos de teste deverão estar na pasta src/tests/unit/models
.
Escreva testes que cubram 100% da camada Service. Seus arquivos de teste deverão estar na pasta src/tests/unit/services
.
Escreva testes que cubram 100% da camada Controller. Seus arquivos de teste deverão estar na pasta src/tests/unit/controllers
.