Skip to content

Commit

Permalink
feat: Product router, controller, service and repository created
Browse files Browse the repository at this point in the history
  • Loading branch information
Axeloooo committed Jan 18, 2024
1 parent af4f80a commit 61a4c6b
Show file tree
Hide file tree
Showing 13 changed files with 367 additions and 80 deletions.
34 changes: 34 additions & 0 deletions backend/src/abstracts/product.abstract.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
type PrismaProduct = {
id: string;
title: string;
size: string;
color: string;
description: string;
gender: string;
category: string;
price: number;
imageUrl: string;
createdAt: Date;
updatedAt: Date;
};

type PrismaProducts = PrismaProduct[];

abstract class ProductProvider {
abstract getProducts(): Promise<PrismaProducts | Error>;

abstract getProductById(id: string): Promise<PrismaProduct | Error>;

abstract createProduct(
title: string,
size: string,
color: string,
description: string,
gender: string,
category: string,
price: number,
imageUrl: string
): Promise<PrismaProduct | Error>;

abstract deleteProduct(id: string): Promise<PrismaProduct | Error>;
}
8 changes: 4 additions & 4 deletions backend/src/controllers/algorithm.controller.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Request, Response, NextFunction } from "express";
import { BadRequestError } from "../errors/errors.js";
import { HttpBadRequestError } from "../errors/http.error.js";
import { AlgorithmServiceInterface } from "../../types.js";

class AlgorithmController {
Expand All @@ -13,7 +13,7 @@ class AlgorithmController {
try {
const prompt: string = req.body.prompt;
if (!prompt) {
return next(new BadRequestError("No string was provided!"));
return next(new HttpBadRequestError());
}

const isEcoFriendly: boolean =
Expand All @@ -23,8 +23,8 @@ class AlgorithmController {
return res.status(200).json("Clothing is not eco-friendly!");
}
return res.status(200).json("Clothing is eco-friendly!");
} catch (err) {
next(err);
} catch (e) {
next(e);
}
};
}
Expand Down
70 changes: 70 additions & 0 deletions backend/src/controllers/product.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { Request, Response, NextFunction } from "express";

class ProductController {
constructor(private service: ProductProvider) {
this.service = service;
}

getProducts = async (
req: Request,
res: Response,
next: NextFunction
): Promise<Response<any, Record<string, any>> | void> => {
try {
const products = await this.service.getProducts();
return res.status(200).json(products);
} catch (e) {
next(e);
}
};

getProductById = async (
req: Request,
res: Response,
next: NextFunction
): Promise<Response<any, Record<string, any>> | void> => {
try {
const product = await this.service.getProductById(req.params.id);
return res.status(200).json(product);
} catch (e) {
next(e);
}
};

postProduct = async (
req: Request,
res: Response,
next: NextFunction
): Promise<Response<any, Record<string, any>> | void> => {
try {
const newProduct = await this.service.createProduct(
req.body.title,
req.body.size,
req.body.color,
req.body.description,
req.body.gender,
req.body.category,
req.body.price,
req.body.imageUrl
);
return res.status(201).json(newProduct);
} catch (e) {
next(e);
}
};

deleteProduct = async (
req: Request,
res: Response,
next: NextFunction
): Promise<Response<any, Record<string, any>> | void> => {
try {
const product = await this.service.deleteProduct(req.params.id);
return res.status(200).json(product);
} catch (e) {
next(e);
}
};
}

export default ProductController;
27 changes: 0 additions & 27 deletions backend/src/errors/errors.ts

This file was deleted.

7 changes: 7 additions & 0 deletions backend/src/errors/http.error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export class HttpBadRequestError extends Error {}

export class HttpUnauthorizedError extends Error {}

export class HttpForbiddenError extends Error {}

export class HttpNotFoundError extends Error {}
11 changes: 11 additions & 0 deletions backend/src/errors/prisma.error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export class PrismaClientKnownRequestError extends Error {}

export class PrismaClientUnknownRequestError extends Error {}

