Projeto Trybesmith
Crie uma loja de itens medievais, como aquelas espadas feitas sob encomenda para uma pessoa específica, no formato de uma API, utilizando Typescript e Sequelize.
Desenvolva as camadas de Service e Controllers da aplicação em seu código, utilizando JWT para autenticar algumas rotas, além de testes para garantir o correto funcionamento delas. A aplicação terá endpoints que darão suporte a operações de criação, leitura e atualização de informações.
- Não há Front-end neste projeto.
- Sua API deve ser desenvolvida dentro da pasta
./src
. - Seus testes deverão ser desenvolvidos na raiz da aplicação, em um diretório chamado
tests
.
🐳 Especificações sobre uso do Docker
Rode os serviços
app-trybesmith
edb
com o comandodocker-compose up -d --build
.
-
Lembre-se de parar o
mysql
se estiver usando localmente na porta padrão (3306
), ou adapte, caso queria fazer uso da aplicação em containers -
Esses serviços irão inicializar um container chamado
trybesmith_api
e outro chamadotrybesmith_db
. -
A partir daqui você pode rodar o container
trybesmith_api
via CLI ou abri-lo no VS Code.Instale as dependências [Caso existam] com
npm install
Rode o comandonpm run db:reset
(este comando vai funcionar somente após a criação do tipos solicitados no requisito) para criar o banco de dados, as tabelas que serão utilizadas e populá-las. Use o comandodocker exec -it trybesmith_api bash
para entrar no container.- Ele te dará acesso ao terminal interativo do container criado pelo compose, que está rodando em segundo plano.
Para visualizar o logs do nodemon em seu terminal use os seguintes comandos:
docker ps
: para visualizar os containers ativos e pegar oCONTAINER ID
;docker logs -f <id_do_container>
: para visualizar os logs do seu servidor com nodemon;
🧪 Execução de testes localmente
Para rodar os seus testes localmente utilize o seguinte comando:
npm run test:local
Para os verificar seus testes de cobertura utilize o seguinte comando:
npm run test:coverage
Para rodar os testes de um único exercício faça:
npm test <N>
## Exemplo: npm test 01
Para todos os exercícios faça:
npm test
🪑 Tabelas
O banco terá três tabelas: pessoas usuárias (users
), produtos (products
) e pedidos (orders
).
Toda a parte de criação do banco de dados, das tabelas, seeders e models do sequelize já está pronta. Você pode verificar toda a configuração e associações nos arquivos dentro do diretório src/database
.
‼️ Antes de começar a desenvolver
- Clone o repositório
-
git clone https://github.com/tryber/sd-027-b-project-trybesmith.git
. -
Entre na pasta do repositório que você acabou de clonar:
cd sd-027-b-project-trybesmith
- Instale as dependências [Caso existam]
-
npm install
- Crie uma branch a partir da branch
main
- Crie uma branch a partir da branch
-
Verifique se você está na branch
main
- Exemplo:
git branch
- Exemplo:
-
Se você não estiver, mude para a branch
main
- Exemplo:
git checkout main
- Exemplo:
-
Agora crie uma branch à qual 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-027-b-project-trybesmith
- Adicione as mudanças ao stage do Git e faça um
commit
- Você deve criar uma branch no seguinte formato:
-
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 )
- Adicione a sua branch com o novo
commit
ao repositório remoto
- Usando o exemplo anterior:
git push -u origin joaozinho-sd-027-b-project-trybesmith
- Crie um novo
Pull Request
(PR)
- Exemplo:
-
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
-
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" dos seus colegas, 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-027-b
.
-
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
Usaremos o ESLint para fazer a análise estática do seu código.
Este projeto já vem com as dependências relacionadas ao linter configuradas nos arquivos package.json
.
Para poder rodar o ESLint
em um projeto basta executar o comando npm install
dentro do projeto e depois npm run lint
. Se a análise do ESLint
encontrar problemas no seu código, tais problemas 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
no VSCode
. Para isso, basta fazer o download do plugin ESLint
e instalá-lo.
🍪 Informações sobre a API
👀 Observações importantes:
-
O não cumprimento de um requisito, total ou parcialmente, impactará em sua avaliação;
-
O projeto deve rodar na porta 3001;
-
Use os verbos
HTTP
adequados para cada operação; -
Agrupe e padronize suas URLs em cada recurso;
-
Garanta que seus endpoints sempre retornem uma resposta, havendo sucesso nas operações ou não;
-
Retorne os códigos de status corretos (recurso criado, erro de validação, etc).
-
Siga o padrão de nomenclatura de diretórios para cada camada como visto no conteúdo.
Há dois arquivos no diretório ./src/
: server.ts
e app.ts
, ambos não devem ser renomeados ou apagados. Você poderá fazer modificações em ambos os arquivos, porém no arquivo app.ts
o seguinte trecho de código não deve ser removido:
import express from 'express';
const app = express();
app.use(express.json());
export default app;
Isso está configurado para o avaliador funcionar corretamente.
🗣 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!
FORMULÁRIO DE AVALIAÇÃO DE PROJETO
🗂 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.
Implemente todos os tipos Order
, Product
e User
, do projeto na pasta src/types
de forma adequada. Isso é necessário para as migrations rodarem.
Atenção
1 - Crie um endpoint para o cadastro de produtos e testes que cubram as funcionalidades deste endpoint
- O endpoint deve ser acessível no caminho (
/products
); - Os produtos enviados devem ser salvos na tabela
products
do banco de dados; - O endpoint deve receber a seguinte estrutura:
{
"name": "Martelo de Thor",
"price": "30 peças de ouro",
"orderId": 4
}
As ordens dos pedidos de id 1 a 3 já foram criados pelo seeders no banco de dados, sendo assim novos produtos devem passar um novo orderId
, pois os produtos são exclusivos.
- Os testes devem garantir no mínimo 30% de cobertura do código das camadas
Service
eController
.
De olho na dica 👀:
Para construir seus testes use o método
.build()
quando for necessário;Lembre do Type Assertion para testar tipos.
As seguintes verificações serão feitas:
👉 Para caso os dados sejam enviados corretamente
-
[Será validado que é possível cadastrar um produto com sucesso]
- O resultado retornado para cadastrar o produto com sucesso deverá ser conforme exibido abaixo, com um status http
201
:
{ "id": 6, "name": "Martelo de Thor", "price": "30 peças de ouro" }
- O resultado retornado para cadastrar o produto com sucesso deverá ser conforme exibido abaixo, com um status http
-
[Será validado que os testes estão cobrindo pelo menos 30% das camadas
Service
eController
.]
2 - Crie um endpoint para a listagem de produtos e testes que cubram as funcionalidades deste endpoint
- O endpoint deve ser acessível no caminho (
/products
); - Os testes devem garantir no mínimo 45% de cobertura do código das camadas
Service
eController
.
Além disso, as seguintes verificações serão feitas:
👉 Para caso os dados sejam enviados corretamente
-
[Será validado que é possível listar todos os produtos com sucesso]
- O resultado retornado para listar produtos com sucesso deverá ser conforme exibido abaixo, com um status http
200
:
[ { "id": 1, "name": "Pedra Filosofal", "price": "20 gold", "orderId": null }, { "id": 2, "name": "Lança do Destino", "price": "100 diamond", "orderId": 1 } ]
- O resultado retornado para listar produtos com sucesso deverá ser conforme exibido abaixo, com um status http
-
[Será validado que os testes estão cobrindo pelo menos 50% das camadas
Service
eController
.]
3 - Crie um endpoint para listar todos os pedidos e testes que cubram as funcionalidades deste endpoint
- O endpoint deve ser acessível no caminho (
/orders
). - Essa rota deve retornar todos os pedidos e os
id
s dos produtos associados a estes. - Os testes devem garantir no mínimo 60% de cobertura do código das camadas
Service
eController
.
De olho na dica 👀: Todos os produtos são itens artesanais, portanto, únicos. Por isso são os produtos que contêm os id
s dos pedidos.
De olho na dica 👀: Você precisará combinar a lógica de dois models aqui 😉
Além disso, as seguintes verificações serão feitas:
👉 Para orders
-
[Será validado que é possível listar todos os pedidos com sucesso]
- Quando houver mais de um pedido, o resultado retornado para listar pedidos com sucesso deverá ser conforme exibido abaixo, com um status http
200
:
[ { "id": 1, "userId": 2, "productIds": [1, 2] }, { "id": 2, "userId": 1, "productIds": [3, 4] } ]
- Quando houver mais de um pedido, o resultado retornado para listar pedidos com sucesso deverá ser conforme exibido abaixo, com um status http
-
[Será validado que os testes estão cobrindo pelo menos 60% das camadas
Service
eController
.]
4 - Crie um endpoint para o login de pessoas usuárias e testes que cubram as funcionalidades deste endpoint
-
O endpoint deve ser acessível no caminho (
/login
). -
A rota deve receber os campos
username
epassword
, e esses campos devem ser validados no banco de dados. -
Um token
JWT
deve ser gerado e retornado caso haja sucesso no login. No seu payload deve estar presente o id e username. -
O endpoint deve receber a seguinte estrutura:
{
"username": "string",
"password": "string"
}
- Os testes devem garantir no mínimo 70% de cobertura do código das camadas
Service
eController
.
Além disso, as seguintes verificações serão feitas:
👉 Para caso haja problemas no login
-
[Será validado que o campo "username" é enviado]
- Se o login não tiver o campo "username", o resultado retornado deverá ser um status http
400
e
{ "message": "\"username\" and \"password\" are required" }
- Se o login não tiver o campo "username", o resultado retornado deverá ser um status http
-
[Será validado que o campo "password" é enviado]
- Se o login não tiver o campo "password", o resultado retornado deverá ser um status http
400
e
{ "message": "\"username\" and \"password\" are required" }
- Se o login não tiver o campo "password", o resultado retornado deverá ser um status http
-
[Será validado que não é possível fazer login com um username inválido]
- Se o login tiver um username que não exista no banco de dados ele será considerado inválido e o resultado retornado deverá ser um status http
401
e
{ "message": "Username or password invalid" }
- Se o login tiver um username que não exista no banco de dados ele será considerado inválido e o resultado retornado deverá ser um status http
-
[Será validado que não é possível fazer login com uma senha inválida]
- Se o login tiver uma senha que não corresponda à senha salva no banco de dados, ela será considerada inválida e o resultado retornado deverá ser um status http
401
e
{ "message": "Username or password invalid" }
De olho na dica 👀: As senhas salvas no banco de dados estão encriptadas com o bcrypt, portanto, você deve levar isso em consideração no momento de compará-las com as enviadas na requisição e utilizar o método adequado.
- Se o login tiver uma senha que não corresponda à senha salva no banco de dados, ela será considerada inválida e o resultado retornado deverá ser um status http
👉 Para caso os dados sejam enviados corretamente
-
[Será validado que é possível fazer login com sucesso]
- Se o login foi feito com sucesso, o resultado deverá ser um status http
200
e deverá retornar um token no formato abaixo (a token não precisa ser exatamente igual a essa):
{ "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" }
- Se o login foi feito com sucesso, o resultado deverá ser um status http
-
[Será validado que os testes estão cobrindo pelo menos 70% das camadas
Service
eController
.]
- Neste requisito iremos desenvolver validações referentes a criação do endpoint do requisito 1.
- Os testes devem garantir no mínimo 80% de cobertura do código das camadas
Service
eController
.
As seguintes validações deverão ser realizadas:
👉 Para name
-
[Será validado que o campo "name" é obrigatório]
- Se o campo "name" não for informado, o resultado retornado deverá ser um status http
400
e
{ "message": "\"name\" is required" }
- Se o campo "name" não for informado, o resultado retornado deverá ser um status http
-
[Será validado que o campo "name" tem o tipo string]
- Se o campo "name" não for do tipo
string
, o resultado retornado deverá ser um status http422
e
{ "message": "\"name\" must be a string" }
- Se o campo "name" não for do tipo
-
[Será validado que o campo "name" é uma string com mais de 2 caracteres]
- Se o campo "name" não for uma string com mais de 2 caracteres, o resultado retornado deverá ser um status http
422
e
{ "message": "\"name\" length must be at least 3 characters long" }
- Se o campo "name" não for uma string com mais de 2 caracteres, o resultado retornado deverá ser um status http
👉 Para price
-
[Será validado que o campo "price" é obrigatório]
- Se o campo "price" não for informado, o resultado retornado deverá ser um status http
400
e
{ "message": "\"price\" is required" }
- Se o campo "price" não for informado, o resultado retornado deverá ser um status http
-
[Será validado que o campo "price" tem o tipo string]
- Se o campo "price" não for do tipo
string
, o resultado retornado deverá ser um status http422
e
{ "message": "\"price\" must be a string" }
- Se o campo "price" não for do tipo
-
[Será validado que o campo "price" é uma string com mais de 2 caracteres]
- Se o campo "price" não for uma string com mais de 2 caracteres, o resultado retornado deverá ser um status http
422
e
{ "message": "\"price\" length must be at least 3 characters long" }
- Se o campo "price" não for uma string com mais de 2 caracteres, o resultado retornado deverá ser um status http
-
[Será validado que os testes estão cobrindo pelo menos 80% das camadas
Service
eController
.]