Adiciona estrutura do req 5 em diante

This commit is contained in:
Michel Pereira 2021-10-22 01:51:23 -03:00
parent 4481f23877
commit bd3bdd3bf8
8 changed files with 343 additions and 2 deletions

View file

@ -0,0 +1,92 @@
const router = require('express').Router();
const rescue = require('express-rescue');
const sales = require('../services/sales');
const CREATED = 201;
const OK = 200;
router.get('/', rescue(async (req, res) => {
const result = await sales.getAll();
res.status(result.status).json({ sales: [...result.sales] });
}));
router.get('/:id', async (req, res) => {
const { id } = req.params;
const result = await sales.getById(id);
if (result.code) {
return res.status(result.status).json({
err: {
code: result.code,
message: result.message,
},
});
}
const { _id, name, quantity } = result;
res.status(200).json({ id: _id, name, quantity });
});
router.post('/', rescue(async (req, res) => {
const { productId, quantity } = req.body;
const result = await sales.create(productId, quantity); // Se der algum erro, o SERVICES interrompe e retorna código de personalizado.
if (result.code) {
return res.status(result.status).json({
err: {
code: result.code,
message: result.message,
},
});
}
res.status(CREATED).json({ _id: result, productId, quantity }); // Se não houver erro, o SERVICE repassa insertedId da MODEL que é usado aqui.
}));
router.put('/:id', rescue(async (req, res) => {
const { id } = req.params; // Talvez tenha que validar o id também. Depois vejo.
const { name, quantity } = req.body;
const updateLog = await sales.update(id, name, quantity); // Retorna apenas o log de update
// DEBUG:
console.log('CONTROLLER: retorno updateLog:');
console.log(updateLog);
if (updateLog.code) {
return res.status(updateLog.status).json({
err: {
code: updateLog.code,
message: updateLog.message,
},
});
}
res.status(OK).json({ id, name, quantity });
}));
router.delete('/:id', rescue(async (req, res) => {
const { id } = req.params;
const result = await sales.deleteIt(id); // Retorna apenas o log de delete
// DEBUG:
console.log('CONTROLLER: retorno result:');
console.log(result);
if (result.code) {
return res.status(result.status).json({
err: {
code: result.code,
message: result.message,
},
});
}
const { _id, name, quantity } = result;
res.status(200).json({ id: _id, name, quantity });
}));
module.exports = router;

View file

@ -1,5 +1,6 @@
const express = require('express');
const products = require('./controllers/products');
const sales = require('./controllers/sales');
const PORT = '3000';
@ -13,6 +14,7 @@ app.get('/', (_request, response) => {
});
app.use('/products', products);
app.use('/sales', sales);
app.all('*', (req, res) => res.status(404).send('Router not found'));

View file