export class PrismaClientRustPanicError extends Error {}

export class PrismaClientInitializationError extends Error {}

export class PrismaClientValidationError extends Error {}

export class PrismaGenericError extends Error {}
1 change: 1 addition & 0 deletions backend/src/errors/product.error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export class ProductNotFoundError extends Error {}
32 changes: 4 additions & 28 deletions backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,20 @@ import express, { Express } from "express";
import cors from "cors";
import { PORT } from "./config/config.js";
import errorHandler from "./middlewares/error.middleware.js";

import { PrismaClient } from "@prisma/client";
import algorithmRouter from "./routes/algorithm.routes.js";
import productRouter from "./routes/product.routes.js";

import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
export const app: Express = express();
export const prisma = new PrismaClient();

app.use(express.json());

app.use(cors());

app.use("/api/v1/algorithm", algorithmRouter);

app.post("/product", async (request, response) => {
const {title, size, color, description, gender, category, price, imageUrl} = request.body
const newProduct = await prisma.product.create({
data: {
title, size, color, description, gender, category, price, imageUrl
}
})
response.json(newProduct)
})

app.get("/products", async (request, response) => {
//add filtering
const prods = await prisma.product.findMany();

response.json(prods);
});

app.get("/product/:id", async (request, response) => {
let prodID = request.params.id;
const product = await prisma.product.findUnique({
where: {id: prodID}
})

response.json(product);
});
app.use("/api/v1/products", productRouter);

app.use(errorHandler);

Expand Down
55 changes: 35 additions & 20 deletions backend/src/middlewares/error.middleware.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,45 @@
import { Request, Response, NextFunction } from "express";
import {
BadRequestError,
ForbiddenError,
NotFoundError,
UnauthorizedError,
} from "../errors/errors.js";

HttpBadRequestError,
HttpForbiddenError,
HttpNotFoundError,
HttpUnauthorizedError,
} from "../errors/http.error.js";
import {
PrismaClientInitializationError,
PrismaClientRustPanicError,
PrismaClientUnknownRequestError,
PrismaClientValidationError,
PrismaGenericError,
} from "../errors/prisma.error.js";
import { ProductNotFoundError } from "../errors/product.error.js";
export default function errorHandler(
err: Error,
e: Error,
req: Request,
res: Response,
next: NextFunction
) {
if (err instanceof BadRequestError) {
res.status(400).json(err.message);
} else if (err instanceof UnauthorizedError) {
res.status(401).json(err.message);
} else if (err instanceof ForbiddenError) {
res.status(403).json(err.message);
} else if (err instanceof NotFoundError) {
res.status(404).json(err.message);
if (e instanceof HttpBadRequestError) {
res.status(400).json({ error: "Bad Request Error" });
} else if (e instanceof HttpUnauthorizedError) {
res.status(401).json({ error: "Unauthorized Error" });
} else if (e instanceof HttpForbiddenError) {
res.status(403).json({ error: "Forbidden Error" });
} else if (e instanceof HttpNotFoundError) {
res.status(404).json({ error: "Not Found Error" });
} else if (e instanceof PrismaClientUnknownRequestError) {
res.status(500).json({ error: "Prisma Client Unknown Request Error" });
} else if (e instanceof PrismaClientRustPanicError) {
res.status(500).json({ error: "Prisma Client Rust Panic Error" });
} else if (e instanceof PrismaClientInitializationError) {
res.status(500).json({ error: "Prisma Client Initialization Error" });
} else if (e instanceof PrismaClientValidationError) {
res.status(500).json({ error: "Prisma Client Validation Error" });
} else if (e instanceof PrismaGenericError) {
res.status(500).json({ error: "Prisma Generic Error" });
} else if (e instanceof ProductNotFoundError) {
res.status(500).json({ error: "Product Not Found Error" });
} else {
res.status(500).json({
name: err.name,
message: err.message,
stack: err.stack,
});
res.status(500).json({ error: "Unexpected error" });
}
}
Loading

0 comments on commit 61a4c6b

Please sign in to comment.