adding the plan post api
This commit is contained in:
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- Added the required column `subscriptionId` to the `Account` table without a default value. This is not possible if the table is not empty.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- CreateEnum
|
||||||
|
CREATE TYPE "PType" AS ENUM ('FREE', 'STANDARD', 'PRO');
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Account" ADD COLUMN "isSubscribe" BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
ADD COLUMN "subscriptionId" TEXT NOT NULL;
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "Plan" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"planName" TEXT NOT NULL,
|
||||||
|
"price" INTEGER NOT NULL,
|
||||||
|
"planType" "PType" NOT NULL,
|
||||||
|
"planDesc" TEXT NOT NULL,
|
||||||
|
"planFeatures" JSONB NOT NULL,
|
||||||
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "Plan_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "Account" ADD CONSTRAINT "Account_subscriptionId_fkey" FOREIGN KEY ("subscriptionId") REFERENCES "Plan"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
-- DropForeignKey
|
||||||
|
ALTER TABLE "Account" DROP CONSTRAINT "Account_subscriptionId_fkey";
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Account" ALTER COLUMN "subscriptionId" DROP NOT NULL;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "Account" ADD CONSTRAINT "Account_subscriptionId_fkey" FOREIGN KEY ("subscriptionId") REFERENCES "Plan"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||||
@@ -12,6 +12,9 @@ model Account {
|
|||||||
lastOtpSendingTime DateTime?
|
lastOtpSendingTime DateTime?
|
||||||
isDeleted Boolean @default(false)
|
isDeleted Boolean @default(false)
|
||||||
isAccountVerified Boolean @default(false)
|
isAccountVerified Boolean @default(false)
|
||||||
|
isSubscribe Boolean @default(false)
|
||||||
|
subscriptionId String?
|
||||||
|
plan Plan? @relation(fields: [subscriptionId], references: [id])
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now())
|
updatedAt DateTime @default(now())
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
enum PType {
|
||||||
|
FREE
|
||||||
|
STANDARD
|
||||||
|
PRO
|
||||||
|
}
|
||||||
|
|
||||||
|
model Plan {
|
||||||
|
id String @id @default(uuid())
|
||||||
|
planName String
|
||||||
|
price Int
|
||||||
|
planType PType
|
||||||
|
planDesc String
|
||||||
|
planFeatures Json
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
account Account[]
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
|
||||||
|
import catchAsync from "../../utils/catch_async";
|
||||||
|
import manageResponse from "../../utils/manage_response";
|
||||||
|
import { plan_service } from "./plan.service";
|
||||||
|
|
||||||
|
const get_all_plan = catchAsync(async (req, res) => {
|
||||||
|
const result = await plan_service.get_all_plan_from_db(req);
|
||||||
|
manageResponse(res, {
|
||||||
|
success: true,
|
||||||
|
statusCode: 200,
|
||||||
|
message: "All plan fetched successfully.",
|
||||||
|
data: result,
|
||||||
|
meta: {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const get_single_plan = catchAsync(async (req, res) => {
|
||||||
|
const result = await plan_service.get_single_plan_from_db(req);
|
||||||
|
manageResponse(res, {
|
||||||
|
success: true,
|
||||||
|
statusCode: 200,
|
||||||
|
message: "Single plan fetched successfully.",
|
||||||
|
data: result,
|
||||||
|
meta: {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const create_plan = catchAsync(async (req, res) => {
|
||||||
|
const result = await plan_service.create_plan_into_db(req);
|
||||||
|
manageResponse(res, {
|
||||||
|
success: true,
|
||||||
|
statusCode: 200,
|
||||||
|
message: "plan created successfully.",
|
||||||
|
data: result,
|
||||||
|
meta: {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const update_plan = catchAsync(async (req, res) => {
|
||||||
|
const result = await plan_service.update_plan_into_db(req);
|
||||||
|
manageResponse(res, {
|
||||||
|
success: true,
|
||||||
|
statusCode: 200,
|
||||||
|
message: "plan updated successfully.",
|
||||||
|
data: result,
|
||||||
|
meta: {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const delete_plan = catchAsync(async (req, res) => {
|
||||||
|
const result = await plan_service.delete_plan_from_db(req);
|
||||||
|
manageResponse(res, {
|
||||||
|
success: true,
|
||||||
|
statusCode: 200,
|
||||||
|
message: "plan deleted successfully.",
|
||||||
|
data: result,
|
||||||
|
meta: {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
export const plan_controller = {
|
||||||
|
get_all_plan,
|
||||||
|
get_single_plan,
|
||||||
|
create_plan,
|
||||||
|
update_plan,
|
||||||
|
delete_plan,
|
||||||
|
};
|
||||||
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
import { Router } from "express";
|
||||||
|
import RequestValidator from "../../middlewares/request_validator";
|
||||||
|
import { plan_controller } from "./plan.controller";
|
||||||
|
import { plan_validations } from "./plan.validation";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
router.get("/", plan_controller.get_all_plan);
|
||||||
|
router.post(
|
||||||
|
"/",
|
||||||
|
RequestValidator(plan_validations.create_plan),
|
||||||
|
plan_controller.create_plan,
|
||||||
|
);
|
||||||
|
router.get("/:id", plan_controller.get_single_plan);
|
||||||
|
router.patch(
|
||||||
|
"/:id",
|
||||||
|
RequestValidator(plan_validations.update_plan),
|
||||||
|
plan_controller.update_plan,
|
||||||
|
);
|
||||||
|
router.delete("/:id", plan_controller.delete_plan);
|
||||||
|
|
||||||
|
export default router;
|
||||||
|
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
import { Request } from "express";
|
||||||
|
import { prisma } from "../../lib/prisma";
|
||||||
|
|
||||||
|
const get_all_plan_from_db = async (req: Request) => {
|
||||||
|
// define your own login here
|
||||||
|
const result = await prisma.plan.findMany();
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
const get_single_plan_from_db = async (req: Request) => {
|
||||||
|
// define your own login here
|
||||||
|
const { id } = req.params ;
|
||||||
|
const result = await prisma.plan.findUnique({ where: { id } });
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
const create_plan_into_db = async (req: Request) => {
|
||||||
|
// define your own login here
|
||||||
|
console.log(req.body)
|
||||||
|
const result = await prisma.plan.create({ data: req.body });
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
const update_plan_into_db = async (req: Request) => {
|
||||||
|
// define your own login here
|
||||||
|
const { id } = req.params;
|
||||||
|
const result = await prisma.plan.update({ where: { id }, data: req.body });
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
const delete_plan_from_db = async (req: Request) => {
|
||||||
|
// define your own login here
|
||||||
|
const { id } = req.params;
|
||||||
|
const result = await prisma.plan.delete({ where: { id } });
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const plan_service = {
|
||||||
|
get_all_plan_from_db,
|
||||||
|
get_single_plan_from_db,
|
||||||
|
create_plan_into_db,
|
||||||
|
update_plan_into_db,
|
||||||
|
delete_plan_from_db,
|
||||||
|
};
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
|
||||||
|
export const planSwaggerDocs = {
|
||||||
|
"/api/plan": {
|
||||||
|
post: {
|
||||||
|
tags: ["plan"],
|
||||||
|
summary: "Create new plan",
|
||||||
|
description: "",
|
||||||
|
requestBody: {
|
||||||
|
required: true,
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
example: JSON.stringify({
|
||||||
|
|
||||||
|
"planName": "PRO Plan",
|
||||||
|
"price": 12,
|
||||||
|
"planType": "PRO",
|
||||||
|
"planDesc": "The plan is only for pro users",
|
||||||
|
"planFeatures": {
|
||||||
|
"storage": "10GB",
|
||||||
|
"projects": 5,
|
||||||
|
"support": "Email Support"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}), // put your request body
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
responses: {
|
||||||
|
201: { description: "plan created successfully" },
|
||||||
|
500: { description: "Validation error or internal server error" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
get: {
|
||||||
|
tags: ["plan"],
|
||||||
|
summary: "Get all plan",
|
||||||
|
description: "",
|
||||||
|
parameters: [
|
||||||
|
{
|
||||||
|
name: "page",
|
||||||
|
in: "query",
|
||||||
|
required: false,
|
||||||
|
schema: { type: "number" },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "limit",
|
||||||
|
in: "query",
|
||||||
|
required: false,
|
||||||
|
schema: { type: "number" },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
responses: {
|
||||||
|
200: { description: "plan fetched successfully" },
|
||||||
|
401: { description: "unauthorized" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"/api/plan/{id}": {
|
||||||
|
get: {
|
||||||
|
tags: ["plan"],
|
||||||
|
summary: "Get single plan",
|
||||||
|
description: "",
|
||||||
|
parameters: [
|
||||||
|
{
|
||||||
|
name: "id",
|
||||||
|
in: "path",
|
||||||
|
required: true,
|
||||||
|
schema: { type: "string" },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
responses: {
|
||||||
|
200: { description: "plan fetched successfully" },
|
||||||
|
401: { description: "unauthorized" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
patch: {
|
||||||
|
tags: ["plan"],
|
||||||
|
summary: "Update plan",
|
||||||
|
description: "",
|
||||||
|
parameters: [
|
||||||
|
{
|
||||||
|
name: "id",
|
||||||
|
in: "path",
|
||||||
|
required: true,
|
||||||
|
schema: { type: "string" },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
requestBody: {
|
||||||
|
required: true,
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
example: JSON.stringify({}), // put your request body
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
responses: {
|
||||||
|
200: { description: "plan updated successfully" },
|
||||||
|
500: { description: "Validation error or internal server error" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
delete: {
|
||||||
|
tags: ["plan"],
|
||||||
|
summary: "Delete plan",
|
||||||
|
description: "",
|
||||||
|
parameters: [
|
||||||
|
{
|
||||||
|
name: "id",
|
||||||
|
in: "path",
|
||||||
|
required: true,
|
||||||
|
schema: { type: "string" },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
responses: {
|
||||||
|
200: { description: "plan delete successfully" },
|
||||||
|
401: { description: "unauthorized" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
const create_plan = z.object({
|
||||||
|
planName: z.string(),
|
||||||
|
price: z.number(),
|
||||||
|
planType: z.enum(["FREE", "STANDARD", "PRO"]),
|
||||||
|
planDesc: z.string(),
|
||||||
|
planFeatures: z.union([
|
||||||
|
z.string(),
|
||||||
|
z.number(),
|
||||||
|
z.boolean(),
|
||||||
|
z.null(),
|
||||||
|
z.array(z.any()),
|
||||||
|
z.record(z.string(), z.any())
|
||||||
|
])
|
||||||
|
});
|
||||||
|
const update_plan = z.object({});
|
||||||
|
|
||||||
|
export const plan_validations = {
|
||||||
|
create_plan,
|
||||||
|
update_plan,
|
||||||
|
};
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
import { Router } from "express";
|
import { Router } from "express";
|
||||||
import accountRouter from "./app/modules/account/account.route";
|
import accountRouter from "./app/modules/account/account.route";
|
||||||
import profileRoute from "./app/modules/profile/profile.route";
|
import profileRoute from "./app/modules/profile/profile.route";
|
||||||
|
import planRoute from "./app/modules/plan/plan.route";
|
||||||
|
|
||||||
const appRouter = Router();
|
const appRouter = Router();
|
||||||
|
|
||||||
const moduleRoutes = [
|
const moduleRoutes = [
|
||||||
|
{ path: "/plan", route: planRoute },
|
||||||
{ path: "/profile", route: profileRoute },{ path: "/auth", route: accountRouter }];
|
{ path: "/profile", route: profileRoute },{ path: "/auth", route: accountRouter }];
|
||||||
|
|
||||||
moduleRoutes.forEach((route) => appRouter.use(route.path, route.route));
|
moduleRoutes.forEach((route) => appRouter.use(route.path, route.route));
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
import app from "./app";
|
import app from "./app";
|
||||||
import { configs } from "./app/configs/index";
|
import { configs } from "./app/configs/index";
|
||||||
import { prisma } from "./app/lib/prisma";
|
import { prisma } from "./app/lib/prisma";
|
||||||
import "./app/queues/worker";
|
// import "./app/queues/worker";
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import path from "path";
|
|||||||
import { configs } from "./app/configs";
|
import { configs } from "./app/configs";
|
||||||
import { accountSwaggerDocs } from "./app/modules/account/account.swagger";
|
import { accountSwaggerDocs } from "./app/modules/account/account.swagger";
|
||||||
import { profileSwaggerDocs } from "./app/modules/profile/profile.swagger";
|
import { profileSwaggerDocs } from "./app/modules/profile/profile.swagger";
|
||||||
|
import { planSwaggerDocs } from "./app/modules/plan/plan.swagger";
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
const __dirname = path.dirname(__filename);
|
const __dirname = path.dirname(__filename);
|
||||||
@@ -18,6 +19,7 @@ export const swaggerOptions = {
|
|||||||
paths: {
|
paths: {
|
||||||
...accountSwaggerDocs,
|
...accountSwaggerDocs,
|
||||||
...profileSwaggerDocs,
|
...profileSwaggerDocs,
|
||||||
|
...planSwaggerDocs,
|
||||||
},
|
},
|
||||||
servers:
|
servers:
|
||||||
configs.env === "production"
|
configs.env === "production"
|
||||||
|
|||||||
Reference in New Issue
Block a user