Compare commits

..

No commits in common. "main" and "develop" have entirely different histories.

73 changed files with 5237 additions and 4873 deletions

View file

@ -1,10 +0,0 @@
.editorconfig
.eslintignore
.env
.eslintrc.json
.git
.github
.gitignore
Dockerfile*
.dockerignore
node_modules

View file

@ -1,4 +0,0 @@
PORT=
DB_NAME=
DB_HOST=
DB_PORT=

11
.github/CODEOWNERS vendored Normal file
View file

@ -0,0 +1,11 @@
# This is a comment.
# Each line is a file pattern followed by one or more owners.
# These owners will be the default owners for everything in
# the repo. Unless a later match takes precedence,
# @global-owner1 and @global-owner2 will be requested for
# review when someone opens a pull request.
# * @global-owner1 @global-owner2
* @tryber/pr-locker

117
.github/workflows/main.yml vendored Normal file
View file

@ -0,0 +1,117 @@
on:
workflow_dispatch:
inputs:
dispatch_token:
description: 'Token that authorize the dispatch'
required: true
head_sha:
description: 'Head commit SHA that dispatched the workflow'
required: true
pr_author_username:
description: 'Pull Request author username'
required: true
pr_number:
description: 'Pull Request number that dispatched the workflow'
required: true
jobs:
ESLint-evaluator:
runs-on: self-hosted
name: ESLint
steps:
- name: Fetch project repository
uses: actions/checkout@v2
- name: Fetch Blocked Files Checkout action
uses: actions/checkout@v2
with:
repository: betrybe/blocked-files-checkout-action
ref: v2
token: ${{ secrets.GIT_HUB_PAT }}
path: .github/actions/blocked-files-checkout
- name: Fetch ESLint evaluator
uses: actions/checkout@v2
with:
repository: betrybe/eslint-linter-action
ref: v3
token: ${{ secrets.GIT_HUB_PAT }}
path: .github/actions/eslint-evaluator
- name: Setup NodeJS
uses: actions/setup-node@v1.4.4
with:
node-version: '14'
- name: Restore protected files
uses: ./.github/actions/blocked-files-checkout
with:
restore_branch: 'master'
- name: Run ESLint evaluator
uses: ./.github/actions/eslint-evaluator
with:
token: ${{ secrets.GITHUB_TOKEN }}
pr_number: ${{ github.event.inputs.pr_number }}
Evaluator:
runs-on: self-hosted
name: Evaluator
needs: [ESLint-evaluator]
services:
mongodb:
image: mongo
ports:
- "27017:27017"
options: -v ${{ github.workspace }}:/github/workspace
steps:
- name: Fetch project repository
uses: actions/checkout@v2
- name: Fetch Blocked Files Checkout action
uses: actions/checkout@v2
with:
repository: betrybe/blocked-files-checkout-action
ref: v2
token: ${{ secrets.GIT_HUB_PAT }}
path: .github/actions/blocked-files-checkout
- name: Fetch Jest evaluator
uses: actions/checkout@v2
with:
repository: betrybe/jest-evaluator-action
ref: v9
token: ${{ secrets.GIT_HUB_PAT }}
path: .github/actions/jest-evaluator
- name: Fetch Store evaluation
uses: actions/checkout@v2
with:
repository: betrybe/store-evaluation-action
ref: v2
token: ${{ secrets.GIT_HUB_PAT }}
path: .github/actions/store-evaluation
- name: Setup NodeJS
uses: actions/setup-node@v1.4.4
with:
node-version: '12'
- name: Restore protected files
uses: ./.github/actions/blocked-files-checkout
with:
restore_branch: 'master'
- name: Run Jest evaluation
id: evaluator
uses: ./.github/actions/jest-evaluator
with:
pr_author_username: ${{ github.event.inputs.pr_author_username }}
npm-start: true
- name: Run Store evaluation
uses: ./.github/actions/store-evaluation
with:
evaluation-data: ${{ steps.evaluator.outputs.result }}
environment: production
pr-number: ${{ github.event.inputs.pr_number }}

2
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,2 @@
{
}

View file

@ -1,21 +0,0 @@
# Essa porta, em EXPOSE, é a padrão, mas poderia ser modificado, por definir numa variavel PORT -- como feito na linha 19, por exemplo.
# Se for fazer o build fora do compose.yml e com rede separada, o nome do container precisa ser o mesmo da variável DB_HOST.
FROM node:lts-bullseye-slim
WORKDIR /myapp
COPY package*.json ./
RUN npm install
COPY . .
ENV DB_NAME GamesStore
ENV DB_HOST games-store-db
ENV PORT 3001
EXPOSE 3001
ENTRYPOINT ["npm", "start"]

View file

@ -1,21 +0,0 @@
# Essa porta, em EXPOSE, é a padrão, mas poderia ser modificado, por definir numa variavel PORT -- como feito na linha 19, por exemplo.
# Se for fazer o build fora do compose.yml e com rede separada, o nome do container precisa ser o mesmo da variável DB_HOST.
FROM node:lts-bullseye-slim
WORKDIR /myapp
COPY package*.json ./
RUN npm install
COPY . .
ENV DB_NAME GamesStore
ENV DB_HOST games-store-db
ENV PORT 3001
EXPOSE 3001
ENTRYPOINT ["npm", "run", "dev"]

398
README.md
View file

