4 Commits

Author SHA1 Message Date
rahat0078 49cb339e5a feat(analytics:admin): andmin analytics dashboard api done 2026-05-16 23:30:05 +06:00
sharafat 64a0a80a2a merge sharafat and rahat branch 2026-04-30 21:45:27 +06:00
rahat0078 7d89f3f4ea feat(stats): seller stat api completed 2026-04-29 20:18:49 +06:00
rahat0078 86b2292272 feat(support): update Swagger documentation for support endpoints 2026-04-17 00:19:22 +06:00
17 changed files with 791 additions and 70 deletions
+1
View File
@@ -20,6 +20,7 @@
"cloudinary": "^2.7.0", "cloudinary": "^2.7.0",
"cookie-parser": "^1.4.7", "cookie-parser": "^1.4.7",
"cors": "^2.8.5", "cors": "^2.8.5",
"dayjs": "^1.11.20",
"dotenv": "^17.3.1", "dotenv": "^17.3.1",
"express": "^5.1.0", "express": "^5.1.0",
"ioredis": "^5.10.1", "ioredis": "^5.10.1",
-1
View File
@@ -8,7 +8,6 @@ model Profile {
shopAddress String? shopAddress String?
shopMapLocation String? shopMapLocation String?
shopCategory String? shopCategory String?
} }
@@ -0,0 +1,34 @@
import { Request, Response } from "express";
import catchAsync from "../../utils/catch_async.js";
import manageResponse from "../../utils/manage_response.js";
import { analytics_service } from "./analytics.service.js";
const getOverview = catchAsync(async (req: Request, res: Response) => {
const range = (req.query.range as "7d" | "30d") || "7d";
const result = await analytics_service.getOverview(range);
manageResponse(res, {
success: true,
statusCode: 200,
message: "Analytics overview fetched successfully.",
data: result,
meta: {},
});
});
const getLastSevenDaysRevenue = catchAsync(
async (req: Request, res: Response) => {
const result = await analytics_service.getLastSevenDaysRevenue();
manageResponse(res, {
success: true,
statusCode: 200,
message: "Analytics overview fetched successfully.",
data: result,
meta: {},
});
},
);
export const analytics_controller = {
getOverview,
getLastSevenDaysRevenue,
};
@@ -0,0 +1,25 @@
import { Router } from "express";
// import RequestValidator from "../../middlewares/request_validator.js";
import { analytics_controller } from "./analytics.controller.js";
import auth from "../../middlewares/auth.js";
// import { analytics_validations } from "./analytics.validation.js";
//! "/admin/analytics"
const router = Router();
router.get("/overview", auth("ADMIN"), analytics_controller.getOverview);
router.get("/revenue-overview", auth("ADMIN"), analytics_controller.getLastSevenDaysRevenue);
// router.post(
// "/",
// RequestValidator(analytics_validations.create_analytics),
// analytics_controller.create_analytics,
// );
export default router;
@@ -0,0 +1,190 @@
import { Request } from "express";
import { prisma } from "../../lib/prisma.js";
import dayjs from "dayjs";
const getOverview = async (range: "7d" | "30d") => {
const days = range === "30d" ? 30 : 7;
const now = dayjs();
const currentStartDate = now.subtract(days, "day").startOf("day").toDate();
const currentEndDate = now.endOf("day").toDate();
const previousStartDate = now
.subtract(days * 2, "day")
.startOf("day")
.toDate();
const previousEndDate = now.subtract(days, "day").endOf("day").toDate();
const rangeFilter = (start: Date, end: Date) => ({
gte: start,
lte: end,
});
const [
currentActiveStores,
previousActiveStores,
currentRevenue,
previousRevenue,
currentSignups,
previousSignups,
currentPendingActions,
previousPendingActions,
] = await Promise.all([
prisma.profile.count({
where: {
account: {
isAccountVerified: true,
},
},
}),
prisma.profile.count({
where: {
account: {
isDeleted: false,
isAccountVerified: true,
createdAt: rangeFilter(previousStartDate, previousEndDate),
},
},
}),
prisma.order.aggregate({
_sum: {
productPrice: true,
},
where: {
status: "DELIVERED",
createdAt: rangeFilter(currentStartDate, currentEndDate),
},
}),
prisma.order.aggregate({
_sum: {
productPrice: true,
},
where: {
status: "DELIVERED",
createdAt: rangeFilter(previousStartDate, previousEndDate),
},
}),
prisma.account.count({
where: {
createdAt: rangeFilter(currentStartDate, currentEndDate),
},
}),
prisma.account.count({
where: {
createdAt: rangeFilter(previousStartDate, previousEndDate),
},
}),
prisma.order.count({
where: {
status: {
in: ["INITIATED", "CONFIRMED"],
},
createdAt: rangeFilter(currentStartDate, currentEndDate),
},
}),
prisma.order.count({
where: {
status: {
in: ["INITIATED", "CONFIRMED"],
},
createdAt: rangeFilter(previousStartDate, previousEndDate),
},
}),
]);
const percentage = (current: number, previous: number) => {
// avoid division by zero
if (previous === 0) return current > 0 ? 100 : 0;
return Number((((current - previous) / previous) * 100).toFixed(2));
};
const currentRevenueTotal = currentRevenue._sum.productPrice ?? 0;
const previousRevenueTotal = previousRevenue._sum.productPrice ?? 0;
return {
activeStores: {
total: currentActiveStores,
changePercentage: percentage(currentActiveStores, previousActiveStores),
},
revenue: {
total: currentRevenueTotal,
changePercentage: percentage(currentRevenueTotal, previousRevenueTotal),
},
signups: {
total: currentSignups,
changePercentage: percentage(currentSignups, previousSignups),
},
pendingActions: {
total: currentPendingActions,
changePercentage: percentage(
currentPendingActions,
previousPendingActions,
),
},
};
};
const getLastSevenDaysRevenue = async () => {
const startDate = dayjs().subtract(6, "day").startOf("day").toDate();
const endDate = dayjs().endOf("day").toDate();
const orders = await prisma.order.findMany({
where: {
status: "DELIVERED",
createdAt: {
gte: startDate,
lte: endDate,
},
},
select: {
productPrice: true,
productQuantity: true,
createdAt: true,
},
});
const revenueMap: Record<string, number> = {};
for (let i = 0; i < 7; i++) {
const date = dayjs(startDate).add(i, "day");
revenueMap[date.format("dddd")] = 0;
}
for (const order of orders) {
const day = dayjs(order.createdAt).format("dddd");
revenueMap[day] += order.productPrice * order.productQuantity;
}
const data = Object.entries(revenueMap).map(([day, revenue]) => ({
day,
revenue,
}));
return data;
};
export const analytics_service = {
getOverview, getLastSevenDaysRevenue
};
@@ -0,0 +1,92 @@
export const analyticsSwaggerDocs = {
"/api/admin/analytics/overview": {
get: {
tags: ["Analytics"],
summary: "Get analytics overview (7d / 30d comparison)",
description:
"Returns aggregated analytics including active stores, revenue, signups, and percentage change compared to previous period.",
parameters: [
{
name: "range",
in: "query",
required: true,
description: "Time range for analytics overview",
schema: {
type: "string",
enum: ["7d", "30d"],
example: "7d",
},
},
],
responses: {
200: {
description: "Analytics overview fetched successfully",
content: {
"application/json": {
schema: {
type: "object",
properties: {
activeStores: {
type: "object",
properties: {
total: { type: "number", example: 120 },
changePercentage: {
type: "number",
example: 5.23,
},
},
},
revenue: {
type: "object",
properties: {
total: { type: "number", example: 45230 },
changePercentage: {
type: "number",
example: -3.45,
},
},
},
signups: {
type: "object",
properties: {
total: { type: "number", example: 340 },
changePercentage: {
type: "number",
example: 12.1,
},
},
},
},
},
},
},
},
401: {
description: "Unauthorized",
},
500: {
description: "Internal server error",
},
},
},
},
"/api/admin/analytics/revenue-overview": {
get: {
tags: ["Analytics"],
summary: "Get analytics revenue overview (last 7 days)",
description: "",
responses: {
200: {
description: "Revenue overview fetched successfully",
},
401: {
description: "Unauthorized",
},
500: {
description: "Internal server error",
},
},
},
},
};
@@ -0,0 +1,10 @@
import { z } from "zod";
const create_analytics = z.object({});
const update_analytics = z.object({});
export const analytics_validations = {
create_analytics,
update_analytics,
};
@@ -0,0 +1,92 @@
import manageResponse from "../../utils/manage_response";
import { Request, Response } from "express";
import catchAsync from "../../utils/catch_async";
import { statictics_service } from "./statictics.service";
const get_seller_stats = catchAsync(async (req: Request, res: Response) => {
const shopAccountId = req.user?.accountId;
if (!shopAccountId) {
return res.status(401).json({
success: false,
message: "Unauthorized",
});
}
const range = (req.query.range as "7d" | "30d" | "all") || "7d";
const result = await statictics_service.get_seller_stats_fromDb(
shopAccountId,
range,
);
manageResponse(res, {
success: true,
statusCode: 200,
message: "All statictics fetched successfully.",
data: result,
meta: {},
});
});
// const get_all_statictics = catchAsync(async (req, res) => {
// const result = await statictics_service.get_all_statictics_from_db(req);
// manageResponse(res, {
// success: true,
// statusCode: 200,
// message: "All statictics fetched successfully.",
// data: result,
// meta: {},
// });
// });
// const get_single_statictics = catchAsync(async (req, res) => {
// const result = await statictics_service.get_single_statictics_from_db(req);
// manageResponse(res, {
// success: true,
// statusCode: 200,
// message: "Single statictics fetched successfully.",
// data: result,
// meta: {},
// });
// });
// const create_statictics = catchAsync(async (req, res) => {
// const result = await statictics_service.create_statictics_into_db(req);
// manageResponse(res, {
// success: true,
// statusCode: 200,
// message: "statictics created successfully.",
// data: result,
// meta: {},
// });
// });
// const update_statictics = catchAsync(async (req, res) => {
// const result = await statictics_service.update_statictics_into_db(req);
// manageResponse(res, {
// success: true,
// statusCode: 200,
// message: "statictics updated successfully.",
// data: result,
// meta: {},
// });
// });
// const delete_statictics = catchAsync(async (req, res) => {
// const result = await statictics_service.delete_statictics_from_db(req);
// manageResponse(res, {
// success: true,
// statusCode: 200,
// message: "statictics deleted successfully.",
// data: result,
// meta: {},
// });
// });
export const statictics_controller = {
get_seller_stats,
// get_all_statictics,
// get_single_statictics,
// create_statictics,
// update_statictics,
// delete_statictics,
};
@@ -0,0 +1,24 @@
import { Router } from "express";
import auth from "../../middlewares/auth.js";
import { statictics_controller } from "./statictics.controller.js";
// import { statictics_controller } from "./statictics.controller";
// import { statictics_validations } from "./statictics.validation";
const router = Router();
router.get("/seller", auth("USER"), statictics_controller.get_seller_stats);
// router.post(
// "/",
// RequestValidator(statictics_validations.create_statictics),
// statictics_controller.create_statictics,
// );
// router.get("/:id", statictics_controller.get_single_statictics);
// router.patch(
// "/:id",
// RequestValidator(statictics_validations.update_statictics),
// statictics_controller.update_statictics,
// );
// router.delete("/:id", statictics_controller.delete_statictics);
export const staticticsRoute = router;
@@ -0,0 +1,151 @@
// import { Request } from "express";
// import { prisma } from "../../lib/prisma";
import { prisma } from "../../lib/prisma";
type Range = "7d" | "30d" | "all";
const get_seller_stats_fromDb = async (shopAccountId: string, range: Range) => {
let createdAtFilter: any = {};
if (range !== "all") {
const days = range === "7d" ? 7 : 30;
const from = new Date();
from.setDate(from.getDate() - days);
createdAtFilter = { gte: from };
}
const baseWhere: any = {
shopAccountId,
...(range !== "all" && { createdAt: createdAtFilter }),
};
const [
totalOrders,
completedOrders,
pendingOrders,
rejectedOrders,
revenueResult,
last7DaysRejected,
ordersForChart,
] = await Promise.all([
prisma.order.count({ where: baseWhere }),
prisma.order.count({
where: { ...baseWhere, status: "DELIVERED" },
}),
prisma.order.count({
where: {
...baseWhere,
status: { in: ["INITIATED", "CONFIRMED", "ONGOING"] },
},
}),
prisma.order.count({
where: { ...baseWhere, status: "CANCELLED" },
}),
prisma.order.aggregate({
where: { ...baseWhere, status: "DELIVERED" },
_sum: { productPrice: true },
}),
prisma.order.count({
where: {
shopAccountId,
status: "CANCELLED",
createdAt: {
gte: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
},
},
}),
range !== "all"
? prisma.order.findMany({
where: {
shopAccountId,
status: "DELIVERED",
createdAt: createdAtFilter,
},
select: {
productPrice: true,
createdAt: true,
},
})
: Promise.resolve([]),
]);
const totalRevenue = revenueResult._sum.productPrice || 0;
const avgOrderValue =
completedOrders > 0 ? totalRevenue / completedOrders : 0;
const dailyMap: Record<string, number> = {};
for (const o of ordersForChart) {
const date = o.createdAt.toISOString().split("T")[0];
if (!dailyMap[date]) dailyMap[date] = 0;
dailyMap[date] += o.productPrice;
}
const dailyRevenue = Object.entries(dailyMap).map(([date, revenue]) => ({
date,
revenue,
}));
return {
totalOrders,
completedOrders,
pendingOrders,
rejectedOrders,
totalRevenue,
avgOrderValue,
last7DaysRejected,
dailyRevenue,
};
};
// const get_all_statictics_from_db = async (req: Request) => {
// // define your own login here
// const result = await prisma.statictics.findMany();
// return result;
// };
// const get_single_statictics_from_db = async (req: Request) => {
// // define your own login here
// const { id } = req.params;
// const result = await prisma.statictics.findUnique({where:{id}});
// return result;
// };
// const create_statictics_into_db = async (req: Request) => {
// // define your own login here
// const result = await prisma.statictics.create({data:req.body});
// return result;
// };
// const update_statictics_into_db = async (req: Request) => {
// // define your own login here
// const { id } = req.params;
// const result = await prisma.statictics.update({where:{id},data:req.body});
// return result;
// };
// const delete_statictics_from_db = async (req: Request) => {
// // define your own login here
// const { id } = req.params;
// const result = await prisma.statictics.delete({where:{id}});
// return result;
// };
export const statictics_service = {
get_seller_stats_fromDb,
// get_all_statictics_from_db,
// get_single_statictics_from_db,
// create_statictics_into_db,
// update_statictics_into_db,
// delete_statictics_from_db,
};
@@ -1,12 +1,11 @@
export const staticticsSwaggerDocs = { export const staticticsSwaggerDocs = {
"/api/statictics": { "/api/statictics": {
post: { post: {
tags: ["statictics"], tags: ["statictics"],
summary: "Create new statictics", summary: "Create new statictics",
description: "", description: "",
requestBody: { requestBody: {
required: true, required: true,
content: { content: {
"application/json": { "application/json": {
@@ -45,33 +44,34 @@ export const staticticsSwaggerDocs = {
}, },
"/api/statictics/seller": { "/api/statictics/seller": {
get: { get: {
tags: ["statistics"], tags: ["statistics"],
summary: "Get seller statistics", summary: "Get seller statistics",
description: "Fetch seller dashboard stats (7d, 30d, all)", description: "Fetch seller dashboard stats (7d, 30d, all)",
parameters: [ parameters: [
{ {
name: "range", name: "range",
in: "query", in: "query",
required: false, required: false,
schema: { schema: {
type: "string", type: "string",
enum: ["7d", "30d", "all"], enum: ["7d", "30d", "all"],
default: "7d", default: "7d",
},
description: "Time range for statistics",
}, },
], description: "Time range for statistics",
},
],
responses: { responses: {
200: { 200: {
description: "Statistics fetched successfully", description: "Statistics fetched successfully",
}, },
401: { 401: {
description: "Unauthorized", description: "Unauthorized",
},
}, },
}, },
},
}, },
"/api/statictics/{id}": { "/api/statictics/{id}": {
@@ -136,3 +136,6 @@ export const staticticsSwaggerDocs = {
}, },
}, },
}; };
@@ -0,0 +1,10 @@
import { z } from "zod";
const create_statictics = z.object({});
const update_statictics = z.object({});
export const statictics_validations = {
create_statictics,
update_statictics,
};
+37 -21
View File
@@ -1,17 +1,14 @@
import { Request, Response } from "express"; import { Request, Response } from "express";
import catchAsync from "../../utils/catch_async.js"; import catchAsync from "../../utils/catch_async.js";
import manageResponse from "../../utils/manage_response.js"; import manageResponse from "../../utils/manage_response.js";
import { support_service } from "./support.service.js"; import { support_service } from "./support.service.js";
const createSupport = catchAsync(async (req: Request, res: Response) => { const createSupport = catchAsync(async (req: Request, res: Response) => {
const id = req?.user?.accountId; const id = req?.user?.accountId;
const data = { const data = {
...req.body, ...req.body,
storeAccountId: id as string storeAccountId: id as string,
} };
const result = await support_service.createSupportIntoDB(data); const result = await support_service.createSupportIntoDB(data);
manageResponse(res, { manageResponse(res, {
@@ -23,31 +20,43 @@ const createSupport = catchAsync(async (req: Request, res: Response) => {
}); });
}); });
const getAllSupport = catchAsync(async (req: Request, res: Response) => { const getAllSupport = catchAsync(async (req: Request, res: Response) => {
const role = req?.user?.role; const role = req?.user?.role;
const id = req?.user?.accountId; const id = req?.user?.accountId;
const search = req?.query?.search; const search = req?.query?.search;
const type = req?.query?.type; const type = req?.query?.type;
const status = req?.query?.status; const status = req?.query?.status;
const page = Number(req?.query?.page) || 1;
const limit = Number(req?.query?.limit) || 10;
const result = await support_service.getAllSupportFromDB(id as string, role as string, search as string, type as string, status as string); const result = await support_service.getAllSupportFromDB(
id as string,
role as string,
search as string,
type as string,
status as string,
page,
limit
);
manageResponse(res, { manageResponse(res, {
success: true, success: true,
statusCode: 200, statusCode: 200,
message: "All support fetched successfully.", message: "All support fetched successfully.",
data: result, data: result.data,
meta: {}, meta: result.meta,
}); });
}); });
const get_single_support = catchAsync(async (req, res) => { const get_single_support = catchAsync(async (req, res) => {
const {id} = req.params; const { id } = req.params;
const userId = req?.user?.accountId; const userId = req?.user?.accountId;
const role = req?.user?.role const role = req?.user?.role;
const result = await support_service.getSingleSupportFromDB(
const result = await support_service.getSingleSupportFromDB(id as string, userId as string, role as string); id as string,
userId as string,
role as string,
);
manageResponse(res, { manageResponse(res, {
success: true, success: true,
statusCode: 200, statusCode: 200,
@@ -57,15 +66,18 @@ const get_single_support = catchAsync(async (req, res) => {
}); });
}); });
const update_support = catchAsync(async (req, res) => { const update_support = catchAsync(async (req, res) => {
const {id} = req.params; const { id } = req.params;
const userId = req?.user?.accountId; const userId = req?.user?.accountId;
const role = req?.user?.role; const role = req?.user?.role;
const data = req.body const data = req.body;
const result = await support_service.updateSupportIntoDB(
const result = await support_service.updateSupportIntoDB(id as string, userId as string, role as string, data); id as string,
userId as string,
role as string,
data,
);
manageResponse(res, { manageResponse(res, {
success: true, success: true,
statusCode: 200, statusCode: 200,
@@ -76,11 +88,15 @@ const update_support = catchAsync(async (req, res) => {
}); });
const delete_support = catchAsync(async (req, res) => { const delete_support = catchAsync(async (req, res) => {
const {id} = req.params; const { id } = req.params;
const userId = req?.user?.accountId; const userId = req?.user?.accountId;
const role = req?.user?.role const role = req?.user?.role;
const result = await support_service.deleteSupportFromDB(id as string, userId as string, role as string); const result = await support_service.deleteSupportFromDB(
id as string,
userId as string,
role as string,
);
manageResponse(res, { manageResponse(res, {
success: true, success: true,
statusCode: 200, statusCode: 200,
+28 -9
View File
@@ -13,6 +13,8 @@ const getAllSupportFromDB = async (
search?: string, search?: string,
type?: string, type?: string,
status?: string, status?: string,
page: number = 1,
limit: number = 10,
) => { ) => {
const andCondition: Prisma.SupportWhereInput[] = []; const andCondition: Prisma.SupportWhereInput[] = [];
@@ -55,14 +57,31 @@ const getAllSupportFromDB = async (
const whereCondition: Prisma.SupportWhereInput = const whereCondition: Prisma.SupportWhereInput =
andCondition.length > 0 ? { AND: andCondition } : {}; andCondition.length > 0 ? { AND: andCondition } : {};
const result = await prisma.support.findMany({ const skip = (page - 1) * limit;
where: whereCondition,
orderBy: {
createdAt: "desc",
},
});
return result; const [data, total] = await Promise.all([
prisma.support.findMany({
where: whereCondition,
skip,
take: limit,
orderBy: {
createdAt: "desc",
},
}),
prisma.support.count({
where: whereCondition,
}),
]);
return {
meta: {
page,
limit,
total,
totalPage: Math.ceil(total / limit),
},
data,
};
}; };
const getSingleSupportFromDB = async ( const getSingleSupportFromDB = async (
@@ -125,8 +144,8 @@ const deleteSupportFromDB = async (
} }
const result = await prisma.support.delete({ const result = await prisma.support.delete({
where: {id} where: { id },
}) });
return result; return result;
}; };
+58 -11
View File
@@ -1,18 +1,18 @@
export const supportSwaggerDocs = {
export const supportSwaggerDocs = {
"/api/support": { "/api/support": {
post: { post: {
tags: ["support"], tags: ["support"],
summary: "Create new support", summary: "Create new support",
description: "", description:
"type must be: TECHNICAL | BILLING | DOMAIN | TEMPLATE | PAYMENT | ACCOUNT | FEATURE_REQUEST | BUG | OTHER",
requestBody: { requestBody: {
required: true, required: true,
content: { content: {
"application/json": { "application/json": {
example: JSON.stringify({ example: JSON.stringify({
"issueName": "Your issue name", issueName: "Your issue name",
"description": "Issue description", description: "Issue description",
"type": "Issue Type" type: "Issue Type",
}), // put your request body }), // put your request body
}, },
}, },
@@ -39,6 +39,45 @@
required: false, required: false,
schema: { type: "number" }, schema: { type: "number" },
}, },
{
name: "search",
in: "query",
required: false,
description: "Search by issue name or description",
schema: {
type: "string",
},
},
{
name: "type",
in: "query",
required: false,
description: "Filter by support type",
schema: {
type: "string",
enum: [
"TECHNICAL",
"BILLING",
"DOMAIN",
"TEMPLATE",
"PAYMENT",
"ACCOUNT",
"FEATURE_REQUEST",
"BUG",
"OTHER",
],
},
},
{
name: "status",
in: "query",
required: false,
description: "Filter by support status",
schema: {
type: "string",
enum: ["OPEN", "IN_PROGRESS", "RESOLVED", "REJECTED"],
},
},
], ],
responses: { responses: {
200: { description: "support fetched successfully" }, 200: { description: "support fetched successfully" },
@@ -68,7 +107,11 @@
patch: { patch: {
tags: ["support"], tags: ["support"],
summary: "Update support", summary: "Update support",
description: "", description: `type(enum): TECHNICAL | BILLING | DOMAIN | TEMPLATE | PAYMENT | ACCOUNT | FEATURE_REQUEST | BUG | OTHER \n
status(enum): OPEN
| IN_PROGRESS
| RESOLVED
| REJECTED`,
parameters: [ parameters: [
{ {
name: "id", name: "id",
@@ -81,7 +124,14 @@
required: true, required: true,
content: { content: {
"application/json": { "application/json": {
example: JSON.stringify({}), // put your request body example: JSON.stringify({
issueName: "Your issue name",
description: "Issue description",
type: "Issue Type",
status: "issue current status",
resolvedBy: "dataTime()",
resolvedAt: "dateTime()",
}), // put your request body
}, },
}, },
}, },
@@ -109,6 +159,3 @@
}, },
}, },
}; };
+5 -1
View File
@@ -4,12 +4,16 @@ import orderRoute from "./app/modules/order/order.route.js";
import planRoute from "./app/modules/plan/plan.route.js"; import planRoute from "./app/modules/plan/plan.route.js";
import profileRoute from "./app/modules/profile/profile.route.js"; import profileRoute from "./app/modules/profile/profile.route.js";
import supportRoute from "./app/modules/support/support.route.js"; import supportRoute from "./app/modules/support/support.route.js";
import templateRoute from "./app/modules/template/template.route"; import templateRoute from "./app/modules/template/template.route.js";
import { staticticsRoute } from "./app/modules/statictics/statictics.route.js";
import analyticsRoute from "./app/modules/analytics/analytics.route.js";
const appRouter = Router(); const appRouter = Router();
const moduleRoutes = [ const moduleRoutes = [
{ path: "/admin/analytics", route: analyticsRoute },
{ path: "/template", route: templateRoute }, { path: "/template", route: templateRoute },
{ path: "/statictics", route: staticticsRoute },
{ path: "/order", route: orderRoute }, { path: "/order", route: orderRoute },
{ path: "/support", route: supportRoute }, { path: "/support", route: supportRoute },
{ path: "/plan", route: planRoute }, { path: "/plan", route: planRoute },
+5 -1
View File
@@ -6,7 +6,9 @@ import { orderSwaggerDocs } from "./app/modules/order/order.swagger.js";
import { planSwaggerDocs } from "./app/modules/plan/plan.swagger.js"; import { planSwaggerDocs } from "./app/modules/plan/plan.swagger.js";
import { profileSwaggerDocs } from "./app/modules/profile/profile.swagger.js"; import { profileSwaggerDocs } from "./app/modules/profile/profile.swagger.js";
import { supportSwaggerDocs } from "./app/modules/support/support.swagger.js"; import { supportSwaggerDocs } from "./app/modules/support/support.swagger.js";
import { templateSwaggerDocs } from "./app/modules/template/template.swagger"; import { templateSwaggerDocs } from "./app/modules/template/template.swagger.js";
import { staticticsSwaggerDocs } from "./app/modules/statictics/statictics.swagger.js";
import { analyticsSwaggerDocs } from "./app/modules/analytics/analytics.swagger";
const __filename = fileURLToPath(import.meta.url); const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename); const __dirname = path.dirname(__filename);
@@ -26,6 +28,8 @@ export const swaggerOptions = {
...profileSwaggerDocs, ...profileSwaggerDocs,
...supportSwaggerDocs, ...supportSwaggerDocs,
...templateSwaggerDocs, ...templateSwaggerDocs,
...staticticsSwaggerDocs,
...analyticsSwaggerDocs,
}, },
servers: servers:
configs.env === "production" configs.env === "production"