Skip to content

Commit

Permalink
Merge pull request #18 from GenieWizards/feature/8-crud-group-table
Browse files Browse the repository at this point in the history
Feature/8 crud group table
  • Loading branch information
shivamvijaywargi authored Nov 15, 2024
2 parents aa55efc + a505fdf commit dd77612
Show file tree
Hide file tree
Showing 6 changed files with 247 additions and 1 deletion.
Binary file modified bun.lockb
Binary file not shown.
3 changes: 2 additions & 1 deletion src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { configureOpenAPI } from "./common/lib/configure-open-api.lib";
import { createApp } from "./common/lib/create-app.lib";
import { authRouter } from "./modules/auth/auth.index";
import { categoryRouter } from "./modules/categories/category.index";
import { groupRouters } from "./modules/group/group.index";
import { healthCheckRouter } from "./modules/health-check/health-check.index";

export const app = createApp();

const routesV1 = [authRouter, categoryRouter];
const routesV1 = [authRouter, categoryRouter, groupRouters];

configureOpenAPI(app);

Expand Down
89 changes: 89 additions & 0 deletions src/modules/group/group.handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import type { AppRouteHandler } from "@/common/lib/types";
import type { TSelectGroupSchema } from "@/db/schemas/group.model";

import * as HTTPStatusCodes from "@/common/utils/http-status-codes.util";

import type { TCreateGroupRoute, TDeleteGroupRoute } from "./group.routes";

import { createGroupRepository, deleteGroupRepository } from "./group.repository";

export const createGroup: AppRouteHandler<TCreateGroupRoute> = async (c) => {
const user = c.get("user");
const payload = c.req.valid("json");
const logger = c.get("logger");

if (!user) {
logger.error("User is not authorized to create group");
return c.json(
{
success: false,
message: "You are not authorized, please login",
},
HTTPStatusCodes.UNAUTHORIZED,
);
}

const group: TSelectGroupSchema | null = await createGroupRepository(payload);

if (!group) {
logger.error("Failed to create group");
return c.json(
{
success: false,
message: "Failed to create group",
},
HTTPStatusCodes.INTERNAL_SERVER_ERROR,
);
}

logger.debug(`Group created successfully with name ${group.name}`);

return c.json(
{
success: true,
message: "Group created successfully",
data: group,
},
HTTPStatusCodes.CREATED,
);
};

export const deleteGroup: AppRouteHandler<TDeleteGroupRoute> = async (c) => {
const user = c.get("user");
const params = c.req.valid("param");
const logger = c.get("logger");

if (!user) {
logger.error("User is not authorized to delete group");
return c.json(
{
success: false,
message: "You are not authorized, please login",
},
HTTPStatusCodes.UNAUTHORIZED,
);
}

const deletedGroupId: string | null = await deleteGroupRepository(params.id);

if (!deletedGroupId) {
logger.error(`Group with ${params.id} not found`);
return c.json(
{
success: false,
message: `Group with ${params.id} not found`,
},
HTTPStatusCodes.NOT_FOUND,
);
}

logger.debug(`Group with ${deletedGroupId} deleted successfully`);

return c.json(
{
success: true,
message: `Group with ${deletedGroupId} deleted successfully`,
},
HTTPStatusCodes.OK,
);
};
8 changes: 8 additions & 0 deletions src/modules/group/group.index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { createRouter } from "@/common/lib/create-app.lib";

import * as handlers from "./group.handler";
import * as routes from "./group.routes";

export const groupRouters = createRouter()
.openapi(routes.createGroupRoute, handlers.createGroup)
.openapi(routes.deleteGroupRoute, handlers.deleteGroup);
28 changes: 28 additions & 0 deletions src/modules/group/group.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { eq } from "drizzle-orm";

import type { TInsertGroupSchema } from "@/db/schemas/group.model";

import { db } from "@/db/adapter";
import groupModel from "@/db/schemas/group.model";

export async function createGroupRepository(
groupPayload: TInsertGroupSchema,
) {
const [group] = await db
.insert(groupModel)
.values(groupPayload)
.returning();

return group;
}

export async function deleteGroupRepository(
groupId: string,
) {
const [deletedGroups] = await db
.delete(groupModel)
.where(eq(groupModel.id, groupId))
.returning();

return deletedGroups?.id || null;
}
120 changes: 120 additions & 0 deletions src/modules/group/group.routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { createRoute } from "@hono/zod-openapi";
import { z } from "zod";

import { AuthRoles } from "@/common/enums";
import jsonContentRequired from "@/common/helpers/json-content-required.helper";
import { jsonContent } from "@/common/helpers/json-content.helper";
import { authMiddleware, checkRoleGuard, requireAuth } from "@/common/middlewares/auth.middleware";
import * as HTTPStatusCodes from "@/common/utils/http-status-codes.util";
import { insertGroupSchema, selectGroupSchema } from "@/db/schemas/group.model";

const tags = ["Groups"];

export const createGroupRoute = createRoute({
tags,
method: "post",
path: "/group",
middleware: [
authMiddleware(),
requireAuth(),
checkRoleGuard(AuthRoles.ADMIN, AuthRoles.USER),
] as const,
request: {
body: jsonContentRequired(
insertGroupSchema.omit({
id: true,
status: true,
createdAt: true,
updatedAt: true,
}),
"Group creation",
),
},
responses: {
[HTTPStatusCodes.CREATED]: jsonContent(
z.object({
success: z.boolean().default(true),
message: z.string(),
data: selectGroupSchema,
}),
"Group created successfully",
),
[HTTPStatusCodes.BAD_REQUEST]: jsonContent(
z.object({
success: z.boolean().default(false),
message: z.string(),
}),
"Validation error(s)",
),
[HTTPStatusCodes.UNAUTHORIZED]: jsonContent(
z.object({
success: z.boolean().default(false),
message: z.string(),
}),
"You are not authorized, please login",
),
[HTTPStatusCodes.INTERNAL_SERVER_ERROR]: jsonContent(
z.object({
success: z.boolean().default(false),
message: z.string(),
}),
"Failed to create the group",
),
},
});

export const deleteGroupRoute = createRoute({
tags,
method: "delete",
path: "group/:id",
middleware: [
authMiddleware(),
requireAuth(),
checkRoleGuard(AuthRoles.ADMIN, AuthRoles.USER),
] as const,
request: {
params: z.object({
id: z.string(),
}),
},
responses: {
[HTTPStatusCodes.OK]: jsonContent(
z.object({
success: z.boolean().default(true),
message: z.string(),
}),
"Group deleted successfully",
),
[HTTPStatusCodes.NOT_FOUND]: jsonContent(
z.object({
success: z.boolean().default(false),
message: z.string(),
}),
"Group with id does not exist",
),
[HTTPStatusCodes.UNAUTHORIZED]: jsonContent(
z.object({
success: z.boolean().default(false),
message: z.string(),
}),
"You are not authorized, please login",
),
[HTTPStatusCodes.FORBIDDEN]: jsonContent(
z.object({
success: z.boolean().default(false),
message: z.string(),
}),
"You are not allowed to perform this action",
),
[HTTPStatusCodes.INTERNAL_SERVER_ERROR]: jsonContent(
z.object({
success: z.boolean().default(false),
message: z.string(),
}),
"Something went wrong, please try again later",
),
},
});

export type TCreateGroupRoute = typeof createGroupRoute;
export type TDeleteGroupRoute = typeof deleteGroupRoute;

0 comments on commit dd77612

Please sign in to comment.