@ -7,9 +7,11 @@ Ainda em fase de desenvolvimento, porém é possível já utilizar.
### Tem FRONT ?
Aqui está o [link](https://github.com/becauro/games-store-front) do repositório **frontend**, onde desenvolvi algumas interfaces para interagir com esta API.
Aqui está o [link](https://github.com/becauro/games-store-front) do repositório **frontend**.
Desenvolvi algumas interfaces para interagir com essa API.
Ainda estar em desenvolvimento, portanto o Front nem usa tudo que tem no Back ainda.
No entanto, é possível executar esse frontend por aqui também, se seguir a correta opção ("COM FRONT") que deixei na seção [Via DOCKER](#via-docker).
Então, corre lá pra dá uma olhada e aproveite para sentar aquele dedo nos botões de `Code Review` pra ajudar o projeto.
## <span id="sumario">Sumário</span>
@ -19,10 +21,9 @@ No entanto, é possível executar esse frontend por aqui também, se seguir a co
- <a href="#arquitetura-e-padroes">Arquitetura e padrões</a>
- <a href="#tecnologias-utilizadas">Tecnologias utilizadas</a>
- <a href="#futuras-implementacoes">Futuras implementações</a>
- <a href="#requisitos-execucao">Requisitos para execução da API</a>
- <a href="#requisitos-execucao">Requisitos para execução e consumo da API</a>
- [Dependências](#dependencias)
- [Como executar](#como-executar)
- [Via DOCKER](#via-docker)
- [Manualmente](#manualmente-via-host)
- [Endpoints](#endpoints)
- [Linter](#linter)
- [Observações](#observações)
@ -44,10 +45,9 @@ Esse projeto teve como objetivo praticar as seguintes hardskills:
Se trata de uma API de gerenciamento de vendas que manipula **produtos** e **vendas**.
Basicamente é um modesto controle de estoque em forma de CRUD para lidar tanto com produtos como com as vendas .
Seguindo os princípios REST foi desenvolvido alguns ENDPOINTS que se conectam a um banco de dados NÃO relacional (NoSQL), MongoDB.
Começando pela API, foi desenvolvido alguns ENDPOINTS seguindo os princípios do REST que se conectam a um banco de dados NÃO relacional.
Há uma Collection para **produtos** (products) serem cadastrados na aplicação, afim de ser possível fazer vendas com esses produtos.
Da mesma forma, uma Collection para **vendas** (sales) também foi criada. Essas vendas são realizadas conforme a quantidade de produtos disponíveis em estoque.
Depois, foi criado uma Collection para os **produtos** (products) que desejam se cadastrar na aplicação, afim de ser possível fazer vendas com esses produtos. Após isso, uma Collection para **vendas** (sales) também foi criada. As vendas são realizadas conforme a quantidade de produtos disponíveis em estoque.
## Requisitos de Usuário
@ -73,381 +73,41 @@ Da mesma forma, uma Collection para **vendas** (sales) também foi criada. Essas
<a href="#sumario">Sumário</a>
* Autenticação de Usuários (Login)
* Autorizações de usuários com uso de tokens (JWT). Parecido com o que fiz no projeto [Blog API](https://github.com/becauro/blog_api).
* Implantar a aplicação via Cloud ou VPS, para que possa ser consumida e testada externamente.
* Implantar o Banco de Dados em nuvem.
* Autorizações de usuários com uso de tokens (JWT).
* Implantar a aplicação na plataforma (PaaS) do Heroku, para que possa ser consumida e testada externamente.
* Implantar um Banco de Dados na nuvem do [MongoDB Atlas](https://www.mongodb.com/atlas) para que possa ser utilizado via Heroku.
## <span id="requisitos-execucao">Requisitos para execução da API</span>
## <span id="requisitos-execucao">Requisitos para execução e consumo da API:</span>
<a href="#sumario">Sumário</a>
Você pode rodar esse projeto de duas maneiras: 1 - Via Docker 🐳 ou 2 - Manualmente 🖐️
### Opção 1 - Via Docker
1. **Node.js**
2. **MongoDB**
3. **Porta 3000** disponível, ou configurar outra em uma variável de ambiente.
3.1 - A API também estar configurada para, opcinalmente, ler uma variável de ambiente que se chame "PORT".
4. Algum cliente de teste de API (ex.: Postman, Insomnia e etc) caso queira testar as requisições.
Se não tiver, baixe-o no [site oficial](https://docs.docker.com/engine/install/)
## <span id="dependencias">Dependências</span>
<a href="#sumario">Sumário</a>
### Opção 2 - Manualmente (Via Host)
No arquivo `package.json` é listado as dependências necessárias.
Para instalar essas dependências, estando conectado a internet e dentro da pasta do repositório, basta digitar o seguinte comando:
1. **Node.js**
Nodejs é um framework que tem um engine do Chrome modificada o qual permite que exista, no lado servidor, uma aplicação Web desenvolvida em JavaScript.
Portanto é o primeiro sofware que permite esse projeto acontecer.
Já testei com Node nas versões 14 à 18. Acredito que funcione nas outras versões.
Para instalar , configurar e gerenciar Nodejs de forma produtiva, recomendo uso da ferramenta [NVM](https://github.com/nvm-sh/nvm#intro).
Com NVM você consegue, "com um dedo", instalar várias versões do Nodejs e escolher qual usá-las quando precisar.
Mas, se quiser ter mais trabalho, baixe o Nodejs do [site oficial](https://nodejs.org/en/).
2. **MongoDB**
Essa API se comunica com um banco de dados não relacional (noSQL) implementado em MongoDB.
Então precisa ter em _*algum lugar*_ (local ou remotamente) o software gerenciador de servidor de banco dados, MongoDB, que se possa usar aqui.
Caso não o tenha, faça download e instale-o.
[Site oficial](https://www.mongodb.com/try/download/community) para download do _*MongoDB Comunnity Edition*_.
3. **Software cliente** para requição de API (ex.: Postman, Insomnia e etc)
Para testar todos os métodos de requição à essa API, se faz necessário um Software específico para isso.
Dentre os mais conhecidos até o momento são [Postman](https://www.postman.com/downloads) e [Insomnia](https://insomnia.rest/download).
Se for apenas testar o método GET no endpoint, apenas com um browser comum é possível.
Por exemplo. Fazendo uma requisição GET a partir de um Browser (Firefox, Chrome e etc) para a URL **http://localhost:3001/products** , funciona.
`npm install`
## Como Executar
<a href="#sumario">Sumário</a>
### Via DOCKER
--------------------------------------------------------------------------------------------------------------------------------------------------------
Criei diferentes MODOS para executar esse software via Docker. Os classifiquei assim: **"Normal (frontendless)"**, **"Normal + Modo Dev"**, **"Com Frontend"** e **"Com Frontend + Modo Dev"**.
#### <ins> ☑️ NORMAL </ins>
Esse modo é básico e padrão, sem frontend ("frontendless"); é só a API respondendo requisições e conversando com banco de dados.
Trata-se do levantamento de um container que dá acesso a API na porta escolhida (padrão: 3001) e pronto.
Com isso, basta verificar o número IP do gateway da rede docker criada e fazer a requisição para o(s) endpoint(s) desejado(s).
Mostro como fazer tudo isso mais a frente. NADA DEMAIS. ;-)
A seguir temos os passos de como usar esse modo ("Normal"), de acordo com a introdução que fiz acima. Junto deixei algumas recomendações técnicas que possivelmente você só precisa ler uma vez, já que se aplica aos demais modos também.
========= COMO USAR =========
Para executar o sofware nesse modo, faça as seguintes etapas:
**_1. Verifique o arquivo compose.yml_**
Se você for um desenvolvedor, talvez queira mudar algo nesse aquivo para atender às tuas especificidades, como por exemplo _*1 - Porta exposta*_ e _*2 - Nome da rede*_ . Ahh !.. talvez queira, tmbém, colocar uma outra images nos dockerfiles. Sei lá. Umas imagens mais "levinhas" e tal ..🌩️ . Depois vou trocar também.
- Caso decida trocar o valor da variável DB_NAME no arquivo, penso ser boa prática também trocá-las nos arquivos **Dockerfile** e **models/Dockerfile** e VICE-VERSA em prol da legibilidade e documentação. Principalmente se precisar fazer testes ou depurações subindo container, manualmente, sem auxílio do **docker compose**.
Dito isso, se precisas alterar algo mais nesses arquivos ("compose" e "Dockerfiles"), LEIA, antes, as linhas comentadas dentro dos arquivos para não cometer um "ato falho" que inviabilize a execuçao do software. O valor de uma variável pode está vinculado à uma lógica usada em outro local que ler essa variável. Um exemplo disso são as variáveis de ambientes DB_HOST e PORT do serviço de **_backend_**.
Ok! Próximo ...
**_2. Execute o docker compose**
Instalado os requisitos e as dependências necessárias, basta seguir as seguintes etapas:
Estando na pasta do arquivo _compose.yml_, via CLI, basta digitar:
1. Dentro pasta do projeto, execute o comando: `npm start`.
2. Em seguida, abra algum cliente de API (ex.: Postman, Insomnia e etc) e faça as requisições para os ENDPOINTs de **http://localhost:3000** (Essa porta 3000 está como padrão alternativo à ausência de uma variável de ambiente para porta).
2.1 - Recomendo usar um `127.0.0.1` ao invés de `localhost`, quando estiver executando outro servidor web, simultâneamente, na mesma máquina. Tive alguns erros com 'localhost' em mais de um servidor. Talvez seja "algo particular", mas não custa avisar. :-)
~~~shell
docker compose up -d
~~~
**_3. Localize o container criado_**
O nome do container deixei que fosse gerado automaticamente, com estrutura padrão, formado por:
`nome_da_PASTA + nome do SERVIÇO + um NÚMERO`
Então o primeiro container do projeto para o serviço de backend, por exemplo, terá um nome parecido com: `games-store-back-backend-1`.
**Observação**: Você pode, manualmente, criar um banco chamado `StoreManager` com uma Collection chamada `products`, e então usar algum dos objetos que se encontram no array do arquivo `dataTestForDb.json` (na raiz do projeto) para cadastrar algum produto na API. Esse objetos são alguns produtos que já estão no formato (shape / schema) que deve se usado pelo banco para não haver problema nos retornos das requisições à API. Se preferir, pode ainda popular o banco (usando um insertMany()) passando o array de produtos que está dentro desse mesmo arquivo, `dataTestForDb.json`.
**_4. Identifique o IP do gateway do container_**
Como criei numa rede nesse projeto, a documentação docker classifica isso como "user-defined bridge", logo para acessar o container a partir do host, precisamos usar o ip que Docker define para o gateway dessa rede que criamos. Portanto, depois que subimos o(s) container(s), precisamos localizar o número IP do gateway desse container para poder conseguir fazer requisição usando esse IP.
Existem diversas maneiras de fazer isso se estiver usando o Docke via CLI. A que acho mais fácil é inspecionar o próprio container e, com auxílio do grep, filtrar a palavra "Gateway" que já vem acompanhado com seu repspectivo número IP. Veja abaixo:
Os dados que se encontram no arquivo `dataTestForDb.json`, foi obtido do ENDPOINT de produtos _gamers_, da API pública do _Mercado Livre_: `https://api.mercadolibre.com/sites/MLB/search?category=MLB1144`.
Sintaxe:
~~~shell
sudo docker container inspect < nome ou id do container > | grep Gateway
~~~
**_5. Faça requisição para um endpoint_**
De posse do número IP, usando alguma ferramenta de requisição como [Postman](https://www.postman.com/downloads) e [Insomnia](https://insomnia.rest/download), faça requisição para um endpoint da API.
Use o IP do Gateway obtido na etapa anterior.
Escolha um dos endpoints que listei mais à frente, na seção [Endpoints](#endpoints).
Exemplo com endpoint `products` seria: `<IP DO GATEWAY>:3001/products`
#### <ins> ☑️ NORMAL + MODO DEV </ins>
Esse modo meio que herda todas observações do modo NORMAL citado anteriormente, portanto, não vou reptir quase nada, "apenas fazer algumas referências e acrescentar as diferenças" (poeta, eu ?).
Esse modo consiste em usar outro arquivo de docker compose (_**compose-dev.yml**_) o qual se conecta a outro arquivo Dockerfile (_**Dockerfile-dev**_) configurados de forma que permita que as alterações de código feitas no host, reflita, em tempo real, dentro do container e vice-versa.
Esse modo facilita para quem está desenvolvendo (daí o sobrenome "modo dev") ou fazendo alterações no projeto, pois não precisa ficar fazendo rebuild a cada alteração, nem reiniciar o container, bastando, apenas, fazer uma nova requisição para o endpoint desejado. Lógico que em produção seriaa usado o arquivo compose do modo NORMAL por exemplo.
========= COMO ISSO FUNCIONA =========
Como menionado, o **compose-dev.yml** usa como contexto de build o arquivo **Dockergile-dev**. Esse Dockerfile-dev tem nada menos ue um comando diferente no entrypoint, que é o comando `npm run dev`, ao invés de `npm stat`. Esse comando _npm run dev_ que executa o script que tem **nodemon** no `package.json` no lugar do **node**.
O **_nodemon_** é uma ferremnta que executar script JS mas monitora em tempo real mudanças ocorridas no código e, automaticamente, reinicia o servidor quado qualquer alteração é salva.
No **compose-dev.yml** também foi adicionado um volume do tipo **bind mount**. Isso que permite vincular a pasta raiz do projeto entre host e container, sem precisar fazer rebuild toda hora só pra desenvolvimento. As mudanças em qualquer parte do projeto no host, refletem, diretamente, dento do container e VICE-VERSA.
========= COMO USAR =========
Para executar o sofware nesse modo, faça as seguintes etapas (as mesmas do modo NORMAL com "pífias" exceções):
**_1. Verifique o arquivo compose-dev.yml_**
Considere todas observações apresetadas no modo NORMAL.➿
Aqui só trocamos o arquivo do docker compose ( que passa a ser `compose-dev.yml`)
**_2. Execute o docker compose_**
Aqui também só muda um pouco a sintaxe. Como é um arquivo diferente do padrão, tem que usar a flag -f passando o caminho para o arquivo do docker compose que deseja usar. Se esquecer dessa flag , o docker compose assume o arquivo errado (compose.yml) e irá levantar containers do modo NORMAL, ao invés de NORMAL + MODO DEV:
~~~shell
docker compose -f compose-dev.yml up -d
~~~
Note: Pra descer container também use a flag -f , hein. 👁️
**_3. Localize o container criado_**
Da mesma maneira já explicada no modo NORMAL. ➿
O nome do container deixei ser gerado automaticamente, com estrutura padrão, formado por:
`nome_da_PASTA + nome do SERVIÇO + um NÚMERO`
**_4. Identifique o IP do gateway do container_**
Da mesma maneira já explicado no modo NORMAL.➿
Resumindo...
~~~shell
sudo docker network inspect < nome ou id da rede > | grep Gateway
~~~
**_5. Faça requisição para um endpoint_**
Da mesma maneira já explicado no modo NORMAL.➿
Use o IP do Gateway obtido na etapa anterior.
Escolha um dos endpoints que listei mais à frente, na seção [Endpoints](#endpoints).
Exemplo com endpoint `products` seria: `<IP DO GATEWAY>:3001/products`
#### <ins> ☑️ COM FRONTEND </ins>
Esse modo consiste em excutar a API (esse repositório atual em que estamos) juntamente com o frontend (outro repositório mencionado no começo da documentação). O backend continuará executando na porta 3001 do IP do Gateway, e o frontend executará na porta 3000 do IP do Gateway.
Mas o frontend consegue ser acessado, TAMBÈM, pelo localhost. Então, se usar a URL localhost:3000, já consegue acessar tudo (front, back e databse) de uma vez śó.
No entanto, **há pré-requisitos** para se usar esse modo, devido as configurações feitas no arquivo do docker compose. Caso não sejam atendidos, o modo não funionará. Os pré-requisitos são: 1 - Baixar/clonar previamente o repositório de frontend, 2 - O nome da pasta raiz do repositório de frontend precisa ser "games-store-frontend", 3 - A pasta precisa estar na pasta PAI deste projeto aqui (backend) 4 - Garantir todas permisões de excução recursiva. A seguir vou dar a opção de como preencher esses requistos de uma vez só, e de duas maneiras. 😺
========= COMO ATENDER PRÉ-REQUISITOS =========
As duas que acho melhor de conseguir isso são:
A) Usando o git clone e depois um simples comando:
* Clone o repostiório frontend ([Link do repo](https://github.com/becauro/games-store-front))
* Depois , para evitar problema, dê permissão recursiva para o repositório baixado: `chmod -R 777 games-store-front`
Essas duas etapas já deveria, automaticamente, preencher todas as condições preestabelecidas.
Mas se por algum motivo não puder usar git, tem a opção dois abaixo.
B) Obter frontend sem git clone, usando meu script shell:
Acho que forma mais fácil e rápida de preencher todos os requisitos sem usar git, é executando script em shell (em padrão POSIX) que criei: `download_front.sh`. hehe 🥰
Esse script encontra-se na raíz do projeto. O que ele basicamente faz é baixar, extrair, mover para a pasta certa, renomear e configura as permissões necessárias para o repositório frontend baixado.
Portanto, se for utilizá-lo, não esqueça de o executar **com privilêgios elevados** (sudo , root e etc) e verifique se na sua saída são emitidos vários "OK" em cada etapa.
Se houver alguma marcação de "FAIL" após a execução do script, siga instruções apresentadas e execute o script novamente, se for o caso.
========= COMO USAR =========
Com o repositório frontend baixado em uma pasta acima da que se encontramos, seguimos as mesmas etapas descritas nos modos anteriores. Aqui vai um "resumo do resumo" delas.
São praticamente as mesmas etapas do modo NORMAL com pequenas exceções:
**_1. Verifique o arquivo compose-with-front.yml_**
Considere todas observações apresentadas no modo NORMAL. ➿
Só trocamos o arquivo do docker compose, que passa a ser o `compose-with-front.yml`.
**_2. Execute o docker compose_**
Aqui também só muda um pouco a sintaxe. Como é um arquivo diferente do padrão, tem que usar a flag -f passando o caminho para o arquivo do docker compose que deseja usar. Se esquecer dessa flag , o docker compose assume o arquivo errado (compose.yml) e irá levantar containers do modo NORMAL, ao invés de COM FRONTEND:
~~~shell
docker compose -f compose-with-front.yml up -d
~~~
Note: Pra descer container também use a flag -f , hein. 👁️
**_3. Localize o container criado_**
Da mesma maneira já explicada no modo NORMAL. ➿
O nome do container deixei ser gerado automaticamente, com estrutura padrão, formado por:
`nome_da_PASTA + nome do SERVIÇO + um NÚMERO`
**_4. Identifique o IP do gateway do container_**
Da mesma maneira já explicado no modo NORMAL. ➿
Resumindo...
~~~shell
sudo docker network inspect < nome ou id da rede > | grep Gateway
~~~
**_5. Faça requisição para um endpoint_**
Da mesma maneira já explicado no modo NORMAL.➿
Use o IP do Gateway obtido na etapa anterior.
Escolha um dos endpoints que listei mais à frente, na seção [Endpoints](#endpoints).
Exemplo com endpoint `products` seria: `<IP DO GATEWAY>:3001/products`
#### <ins> ☑️ COM FRONTEND + MODO DEV </ins>
Esse modo herda a mesmas funcionalidades **E PRÉ_REQUISITOS** do modo COM FRONTEND, mas com adição das características de **"modo-dev"** já explicadas no modo NORMAL + MODO DEV.
Ou seja, você terá containers backend e frontend juntos, mas poderá aplicar alterações a partir do host, e ver mudanças repercurtirem em tempo real devido ao **nodemon**. Mais detalhes: os mesmos descritos no modo NORMAL + MODO DEV. Bom, qualquer coisa leia novamente o modo NORMAL + MODO DEV ali em cima e modo COM FRONTEND.
========= COMO USAR =========
Com os **PRÉ_REQUISITOS** atendidos seguimos as mesmas etapas descritas nos modos anteriores. Aqui vai um "resumo do resumo" delas.
São praticamente as mesmas etapas do modo NORMAL com pequenas exceções:
**_1. Verifique o arquivo compose-dev-with-front.yml_**
Considere todas observações apresentadas no modo NORMAL. ➿
Só trocamos o arquivo do docker compose (que passa a ser `compose-dev-with-front.yml`)
**_2. Execute o docker compose_**
Aqui também só muda um pouco a sintaxe. Como é um arquivo diferente do padrão, tem que usar a flag -f passando o caminho para o arquivo do docker compose que deseja usar. Se esquecer dessa flag , o docker compose assume o arquivo errado (compose.yml) e irá levantar containers do modo NORMAL, ao invés de COM FRONTEND + MODO DEV:
~~~shell
docker compose -f compose-dev-with-front.yml up -d
~~~
Note: Pra descer container também use a flag -f , hein. 👁️
**_3. Localize o container criado_**
Da mesma maneira já explicada no modo NORMAL. ➿
O nome do container deixei ser gerado automaticamente, com estrutura padrão, formado por:
`nome_da_PASTA + nome do SERVIÇO + um NÚMERO`
**_4. Identifique o IP do gateway do container_**
Da mesma maneira já explicado no modo NORMAL. ➿
Resumindo...
~~~shell
sudo docker network inspect < nome ou id da rede > | grep Gateway
~~~
**_5. Faça requisição para um endpoint_**
Da mesma maneira já explicado no modo NORMAL.➿
Use o IP do Gateway obtido na etapa anterior.
Escolha um dos endpoints que listei mais à frente, na seção [Endpoints](#endpoints).
Exemplo com endpoint `products` seria: `<IP DO GATEWAY>:3001/products`
### Manualmente (Via HOST)
--------------------------------------------------------------------------------------------------------------------------------------------------------
Instalado os requisitos e as dependências necessárias, basta seguir as seguintes etapas:
**1. Variáveis de ambiente**
Existe um arquivo na raiz do projeto chamado `.env.model`.
Apesar de já explicado no tópico "Requisitos para execução da API", não custa ratificar aqui.
As configurações do projeto também podem ser alteradas nesse arquivo, adicionando o valor desejado após o sinal de igual (=) em cada variável.
**Lógico que não é obrigado essa alteração**, desde que não exista problemas com as configurações padrões do projeto.
Se for usar o arquivo, terá que renomea-lo parar `.env`.
As variáveis do arquivo .env.model são as seguintes:
_*PORT*_, _*DB_NAME*_, _*DB_HOST*_ e _*DB_PORT*_.
**PORT** diz respeito a porta em que o servidor irá rodar. Se nada for atribuido a essa variável, o servidor rodará na porta `3001`.
**DB_NAME** refere-se ao nome do banco de dados que será criado. Se nada for atribuido, o nome do banco será `GamesStore`.
**DB_HOST** refere-se ao local (hostname ou IP) do Banco de Dados. Se nada for atribuído, será considerado `localhost`.
**DB_PORT** poderá receber a porta onde se encontra o Banco de Dados. Se nada for atribuído, será considerado a porta `27017`.
**2. Banco de Dados MongoDB**
Coloque em execução o software servidor de banco de dados MongoDB.
**3. Execute o script para importar dados para o banco de dados**
Para que essa API retorne dados na rota _*products*_, precisa, obviamente, ter dados no banco chamado _*GamesStore*_ (ou no banco com nome que você definiu na variável DB_NAME no arquivo .env) na coleção ("tabela") _*products*_. Por isso criei um shell script `models/db-import-for-host.sh` para automatizar a importação de dados, o qual cria o banco, a collection e importa dados que estão em outro script (arquivo `models/dataTestForDb.js`) para o banco criado. Assim, quando requisitado com GET no ENDPOINT _*products*_ será retornado esses dados previamente importados no banco, isentando a necessidade de criá-los manualmente para testar a API. **Se não quiser usar esse script, ok, a API funciona**, mas sem retornar dados; a menos que, alternativamente, cadastre-os, manualmente, usando a rota de POST, por exemplo.
**Note**: Não criei script (importador de dados) para a rota _*sales*_. Se requisitares algo para esse ENDPOINT, sem ter dados na collection _*sales*_ no banco, não terás retorno de dados.
**Note 2**: Os dados que se encontram no arquivo `models/dataTestForDb.js`, foram obtidos do [ENDPOINT de produtos para gamers, de uma API pública do Mercado Livre](https://api.mercadolibre.com/sites/MLB/search?category=MLB1144). Apenas modifiquei alguns pontos e parâmetros para se adaptar ao meu projeto.
**4. Instale as dependências**
Estando com acesso a internet e dentro da pasta raíz do projeto, execute o comando:
`npm install`
**5. Execute o projeto**
Estando com acesso a internet e dentro da pasta raíz do projeto, execute o comando:
`npm start`
Se tudo ocorreu bem, após executar esse comando o servidor da API do projeto estará disponível para uso. Faça as requisições.
**6. Fazendo requisições**
Use algum software cliente de API (ex.: Postman, Insomnia e etc) e faça as requisições para os ENDPOINTs usando a URL **http://localhost:3001**
Se for o caso, não esqueça de substituir `porta 3001` pela porta que você definiu na variável PORT do arquivo `.env`.
Eu apenas modifiquei alguns nomes de parâmetros nesses dados para se adaptar ao que eu queria. E lógico que fiz isso de forma automática, visto que são muito dados.
## Endpoints
<a href="#sumario">Sumário</a>

View file

@ -1,49 +0,0 @@
services:
frontend:
build:
context: ../games-store-front
dockerfile: ../games-store-front/Dockerfile-with-back
ports:
- 3000:3000
depends_on:
- backend
environment:
- REACT_APP_API_HOST=backend
- REACT_APP_API_PORT=3001
- REACT_APP_WITH_BACK=true
- BROWSER=none
volumes:
- ../games-store-front/.:/myapp
networks:
- games-store-1
backend:
build:
context: .
dockerfile: ./Dockerfile-dev
ports:
- 3001:3001 # A porta da direita precisa ser igual a da variável PORT.
depends_on:
- database
environment:
- DB_HOST=database # Se mudar valor dessa variável, tem que mudar o nome do serviço "database" igualmente E VICE-VERSA; remover nem pensar.
- DB_NAME=GamesStore
- PORT=3001
volumes:
- .:/myapp
networks:
- games-store-1
- games-store-2
database:
build: models/
networks:
- games-store-2
networks:
games-store-1:
name: games-store-front
games-store-2:
name: games-store-db

View file

@ -1,29 +0,0 @@
services:
backend:
build:
context: .
dockerfile: ./Dockerfile-dev
ports:
- 3001:3001 # A porta da direita precisa ser igual a da variável PORT.
depends_on:
- database
environment:
- DB_HOST=database # Se mudar valor dessa variável, tem que mudar o nome do serviço "database" igualmente E VICE-VERSA; remover nem pensar.
- DB_NAME=GamesStore
- PORT=3001
volumes:
- .:/myapp
networks:
- games-store
database:
build: models/
networks:
- games-store
networks:
games-store:
name: games-store

View file

@ -1,43 +0,0 @@
services:
frontend:
build:
context: ../games-store-front
dockerfile: ../games-store-front/Dockerfile-with-back
ports:
- 3000:3000
depends_on:
- backend
environment:
- REACT_APP_API_HOST=backend
- REACT_APP_API_PORT=3001
- REACT_APP_WITH_BACK=true
- BROWSER=none
networks:
- games-store-1
backend:
build: .
ports:
- 3001:3001 # A porta da direita precisa ser igual a da variável PORT.
depends_on:
- database
environment:
- DB_HOST=database # Se mudar valor dessa variável, tem que mudar o nome do serviço "database" igualmente E VICE-VERSA; remover nem pensar.
- DB_NAME=GamesStore
- PORT=3001
networks:
- games-store-1
- games-store-2
database:
build: models/
networks:
- games-store-2
networks:
games-store-1:
name: games-store-front
games-store-2:
name: games-store-db

View file

@ -1,25 +0,0 @@
services:
backend:
build: .
ports:
- 3001:3001 # A porta da direita precisa ser igual a da variável PORT.
depends_on:
- database
environment:
- DB_HOST=database # Se mudar valor dessa variável, tem que mudar o nome do serviço "database" igualmente E VICE-VERSA; remover nem pensar.
- DB_NAME=GamesStore
- PORT=3001
networks:
- games-store
database:
build: models/
networks:
- games-store
networks:
games-store:
name: games-store

View file

@ -8,13 +8,6 @@ const OK = 200;
router.get('/', rescue(async (_req, res) => {
const result = await products.getAll();
res.status(result.status).json({ products: [...result.productS] });
// The following comment is for dev debugging (e.g, To test whether nodemon is working):
/*
res.status(result.status).json({products:[{_id:"63b5f85dae0a4537077d63cc", name:"MICHELLLL", price:6499, thumbnail:"http://http2.mlstatic.com/D_799755-MLA47058389754_082021-I.jpg", description:"",quantity:7}]});
*/
}));
router.get('/search', rescue(async (req, res) => {
@ -99,4 +92,4 @@ router.delete('/:id', rescue(async (req, res) => {
res.status(OK).json({ id: _id, name, quantity });
}));
module.exports = router;
module.exports = router;

View file

@ -1,358 +1,352 @@
db = db.getSiblingDB(mongo_name);
db.products.drop();
db.products.insertMany(
[
{
"name": "Sony Playstation 5 825gb Digital Edition Cor Branco E Preto",
"price": 6499,
"thumbnail": "http://localhost:3001/D_799755-MLA47058389754_082021-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_799755-MLA47058389754_082021-I.jpg",
"description": "",
"quantity": 7
},
{
"name": "Cyberpunk 2077 Standard Edition Cd Projekt Red Ps4 Físico",
"price": 48.2,
"thumbnail": "http://localhost:3001/D_758983-MLA46557070313_062021-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_758983-MLA46557070313_062021-I.jpg",
"description": "",
"quantity": 85
},
{
"name": "Microsoft Xbox Series S 512gb Standard Cor Branco",
"price": 2580,
"thumbnail": "http://localhost:3001/D_635605-MLA44492818317_012021-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_635605-MLA44492818317_012021-I.jpg",
"description": "",
"quantity": 12
},
{
"name": "Fone De Ouvido Gamer Haiz Alpha 1804 Preto E Azul",
"price": 66.87,
"thumbnail": "http://localhost:3001/D_627994-MLA43269928138_082020-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_627994-MLA43269928138_082020-I.jpg",
"description": "",
"quantity": 7
},
{
"name": "Microsoft Xbox Series X 1tb Standard Cor Preto",
"price": 5896,
"thumbnail": "http://localhost:3001/D_794435-MLA45046407331_032021-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_794435-MLA45046407331_032021-I.jpg",
"description": "",
"quantity": 44
},
{
"name": "Grand Theft Auto V Standard Edition Rockstar Games Xbox 360 Físico",
"price": 159.89,
"thumbnail": "http://localhost:3001/D_857968-MLA44384297377_122020-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_857968-MLA44384297377_122020-I.jpg",
"description": "",
"quantity": 325
},
{
"name": "Sony Playstation 5 825gb Standard Cor Branco E Preto",
"price": 6815,
"thumbnail": "http://localhost:3001/D_669939-MLA44492818154_012021-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_669939-MLA44492818154_012021-I.jpg",
"description": "",
"quantity": 9
},
{
"name": "Grand Theft Auto V Standard Edition Rockstar Games Ps4 Físico",
"price": 134.9,
"thumbnail": "http://localhost:3001/D_938202-MLA44384297373_122020-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_938202-MLA44384297373_122020-I.jpg",
"description": "",
"quantity": 115
},
{
"name": "Nintendo Switch Lite 32gb Standard Cor Amarelo",
"price": 1699,
"thumbnail": "http://localhost:3001/D_983434-MLA46868661458_072021-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_983434-MLA46868661458_072021-I.jpg",
"description": "",
"quantity": 7
},
{
"name": "Console Tectoy Sega Master System Evolution Standard Cor Azul",
"price": 259.9,
"thumbnail": "http://localhost:3001/D_755481-MLA32731813512_112019-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_755481-MLA32731813512_112019-I.jpg",
"description": "",
"quantity": 45
},
{
"name": "Headset Over-ear Gamer Hyperx Cloud Stinger Core Black",
"price": 239,
"thumbnail": "http://localhost:3001/D_696228-MLA40782018138_022020-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_696228-MLA40782018138_022020-I.jpg",
"description": "",
"quantity": 1680
},
{
"name": "Marvel's Spider-man: Miles Morales Standard Edition Sony Ps4 Físico",
"price": 177.99,
"thumbnail": "http://localhost:3001/D_944704-MLA44963396558_022021-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_944704-MLA44963396558_022021-I.jpg",
"description": "",
"quantity": 10
},
{
"name": "Console Luatek Lps-505 Cor Cinza",
"price": 91.43,
"thumbnail": "http://localhost:3001/D_978123-MLA45375278666_032021-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_978123-MLA45375278666_032021-I.jpg",
"description": "",
"quantity": 168
},
{
"name": "Sony Playstation 4 1tb Standard Cor Preto Onyx",
"price": 3699,
"thumbnail": "http://localhost:3001/D_985484-MLA40671062848_022020-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_985484-MLA40671062848_022020-I.jpg",
"description": "",
"quantity": 15
},
{
"name": "Marvel's Spider-man Game Of The Year Edition Sony Ps4 Físico",
"price": 136,
"thumbnail": "http://localhost:3001/D_663372-MLA43440081326_092020-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_663372-MLA43440081326_092020-I.jpg",
"description": "",
"quantity": 6
},
{
"name": "Microsoft Xbox One S 1tb Two-controller Bundle Cor Branco",
"price": 3700,
"thumbnail": "http://localhost:3001/D_987070-MLA40186930094_122019-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_987070-MLA40186930094_122019-I.jpg",
"description": "",
"quantity": 2
},
{
"name": "Fone De Ouvido Gamer Haiz Alpha 1804 Preto E Vermelho",
"price": 66.87,
"thumbnail": "http://localhost:3001/D_975756-MLA43269941057_082020-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_975756-MLA43269941057_082020-I.jpg",
"description": "",
"quantity": 135
},
{
"name": "Console Xbox Series S Com Xbox Game Pass Ultimate 3 Meses",
"price": 2799,
"thumbnail": "http://localhost:3001/D_756118-MLB47964495457_102021-O.jpg",
"thumbnail": "http://http2.mlstatic.com/D_756118-MLB47964495457_102021-O.jpg",
"description": "",
"quantity": 200
},
{
"name": "Minecraft Standard Edition Microsoft Xbox 360 Físico",
"price": 189.89,
"thumbnail": "http://localhost:3001/D_901567-MLA45072720953_032021-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_901567-MLA45072720953_032021-I.jpg",
"description": "",
"quantity": 303
},
{
"name": "Microsoft Xbox One S 1tb Pro Evolution Soccer 2020 Cor Branco",
"price": 3200,
"thumbnail": "http://localhost:3001/D_960717-MLA40540552104_012020-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_960717-MLA40540552104_012020-I.jpg",
"description": "",
"quantity": 1
},
{
"name": "Fone De Ouvido Over-ear Gamer Tedge Gt-g10 Preto Com Luz Led",
"price": 129,
"thumbnail": "http://localhost:3001/D_867559-MLA46711199568_072021-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_867559-MLA46711199568_072021-I.jpg",
"description": "",
"quantity": 2648
},
{
"name": "Console Super Arcade Box Retro Pro 16gb Retro Pro Cor Preto",
"price": 409.89,
"thumbnail": "http://localhost:3001/D_922947-MLA41890369054_052020-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_922947-MLA41890369054_052020-I.jpg",
"description": "",
"quantity": 458
},
{
"name": "Fifa 22 Standard Edition Electronic Arts Ps4 Físico",
"price": 249,
"thumbnail": "http://localhost:3001/D_946325-MLA48240317465_112021-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_946325-MLA48240317465_112021-I.jpg",
"description": "",
"quantity": 11
},
{
"name": "Sony Playstation 4 Slim 1tb Mega Pack: Grand Theft Auto V Premium Edition/death Stranding/the Last Of Us Remastered Cor Preto Onyx",
"price": 4986,
"thumbnail": "http://localhost:3001/D_781136-MLA42123426178_062020-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_781136-MLA42123426178_062020-I.jpg",
"description": "",
"quantity": 1
},
{
"name": "Headset Over-ear Gamer Hyperx Cloudx Stinger Core Preto E Verde",
"price": 239,
"thumbnail": "http://localhost:3001/D_984469-MLA44396908884_122020-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_984469-MLA44396908884_122020-I.jpg",
"description": "",
"quantity": 1161
},
{
"name": "Console Playstation 5 Disco - 2 Controles Ps5 Garantia 1 Ano",
"price": 8499,
"thumbnail": "http://localhost:3001/D_674388-MLB46725158008_072021-O.jpg",
"thumbnail": "http://http2.mlstatic.com/D_674388-MLB46725158008_072021-O.jpg",
"description": "",
"quantity": 1
},
{
"name": "Super Mario 3d World + Bowsers Fury Standard Edition Nintendo Switch Físico",
"price": 412.9,
"thumbnail": "http://localhost:3001/D_710282-MLA45076348090_032021-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_710282-MLA45076348090_032021-I.jpg",
"description": "",
"quantity": 37
},
{
"name": "Console Genérica Sup Cor Preto",
"price": 79,
"thumbnail": "http://localhost:3001/D_903336-MLA45579893036_042021-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_903336-MLA45579893036_042021-I.jpg",
"description": "",
"quantity": 28
},
{
"name": "Fone De Ouvido Over-ear Gamer Havit H2002d Vermelho",
"price": 248,
"thumbnail": "http://localhost:3001/D_738573-MLA42668147408_072020-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_738573-MLA42668147408_072020-I.jpg",
"description": "",
"quantity": 89
},
{
"name": "Nintendo Switch Lite 32gb Standard Cor Azul",
"price": 1808,
"thumbnail": "http://localhost:3001/D_757994-MLA46868652599_072021-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_757994-MLA46868652599_072021-I.jpg",
"description": "",
"quantity": 2
},
{
"name": "Mortal Kombat 11 Standard Edition Warner Bros. Ps4 Físico",
"price": 58.29,
"thumbnail": "http://localhost:3001/D_965714-MLA46478134635_062021-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_965714-MLA46478134635_062021-I.jpg",
"description": "",
"quantity": 17
},
{
"name": "Video Game Stick 4k 10mil Jogos Retro 2 Controles Sem Fio",
"price": 529.7,
"thumbnail": "http://localhost:3001/D_775807-MLB47763731738_102021-O.jpg",
"thumbnail": "http://http2.mlstatic.com/D_775807-MLB47763731738_102021-O.jpg",
"description": "",
"quantity": 250
},
{
"name": "Controle Joystick Feir Fr-305 Preto",
"price": 66.25,
"thumbnail": "http://localhost:3001/D_992783-MLA42269190611_062020-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_992783-MLA42269190611_062020-I.jpg",
"description": "",
"quantity": 140
},
{
"name": "Console Genérica Sup Cor Vermelho",
"price": 89,
"thumbnail": "http://localhost:3001/D_749429-MLA45579893035_042021-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_749429-MLA45579893035_042021-I.jpg",
"description": "",
"quantity": 30
},
{
"name": "Pokémon Sword Standard Edition Nintendo Switch Físico",
"price": 366,
"thumbnail": "http://localhost:3001/D_726594-MLA44342030006_122020-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_726594-MLA44342030006_122020-I.jpg",
"description": "",
"quantity": 5
},
{
"name": "Sony Playstation 4 Slim 1tb Mega Pack: The Last Of Us Remastered/god Of War/horizon Zero Dawn Complete Edition Cor Preto Onyx",
"price": 5149,
"thumbnail": "http://localhost:3001/D_751430-MLA40694328907_022020-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_751430-MLA40694328907_022020-I.jpg",
"description": "",
"quantity": 36
},
{
"name": "Novo Xbox Series X 1 Tb Ssd - Garantia 1 Ano - Pode Retirar",
"price": 6999,
"thumbnail": "http://localhost:3001/D_719264-MLB44478664185_012021-O.jpg",
"thumbnail": "http://http2.mlstatic.com/D_719264-MLB44478664185_012021-O.jpg",
"description": "",
"quantity": 1
},
{
"name": "Lego Marvel Super Heroes 2 Warner Bros. Ps4 Físico",
"price": 72.98,
"thumbnail": "http://localhost:3001/D_605211-MLA47492769182_092021-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_605211-MLA47492769182_092021-I.jpg",
"description": "",
"quantity": 89
},
{
"name": "Console Genérica Sup Cor Azul",
"price": 89,
"thumbnail": "http://localhost:3001/D_893604-MLA45579893038_042021-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_893604-MLA45579893038_042021-I.jpg",
"description": "",
"quantity": 21
},
{
"name": "Fone De Ouvido Over-ear Gamer Haiz Deneb Preto E Vermelho Com Luz Vermelho Led",
"price": 85.94,
"thumbnail": "http://localhost:3001/D_648768-MLA43139122238_082020-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_648768-MLA43139122238_082020-I.jpg",
"description": "",
"quantity": 149
},
{
"name": "Mini Super Nintendo 10 Mil Jogos 2 Controles Envio Imediato!",
"price": 629,
"thumbnail": "http://localhost:3001/D_828458-MLB47481373195_092021-O.jpg",
"thumbnail": "http://http2.mlstatic.com/D_828458-MLB47481373195_092021-O.jpg",
"description": "",
"quantity": 1
},
{
"name": "Fifa 22 Standard Edition Electronic Arts Xbox One Físico",
"price": 277,
"thumbnail": "http://localhost:3001/D_711937-MLA48240412033_112021-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_711937-MLA48240412033_112021-I.jpg",
"description": "",
"quantity": 3
},
{
"name": "Playstation 5 C\\ Disco - Ps5 - Garantia 1 Ano - Pode Retirar",
"price": 8099,
"thumbnail": "http://localhost:3001/D_671237-MLB44476073512_012021-O.jpg",
"thumbnail": "http://http2.mlstatic.com/D_671237-MLB44476073512_012021-O.jpg",
"description": "",
"quantity": 1
},
{
"name": "Fone De Ouvido Over-ear Logitech H111 Cinza",
"price": 83.68,
"thumbnail": "http://localhost:3001/D_627846-MLA41179103761_032020-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_627846-MLA41179103761_032020-I.jpg",
"description": "",
"quantity": 51
},
{
"name": "Super Mario Odyssey Standard Edition Nintendo Switch Físico",
"price": 404.99,
"thumbnail": "http://localhost:3001/D_867031-MLA40865317687_022020-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_867031-MLA40865317687_022020-I.jpg",
"description": "",
"quantity": 1
},
{
"name": "Nintendo Switch Lite 32gb Standard Cor Azul-turquesa",
"price": 1835,
"thumbnail": "http://localhost:3001/D_608559-MLA46868652583_072021-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_608559-MLA46868652583_072021-I.jpg",
"description": "",
"quantity": 1
},
{
"name": "Microsoft Xbox One S 500gb Standard Cor Branco",
"price": 2790,
"thumbnail": "http://localhost:3001/D_820192-MLA40655732619_022020-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_820192-MLA40655732619_022020-I.jpg",
"description": "",
"quantity": 1
},
{
"name": "Fone De Ouvido Over-ear Gamer Knup Kp-397 Preto E Vermelho",
"price": 84.9,
"thumbnail": "http://localhost:3001/D_676151-MLA40944956212_022020-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_676151-MLA40944956212_022020-I.jpg",
"description": "",
"quantity": 374
},
{
"name": "The Legend Of Zelda: Skyward Sword Hd Standard Edition Nintendo Switch Físico",
"price": 315,
"thumbnail": "http://localhost:3001/D_906898-MLA46792568061_072021-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_906898-MLA46792568061_072021-I.jpg",
"description": "",
"quantity": 4
},
{
"name": "Nintendo Switch Lite 32gb Standard Cor Cinza",
"price": 1866,
"thumbnail": "http://localhost:3001/D_977008-MLA46868671160_072021-I.jpg",
"thumbnail": "http://http2.mlstatic.com/D_977008-MLA46868671160_072021-I.jpg",
"description": "",
"quantity": 1
}
]);
]

View file

@ -1,210 +0,0 @@
#!/bin/sh
printf "STARTING script ...\n\n";
printf "1 - Verifying if unzip is installed ...\n\n";
unzip -v > /dev/null 2>&1;
if test $? -ne 0 ; then # bash POSIX >> if [[ $(test $? -ne 0) ]]
printf " It seems unzip is not installed. Let's install it now ...\n\n" ;
printf " 1.1 - Installing unzip ...\n\n";
apt-get install unzip -y > /dev/null 2>&1 ;
if ! test $? -eq 0 ; then
printf ' FAIL - Installation FAILED. \n"
printf " Possible solutions here are:\n\n" ;
printf " # Please, execute this script with elevated privileges
printf " # OR: trying install unzip manually then go back here %s \n\n' ':)' ;
printf "See ya! \n\n";
exit 1;
else
printf " OK - unzip INSTALLED\n\n";
fi
else
printf " OK - unzip is ALREADY installed.\n\n";
fi
printf "2 - Verifying if repository is already downloaded ...\n\n" ;
ls front-repo > /dev/null 2>&1
if test $? -ne 0; then
#######
ls ../games-store-front-main > /dev/null 2>&1
if test $? -ne 0; then
ls ../games-store-front > /dev/null 2>&1
if test $? -ne 0; then
printf " Downloading repository ...\n\n" ;
wget -c -O front-repo https://github.com/becauro/games-store-front/archive/refs/heads/main.zip > /dev/null 2>&1 ;
if test $? -ne 0 ; then
printf " FAIL - download FAILED. \n"
printf " Possible solutions here are:\n\n" ;
printf " # Check parent folder permissions then execute this script again\n"
printf " # OR: trying to download the frontend repo manually at https://github.com/becauro/games-store-front/archive/refs/heads/main.zip and rename it to 'front-repo' \n\n" ;
printf " When you get it done, execute this script again\n\n"
printf "Exiting...! \n\n";
exit 1;
else
printf " OK - Repo downloaded!\n\n" ;
fi
else
printf " OK - Repo ALREADY downloaded!\n\n" ;
fi
else
printf " OK - Repo ALREADY downloaded!\n\n" ;
fi
#######
else
printf " OK - Repo ALREADY downloaded!\n\n" ;
fi
printf "3 - Verifying unziping ...\n\n";
ls ../games-store-front-main > /dev/null 2>&1
if test $? -ne 0; then
ls ../games-store-front > /dev/null 2>&1
if test $? -ne 0; then
printf "Unziping the file ... \n\n" ;
unzip front-repo -d .. > /dev/null 2>&1 ;
if test $? -ne 0 ; then
printf " FAIL - unziping FAILED.\n"
printf " Possible solutions --- If you are under the 'games-store-back' folder:\n\n" ;
printf " # Trying unzip the file manually.\n"
printf " # OR: If the folder is already extrated, rename it to 'games-store-front'\n\n"
print " When you get it done, execute this script again\n\n"
printf " Exiting...! \n\n";
exit 1;
else
printf " OK - file unziped! \n\n" ;
fi
else
printf " OK - file ALREADY unziped! \n\n" ;
fi
else
printf " OK - file ALREADY unziped! \n\n" ;
fi
printf "4 - Deleting unziped file ... \n\n" ;
rm front-repo > /dev/null 2>&1 ;
if test $? -ne 0 ; then
printf " WARNING - Deletion FAILED. Maybe you already did it by yourself.\n"
printf " If you not, possible solutions here are: \n\n"
printf " # Execute this script with elevated privileges \n"
printf " # OR: Trying delete the file manually \n\n" ;
printf " NOTE: This step is being ignored. \n\n";
else
printf " OK - file Deleted! \n\n" ;
fi
printf "5 - Checking the extracted folder name... \n\n" ;
ls ../games-store-front > /dev/null 2>&1
if test $? -ne 0; then
printf " Renaming extracted folder ... \n\n" ;
mv ../games-store-front-main ../games-store-front > /dev/null 2>&1 ;
if test $? -ne 0 ; then
printf " FAIL - Renaming FAILED. \n"
printf " Possible solutions here are: \n\n"
printf " # Please, trying to rename the extracted folder to 'games-store-front' MANUALLY \n\n" ;
printf "\nExiting...! \n\n";
exit 1;
else
printf " OK - Folder renamed ! \n\n" ;
fi
else
printf " OK - file ALREADY renamed! \n\n" ;
fi
printf "6 - Changing folder permissions ... \n\n" ;
chmod -R 777 ../games-store-front > /dev/null 2>&1 ;
if test $? -ne 0 ; then
printf " WARNING - Permissions changing FAILED. Maybe you already did it by yourself.\n"
printf " If you not, possible solutions here are: \n\n"
printf " # Execute this script with elevated privileges \n"
printf " # Try set folder permissions manually.\n"
printf " Under the 'games-store-back' folder, just type this command: chmod -R 777 ../games-store-front\n\n"
printf "=========\n"
else
printf " OK - Folder permissions set ! \n\n" ;
fi
printf "END of script!\n\n"
printf "Please, check the parent folder.\n\n"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

View file

@ -1,27 +1,24 @@
const express = require('express');
const cors = require('cors');
require('dotenv').config();
const path = require('path');
const products = require('./controllers/products');
const sales = require('./controllers/sales');
const errorMiddleware = require('./utils/errorMiddleware');
const app = express();
const PORT = process.env.PORT || 3001;
const PORT = process.env.PORT || 3000;
app.use(express.json());
app.use(cors());
app.use(express.static(path.join(`${__dirname}`, '/images')));
app.use('*', cors());
app.use('/products', products);
app.use('/sales', sales);
app.all('*', (_req, res) => res.status(404).send('Router not found'));
app.all('*', (req, res) => res.status(404).send('Router not found'));
app.use(errorMiddleware);
app.listen(PORT, () => {
console.log(`Online na porta ${PORT}`);
});
});

View file

@ -1,3 +0,0 @@
.env
Dockerfile*
.dockerignore

View file

@ -1,10 +0,0 @@
FROM mongo:4.4.6
ENV DB_NAME GamesStore
RUN mkdir /DataForImport
COPY dataTestForDb.js /DataForImport/
COPY db-import.sh /docker-entrypoint-initdb.d/
EXPOSE 27017

View file

@ -1,15 +1,11 @@
const { MongoClient } = require('mongodb');
require('dotenv').config();
const OPTIONS = {
useNewUrlParser: true,
useUnifiedTopology: true,
};
const MONGO_HOST = process.env.DB_HOST || "localhost";
const MONGO_NAME = process.env.DB_NAME || "GamesStore";
const MONGO_PORT = process.env.DB_PORT || 27017;
const MONGO_DB_URL = `mongodb://${MONGO_HOST}:${MONGO_PORT}/${MONGO_NAME}`;
const MONGO_DB_URL = process.env.DB_URL;
let db = null;
@ -24,5 +20,5 @@ const connection = () => (db
console.log(err);
process.exit(1);
}));
module.exports = connection;
module.exports = connection;

View file

@ -1,7 +0,0 @@
#!/bin/bash
mongo --eval "var mongo_name = '$DB_NAME'" dataTestForDb.js > /dev/null
test $? -eq 0 || mongo --eval "var mongo_name = 'GamesStore'" dataTestForDb.js > /dev/null
echo "SCRIPT db-import.sh EXECUTADO"

View file

@ -1,9 +0,0 @@
#!/bin/bash
cd /DataForImport
mongo --eval "var mongo_name = '$DB_NAME'" dataTestForDb.js > /dev/null
test $? -eq 0 || mongo --eval "var mongo_name = 'GamesStore'" dataTestForDb.js > /dev/null
echo "EXECUTADO SCRIPT db-import.sh"

8994
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,13 +1,12 @@
{
"name": "games-store-back",
"name": "sd-0x-store-manager",
"version": "1.0.0",
"description": "Simple CRUD to sales and products",
"main": "index.js",
"scripts": {
"test": "jest --runInBand",
"test:mocha": "nyc --all --include models --include services --include controllers mocha test/unit/*.js --exit",
"start": "node index.js",
"dev": "nodemon index.js",
"start": "nodemon index.js",
"lint": "eslint --no-inline-config --no-error-on-unmatched-pattern -c .eslintrc.json . --ext .js, .jsx"
},
"repository": {
@ -36,7 +35,7 @@
"devDependencies": {
"chai": "^4.3.4",
"eslint-config-trybe-backend": "^1.0.3",
"mocha": "^10.2.0",
"mocha": "^8.4.0",
"mongodb-memory-server": "^6.9.6",
"nodemon": "^2.0.4",
"nyc": "^15.1.0",