Skip to content

Commit

Permalink
feat: Add migration for adding roles to User model and create Product…
Browse files Browse the repository at this point in the history
… model

- Added migration file for adding roles to the User model
- Created a new migration file for creating the Product model and its corresponding table in the database
- Updated the schema.prisma file to include the Role enum and the Product model definition
- Added a new controller file for handling product-related operations
- Implemented the createProduct and updateProduct methods in the Product controller
- Created routes for product CRUD operations, protected by authentication and admin middleware
  • Loading branch information
shanthi1710 committed Jun 19, 2024
1 parent bcc161e commit 9bfefdf
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- CreateEnum
CREATE TYPE "Role" AS ENUM ('ADMIN', 'USER');

-- AlterTable
ALTER TABLE "User" ADD COLUMN "role" "Role" NOT NULL DEFAULT 'USER';
12 changes: 12 additions & 0 deletions prisma/migrations/20240619132413_add_product_table/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-- CreateTable
CREATE TABLE "products" (
"id" SERIAL NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT NOT NULL,
"price" DECIMAL(65,30) NOT NULL,
"tags" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,

CONSTRAINT "products_pkey" PRIMARY KEY ("id")
);
18 changes: 18 additions & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,30 @@ datasource db {
url = env("DATABASE_URL")
}

enum Role {
ADMIN
USER
}

model User {
id String @id @default(cuid())
firstName String @map("first_name")
lastName String? @map("last_name")
email String @unique
password String
role Role @default(USER)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}

model Product {
id Int @id @default(autoincrement())
name String
description String
price Decimal
tags String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map("products")
}
45 changes: 45 additions & 0 deletions src/controllers/products.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Request,Response } from "express";
import { prismaClient } from "../lib/db";
import { NotFoundException } from "../exceptions/not-found";
import { ErrorCode } from "../exceptions/root";

export default class Product{
public static createProduct = async(req:Request,res:Response)=>{

const product = await prismaClient.product.create({
data:{
...req.body,
tags:req.body.tags.join(',')
}
})
res.json(product)
}
public static updateProduct = async(req:Request,res:Response)=>{
try {
const product = req.body;
if(product.tags){
product.tags = product.tags.join(',')
}
const updateProduct = await prismaClient.product.update({
where:{
id:+req.params.id
},
data:product
})
res.json(updateProduct)
} catch (error) {
throw new NotFoundException('Product not found..!',ErrorCode.PRODUCT_NOT_FOUND)
}
}
public static deleteProduct = async(req:Request,res:Response)=>{

}
public static ListProducts = async(req:Request,res:Response)=>{

}
public static getProductsById = async(req:Request,res:Response)=>{

}
}


3 changes: 2 additions & 1 deletion src/exceptions/root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ export enum ErrorCode{
INCORRECT_PASSWORD = 1003,
UNPROCESSABLE_ENTITY =2001,
INTERNAL_SERVER_ERROR = 3001,
UnauthorizedException_ERROR =4001
UnauthorizedException_ERROR =4001,
PRODUCT_NOT_FOUND = 5001
}
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import express,{Express} from "express"
import { PORT } from "./secrets"
import authRouter from './routes/auth.route';
import productRouter from './routes/products.route'
import { json, urlencoded } from 'express';
import { errorMiddleware } from "./middlewares/errors";

Expand All @@ -13,8 +14,10 @@ app.use(urlencoded({ extended: true }));


app.use('/api/v1/auth', authRouter);
app.use('/api/v1/products',productRouter)

app.use(errorMiddleware)

app.listen(PORT,()=>{
console.log(`Server is running on port ${PORT}`);
})
15 changes: 15 additions & 0 deletions src/middlewares/admin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

import { NextFunction,Request,Response } from "express";
import { UnauthorizedException } from "../exceptions/unauthorized";
import { ErrorCode } from "../exceptions/root";
const adminMiddleware = async(req:Request,res:Response,next:NextFunction)=>{
const user = req.user
if(user?.role == 'ADMIN'){
next()

}else{
next (new UnauthorizedException('Unauthorized',ErrorCode.UnauthorizedException_ERROR))
}
}

export default adminMiddleware;
2 changes: 0 additions & 2 deletions src/middlewares/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,11 @@ const authMiddleware = async(req:Request,res:Response,next:NextFunction)=>{
throw new UnauthorizedException('Unauthorized',ErrorCode.UnauthorizedException_ERROR)
}
// 5. to attach the user to the current request object

req.user = user;
next();
} catch (error) {
next (new UnauthorizedException('Unauthorized',ErrorCode.UnauthorizedException_ERROR))
}

}

export default authMiddleware;
14 changes: 14 additions & 0 deletions src/routes/products.route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Router } from "express";
import Product from "../controllers/products.controller"
import { errorHandler } from "../error-handler";
import authMiddleware from "../middlewares/auth";
import adminMiddleware from "../middlewares/admin";

const routes:Router = Router();

routes.post('/',[authMiddleware,adminMiddleware],errorHandler(Product.createProduct))
routes.put('/:id',[authMiddleware,adminMiddleware],errorHandler(Product.updateProduct))
routes.delete('/:id',[authMiddleware,adminMiddleware],errorHandler(Product.deleteProduct))
routes.get('/',[authMiddleware,adminMiddleware],errorHandler(Product.ListProducts))
routes.get('/:id',[authMiddleware,adminMiddleware],errorHandler(Product.getProductsById))
export default routes;

0 comments on commit 9bfefdf

Please sign in to comment.