-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #48 from atlp-rwanda/187530397-bg-swagger-auth
[finishes #187530397] adding auth field for swagger apis
- Loading branch information
Showing
24 changed files
with
905 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { Request, Response } from 'express'; | ||
import { Category, CategoryCreationAttributes } from '../database/models/Category'; | ||
import logger from '../logs/config'; | ||
|
||
export const createCategory = async (req: Request, res: Response) => { | ||
try { | ||
const { name, description } = req.body as CategoryCreationAttributes; | ||
const newCategory = await Category.create({ | ||
name, | ||
description, | ||
}); | ||
res.status(201).json({ status: 201, ok: true, message: 'New category created successully!', data: newCategory }); | ||
} catch (error) { | ||
if (error instanceof Error) { | ||
logger.error(error.message); | ||
} | ||
res.status(500).json({ error: 'Failed to create category' }); | ||
} | ||
}; | ||
|
||
export const getCategory = async (req: Request, res: Response) => { | ||
try { | ||
const categories = await Category.findAll(); | ||
res.status(200).json({ ok: true, data: categories }); | ||
} catch (error) { | ||
if (error instanceof Error) { | ||
logger.error(error.message); | ||
} | ||
res.status(500).json({ error: 'Failed to fetch categories' }); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
import { Request, Response } from 'express'; | ||
import { Product, ProductCreationAttributes } from '../database/models/Product'; | ||
import logger from '../logs/config'; | ||
import uploadImage from '../helpers/claudinary'; | ||
import { validateFields } from '../validations'; | ||
import { Size, SizeCreationAttributes } from '../database/models/Size'; | ||
|
||
export const createProductWithSize = async (req: Request, res: Response) => { | ||
try { | ||
// when products exists | ||
const name = req.body.name; | ||
const thisProductExists = await Product.findOne({ where: { name } }); | ||
|
||
if (thisProductExists) { | ||
return res.status(400).json({ | ||
status: 400, | ||
ok: false, | ||
message: 'This Product already exists, You can update the stock levels instead.', | ||
data: thisProductExists, | ||
}); | ||
} | ||
// handle images | ||
const productImages = ['asdf', 'asdf', 'asdf']; | ||
const images: unknown = req.files; | ||
if (images instanceof Array && images.length > 3) { | ||
for (const image of images) { | ||
const imageBuffer: Buffer = image.buffer; | ||
const url = await uploadImage(imageBuffer); | ||
productImages.push(url); | ||
} | ||
} else { | ||
return res.status(400).json({ | ||
status: 400, | ||
message: 'Product should have at least 4 images', | ||
}); | ||
} | ||
|
||
// Create product | ||
const categoryId = req.params.categoryId; | ||
const requiredFields = ['name', 'description', 'sellerId']; | ||
const missingFields = validateFields(req, requiredFields); | ||
|
||
if (missingFields.length > 0) { | ||
res.status(400).json({ | ||
ok: false, | ||
message: `Required fields are missing: ${missingFields.join(', ')}`, | ||
}); | ||
} | ||
|
||
const { description, discount, sellerId, expiryDate } = req.body; | ||
|
||
const createdProduct = await Product.create({ | ||
sellerId, | ||
name, | ||
description, | ||
discount, | ||
categoryId, | ||
expiryDate, | ||
images: productImages, | ||
}); | ||
|
||
res.status(201).json({ | ||
status: 201, | ||
ok: true, | ||
data: createdProduct, | ||
message: 'Thank you for adding new product in the store!', | ||
}); | ||
} catch (error) { | ||
if (error instanceof Error) { | ||
res.status(500).json({ | ||
status: 500, | ||
ok: false, | ||
message: 'Something went wrong when creating the product', | ||
error: error.message, | ||
}); | ||
} else { | ||
logger.error('Unexpected error', error); | ||
} | ||
} | ||
}; | ||
|
||
export const createProductWithoutSize = async (req: Request, res: Response) => { | ||
try { | ||
// when products exists | ||
const name = req.body.name; | ||
const thisProductExists = await Product.findOne({ where: { name } }); | ||
|
||
if (thisProductExists) { | ||
return res.status(400).json({ | ||
status: 400, | ||
ok: false, | ||
message: 'This Product already exists, You can update the stock levels instead.', | ||
data: thisProductExists, | ||
}); | ||
} | ||
// handle images | ||
const productImages = []; | ||
const images: unknown = req.files; | ||
if (images instanceof Array && images.length > 3) { | ||
for (const image of images) { | ||
const imageBuffer: Buffer = image.buffer; | ||
const url = await uploadImage(imageBuffer); | ||
productImages.push(url); | ||
} | ||
} else { | ||
return res.status(400).json({ | ||
status: 400, | ||
message: 'Product should have at least 4 images', | ||
}); | ||
} | ||
// validate inputs | ||
const categoryId = req.params.categoryId; | ||
const requiredFields = ['name', 'description', 'sellerId', 'price', 'quantity']; | ||
const missingFields = validateFields(req, requiredFields); | ||
|
||
if (missingFields.length > 0) { | ||
res.status(400).json({ | ||
ok: false, | ||
message: `Required fields are missing: ${missingFields.join(', ')}`, | ||
}); | ||
} | ||
|
||
// Create product | ||
const { description, discount, sellerId, expiryDate, price, quantity } = req.body as ProductCreationAttributes; | ||
|
||
const createdProduct = await Product.create({ | ||
sellerId, | ||
name, | ||
description, | ||
discount, | ||
price, | ||
quantity, | ||
categoryId, | ||
expiryDate, | ||
images: productImages, | ||
}); | ||
|
||
res.status(201).json({ | ||
status: 201, | ||
ok: true, | ||
data: createdProduct, | ||
message: 'Thank you for adding new product in the store!', | ||
}); | ||
} catch (error) { | ||
if (error instanceof Error) { | ||
res.status(500).json({ | ||
status: 500, | ||
ok: false, | ||
message: 'Something went wrong when creating the product', | ||
error: error.message, | ||
}); | ||
} else { | ||
logger.error('Unexpected error', error); | ||
} | ||
} | ||
}; | ||
|
||
export const createSize = async (req: Request, res: Response) => { | ||
try { | ||
const { size_name, size_prefix, price, productId } = req.body as SizeCreationAttributes; | ||
const createdSize = await Size.create({ size_name, size_prefix, price, productId }); | ||
res.status(201).json({ | ||
status: 201, | ||
ok: true, | ||
message: 'Product size created successfully', | ||
data: createdSize, | ||
}); | ||
} catch (error) { | ||
if (error instanceof Error) { | ||
res.status(500).json({ | ||
status: 500, | ||
ok: false, | ||
message: 'Something went wrong when creating size', | ||
error: error.message, | ||
}); | ||
logger.error(error.message); | ||
} | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
/* eslint-disable @typescript-eslint/no-unused-vars */ | ||
'use strict'; | ||
const sequelize = require('sequelize'); | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* eslint-disable @typescript-eslint/no-var-requires */ | ||
'use strict'; | ||
|
||
const sequelize = require('sequelize'); | ||
|
||
/** @type {import('sequelize-cli').Migration} */ | ||
module.exports = { | ||
async up(queryInterface, Sequelize) { | ||
await queryInterface.createTable('categories', { | ||
id: { | ||
allowNull: false, | ||
primaryKey: true, | ||
type: Sequelize.UUID, | ||
defaultValue: sequelize.UUIDV4, | ||
unique: true, | ||
}, | ||
name: { | ||
type: Sequelize.STRING, | ||
allowNull: false, | ||
}, | ||
description: { | ||
type: Sequelize.TEXT, | ||
allowNull: true, | ||
}, | ||
createdAt: { | ||
allowNull: false, | ||
type: Sequelize.DATE, | ||
defaultValue: Sequelize.literal('NOW()'), | ||
}, | ||
updatedAt: { | ||
allowNull: false, | ||
type: Sequelize.DATE, | ||
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), | ||
}, | ||
}); | ||
}, | ||
async down(queryInterface) { | ||
await queryInterface.dropTable('categories'); | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
/* eslint-disable @typescript-eslint/no-var-requires */ | ||
'use strict'; | ||
|
||
const sequelize = require('sequelize'); | ||
|
||
/** @type {import('sequelize-cli').Migration} */ | ||
module.exports = { | ||
async up(queryInterface, Sequelize) { | ||
await queryInterface.createTable('products', { | ||
id: { | ||
allowNull: false, | ||
primaryKey: true, | ||
type: Sequelize.UUID, | ||
defaultValue: sequelize.UUIDV4, | ||
unique: true, | ||
}, | ||
name: { | ||
type: Sequelize.STRING, | ||
allowNull: false, | ||
}, | ||
description: { | ||
type: Sequelize.TEXT, | ||
allowNull: false, | ||
}, | ||
discount: { | ||
type: Sequelize.FLOAT, | ||
allowNull: true, | ||
defaultValue: 1, | ||
}, | ||
images: { | ||
type: Sequelize.ARRAY(Sequelize.STRING), | ||
allowNull: false, | ||
}, | ||
color: { | ||
type: Sequelize.ARRAY(Sequelize.STRING), | ||
allowNull: true, | ||
}, | ||
expiryDate: { | ||
type: Sequelize.DATE, | ||
allowNull: true, | ||
}, | ||
price: { | ||
type: Sequelize.FLOAT, | ||
allowNull: true, | ||
}, | ||
quantity: { | ||
type: Sequelize.INTEGER, | ||
defaultValue: 1, | ||
allowNull: false, | ||
}, | ||
sellerId: { | ||
type: Sequelize.UUID, | ||
references: { | ||
model: 'Users', | ||
key: 'id', | ||
}, | ||
onDelete: 'CASCADE', | ||
onUpdate: 'CASCADE', | ||
allowNull: false, | ||
}, | ||
categoryId: { | ||
type: Sequelize.UUID, | ||
allowNull: false, | ||
references: { | ||
model: 'categories', | ||
key: 'id', | ||
}, | ||
onUpdate: 'CASCADE', | ||
onDelete: 'CASCADE', | ||
}, | ||
createdAt: { | ||
allowNull: false, | ||
type: Sequelize.DATE, | ||
defaultValue: Sequelize.literal('NOW()'), | ||
}, | ||
updatedAt: { | ||
allowNull: false, | ||
type: Sequelize.DATE, | ||
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), | ||
}, | ||
}); | ||
}, | ||
async down(queryInterface) { | ||
await queryInterface.dropTable('product_sizes'); | ||
await queryInterface.dropTable('products'); | ||
}, | ||
}; |
Oops, something went wrong.