└── README.md
/README.md:
--------------------------------------------------------------------------------
1 | ## Escopo do projeto
2 |
3 | Para a implementação deste projeto vamo precisar usar as seguintes tecnologias:
4 |
5 | - **Node.js** para fornecer a possibilidade de executar JS em um servidor
6 | - **Express.js** para criar rotas de api
7 | - **Dotenv** para criarmos configurações com mais facilidade e segurança
8 | - **Nodemon** para termos mais produtividade em nosso ambiente de desenvolvimento
9 | - **MySQL** para persistência de dados
10 | - **Sequelize** para termos mais produtividade ao lidar com o banco de dados
11 | - **JWT** para adicionar segurança e limitar o acesso nas rotas de API
12 | - **JEST** para nos ajudar a testar e manter a qualidade do código
13 |
14 | ## Estrutura de diretório
15 | ```
16 | project-root/
17 | ├── src/
18 | │ ├── config/
19 | │ ├── controllers/
20 | │ ├── middleware/
21 | │ ├── models/
22 | │ ├── routes/
23 | │ ├── services/
24 | │ ├── app.js
25 | │ └── server.js
26 | ├── tests/
27 | ├── .env
28 | ├── .gitignore
29 | └── package.json
30 | ```
31 |
32 | ## Response status code
33 | - [200 OK](https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Status/200)
34 | - Indica que a API REST executou com êxito qualquer ação solicitada pelo cliente
35 | - Ao contrário do código de status 204, uma 200 deve incluir um corpo de resposta
36 | - [201 CREATED](https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Status/201)
37 | - Indica que a requisição foi bem sucedida e que um novo recurso foi criado
38 | - [204 No content](https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Status/204)
39 | - O código de status 204 geralmente é enviado em resposta a uma solicitação PUT ou DELETE quando a API se recusa a retornar qualquer corpo de mensagem no response
40 | - A resposta 204 NÃO DEVE incluir um corpo de mensagem
41 | - [400 Bad Request](https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Status/400)
42 | - Indica que o servidor não pode ou não irá processar a requisição devido a alguma coisa que foi entendida como um erro do cliente
43 | - [401 Unauthorized](https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Status/401)
44 | - Indica que a solicitação não foi aplicada porque não possui credenciais de autenticação válidas para o recurso de destino
45 | - [404 Not Found](https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Status/404)
46 | - Indica que o servidor não conseguiu encontrar o recurso solicitado
47 |
48 |
49 | ## Seção 01 - Implementar o banco de dados da aplicação
50 |
51 |
52 | Requisito 01 - Criar a tabela de usuários
53 |
54 | O objetivo deste requisito é criar a tabela de usuários no banco de dados utilizando o Sequelize ORM. A tabela deve conter as colunas a seguir:
55 |
56 | - **id**: Coluna do tipo INTEGER que representa a chave primária da tabela. Seu valor deve ser incrementado automaticamente pelo banco de dados
57 | - **firstname**: Coluna do tipo STRING e de preenchimento obrigatório que armazena o primeiro nome do usuário
58 | - **surname**: Coluna do tipo STRING e de preenchimento obrigatório que armazena o sobrenome do usuário.
59 | - **email**: Coluna do tipo STRING e de preenchimento obrigatório que armazena o endereço de email do usuário
60 | - **password**: Coluna do tipo STRING e de preenchimento obrigatório que armazena a senha do usuário. O valor a ser armazenado deve ser o hash da senha gerado pelo pacote bcrypt.
61 |
62 | > Use a configuração `timestamps: true` do sequelize para gerar as colunas **created_at** e **updated_at**
63 |
64 |
65 |
66 |
67 | Requisito 02 - Criar a tabela de categorias
68 |
69 | O objetivo deste requisito é criar a tabela de categorias no banco de dados utilizando o Sequelize ORM. A tabela deve conter as colunas a seguir:
70 |
71 | - **id**: Coluna do tipo INTEGER que representa a chave primária da tabela. Seu valor deve ser incrementado automaticamente pelo banco de dados
72 | - **name**: Coluna do tipo STRING e de preenchimento obrigatório que armazena o nome da categoria
73 | - **slug**: Coluna do tipo STRING, e de preenchimento obrigatório que armazena o slug da categoria.
74 | - **use_in_menu**: Coluna do tipo BOOLEAN e de preenchimento opcional que define se a categoria pode ser exibida no menu. Valor padrão deve ser 0.
75 |
76 | > Use a configuração `timestamps: true` do sequelize para gerar as colunas **created_at** e **updated_at**
77 |
78 |
79 |
80 |
81 | Requisito 03 - Criar a tabela de produtos
82 |
83 | O objetivo deste requisito é criar a tabela de produtos no banco de dados utilizando o Sequelize ORM. A tabela deve conter as colunas a seguir:
84 |
85 | - **id**: Coluna do tipo INTEGER que representa a chave primária da tabela. Seu valor deve ser incrementado automaticamente pelo banco de dados
86 | - **enabled**: Coluna do tipo BOOLEAN e de preenchimento opcional que define se o produto está habilitado (1) ou desabilitado (0). Valor padrão deve ser 0.
87 | - **name**: Coluna do tipo STRING e de preenchimento obrigatório que armazena o nome do produto.
88 | - **slug**: Coluna do tipo STRING e de preenchimento obrigatório que armazena o slug do produto.
89 | - **use_in_menu**: Coluna do tipo BOOLEAN e de preenchimento opcional que define se a categoria pode ser exibida no menu. Valor padrão deve ser 0.
90 | - **stock**: Coluna do tipo INTEGER e de preenchimento opcional que armazena a quantidade de produto disponível. Valor padrão deve ser 0.
91 | - **description**: Coluna do tipo STRING e de preenchimento opcional que armazena a descrição do produto.
92 | - **price**: Coluna do tipo FLOAT e de preenchimento obrigatório que armazena o preço do produto.
93 | - **price_with_discount**: Coluna do tipo FLOAT e de preenchimento obrigatório que armazena o preço do produto com desconto.
94 |
95 | > Use a configuração `timestamps: true` do sequelize para gerar as colunas **created_at** e **updated_at**
96 |
97 |
98 |
99 |
100 | Requisito 04 - Criar a tabela de imagens do produto
101 |
102 | O objetivo deste requisito é criar a tabela de imagens dos produtos no banco de dados utilizando o Sequelize ORM. A tabela deve conter as colunas a seguir:
103 |
104 | - **id**: Coluna do tipo INTEGER que representa a chave primária da tabela. Seu valor deve ser incrementado automaticamente pelo banco de dados
105 | - **product_id**: Coluna do tipo INTEGER que representa a chave estrangeira da tabela. Seu valor deve ser uma referência de um valor existente na primary key da tabela de produtos
106 | - **enabled**: Coluna do tipo BOOLEAN e de preenchimento opcional que define se o produto está habilitado (1) ou desabilitado (0). Valor padrão deve ser 0.
107 | - **path**: Coluna do tipo STRING e de preenchimento obrigatório que armazena o caminho relativo da imagem salva no servidor.
108 |
109 |
110 |
111 |
112 | Requisito 05 - Criar a tabela de opções do produto
113 |
114 | O objetivo deste requisito é criar a tabela de opções do produto no banco de dados utilizando o Sequelize ORM. A tabela deve conter as colunas a seguir:
115 |
116 | - **id**: Coluna do tipo INTEGER que representa a chave primária da tabela. Seu valor deve ser incrementado automaticamente pelo banco de dados
117 | - **product_id**: Coluna do tipo INTEGER e de preenchimento obrigatório que representa a chave estrangeira da tabela. Seu valor deve ser uma referência de um valor existente na primary key da tabela de produtos
118 | - **title**: Coluna do tipo STRING e de preenchimento obrigatório que armazena o título da opção.
119 | - **shape**: Coluna do tipo ENUM e de preenchimento opcional que armazena o formato em que a opção do produto deve ser renderizada. Essa coluna deve aceitar apenas dois valores (square ou circle). Valor padrão deve ser "square"
120 | - **radius**: Coluna do tipo INTEGER e de preenchimento opcional que armazena o valor do `border-radius` da opção do produto. Valor padrão deve ser 0
121 | - **type**: Coluna do tipo ENUM e de preenchimento opcional que armazena o tipo do input usado como opção. Essa coluna deve aceitar apenas dois valores (text ou color). Valor padrão deve ser "text"
122 | - **values**: Coluna do tipo STRING e de preenchimento obrigatório que armazena todas as opção do produto separadas por vírgula.
123 |
124 |
125 |
126 |
127 | Requisito 06 - Criar a tabela de produtos e categoria
128 |
129 | O objetivo deste requisito é criar a tabela de opções do produto no banco de dados utilizando o Sequelize ORM. A tabela deve conter as colunas a seguir:
130 |
131 | - **product_id**: Coluna do tipo INTEGER e de preenchimento obrigatório que representa a chave estrangeira da tabela. Seu valor deve ser referência de um valor existente na primary key da tabela de produtos
132 | - **category_id**: Coluna do tipo INTEGER e de preenchimento obrigatório que representa a chave estrangeira da tabela. Seu valor deve ser referência de um valor existente na primary key da tabela de categorias
133 |
134 |
135 |
136 | ## Seção 02 - Implementar endpoints para o CRUD de usuarios
137 |
138 |
139 | Requisito 01 - Criar endpoint para obter informações do usuário pelo ID
140 |
141 | - GET /v1/user/:id
142 |
143 | **Response body**
144 | ```json
145 | {
146 | "id": 1,
147 | "firstname": "user firstname",
148 | "surname": "user surname",
149 | "email": "user@mail.com"
150 | }
151 | ```
152 |
153 | **Response Status Code**
154 | - 200 OK - Deve ser retornado quando a requisição foi bem sucedida
155 | - 404 Not Found - Deve ser retornado quando o recurso solicitado não existe
156 |
157 |
158 |
159 |
160 | Requisito 02 - Criar endpoint de cadastro de usuário
161 |
162 | - POST /v1/user
163 |
164 | **Headers**
165 | - Content-type: application/json
166 |
167 | **Payload**
168 |
169 | ```json
170 | {
171 | "firstname": "user firstname",
172 | "surname": "user surname",
173 | "email": "user@mail.com",
174 | "password": "123@123",
175 | "confirmPassword": "123@123",
176 | }
177 | ```
178 |
179 | **Response Status Code**
180 | - 201 Created - Deve ser retornado quando o cadastro for bem sucedido
181 | - 400 Bad Request - Deve ser retornado quando a os dados da requisição estiverem incorretos
182 |
183 |
184 |
185 | Requisito 04 - Criar endpoint atualizar usuário
186 |
187 | - PUT /v1/user/:id
188 |
189 | **Headers**
190 | - Content-type: application/json
191 |
192 | **Payload**
193 | ```json
194 | {
195 | "firstname": "user firstname",
196 | "surname": "user surname",
197 | "email": "user@mail.com",
198 | }
199 | ```
200 |
201 | **Response Status Code**
202 | - 204 No Content - Deve ser retornado quando a requisição foi bem sucedida mas nenhum corpo deve ser retornado.
203 | - 400 Bad Request - Deve ser retornado quando a os dados da requisição estiverem incorretos
204 | - 401 Unauthorized - Deve ser retornado quando o token de autorização não for enviado ou estiver incorreto
205 | - 404 Not Found - Deve ser retornado quando o recurso solicitado não existe
206 |
207 |
208 |
209 |
210 | Requisito 05 - Criar endpoint de deletar usuário
211 |
212 | - DELETE /v1/user/:id
213 |
214 | **Headers**
215 | - Content-type: application/json
216 |
217 | **Response Status Code**
218 | - 204 No Content - Deve ser retornado quando a requisição foi bem sucedida mas nenhum corpo deve ser retornado.
219 | - 401 Unauthorized - Deve ser retornado quando o token de autorização não for enviado ou estiver incorreto
220 | - 404 Not Found - Deve ser retornado quando o recurso solicitado não existe
221 |
222 |
223 |
224 | ## Seção 03 - Implementar endpoints para o CRUD de categorias
225 |
226 |
227 | Requisito 01 - Criar endpoint para obter uma lista de categorias
228 |
229 | - GET /v1/category/search
230 |
231 | **Query params**
232 | - `limit=-1`
233 | - Query string para definir o limit de itens por página
234 | - Use `-1` como valor para buscar todos os itens
235 | - Padrão: 12
236 | - `page=1`
237 | - Query string para definir a paginação dos dados retornados
238 | - Quando `limit` receber `-1` a opção de `page` não tem nenhum efeito no resultado da busca e pode ser omitida da query string
239 | - Padrão: 1
240 | - `fields=name,slug`
241 | - Query string para limitar quais campos serão retornados
242 | - `use_in_menu=true`
243 | - Query string para filtrar apenas as categorias que podem aparecer no menu
244 |
245 | **Response body**
246 | ```json
247 | {
248 | "data": [
249 | {
250 | "id": 1,
251 | "name": "Shoes",
252 | "slug": "shoes",
253 | "use_in_menu": true
254 | },
255 | {
256 | "id": 2,
257 | "name": "Offers",
258 | "slug": "offers",
259 | "use_in_menu": true
260 | },
261 | {
262 | "id": 3,
263 | "name": "Black Friday",
264 | "slug": "black-friday",
265 | "use_in_menu": false
266 | }
267 | ],
268 | "total": 10,
269 | "limit": -1,
270 | "page": 1
271 | }
272 | ```
273 |
274 | **Response Status Code**
275 | - 200 OK - Deve ser retornado quando a requisição foi bem sucedida
276 | - 400 Bad Request - Deve ser retornado quando a os dados da requisição estiverem incorretos
277 |
278 |
279 |
280 | Requisito 02 - Criar endpoint para obter informações da categoria pelo ID
281 |
282 | - GET /v1/category/:id
283 |
284 | **Response body**
285 | ```json
286 | {
287 | "id": 1,
288 | "name": "Shoes",
289 | "slug": "shoes",
290 | "use_in_menu": true
291 | }
292 | ```
293 |
294 | **Response Status Code**
295 | - 200 OK - Deve ser retornado quando a requisição foi bem sucedida
296 | - 404 Not Found - Deve ser retornado quando o recurso solicitado não existe
297 |
298 |
299 |
300 |
301 | Requisito 03 - Criar endpoint de cadastro de categoria
302 |
303 | - POST /v1/category
304 |
305 | **Headers**
306 | - Content-type: application/json
307 |
308 | **Payload**
309 |
310 | ```json
311 | {
312 | "name": "Shoes",
313 | "slug": "shoes",
314 | "use_in_menu": true
315 | }
316 | ```
317 |
318 | **Response Status Code**
319 | - 201 Created - Deve ser retornado quando o cadastro for bem sucedido
320 | - 400 Bad Request - Deve ser retornado quando a os dados da requisição estiverem incorretos
321 | - 401 Unauthorized - Deve ser retornado quando o token de autorização não for enviado ou estiver incorreto
322 |
323 |
324 |
325 | Requisito 04 - Criar endpoint de atualização de categoria
326 |
327 | - PUT /v1/category/:id
328 |
329 | **Headers**
330 | - Content-type: application/json
331 |
332 | **Payload**
333 | ```json
334 | {
335 | "name": "Shoes",
336 | "slug": "shoes",
337 | "use_in_menu": true
338 | }
339 | ```
340 |
341 | **Response Status Code**
342 | - 204 No Content - Deve ser retornado quando a requisição foi bem sucedida mas nenhum corpo deve ser retornado.
343 | - 400 Bad Request - Deve ser retornado quando a os dados da requisição estiverem incorretos
344 | - 401 Unauthorized - Deve ser retornado quando o token de autorização não for enviado ou estiver incorreto
345 | - 404 Not Found - Deve ser retornado quando o recurso solicitado não existe
346 |
347 |
348 |
349 | Requisito 05 - Criar endpoint de deletar categoria
350 |
351 | - DELETE /v1/category/:id
352 |
353 | **Headers**
354 | - Content-type: application/json
355 |
356 | **Response Status Code**
357 | - 204 No Content - Deve ser retornado quando a requisição foi bem sucedida mas nenhum corpo deve ser retornado.
358 | - 401 Unauthorized - Deve ser retornado quando o token de autorização não for enviado ou estiver incorreto
359 | - 404 Not Found - Deve ser retornado quando o recurso solicitado não existe
360 |
361 |
362 | ## Seção 04 - Implementar endpoints para o CRUD de produtos
363 |
364 |
365 | Requisito 01 - Criar endpoint para obter uma lista de produtos
366 |
367 | - GET /v1/product/search
368 |
369 | **Query params**
370 | - `limit=30`
371 | - Query string para definir o limit de itens por página
372 | - Use `-1` como valor para buscar todos os itens
373 | - Padrão: 12
374 | - `page=2`
375 | - Query string para definir a paginação dos dados retornados
376 | - Quando `limit` receber `-1` a opção de `page` não tem nenhum efeito no resultado da busca e pode ser omitida da query string
377 | - Padrão: 1
378 | - `fields=name,images,price`
379 | - Query string para limitar quais campos serão retornados
380 | - `match=Tênis`
381 | - Query string usada para filtrar o resultado de produtos por um termo que combine com o nome ou descrição do produto
382 | - `category_ids=15,24`
383 | - Query string usada para filtrar o resultado de produtos pelo ID das categorias
384 | - `price-range=100-200`
385 | - Query string para filtrar o resultado de produtos por uma determinada "janela" de preços
386 | - `option[45]=GG,PP`
387 | - Query string para filtrar o resultado de produtos pelo valor das opções disponíveis
388 |
389 | **Response body**
390 | ```json
391 | {
392 | "data": [
393 | {
394 | "id": 1,
395 | "enabled": true,
396 | "name": "Produto 01",
397 | "slug": "produto-01",
398 | "stock": 10,
399 | "description": "Descrição do produto 01",
400 | "price": 119.90,
401 | "price_with_discount": 99.90,
402 | "category_ids": [1, 15, 24, 68],
403 | "images": [
404 | {
405 | "id": 1,
406 | "content": "https://store.com/media/product-01/image-01.png"
407 | },
408 | {
409 | "id": 2,
410 | "content": "https://store.com/media/product-01/image-02.png"
411 | },
412 | {
413 | "id": 3,
414 | "content": "https://store.com/media/product-01/image-02.jpg"
415 | }
416 | ],
417 | "options": [
418 | {
419 | "id": 1
420 | ...
421 | },
422 | {
423 | "id": 2
424 | ...
425 | }
426 | ]
427 | }
428 | ],
429 | "total": 120,
430 | "limit": 12,
431 | "page": 1,
432 | }
433 | ```
434 | **Response Status Code**
435 | - 200 OK - Deve ser retornado quando a requisição foi bem sucedida
436 | - 400 Bad Request - Deve ser retornado quando a os dados da requisição estiverem incorretos
437 |
438 |
439 |
440 | Requisito 02 - Criar endpoint para obter informações do produto pelo ID
441 |
442 | - GET /v1/product/:id
443 |
444 | **Response body**
445 | ```json
446 | {
447 | "id": 1,
448 | "enabled": true,
449 | "name": "Produto 01",
450 | "slug": "product-01",
451 | "stock": 10,
452 | "description": "Descrição do produto 01",
453 | "price": 119.90,
454 | "price_with_discount": 99.90,
455 | "category_ids": [1, 15, 24, 68],
456 | "images": [
457 | {
458 | "id": 1,
459 | "content": "https://store.com/media/product-01/image-01.png"
460 | },
461 | {
462 | "id": 2,
463 | "content": "https://store.com/media/product-01/image-02.png"
464 | },
465 | {
466 | "id": 3,
467 | "content": "https://store.com/media/product-01/image-02.jpg"
468 | }
469 | ],
470 | "options": [
471 | {
472 | "id": 1
473 | ...
474 | },
475 | {
476 | "id": 2
477 | ...
478 | }
479 | ]
480 | }
481 | ```
482 |
483 | **Response Status Code**
484 | - 200 OK - Deve ser retornado quando a requisição foi bem sucedida
485 | - 404 Not Found - Deve ser retornado quando o recurso solicitado não existe
486 |
487 |
488 |
489 | Requisito 03 - Criar endpoint de criação de produto
490 |
491 | - POST /v1/product
492 |
493 | **Headers**
494 | - Content-type: application/json
495 |
496 | **Payload**
497 |
498 | ```json
499 | {
500 | "enabled": true,
501 | "name": "Produto 01",
502 | "slug": "produto-01",
503 | "stock": 10,
504 | "description": "Descrição do produto 01",
505 | "price": 119.90,
506 | "price_with_discount": 99.90,
507 | "category_ids": [1, 15, 24, 68],
508 | "images": [
509 | {
510 | "type": "image/png",
511 | "content": "base64 da imagem 1"
512 | },
513 | {
514 | "type": "image/png",
515 | "content": "base64 da imagem 2"
516 | },
517 | {
518 | "type": "image/jpg",
519 | "content": "base64 da imagem 3"
520 | }
521 | ],
522 | "options": [
523 | {
524 | "title": "Cor",
525 | "shape": "square",
526 | "radius": "4px",
527 | "type": "text",
528 | "value": ["PP", "GG", "M"]
529 | },
530 | {
531 | "title": "Tamanho",
532 | "shape": "circle",
533 | "type": "color",
534 | "values": ["#000", "#333"]
535 | }
536 | ]
537 | }
538 | ```
539 |
540 | **Response Status Code**
541 | - 201 Created - Deve ser retornado quando o cadastro for bem sucedido
542 | - 400 Bad Request - Deve ser retornado quando a os dados da requisição estiverem incorretos
543 | - 401 Unauthorized - Deve ser retornado quando o token de autorização não for enviado ou estiver incorreto
544 |
545 |
546 |
547 | Requisito 04 - Criar endpoint de atualização de produto
548 |
549 | - PUT /v1/product/:id
550 |
551 | **Headers**
552 | - Content-type: application/json
553 |
554 | **Payload**
555 |
556 | ```json
557 | {
558 | "enabled": true,
559 | "name": "Produto 01 atualizado",
560 | "slug": "produto-01-atualizado",
561 | "stock": 20,
562 | "description": "Descrição do produto 01 atualizado",
563 | "price": 49.9,
564 | "price_with_discount": 0,
565 | "category_ids": [1, 15, 24, 68],
566 | "images": [
567 | {
568 | "type": "image/png",
569 | "content": "base64 da imagem 1"
570 | },
571 | {
572 | "id": 2,
573 | "deleted": true
574 | },
575 | {
576 | "id": 3,
577 | "content": "base64 da imagem 3"
578 | },
579 | {
580 | "id": 1,
581 | "content": "https://store.com/media/product-01/image-01.jpg"
582 | }
583 | ],
584 | "options": [
585 | {
586 | "id": 1,
587 | "deleted": true,
588 | }
589 | {
590 | "id": 2,
591 | "radius": "10px",
592 | "value": ["42/43", "44/45"]
593 | },
594 | {
595 | "title": "Tipo",
596 | "shape": "square",
597 | "type": "text",
598 | "values": ["100% algodão", "65% algodão"]
599 | }
600 | ]
601 | }
602 | ```
603 |
604 | **Response Status Code**
605 | - 204 No Content - Deve ser retornado quando a requisição foi bem sucedida mas nenhum corpo deve ser retornado.
606 | - 400 Bad Request - Deve ser retornado quando a os dados da requisição estiverem incorretos
607 | - 401 Unauthorized - Deve ser retornado quando o token de autorização não for enviado ou estiver incorreto
608 | - 404 Not Found - Deve ser retornado quando o recurso solicitado não existe
609 |
610 |
611 |
612 |
613 | Requisito 05 - Criar endpoint de atualização de produto
614 |
615 | - DELETE /v1/product/:id
616 |
617 | **Headers**
618 | - Content-type: application/json
619 |
620 | **Response Status Code**
621 | - 204 No Content - Deve ser retornado quando a requisição foi bem sucedida mas nenhum corpo deve ser retornado.
622 | - 401 Unauthorized - Deve ser retornado quando o token de autorização não for enviado ou estiver incorreto
623 | - 404 Not Found - Deve ser retornado quando o recurso solicitado não existe
624 |
625 |
626 |
627 | ## Seção 05 - Implementar e validar token JWT
628 |
629 | Requisito 01 - Criar endpoint de geração do token JWT
630 |
631 | - POST /v1/user/token
632 |
633 | **Headers**
634 | - Content-type: application/json
635 |
636 | **Payload**
637 |
638 | ```json
639 | {
640 | "email": "user@mail.com",
641 | "password": "123@123",
642 | }
643 | ```
644 |
645 | **Response body**
646 | ```json
647 | {
648 | "token": "",
649 | }
650 | ```
651 |
652 | **Response Status Code**
653 | - 200 OK - Deve ser retornado quando a requisição foi bem sucedida
654 | - 400 Bad Request - Deve ser retornado quando a os dados da requisição estiverem incorretos
655 |
656 |
657 |
658 | Requisito 02 - Validar token nos métodos POST, PUT e DELETE
659 |
660 | Todos os endpoints POST, PUT e DELETE devem conter o cabeçalho `Authorization: Bearer `, caso contrario a requisição
661 | deve ser rejeitada com o status code **400 Bad Request**
662 |
--------------------------------------------------------------------------------