Skip to content

Commit

Permalink
Merge pull request #240 from deolla/feat/get-product
Browse files Browse the repository at this point in the history
feat: Implement GET All User Products Endoint with Pagination (Page, Limit, Offset)
  • Loading branch information
incredible-phoenix246 authored Jul 24, 2024
2 parents dc4e16b + 675091f commit 593c056
Show file tree
Hide file tree
Showing 16 changed files with 1,154 additions and 819 deletions.
5 changes: 4 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ SMTP_USER=
SMTP_PASSWORD=
SMTP_HOST=
SMTP_SERVICE=
TWILIO_SID=
TWILIO_AUTH_TOKEN=
TWILIO_PHONE_NUMBER=
TWILIO_ACCOUNT_SID=
TWILIO_AUTH_TOKEN=
#Redis Configuration
REDIS_HOST=
REDIS_PORT=
REDIS_PORT=
10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"test:email": "jest views/email/tests",
"typeorm": "typeorm-ts-node-commonjs",
"build": "tsc",
"seed": "ts-node src/seeder.ts",
"prod": "node build/index.js",
"migrate": "typeorm-ts-node-commonjs migration:run -d src/data-source",
"migration:create": "typeorm-ts-node-commonjs migration:create db/migrations/migration",
Expand All @@ -35,6 +36,9 @@
"@types/supertest": "^6.0.2",
"@types/swagger-jsdoc": "^6.0.4",
"@types/swagger-ui-express": "^4.1.6",
"jest": "^29.7.0",
"supertest": "^7.0.0",
"ts-jest": "^29.2.3",
"husky": "^9.1.1",
"lint-staged": "^15.2.7",
"prettier": "^3.3.3",
Expand Down Expand Up @@ -63,19 +67,21 @@
"express-validator": "^7.1.0",
"fs-extra": "^11.2.0",
"handlebars": "^4.7.8",

"jest-mock-extended": "^3.0.7",

"jest": "^29.7.0",
"json2csv": "^6.0.0-alpha.2",

"jsonwebtoken": "^9.0.2",
"node-mailer": "^0.1.1",
"pdfkit": "^0.15.0",
"pg": "^8.12.0",
"pino": "^9.3.1",
"pino-pretty": "^11.2.1",
"reflect-metadata": "^0.1.14",
"supertest": "^7.0.0",
"swagger-jsdoc": "^6.2.8",
"swagger-ui-express": "^5.0.1",
"ts-jest": "^29.2.3",
"ts-node-dev": "^2.0.0",
"twilio": "^5.2.2",
"typeorm": "^0.3.20",
Expand Down
4 changes: 2 additions & 2 deletions src/controllers/AuthController.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Request, Response, NextFunction } from "express";
import { AuthService } from "../services";
import { AuthService } from "../services/auth.services";

const authService = new AuthService();

