Add seeders and Product service
This commit is contained in:
parent
def02622a6
commit
2c73524597
28
md-seed-config.js
Normal file
28
md-seed-config.js
Normal file
@ -0,0 +1,28 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { GenderSeeder, UnitSeeder, ActivitySeeder, ProductSeeder } = require('./src/seeders');
|
||||
|
||||
const config = require('./src/config/config');
|
||||
|
||||
const mongoURL = config.mongoose.url
|
||||
|
||||
/**
|
||||
* Seeders List
|
||||
* order is important
|
||||
* @type {Object}
|
||||
*/
|
||||
module.exports.seedersList = {
|
||||
GenderSeeder,
|
||||
UnitSeeder,
|
||||
ActivitySeeder,
|
||||
};
|
||||
/**
|
||||
* Connect to mongodb implementation
|
||||
* @return {Promise}
|
||||
*/
|
||||
module.exports.connect = async () =>
|
||||
await mongoose.connect(mongoURL, { useNewUrlParser: true });
|
||||
/**
|
||||
* Drop/Clear the database implementation
|
||||
* @return {Promise}
|
||||
*/
|
||||
module.exports.dropdb = async () => mongoose.connection.db.dropDatabase();
|
@ -21,6 +21,8 @@
|
||||
"coverage:coveralls": "jest -i --coverage --coverageReporters=text-lcov | coveralls",
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "eslint . --fix",
|
||||
"db:seed": "npx md-seed run",
|
||||
"db:drop": "npx md-seed run --dropdb",
|
||||
"prettier": "prettier --check **/*.js",
|
||||
"prettier:fix": "prettier --write **/*.js"
|
||||
},
|
||||
@ -59,6 +61,7 @@
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"moment": "^2.24.0",
|
||||
"mongoose": "^5.7.7",
|
||||
"mongoose-data-seed": "^2.1.6",
|
||||
"morgan": "^1.9.1",
|
||||
"nodemailer": "^6.3.1",
|
||||
"passport": "^0.4.0",
|
||||
@ -87,5 +90,8 @@
|
||||
"nodemon": "^2.0.0",
|
||||
"prettier": "^2.0.5",
|
||||
"supertest": "^4.0.2"
|
||||
},
|
||||
"mdSeed": {
|
||||
"seedersFolder": "./src/seeders"
|
||||
}
|
||||
}
|
||||
|
@ -4,11 +4,6 @@ const ApiError = require('../utils/ApiError');
|
||||
const catchAsync = require('../utils/catchAsync');
|
||||
const { activityService } = require('../services');
|
||||
|
||||
const createActivity = catchAsync(async (req, res) => {
|
||||
const activity = await activityService.createActivity(req.body);
|
||||
res.status(httpStatus.CREATED).send(activity);
|
||||
});
|
||||
|
||||
const getActivities = catchAsync(async (req, res) => {
|
||||
const filter = pick(req.query, ['name', 'factor']);
|
||||
const options = pick(req.query, ['sortBy', 'limit', 'page']);
|
||||
@ -24,20 +19,7 @@ const getActivity = catchAsync(async (req, res) => {
|
||||
res.send(activity);
|
||||
});
|
||||
|
||||
const updateActivity = catchAsync(async (req, res) => {
|
||||
const activity = await activityService.updateActivityById(req.params.activityId, req.body);
|
||||
res.send(activity);
|
||||
});
|
||||
|
||||
const deleteActivity = catchAsync(async (req, res) => {
|
||||
await activityService.deleteActivityById(req.params.activityId);
|
||||
res.status(httpStatus.NO_CONTENT).send();
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
createActivity,
|
||||
getActivities,
|
||||
getActivity,
|
||||
updateActivity,
|
||||
deleteActivity,
|
||||
};
|
||||
|
25
src/controllers/gender.controller.js
Normal file
25
src/controllers/gender.controller.js
Normal file
@ -0,0 +1,25 @@
|
||||
const httpStatus = require('http-status');
|
||||
const pick = require('../utils/pick');
|
||||
const ApiError = require('../utils/ApiError');
|
||||
const catchAsync = require('../utils/catchAsync');
|
||||
const { genderService } = require('../services');
|
||||
|
||||
const getGenders = catchAsync(async (req, res) => {
|
||||
const filter = pick(req.query, ['name']);
|
||||
const options = pick(req.query, ['sortBy', 'limit', 'page']);
|
||||
const result = await genderService.queryGenders(filter, options);
|
||||
res.send(result);
|
||||
});
|
||||
|
||||
const getGender = catchAsync(async (req, res) => {
|
||||
const gender = await genderService.getGenderById(req.params.genderId);
|
||||
if (!gender) {
|
||||
throw new ApiError(httpStatus.NOT_FOUND, 'Activity not found');
|
||||
}
|
||||
res.send(gender);
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
getGenders,
|
||||
getGender,
|
||||
};
|
43
src/controllers/product.controller.js
Normal file
43
src/controllers/product.controller.js
Normal file
@ -0,0 +1,43 @@
|
||||
const httpStatus = require('http-status');
|
||||
const pick = require('../utils/pick');
|
||||
const ApiError = require('../utils/ApiError');
|
||||
const catchAsync = require('../utils/catchAsync');
|
||||
const { productService } = require('../services');
|
||||
|
||||
const createProduct = catchAsync(async (req, res) => {
|
||||
const product = await productService.createProduct(req.body);
|
||||
res.status(httpStatus.CREATED).send(product);
|
||||
});
|
||||
|
||||
const getProducts = catchAsync(async (req, res) => {
|
||||
const filter = pick(req.query, ['name', 'barcode']);
|
||||
const options = pick(req.query, ['sortBy', 'limit', 'page']);
|
||||
const result = await productService.queryProducts(filter, options);
|
||||
res.send(result);
|
||||
});
|
||||
|
||||
const getProduct = catchAsync(async (req, res) => {
|
||||
const product = await productService.getProduct(req.params.productId);
|
||||
if (!product) {
|
||||
throw new ApiError(httpStatus.NOT_FOUND, 'Product not found');
|
||||
}
|
||||
res.send(product);
|
||||
});
|
||||
|
||||
const updateProduct = catchAsync(async (req, res) => {
|
||||
const product = await productService.getProductById(req.params.productId, req.body);
|
||||
res.send(product);
|
||||
});
|
||||
|
||||
const deleteProduct = catchAsync(async (req, res) => {
|
||||
await productService.deleteProductById(req.params.productId);
|
||||
res.status(httpStatus.NO_CONTENT).send();
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
createProduct,
|
||||
getProducts,
|
||||
getProduct,
|
||||
updateProduct,
|
||||
deleteProduct,
|
||||
};
|
@ -4,11 +4,6 @@ const ApiError = require('../utils/ApiError');
|
||||
const catchAsync = require('../utils/catchAsync');
|
||||
const { unitService } = require('../services');
|
||||
|
||||
const createUnit = catchAsync(async (req, res) => {
|
||||
const unit = await unitService.createUnit(req.body);
|
||||
res.status(httpStatus.CREATED).send(unit);
|
||||
});
|
||||
|
||||
const getUnits = catchAsync(async (req, res) => {
|
||||
const filter = pick(req.query, ['name']);
|
||||
const options = pick(req.query, ['sortBy', 'limit', 'page']);
|
||||
@ -24,20 +19,7 @@ const getUnit = catchAsync(async (req, res) => {
|
||||
res.send(unit);
|
||||
});
|
||||
|
||||
const updateUnit = catchAsync(async (req, res) => {
|
||||
const unit = await unitService.updateUnitById(req.params.unitId, req.body);
|
||||
res.send(unit);
|
||||
});
|
||||
|
||||
const deleteUnit = catchAsync(async (req, res) => {
|
||||
await unitService.deleteUnitById(req.params.unitId);
|
||||
res.status(httpStatus.NO_CONTENT).send();
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
createUnit,
|
||||
getUnits,
|
||||
getUnit,
|
||||
updateUnit,
|
||||
deleteUnit,
|
||||
};
|
||||
|
@ -8,6 +8,7 @@ const activitySchema = mongoose.Schema(
|
||||
unique: true,
|
||||
required: true,
|
||||
trim: true,
|
||||
index: true,
|
||||
},
|
||||
factor: {
|
||||
type: Number,
|
||||
|
28
src/models/gender.model.js
Normal file
28
src/models/gender.model.js
Normal file
@ -0,0 +1,28 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { toJSON, paginate } = require('./plugins');
|
||||
|
||||
const genderSchema = mongoose.Schema(
|
||||
{
|
||||
name: {
|
||||
type: String,
|
||||
unique: true,
|
||||
required: true,
|
||||
trim: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
timestamps: true,
|
||||
}
|
||||
);
|
||||
|
||||
genderSchema.plugin(toJSON);
|
||||
genderSchema.plugin(paginate);
|
||||
|
||||
genderSchema.statics.isNameTaken = async function (name, excludeUnitId) {
|
||||
const gender = await this.findOne({ name, _id: { $ne: excludeUnitId } });
|
||||
return !!gender;
|
||||
};
|
||||
|
||||
const Gender = mongoose.model('Gender', genderSchema);
|
||||
|
||||
module.exports = Gender;
|
@ -2,4 +2,6 @@ module.exports.Token = require('./token.model');
|
||||
module.exports.User = require('./user.model');
|
||||
module.exports.Profile = require('./profile.model');
|
||||
module.exports.Activity = require('./activity.model');
|
||||
module.exports.Product = require('./product.model');
|
||||
module.exports.Unit = require('./unit.model');
|
||||
module.exports.Gender = require('./gender.model');
|
||||
|
@ -3,14 +3,42 @@ const { toJSON, paginate } = require('./plugins');
|
||||
|
||||
const productSchema = mongoose.Schema(
|
||||
{
|
||||
name: {
|
||||
type: String,
|
||||
unique: true,
|
||||
trim: true,
|
||||
index: true,
|
||||
required: true,
|
||||
},
|
||||
brand: {
|
||||
type: String,
|
||||
trim: true,
|
||||
},
|
||||
barcode: {
|
||||
type: Number,
|
||||
unique: true,
|
||||
index: true,
|
||||
},
|
||||
unit: {
|
||||
type: mongoose.SchemaTypes.ObjectId,
|
||||
ref: 'Unit',
|
||||
required: true,
|
||||
},
|
||||
capacity: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
package: {
|
||||
capacity: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
unit: {
|
||||
type: mongoose.SchemaTypes.ObjectId,
|
||||
ref: 'Unit',
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
kcal: {
|
||||
type: Number,
|
||||
required: true,
|
||||
@ -29,12 +57,6 @@ const productSchema = mongoose.Schema(
|
||||
},
|
||||
salt: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
unit: {
|
||||
type: mongoose.SchemaTypes.ObjectId,
|
||||
ref: 'Unit',
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -42,13 +64,19 @@ const productSchema = mongoose.Schema(
|
||||
}
|
||||
);
|
||||
|
||||
// add plugin that converts mongoose to json
|
||||
productSchema.plugin(toJSON);
|
||||
productSchema.plugin(paginate);
|
||||
|
||||
/**
|
||||
* @typedef Product
|
||||
*/
|
||||
productSchema.statics.isNameTaken = async function (name, excludeProductId) {
|
||||
const product = await this.findOne({ name, _id: { $ne: excludeProductId } });
|
||||
return !!product;
|
||||
};
|
||||
|
||||
productSchema.statics.isBarcodeTaken = async function (barcode, excludeProductId) {
|
||||
const product = await this.findOne({ barcode, _id: { $ne: excludeProductId } });
|
||||
return !!product;
|
||||
};
|
||||
|
||||
const Product = mongoose.model('Product', productSchema);
|
||||
|
||||
module.exports = Product;
|
||||
|
@ -3,9 +3,9 @@ const { toJSON, paginate } = require('./plugins');
|
||||
|
||||
const profileSchema = mongoose.Schema(
|
||||
{
|
||||
sex: {
|
||||
type: String,
|
||||
enum: ['male', 'female'],
|
||||
gender: {
|
||||
type: mongoose.SchemaTypes.ObjectId,
|
||||
ref: 'Gender',
|
||||
required: true,
|
||||
},
|
||||
birthday: {
|
||||
@ -35,6 +35,7 @@ const profileSchema = mongoose.Schema(
|
||||
type: mongoose.SchemaTypes.ObjectId,
|
||||
ref: 'User',
|
||||
required: true,
|
||||
index: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -8,6 +8,7 @@ const unitSchema = mongoose.Schema(
|
||||
unique: true,
|
||||
required: true,
|
||||
trim: true,
|
||||
index: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -15,19 +16,12 @@ const unitSchema = mongoose.Schema(
|
||||
}
|
||||
);
|
||||
|
||||
// add plugin that converts mongoose to json
|
||||
unitSchema.plugin(toJSON);
|
||||
unitSchema.plugin(paginate);
|
||||
|
||||
/**
|
||||
* Check if name is taken
|
||||
* @param {string} name - The unit's name
|
||||
* @param {ObjectId} [excludeUnitId] - The id of the unit to be excluded
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
unitSchema.statics.isNameTaken = async function (name, excludeUnitId) {
|
||||
const activity = await this.findOne({ name, _id: { $ne: excludeUnitId } });
|
||||
return !!activity;
|
||||
const unit = await this.findOne({ name, _id: { $ne: excludeUnitId } });
|
||||
return !!unit;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -10,12 +10,14 @@ const userSchema = mongoose.Schema(
|
||||
type: String,
|
||||
required: true,
|
||||
trim: true,
|
||||
index: true,
|
||||
},
|
||||
email: {
|
||||
type: String,
|
||||
required: true,
|
||||
unique: true,
|
||||
trim: true,
|
||||
index: true,
|
||||
lowercase: true,
|
||||
validate(value) {
|
||||
if (!validator.isEmail(value)) {
|
||||
|
@ -8,14 +8,11 @@ const router = express.Router();
|
||||
|
||||
router
|
||||
.route('/')
|
||||
.post(auth('manageActivities'), validate(activityValidation.createActivity), activityController.createActivity)
|
||||
.get(auth('getActivities'), validate(activityValidation.getActivities), activityController.getActivities);
|
||||
.get(auth(), validate(activityValidation.getActivities), activityController.getActivities);
|
||||
|
||||
router
|
||||
.route('/:activityId')
|
||||
.get(auth('getActivities'), validate(activityValidation.getActivity), activityController.getActivity)
|
||||
.patch(auth('manageActivities'), validate(activityValidation.updateActivity), activityController.updateActivity)
|
||||
.delete(auth('manageActivities'), validate(activityValidation.deleteActivity), activityController.deleteActivity);
|
||||
.get(auth(), validate(activityValidation.getActivity), activityController.getActivity)
|
||||
|
||||
module.exports = router;
|
||||
|
||||
|
17
src/routes/v1/gender.route.js
Normal file
17
src/routes/v1/gender.route.js
Normal file
@ -0,0 +1,17 @@
|
||||
const express = require('express');
|
||||
const auth = require('../../middlewares/auth');
|
||||
const validate = require('../../middlewares/validate');
|
||||
const genderValidation = require('../../validations/gender.validation');
|
||||
const genderController = require('../../controllers/gender.controller');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router
|
||||
.route('/')
|
||||
.get(auth(), validate(genderValidation.getGenders), genderController.getGenders);
|
||||
|
||||
router
|
||||
.route('/:genderId')
|
||||
.get(auth(), validate(genderValidation.getGender), genderController.getGender)
|
||||
|
||||
module.exports = router;
|
@ -4,6 +4,7 @@ const userRoute = require('./user.route');
|
||||
const profileRoute = require('./profile.route');
|
||||
const activityRoute = require('./activity.route');
|
||||
const unitRoute = require('./unit.route');
|
||||
const genderRoute = require('./gender.route');
|
||||
const docsRoute = require('./docs.route');
|
||||
|
||||
const router = express.Router();
|
||||
@ -13,6 +14,7 @@ router.use('/users', userRoute);
|
||||
router.use('/profiles', profileRoute);
|
||||
router.use('/activities', activityRoute);
|
||||
router.use('/units', unitRoute);
|
||||
router.use('/genders', genderRoute);
|
||||
router.use('/docs', docsRoute);
|
||||
|
||||
module.exports = router;
|
||||
|
20
src/routes/v1/product.route.js
Normal file
20
src/routes/v1/product.route.js
Normal file
@ -0,0 +1,20 @@
|
||||
const express = require('express');
|
||||
const auth = require('../../middlewares/auth');
|
||||
const validate = require('../../middlewares/validate');
|
||||
const productValidation = require('../../validations/product.validation');
|
||||
const productController = require('../../controllers/product.controller');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router
|
||||
.route('/')
|
||||
.post(auth(), validate(productValidation.createProduct), productController.createProduct)
|
||||
.get(auth(), validate(productValidation.getProducts), productController.getProducts);
|
||||
|
||||
router
|
||||
.route('/:productId')
|
||||
.get(auth(), validate(productValidation.getProduct), productController.getProduct)
|
||||
.patch(auth(), validate(productValidation.updateProduct), productController.updateProduct)
|
||||
.delete(auth(), validate(productValidation.deleteProduct), productController.deleteProduct);
|
||||
|
||||
module.exports = router;
|
@ -8,217 +8,10 @@ const router = express.Router();
|
||||
|
||||
router
|
||||
.route('/')
|
||||
.post(auth('manageUnits'), validate(unitValidation.createUnit), unitController.createUnit)
|
||||
.get(auth('getUnits'), validate(unitValidation.getUnits), unitController.getUnits);
|
||||
.get(auth(), validate(unitValidation.getUnits), unitController.getUnits);
|
||||
|
||||
router
|
||||
.route('/:activityId')
|
||||
.get(auth('getUnits'), validate(unitValidation.getUnit), unitController.getUnit)
|
||||
.patch(auth('manageUnits'), validate(unitValidation.updateUnit), unitController.updateUnit)
|
||||
.delete(auth('manageUnits'), validate(unitValidation.deleteUnit), unitController.deleteUnit);
|
||||
.get(auth(), validate(unitValidation.getUnit), unitController.getUnit)
|
||||
|
||||
module.exports = router;
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* tags:
|
||||
* name: Units
|
||||
* description: Unit management
|
||||
*/
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* path:
|
||||
* /units:
|
||||
* post:
|
||||
* summary: Create a unit
|
||||
* description: Only admins can create units.
|
||||
* tags: [Units]
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* required:
|
||||
* - name
|
||||
* properties:
|
||||
* name:
|
||||
* type: string
|
||||
* description: must be unique
|
||||
* example:
|
||||
* name: g
|
||||
* responses:
|
||||
* "201":
|
||||
* description: Created
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Unit'
|
||||
* "400":
|
||||
* "401":
|
||||
* $ref: '#/components/responses/Unauthorized'
|
||||
* "403":
|
||||
* $ref: '#/components/responses/Forbidden'
|
||||
*
|
||||
* get:
|
||||
* summary: Get all units
|
||||
* description: Only admins can retrieve all units.
|
||||
* tags: [Units]
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* parameters:
|
||||
* - in: query
|
||||
* name: name
|
||||
* schema:
|
||||
* type: string
|
||||
* description: unit name
|
||||
* - in: query
|
||||
* name: name
|
||||
* schema:
|
||||
* type: string
|
||||
* description: Unit name
|
||||
* - in: query
|
||||
* name: sortBy
|
||||
* schema:
|
||||
* type: string
|
||||
* description: sort by query in the form of field:desc/asc (ex. name:asc)
|
||||
* - in: query
|
||||
* name: limit
|
||||
* schema:
|
||||
* type: integer
|
||||
* minimum: 1
|
||||
* default: 10
|
||||
* description: Maximum number of units
|
||||
* - in: query
|
||||
* name: page
|
||||
* schema:
|
||||
* type: integer
|
||||
* minimum: 1
|
||||
* default: 1
|
||||
* description: Page number
|
||||
* responses:
|
||||
* "200":
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* results:
|
||||
* type: array
|
||||
* items:
|
||||
* $ref: '#/components/schemas/Unit'
|
||||
* page:
|
||||
* type: integer
|
||||
* example: 1
|
||||
* limit:
|
||||
* type: integer
|
||||
* example: 10
|
||||
* totalPages:
|
||||
* type: integer
|
||||
* example: 1
|
||||
* totalResults:
|
||||
* type: integer
|
||||
* example: 1
|
||||
* "401":
|
||||
* $ref: '#/components/responses/Unauthorized'
|
||||
* "403":
|
||||
* $ref: '#/components/responses/Forbidden'
|
||||
*/
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* path:
|
||||
* /units/{id}:
|
||||
* get:
|
||||
* summary: Get a unit
|
||||
* description: Logged in users and admins can fetch units.
|
||||
* tags: [Units]
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* description: Unit id
|
||||
* responses:
|
||||
* "200":
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Unit'
|
||||
* "401":
|
||||
* $ref: '#/components/responses/Unauthorized'
|
||||
* "403":
|
||||
* $ref: '#/components/responses/Forbidden'
|
||||
* "404":
|
||||
* $ref: '#/components/responses/NotFound'
|
||||
*
|
||||
* patch:
|
||||
* summary: Update a unit
|
||||
* description: Only admins can update units.
|
||||
* tags: [Users]
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* description: Unit id
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* name:
|
||||
* type: string
|
||||
* description: must be unique
|
||||
* example:
|
||||
* name: g
|
||||
* responses:
|
||||
* "200":
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Unit'
|
||||
* "401":
|
||||
* $ref: '#/components/responses/Unauthorized'
|
||||
* "403":
|
||||
* $ref: '#/components/responses/Forbidden'
|
||||
* "404":
|
||||
* $ref: '#/components/responses/NotFound'
|
||||
*
|
||||
* delete:
|
||||
* summary: Delete a unit
|
||||
* description: Only admins can delete units.
|
||||
* tags: [Users]
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* description: Unit id
|
||||
* responses:
|
||||
* "200":
|
||||
* description: No content
|
||||
* "401":
|
||||
* $ref: '#/components/responses/Unauthorized'
|
||||
* "403":
|
||||
* $ref: '#/components/responses/Forbidden'
|
||||
* "404":
|
||||
* $ref: '#/components/responses/NotFound'
|
||||
*/
|
||||
|
39
src/seeders/activity.seeder.js
Normal file
39
src/seeders/activity.seeder.js
Normal file
@ -0,0 +1,39 @@
|
||||
const { Seeder } = require('mongoose-data-seed');
|
||||
const { Activity } = require('../models');
|
||||
|
||||
const data = [
|
||||
{
|
||||
name: 'very low',
|
||||
factor: 1.2,
|
||||
},
|
||||
{
|
||||
name: 'low',
|
||||
factor: 1.375,
|
||||
},
|
||||
{
|
||||
name: 'average',
|
||||
factor: 1.55,
|
||||
},
|
||||
{
|
||||
name: 'high',
|
||||
factor: 1.725,
|
||||
},
|
||||
{
|
||||
name: 'very high',
|
||||
factor: 1.9,
|
||||
},
|
||||
];
|
||||
|
||||
class ActivitySeeder extends Seeder {
|
||||
async shouldRun() {
|
||||
return Activity.countDocuments()
|
||||
.exec()
|
||||
.then((count) => count === 0);
|
||||
}
|
||||
|
||||
async run() {
|
||||
return Activity.create(data);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ActivitySeeder;
|
25
src/seeders/gender.seeder.js
Normal file
25
src/seeders/gender.seeder.js
Normal file
@ -0,0 +1,25 @@
|
||||
const { Seeder } = require('mongoose-data-seed');
|
||||
const { Gender } = require('../models');
|
||||
|
||||
const data = [
|
||||
{
|
||||
name: 'male',
|
||||
},
|
||||
{
|
||||
name: 'female',
|
||||
},
|
||||
];
|
||||
|
||||
class GenderSeeder extends Seeder {
|
||||
async shouldRun() {
|
||||
return Gender.countDocuments()
|
||||
.exec()
|
||||
.then((count) => count === 0);
|
||||
}
|
||||
|
||||
async run() {
|
||||
return Gender.create(data);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GenderSeeder;
|
4
src/seeders/index.js
Normal file
4
src/seeders/index.js
Normal file
@ -0,0 +1,4 @@
|
||||
module.exports.ActivitySeeder = require('./activity.seeder');
|
||||
module.exports.UnitSeeder = require('./unit.seeder');
|
||||
module.exports.GenderSeeder = require('./gender.seeder');
|
||||
module.exports.ProductSeeder = require('./product.seeder');
|
30
src/seeders/product.seeder.js
Normal file
30
src/seeders/product.seeder.js
Normal file
@ -0,0 +1,30 @@
|
||||
const { Seeder } = require('mongoose-data-seed');
|
||||
const { Product } = require('../models');
|
||||
|
||||
const data = [
|
||||
{
|
||||
barcode: 5449000097750,
|
||||
name: 'cappy - multiwitamina',
|
||||
capacity: 1,
|
||||
kcal: 45,
|
||||
fat: 0,
|
||||
carbohydrates: 10.7,
|
||||
protein: 0,
|
||||
salt: 0,
|
||||
unit: '5fca7e39283d432b84c8e039',
|
||||
},
|
||||
];
|
||||
|
||||
class ProductSeeder extends Seeder {
|
||||
async shouldRun() {
|
||||
return Product.countDocuments()
|
||||
.exec()
|
||||
.then((count) => count === 0);
|
||||
}
|
||||
|
||||
async run() {
|
||||
return Product.create(data);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ProductSeeder;
|
31
src/seeders/unit.seeder.js
Normal file
31
src/seeders/unit.seeder.js
Normal file
@ -0,0 +1,31 @@
|
||||
const { Seeder } = require('mongoose-data-seed');
|
||||
const { Unit } = require('../models');
|
||||
|
||||
const data = [
|
||||
{
|
||||
name: 'kcal',
|
||||
},
|
||||
{
|
||||
name: 'g',
|
||||
},
|
||||
{
|
||||
name: 'ml',
|
||||
},
|
||||
{
|
||||
name: 'l',
|
||||
},
|
||||
];
|
||||
|
||||
class UnitSeeder extends Seeder {
|
||||
async shouldRun() {
|
||||
return Unit.countDocuments()
|
||||
.exec()
|
||||
.then((count) => count === 0);
|
||||
}
|
||||
|
||||
async run() {
|
||||
return Unit.create(data);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = UnitSeeder;
|
@ -1,77 +1,15 @@
|
||||
const httpStatus = require('http-status');
|
||||
const { Activity } = require('../models');
|
||||
const ApiError = require('../utils/ApiError');
|
||||
|
||||
/**
|
||||
* Create a activity
|
||||
* @param {Object} activityBody
|
||||
* @returns {Promise<Activity>}
|
||||
*/
|
||||
const createActivity = async (activityBody) => {
|
||||
if (await Activity.isNameTaken(activityBody.name)) {
|
||||
throw new ApiError(httpStatus.BAD_REQUEST, 'Name already taken');
|
||||
}
|
||||
const activity = await Activity.create(activityBody);
|
||||
return activity;
|
||||
};
|
||||
|
||||
/**
|
||||
* Query for activity
|
||||
* @param {Object} filter - Mongo filter
|
||||
* @param {Object} options - Query options
|
||||
* @param {string} [options.sortBy] - Sort option in the format: sortField:(desc|asc)
|
||||
* @param {number} [options.limit] - Maximum number of results per page (default = 10)
|
||||
* @param {number} [options.page] - Current page (default = 1)
|
||||
* @returns {Promise<QueryResult>}
|
||||
*/
|
||||
const queryActivities = async (filter, options) => {
|
||||
const activities = await Activity.paginate(filter, options);
|
||||
return activities;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get profile by id
|
||||
* @param {ObjectId} id
|
||||
* @returns {Promise<Profile>}
|
||||
*/
|
||||
const getActivityById = async (id) => {
|
||||
return Activity.findById(id);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update activity by id
|
||||
* @param {ObjectId} activityId
|
||||
* @param {Object} updateBody
|
||||
* @returns {Promise<Profile>}
|
||||
*/
|
||||
const updateActivityById = async (activityId, updateBody) => {
|
||||
const activity = await getActivityById(activityId);
|
||||
if (!activity) {
|
||||
throw new ApiError(httpStatus.NOT_FOUND, 'Activity not found');
|
||||
}
|
||||
Object.assign(activity, updateBody);
|
||||
await activity.save();
|
||||
return activity;
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete activity by id
|
||||
* @param {ObjectId} activityId
|
||||
* @returns {Promise<Activity>}
|
||||
*/
|
||||
const deleteActivityById = async (activityId) => {
|
||||
const activity = await getActivityById(activityId);
|
||||
if (!activity) {
|
||||
throw new ApiError(httpStatus.NOT_FOUND, 'Activity not found');
|
||||
}
|
||||
await activity.remove();
|
||||
return activity;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
createActivity,
|
||||
queryActivities,
|
||||
getActivityById,
|
||||
updateActivityById,
|
||||
deleteActivityById,
|
||||
};
|
||||
|
15
src/services/gender.service.js
Normal file
15
src/services/gender.service.js
Normal file
@ -0,0 +1,15 @@
|
||||
const { Unit } = require('../models');
|
||||
|
||||
const queryGenders = async (filter, options) => {
|
||||
const units = await Unit.paginate(filter, options);
|
||||
return units;
|
||||
};
|
||||
|
||||
const getGenderById = async (id) => {
|
||||
return Unit.findById(id);
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
queryGenders,
|
||||
getGenderById,
|
||||
};
|
@ -5,3 +5,4 @@ module.exports.userService = require('./user.service');
|
||||
module.exports.profileService = require('./profile.service');
|
||||
module.exports.activityService = require('./activity.service');
|
||||
module.exports.unitService = require('./unit.service');
|
||||
module.exports.genderService = require('./gender.service');
|
||||
|
55
src/services/product.service.js
Normal file
55
src/services/product.service.js
Normal file
@ -0,0 +1,55 @@
|
||||
const httpStatus = require('http-status');
|
||||
const { Product } = require('../models');
|
||||
const ApiError = require('../utils/ApiError');
|
||||
|
||||
const createProduct = async (productBody) => {
|
||||
if (await Product.isNameTaken(productBody.name)) {
|
||||
throw new ApiError(httpStatus.BAD_REQUEST, 'Product name is taken');
|
||||
}
|
||||
if (await Product.isBarcodeTaken(productBody.barcode)) {
|
||||
throw new ApiError(httpStatus.BAD_REQUEST, 'Product barcode is taken');
|
||||
}
|
||||
const product = await Product.create(productBody);
|
||||
return product;
|
||||
};
|
||||
|
||||
const queryProducts = async (filter, options) => {
|
||||
const products = await Product.paginate(filter, options);
|
||||
return products;
|
||||
};
|
||||
|
||||
const getProductById = async (id) => {
|
||||
return Product.findById(id);
|
||||
};
|
||||
|
||||
const getProductByBarcode = async (barcode) => {
|
||||
return Product.findOne({ barcode });
|
||||
};
|
||||
|
||||
const updateProductById = async (productId, updateBody) => {
|
||||
const product = await getProductById(productId);
|
||||
if (!product) {
|
||||
throw new ApiError(httpStatus.NOT_FOUND, 'Product not found');
|
||||
}
|
||||
Object.assign(product, updateBody);
|
||||
await product.save();
|
||||
return product;
|
||||
};
|
||||
|
||||
const deleteProductById = async (productId) => {
|
||||
const product = await getProductById(productId);
|
||||
if (!product) {
|
||||
throw new ApiError(httpStatus.NOT_FOUND, 'Product not found');
|
||||
}
|
||||
await product.remove();
|
||||
return product;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
createProduct,
|
||||
queryProducts,
|
||||
getProductById,
|
||||
getProductByBarcode,
|
||||
updateProductById,
|
||||
deleteProductById,
|
||||
};
|
@ -1,77 +1,15 @@
|
||||
const httpStatus = require('http-status');
|
||||
const { Unit } = require('../models');
|
||||
const ApiError = require('../utils/ApiError');
|
||||
|
||||
/**
|
||||
* Create a unit
|
||||
* @param {Object} unitBody
|
||||
* @returns {Promise<Unit>}
|
||||
*/
|
||||
const createUnit = async (unitBody) => {
|
||||
if (await Unit.isNameTaken(unitBody.name)) {
|
||||
throw new ApiError(httpStatus.BAD_REQUEST, 'Name already taken');
|
||||
}
|
||||
const unit = await Unit.create(unitBody);
|
||||
return unit;
|
||||
};
|
||||
|
||||
/**
|
||||
* Query for unit
|
||||
* @param {Object} filter - Mongo filter
|
||||
* @param {Object} options - Query options
|
||||
* @param {string} [options.sortBy] - Sort option in the format: sortField:(desc|asc)
|
||||
* @param {number} [options.limit] - Maximum number of results per page (default = 10)
|
||||
* @param {number} [options.page] - Current page (default = 1)
|
||||
* @returns {Promise<QueryResult>}
|
||||
*/
|
||||
const queryUnits = async (filter, options) => {
|
||||
const units = await Unit.paginate(filter, options);
|
||||
return units;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get unit by id
|
||||
* @param {ObjectId} id
|
||||
* @returns {Promise<Unit>}
|
||||
*/
|
||||
const getUnitById = async (id) => {
|
||||
return Unit.findById(id);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update unit by id
|
||||
* @param {ObjectId} unitId
|
||||
* @param {Object} updateBody
|
||||
* @returns {Promise<Unit>}
|
||||
*/
|
||||
const updateUnitById = async (unitId, updateBody) => {
|
||||
const unit = await getUnitById(unitId);
|
||||
if (!unit) {
|
||||
throw new ApiError(httpStatus.NOT_FOUND, 'Unit not found');
|
||||
}
|
||||
Object.assign(unit, updateBody);
|
||||
await Unit.save();
|
||||
return unit;
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete unit by id
|
||||
* @param {ObjectId} unitId
|
||||
* @returns {Promise<Activity>}
|
||||
*/
|
||||
const deleteUnitById = async (unitId) => {
|
||||
const unit = await getUnitById(unitId);
|
||||
if (!unit) {
|
||||
throw new ApiError(httpStatus.NOT_FOUND, 'Unit not found');
|
||||
}
|
||||
await Unit.remove();
|
||||
return unit;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
createUnit,
|
||||
queryUnits,
|
||||
getUnitById,
|
||||
updateUnitById,
|
||||
deleteUnitById,
|
||||
};
|
||||
|
@ -1,13 +1,6 @@
|
||||
const Joi = require('joi');
|
||||
const { objectId } = require('./custom.validation');
|
||||
|
||||
const createActivity = {
|
||||
body: Joi.object().keys({
|
||||
name: Joi.string().required(),
|
||||
factor: Joi.number().required(),
|
||||
}),
|
||||
};
|
||||
|
||||
const getActivities = {
|
||||
query: Joi.object().keys({
|
||||
name: Joi.string(),
|
||||
@ -23,28 +16,7 @@ const getActivity = {
|
||||
}),
|
||||
};
|
||||
|
||||
const updateActivity = {
|
||||
params: Joi.object().keys({
|
||||
activityId: Joi.string().custom(objectId),
|
||||
}),
|
||||
body: Joi.object()
|
||||
.keys({
|
||||
name: Joi.string().required(),
|
||||
factor: Joi.number().required(),
|
||||
})
|
||||
.min(1),
|
||||
};
|
||||
|
||||
const deleteActivity = {
|
||||
params: Joi.object().keys({
|
||||
profileId: Joi.string().custom(objectId),
|
||||
}),
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
createActivity,
|
||||
getActivities,
|
||||
getActivity,
|
||||
updateActivity,
|
||||
deleteActivity,
|
||||
};
|
||||
|
21
src/validations/gender.validation.js
Normal file
21
src/validations/gender.validation.js
Normal file
@ -0,0 +1,21 @@
|
||||
const Joi = require('joi');
|
||||
const { objectId } = require('./custom.validation');
|
||||
|
||||
const getGenders = {
|
||||
query: Joi.object().keys({
|
||||
name: Joi.string(),
|
||||
limit: Joi.number().integer(),
|
||||
page: Joi.number().integer(),
|
||||
}),
|
||||
};
|
||||
|
||||
const getGender = {
|
||||
params: Joi.object().keys({
|
||||
genderId: Joi.string().custom(objectId),
|
||||
}),
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getGenders,
|
||||
getGender,
|
||||
};
|
@ -3,3 +3,4 @@ module.exports.userValidation = require('./user.validation');
|
||||
module.exports.profileValidation = require('./profile.validation');
|
||||
module.exports.activityValidation = require('./activity.validation');
|
||||
module.exports.unitValidation = require('./unit.validation');
|
||||
module.exports.productValidation = require('./product.validation');
|
||||
|
65
src/validations/product.validation.js
Normal file
65
src/validations/product.validation.js
Normal file
@ -0,0 +1,65 @@
|
||||
const Joi = require('joi');
|
||||
const { objectId } = require('./custom.validation');
|
||||
|
||||
const createProduct = {
|
||||
body: Joi.object().keys({
|
||||
barcode: Joi.number(),
|
||||
name: Joi.string().required(),
|
||||
capacity: Joi.number().required(),
|
||||
kcal: Joi.number().required(),
|
||||
fat: Joi.number().required(),
|
||||
carbohydrates: Joi.number().required(),
|
||||
protein: Joi.number().required(),
|
||||
salt: Joi.number(),
|
||||
unit: Joi.string().custom(objectId).required(),
|
||||
}),
|
||||
};
|
||||
|
||||
const getProducts = {
|
||||
query: Joi.object().keys({
|
||||
barcode: Joi.number(),
|
||||
name: Joi.string(),
|
||||
sortBy: Joi.string(),
|
||||
limit: Joi.number().integer(),
|
||||
page: Joi.number().integer(),
|
||||
}),
|
||||
};
|
||||
|
||||
const getProduct = {
|
||||
params: Joi.object().keys({
|
||||
productId: Joi.string().custom(objectId),
|
||||
}),
|
||||
};
|
||||
|
||||
const updateProduct = {
|
||||
params: Joi.object().keys({
|
||||
productId: Joi.required().custom(objectId),
|
||||
}),
|
||||
body: Joi.object()
|
||||
.keys({
|
||||
barcode: Joi.number(),
|
||||
name: Joi.string().required(),
|
||||
capacity: Joi.number().required(),
|
||||
kcal: Joi.number().required(),
|
||||
fat: Joi.number().required(),
|
||||
carbohydrates: Joi.number().required(),
|
||||
protein: Joi.number().required(),
|
||||
salt: Joi.number(),
|
||||
unit: Joi.string().custom(objectId).required(),
|
||||
})
|
||||
.min(1),
|
||||
};
|
||||
|
||||
const deleteProduct = {
|
||||
params: Joi.object().keys({
|
||||
productId: Joi.string().custom(objectId).required(),
|
||||
}),
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
createProduct,
|
||||
getProducts,
|
||||
getProduct,
|
||||
updateProduct,
|
||||
deleteProduct,
|
||||
};
|
@ -1,12 +1,6 @@
|
||||
const Joi = require('joi');
|
||||
const { objectId } = require('./custom.validation');
|
||||
|
||||
const createUnit = {
|
||||
body: Joi.object().keys({
|
||||
name: Joi.string().required(),
|
||||
}),
|
||||
};
|
||||
|
||||
const getUnits = {
|
||||
query: Joi.object().keys({
|
||||
name: Joi.string(),
|
||||
@ -21,27 +15,7 @@ const getUnit = {
|
||||
}),
|
||||
};
|
||||
|
||||
const updateUnit = {
|
||||
params: Joi.object().keys({
|
||||
unitId: Joi.string().custom(objectId),
|
||||
}),
|
||||
body: Joi.object()
|
||||
.keys({
|
||||
name: Joi.string().required(),
|
||||
})
|
||||
.min(1),
|
||||
};
|
||||
|
||||
const deleteUnit = {
|
||||
params: Joi.object().keys({
|
||||
unitId: Joi.string().custom(objectId),
|
||||
}),
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
createUnit,
|
||||
getUnits,
|
||||
getUnit,
|
||||
updateUnit,
|
||||
deleteUnit,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user