@ -8,11 +8,11 @@ const OPTIONS = {
// Para usar com o avaliador:
const MONGO_DB_URL = 'mongodb://mongodb:27017/StoreManager';
// const MONGO_DB_URL = 'mongodb://mongodb:27017/StoreManager';
// Para uso local:
// const MONGO_DB_URL = 'mongodb://localhost:27017/StoreManager';
const MONGO_DB_URL = 'mongodb://localhost:27017/StoreManager';
// const DB_NAME = 'StoreManager'; // outra maneira

View file

@ -0,0 +1,63 @@
const { ObjectId } = require('mongodb');
const connection = require('./connection');
const create = async (name, quantity) => connection()
.then(async (db) => {
const { insertedId } = await db.collection('sales').insertOne({ name, quantity });
return insertedId;
});
const getByName = async (name) => connection()
.then(async (db) => {
const sale = await db.collection('sales').findOne({ name });
if (sale) return sale;
return {};
});
const getAll = async () => connection()
.then(async (db) => {
const saleS = await db.collection('sales').find().toArray();
return saleS;
});
const getById = async (id) => connection()
.then(async (db) => {
const sale = await db.collection('sales').findOne(new ObjectId(id));
return sale;
});
const update = async (id, name, quantity) => connection()
.then(async (db) => {
const updateLog = await db.collection('sales').updateOne({ _id: ObjectId(id) },
{ $set: { name, quantity } });
// // DEBUG:
// console.log('MODEL: retorno updateLog:');
// console.log(updateLog);
return updateLog;
});
const deleteIt = async (id) => connection()
.then(async (db) => {
const deleteLog = await db.collection('sales').deleteOne({ _id: ObjectId(id) });
// // DEBUG:
// console.log('MODEL: retorno deleteLog:');
// console.log(deleteLog);
return deleteLog;
});
module.exports = {
create,
getByName,
getAll,
getById,
update,
deleteIt,
};

View file

@ -0,0 +1,139 @@
const { ObjectId } = require('mongodb');
const models = require('../models/sales');
const validators = require('../utils/validatorsSales');
const OK = 200;
const UNPROCESSABLE_ENTITY = 422;
const CODE = 'invalid_data';
const create = async (productId, quantity) => {
const validQtd = validators.quantity(quantity);
// const validName = validators.name(name);
const notExistsProductMsg = 'Product not exists';
// Qtd format valitation
if (validQtd.code) {
return { code: validQtd.code, status: validQtd.status, message: validQtd.message };
}
// Id format validation
if (!ObjectId.isValid(id)) { // Get error if invalid id format
return { status: UNPROCESSABLE_ENTITY, code: CODE, message: notDeletedMsg };
}
// Check if product already exists
const found = await validators.alreadyExists(productId, existsMsg);
if (!found) {
return { code: CODE, status: UNPROCESSABLE_ENTITY, message: notExistsProductMsg };
}
// Vamos ver o que se segue ...
const insertedId = await models.create(name, quantity);
return insertedId;
};
const getAll = async () => {
const sales = await models.getAll();
return { status: OK, sales };
};
const getById = async (id) => {
const notFoundMsg = 'Wrong id format';
if (!ObjectId.isValid(id)) { // Get error if invalid id format
return { status: UNPROCESSABLE_ENTITY, code: CODE, message: notFoundMsg };
}
const sale = await models.getById(id);
// Get the SAME error if invalid id is not found:
if (!sale) {
return { status: UNPROCESSABLE_ENTITY,
code: CODE,
message: notFoundMsg };
}
return sale;
};
const update = async (id, name, quantity) => {
const validQtd = validators.quantity(quantity);
const validName = validators.name(name);
const notUpdated = 'Ops! nothing updated';
if (validQtd.code) {
return { code: validQtd.code, status: validQtd.status, message: validQtd.message };
}
if (validName.code) {
return { code: validName.code, status: validName.status, message: validName.message };
}
const updateLog = await models.update(id, name, quantity);
if (updateLog.modifiedCount === 0) {
return { status: UNPROCESSABLE_ENTITY,
code: CODE,
message: notUpdated };
}
// DEBUG:
console.log('SERVICES: retorno updateLog:');
console.log(updateLog);
return updateLog;
};
const deleteIt = async (id) => {
const notDeletedMsg = 'Wrong id format';
const errorDeleteMsg = 'Ops!, Item not deleted';
// Searching
if (!ObjectId.isValid(id)) { // Get error if invalid id format
return { status: UNPROCESSABLE_ENTITY, code: CODE, message: notDeletedMsg };
}
const sale = await models.getById(id);
// // DEBUG:
// console.log('SERVICES: retorno sale:');
// console.log(sale);
// Get the SAME error if invalid id was not found:
if (!sale) {
return { status: UNPROCESSABLE_ENTITY,
code: CODE,
message: notDeletedMsg };
}
// Deleting
const deleteLog = await models.deleteIt(id);
if (deleteLog.deletedCount === 0) {
return { status: UNPROCESSABLE_ENTITY,
code: CODE,
message: errorDeleteMsg };
}
// // DEBUG:
// console.log('SERVICES: retorno deleteLog:');
// console.log(deleteLog);
return sale;
};
module.exports = {
create,
getAll,
getById,
update,
deleteIt,
};

45
utils/validatorsSales.js Normal file
View file

@ -0,0 +1,45 @@
const modelsProducts = require('../models/products');
const UNPROCESSABLE_ENTITY = 422;
const CODE = 'invalid_data';
function name(field) {
const lengthMdg = '"name" length must be at least 5 characters long';
if (field.length < 5) {
return { status: UNPROCESSABLE_ENTITY, code: CODE, message: lengthMdg };
}
return {};
}
function quantity(qtd) {
const sizeMsg = '"quantity" must be larger than or equal to 1';
const typeMsg = '"quantity" must be a number';
if (qtd < 1) {
return { status: UNPROCESSABLE_ENTITY, code: CODE, message: sizeMsg };
}
if (typeof qtd !== 'number') {
return { status: UNPROCESSABLE_ENTITY, code: CODE, message: typeMsg };
}
return {};
}
const alreadyExists = async (field, msg) => {
const product = await modelsProducts.getById(field); // Em services/products
if (product.name) {
return true;
}
return false;
};
module.exports = {
name,
quantity,
alreadyExists,
};