Expand Down Expand Up @@ -56,7 +56,7 @@ const authService = new AuthService();
const signUp = async (req: Request, res: Response, next: NextFunction) => {
try {
const { mailSent, newUser, access_token } = await authService.signUp(
req.body
req.body,
);
res.status(201).json({ mailSent, newUser, access_token });
} catch (error) {
Expand Down
2 changes: 1 addition & 1 deletion src/controllers/HelpController.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// src/controllers/UserController.ts
import { Request, Response } from "express";
import { HelpService } from "../services";
import { HelpService } from "../services/help.services";
import { HttpError } from "../middleware";

class HelpController {
Expand Down
70 changes: 34 additions & 36 deletions src/controllers/ProductController.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { Request, Response } from "express";
import { ProductService } from "../services"; // Adjust the import path as necessary
import { ProductService } from "../services/product.services"; // Adjust the import path as necessary

export class ProductController {
private productService = new ProductService();
private productService: ProductService;

constructor() {
this.productService = new ProductService();
}
/**
* @swagger
* tags:
Expand Down Expand Up @@ -126,45 +130,37 @@ export class ProductController {
* type: string
* example: An unexpected error occurred while processing your request. Please try again later
*/
async listProducts(req: Request, res: Response): Promise<void> {
async getProductPagination(req: Request, res: Response) {
try {
const page = parseInt(req.query.page as string) || 1;
const limit = parseInt(req.query.limit as string) || 10;

if (page <= 0 || limit <= 0) {
const paginationData = await this.productService.getProductPagination(
req.query,
);
res.status(200).json({
status: "success",
status_code: 200,
data: paginationData,
});
} catch (err) {
if (err.message.includes("out of range")) {
res.status(400).json({
error: "Page out of range",
message: err.message,
status_code: 400,
});
} else if (err.message.includes("positive integers")) {
res.status(400).json({
status: "bad request",
message: "Invalid query params passed",
error: "Invalid query parameters",
message: err.message,
status_code: 400,
});
return;
} else {
res.status(500).json({
error: "Internal server error",
message: err.message,
status_code: 500,
});
console.error(err);
}

const { products, totalItems } =
await this.productService.getPaginatedProducts(page, limit);

res.json({
success: true,
message: "Products retrieved successfully",
products: products.map((product) => ({
name: product.name,
description: product.description,
price: product.price,
category: product.category,
})),
pagination: {
totalItems,
totalPages: Math.ceil(totalItems / limit),
currentPage: page,
},
status_code: 200,
});
} catch (error) {
res.status(500).json({
status: "error",
message: "Internal server error",
status_code: 500,
});
}
}

Expand Down Expand Up @@ -521,3 +517,5 @@ export class ProductController {
*/
async deleteProduct(req: Request, res: Response) {}
}

export default ProductController;
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,14 @@ server.use("/api/v1/help-center", helpRouter);
server.use("/api/v1", exportRouter);
server.use("/api/v1/sms", smsRouter);
server.use("/api/v1", testimonialRoute);
server.use("/api/v1/products", productRouter);
server.use("/api/v1/blog", blogRouter);
server.use("/api/v1", blogRouter);
server.use("/api/v1/product", productRouter);
server.use("/api/v1/docs", swaggerUi.serve, swaggerUi.setup(swaggerSpec));
server.use("/api/v1/settings", notificationRouter);
server.use("/api/v1/jobs", jobRouter);
server.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
server.use("/api/v1", orgRouter);
server.use("/api/v1", authMiddleware, orgRouter);
server.use("/admin/queues", ServerAdapter.getRouter());
Expand Down
30 changes: 30 additions & 0 deletions src/models/product.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,36 @@ import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from 'typeorm';
import { User } from './user';
import ExtendedBaseEntity from './extended-base-entity';


/**
* @swagger
* components:
* schemas:
* Product:
* type: object
* required:
* - name
* - description
* - price
* - category
* properties:
* id:
* type: string
* description: The auto-generated id of the product
* name:
* type: string
* description: Name of the product
* description:
* type: string
* description: Description of the product
* price:
* type: number
* description: Price of the product
* category:
* type: string
* description: Category of the product
*/

@Entity()
export class Product extends ExtendedBaseEntity {
@PrimaryGeneratedColumn('uuid')
Expand Down
2 changes: 1 addition & 1 deletion src/routes/help-center.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// src/routes/help-center.ts
import { Router } from "express";
import HelpController from "../controllers/HelpController";
import { authMiddleware, verifyAdmin } from "../services";
import { authMiddleware} from "../middleware/auth";

const helpRouter = Router();
const helpController = new HelpController();
Expand Down
85 changes: 82 additions & 3 deletions src/routes/product.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,93 @@
import express from 'express';
import { ProductController } from '../controllers';
import ProductController from '../controllers/ProductController';
import { authMiddleware } from '../middleware';

const productRouter = express.Router();
const productController = new ProductController();

/**
* @swagger
* tags:
* name: Products
* description: API for products management.
*/

/**
* @swagger
* /api/v1/products/:
* get:
* summary: Get paginated products
* tags: [Products]
* parameters:
* - in: query
* name: page
* schema:
* type: integer
* default: 1
* description: Page number
* - in: query
* name: limit
* schema:
* type: integer
* default: 10
* description: Number of items per page
* responses:
* 200:
* description: Success
* content:
* application/json:
* schema:
* type: object
* properties:
* status:
* type: string
* status_code:
* type: integer
* data:
* type: object
* properties:
* page:
* type: integer
* limit:
* type: integer
* totalProducts:
* type: integer
* products:
* type: array
* items:
* $ref: '#/models/product'
* 400:
* description: Invalid query parameters
* content:
* application/json:
* schema:
* type: object
* properties:
* error:
* type: string
* message:
* type: string
* status_code:
* type: integer
* 500:
* description: Internal server error
* content:
* application/json:
* schema:
* type: object
* properties:
* error:
* type: string
* message:
* type: string
* status_code:
* type: integer
*/

productRouter.get(
'/products',
'/',
authMiddleware,
productController.listProducts.bind(productController)
productController.getProductPagination.bind(productController)
);

export { productRouter };
Loading

0 comments on commit 593c056

Please sign in to comment.