# Boas vindas ao repositório Games Store (Backend) Esse projeto é uma API de um sistema de gerenciamento de vendas, onde será possível criar, visualizar, deletar e atualizar os produtos e as vendas. Ou seja, um CRUD. --- ## Sumário - [Habilidades](#habilidades) - [Descrição](#descrição) - [Requisitos de usuário](#requisitos-de-usuário) - Arquitetura e padrões - Tecnologias utilizadas - Futuras implementações - Requisitos para execução e consumo da API - [Dependências](#dependencias) - [Como executar](#como-executar) - [Endpoints](#endpoints) - [Linter](#linter) - [Observações](#observações) - [Requisitos funcionais](#requisitos-funcionais) ## Habilidades Esse projeto teve como objetivo praticar as seguintes hardskills: - Estruturação de uma aplicação em camadas (Arquitetura MSC); - Delegação de responsabilidades específicas para cada parte do app; - Melhora da manutenibilidade e reusabilidade do código; - Aplicação dos padrões REST; - Implementação de uma API intuitiva e facilmente entendível. --- ## Descrição 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 . 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. 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 * Deve ser possível que a pessoa usuária, independente de cadastramento ou login, possa adicionar, ler, deletar e atualizar produtos no seu estoque. (Mas irei implantar Login e autorizações de usuários também brevemente) * O usuário deve poder também enviar vendas para o sistema. Essas vendas devem validar se o produto em questão existe. * Deve, também, ser possível ler, deletar e atualizar vendas. ## Arquitetura e Padrões Sumário * Arquitetura MSC * API RESTfull ## Tecnologias utilizadas Sumário * Node.js * Express * MongoDB * ESLinter (Para auxiliar na análise de erros no código e de algumas boas práticas) ## Futuras implementações Sumário * Autenticação de Usuários (Login) * 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. ## Requisitos para execução e consumo da API: Sumário 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. ## Dependências Sumário 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: `npm install` ## Como Executar Sumário Instalado os requisitos e as dependências necessárias, basta seguir as seguintes etapas: 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. :-) **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`. 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`. 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 Sumário ### Produtos * GET: /products * GET: /products/:id * POST: /products * PUT: /products/:id * DELETE: /products/:id ### Vendas * GET: /sales * GET: /sales/:id * POST: /sales * PUT: /sales/:id * DELETE: /sales/:id ## Linter Sumário Foi usado [ESLint](https://eslint.org/) para fazer a análise estática do código, afim de manter padrões de indentação e espaçamento dos trechos de códigos. No entanto, para usá-lo de forma mais manual, o projeto já vem com as dependências relacionadas ao ESLint configuradas no arquivos `package.json`. Para executá-lo basta usar --- dentro da pasta do projeto --- o comando `npm run lint`. Se a análise do `ESLint` encontrar problemas no 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. ### ESLint de forma automática Particulamente eu preferi utilizar o [plugin `ESLint`](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) pela extensão do `VSCode`, em favor da produtividade. --- ## Observações Sumário ### Estrutura da lista de requisitos funcionais - Em cada requisito você encontrará uma imagem de um protótipo de como sua aplicação deve ficar. ### Estrutura do banco de dados: * **Observação:** O `_id` é gerado automaticamente. * O banco deve ter duas `collections`: uma para os _produtos_ e outra para as _vendas_ * A tabela de **produtos** terá o seguinte nome: `products` * Os campos da collection `products` terão esse formato: ```json { "name": "Sony Playstation 5 825gb Digital Edition Cor Branco E Preto", "price": 6499, "thumbnail": "http://http2.mlstatic.com/D_799755-MLA47058389754_082021-I.jpg", "description": "", "quantity": 7 } ``` * A tabela de **vendas** terá o seguinte nome: `sales` * Os campos da tabela `sales` terão esse formato: ```json { "itensSold": [{ "productId": "5f43cbf4c45ff5104986e81d", "quantity": 2 }] } ``` ### Shape de retorno após "insert" no banco: * A tabela de **produtos** * A resposta retornada após um `insert` (criação) no banco precisa ter o seguinte shape: ```json { "_id": ObjectId("5f43cbf4c45ff5104986e81d"), "name": "Produto tal", "quantity": 10 } ``` * A tabela de **vendas** * A resposta retornada após um `insert` (criação) no banco precisa ter o seguinte shape: ```json { "_id": ObjectId("5f43cc53c45ff5104986e81e"), "itensSold": [{ "productId": "5f43cbf4c45ff5104986e81d", "quantity": 2 }] } ``` ## Requisitos funcionais Sumário Para entender melhor a lógica por trás do código de desenvolvimento da API, é interessante olhar a _Requisitos funcionais_ do projeto. Acesse [aqui](Functional-Requirements.md) o **readme** desses _Requisitos Funcionais_.