From 11f25ca91509331fee2e527402cd1f3990df626c Mon Sep 17 00:00:00 2001 From: Kevin Puig <119972216+k-puig@users.noreply.github.com> Date: Sat, 27 Sep 2025 21:30:08 -0400 Subject: [PATCH] refacto --- concord-server/src/routes/categoryRoutes.ts | 101 ++++++++++++++------ concord-server/src/routes/channelRoutes.ts | 57 ++++++++--- concord-server/src/routes/index.ts | 4 +- 3 files changed, 121 insertions(+), 41 deletions(-) diff --git a/concord-server/src/routes/categoryRoutes.ts b/concord-server/src/routes/categoryRoutes.ts index a6eda64..de396cf 100644 --- a/concord-server/src/routes/categoryRoutes.ts +++ b/concord-server/src/routes/categoryRoutes.ts @@ -9,8 +9,16 @@ import { import { createCategorySchema, + getCategorySchema, + getCategoriesByInstanceIdSchema, + updateCategorySchema, + deleteCategorySchema, + deleteCategoriesByInstanceIdSchema, CreateCategoryInput, + GetCategoryInput, + GetCategoriesByInstanceIdInput, UpdateCategoryInput, + DeleteCategoryInput, DeleteCategoriesByInstanceIdInput, } from "../validators/categoryValidator"; import { zValidator } from "@hono/zod-validator"; @@ -18,8 +26,9 @@ import { Hono } from "hono"; import { describeRoute, resolver } from "hono-openapi"; const categoryRoutes = new Hono() +// Create a new category categoryRoutes.post( - "", + "/", describeRoute({ description: "Create a new category", responses: { @@ -61,6 +70,7 @@ categoryRoutes.post( } ) +// Get a category by ID categoryRoutes.get( "/:id", describeRoute({ @@ -69,13 +79,13 @@ categoryRoutes.get( 200: { description: "Success getting category", content: { - "application/json": { schema: resolver(createCategorySchema) }, + "application/json": { schema: resolver(getCategorySchema) }, }, }, 404: { description: "Category id not found", content: { - "application/json": { schema: resolver(createCategorySchema) }, + "application/json": { schema: resolver(getCategorySchema) }, }, }, }, @@ -91,26 +101,32 @@ categoryRoutes.get( } ); +// Get all categories by instance ID categoryRoutes.get( - "", + "/instance/:instanceId", describeRoute({ description: "Get all categories by instance id", responses: { 200: { description: "Success getting all categories in instance", content: { - "application/json": { schema: resolver(createCategorySchema) }, + "application/json": { schema: resolver(getCategoriesByInstanceIdSchema) }, + }, + }, + 400: { + description: "Bad Request - Missing instance ID", + content: { + "application/json": { schema: resolver(getCategoriesByInstanceIdSchema) }, }, }, }, }), - zValidator("query", createCategorySchema), async (c) => { - const instanceId = c.req.query("instanceId"); + const instanceId = c.req.param("instanceId"); if (!instanceId) { return c.json({ error: "No instance id provided" }, 400); } - + const categoryData = await fetchCategoriesByInstance(instanceId); if (categoryData) { return c.json(categoryData); @@ -120,40 +136,53 @@ categoryRoutes.get( } ); +// Update a category categoryRoutes.put( - "", + "/:id", describeRoute({ description: "Update an existing category", responses: { 200: { description: "Success updating category", content: { - "application/json": { schema: resolver(createCategorySchema) }, + "application/json": { schema: resolver(updateCategorySchema) }, }, }, 400: { description: "Bad Request - Invalid input data", content: { - "application/json": { schema: resolver(createCategorySchema)}, + "application/json": { schema: resolver(updateCategorySchema)}, }, }, 401: { description: "Unauthorized - Admin access required", content: { - "application/json": { schema: resolver(createCategorySchema)}, + "application/json": { schema: resolver(updateCategorySchema)}, }, }, 404: { description: "Category id or User Id not found", content: { - "application/json": { schema: resolver(createCategorySchema)}, + "application/json": { schema: resolver(updateCategorySchema)}, }, }, }, }), - zValidator("json", createCategorySchema), + zValidator("json", updateCategorySchema), async (c) => { + const id = c.req.param("id"); const data = c.req.valid("json") as UpdateCategoryInput; + + // Ensure the ID in the path matches the one in the body + if (data.id && data.id !== id) { + return c.json({ error: "ID in path does not match ID in body" }, 400); + } + + // Set ID from path if not in body + if (!data.id) { + data.id = id; + } + const categoryData = await updateExistingCategory(data); if (categoryData) { return c.json(categoryData); @@ -163,40 +192,48 @@ categoryRoutes.put( } ); +// Delete a specific category categoryRoutes.delete( - "", + "/:id", describeRoute({ description: "Delete an existing category", responses: { 200: { description: "Success deleting category", content: { - "application/json": { schema: resolver(createCategorySchema) }, + "application/json": { schema: resolver(deleteCategorySchema) }, }, }, 400: { description: "Bad Request - Invalid input data", content: { - "application/json": { schema: resolver(createCategorySchema)}, + "application/json": { schema: resolver(deleteCategorySchema)}, }, }, 401: { description: "Unauthorized - Admin access required", content: { - "application/json": { schema: resolver(createCategorySchema)}, + "application/json": { schema: resolver(deleteCategorySchema)}, }, }, 404: { description: "Category id or User Id not found", content: { - "application/json": { schema: resolver(createCategorySchema)}, + "application/json": { schema: resolver(deleteCategorySchema)}, }, }, }, }), - zValidator("json", createCategorySchema), + zValidator("json", deleteCategorySchema), async (c) => { - const data = c.req.valid("json") as UpdateCategoryInput; + const id = c.req.param("id"); + const data = c.req.valid("json") as DeleteCategoryInput; + + // Ensure the ID in the path matches the one in the body + if (data.id !== id) { + return c.json({ error: "ID in path does not match ID in body" }, 400); + } + const categoryData = await deleteExistingCategory(data); if (categoryData) { return c.json(categoryData); @@ -206,40 +243,48 @@ categoryRoutes.delete( } ) +// Delete all categories by instance ID categoryRoutes.delete( - "/:id/:userId", + "/instance/:instanceId", describeRoute({ description: "Delete all categories by instance id", responses: { 200: { description: "Success deleting all categories in instance", content: { - "application/json": { schema: resolver(createCategorySchema) }, + "application/json": { schema: resolver(deleteCategoriesByInstanceIdSchema) }, }, }, 400: { description: "Bad Request - Invalid input data", content: { - "application/json": { schema: resolver(createCategorySchema)}, + "application/json": { schema: resolver(deleteCategoriesByInstanceIdSchema)}, }, }, 401: { description: "Unauthorized - Admin access required", content: { - "application/json": { schema: resolver(createCategorySchema)}, + "application/json": { schema: resolver(deleteCategoriesByInstanceIdSchema)}, }, }, 404: { description: "Instance id or User Id not found", content: { - "application/json": { schema: resolver(createCategorySchema)}, + "application/json": { schema: resolver(deleteCategoriesByInstanceIdSchema)}, }, }, }, }), - zValidator("json", createCategorySchema), + zValidator("json", deleteCategoriesByInstanceIdSchema), async (c) => { + const instanceId = c.req.param("instanceId"); const data = c.req.valid("json") as DeleteCategoriesByInstanceIdInput; + + // Ensure the instanceId in the path matches the one in the body + if (data.instanceId !== instanceId) { + return c.json({ error: "Instance ID in path does not match Instance ID in body" }, 400); + } + const categoryData = await deleteAllCategoriesByInstance(data); if (categoryData) { return c.json(categoryData); @@ -249,6 +294,4 @@ categoryRoutes.delete( } ) - - export { categoryRoutes }; \ No newline at end of file diff --git a/concord-server/src/routes/channelRoutes.ts b/concord-server/src/routes/channelRoutes.ts index b8a3dd6..e650baf 100644 --- a/concord-server/src/routes/channelRoutes.ts +++ b/concord-server/src/routes/channelRoutes.ts @@ -28,8 +28,9 @@ import { describeRoute, resolver } from "hono-openapi"; const channelRoutes = new Hono() +// Create a new channel channelRoutes.post( - "/channel/create", + "/", describeRoute({ description: "Create a new channel", responses: { @@ -71,6 +72,7 @@ channelRoutes.post( } ) +// Get a channel by ID channelRoutes.get( "/:id", describeRoute({ @@ -101,8 +103,9 @@ channelRoutes.get( } ); +// Get all channels by category ID channelRoutes.get( - "", + "/category/:categoryId", describeRoute({ description: "Get all channels by category id", responses: { @@ -112,15 +115,20 @@ channelRoutes.get( "application/json": { schema: resolver(getChannelsByCategoryIdSchema) }, }, }, + 400: { + description: "Bad Request - Missing category ID", + content: { + "application/json": { schema: resolver(getChannelsByCategoryIdSchema) }, + }, + }, }, }), - zValidator("query", getChannelsByCategoryIdSchema), async (c) => { - const categoryId = c.req.query("categoryId"); + const categoryId = c.req.param("categoryId"); if (!categoryId) { return c.json({ error: "No category id provided" }, 400); } - + const channels = await fetchChannelsByCategory(categoryId); if (channels) { return c.json(channels); @@ -130,8 +138,9 @@ channelRoutes.get( } ); +// Update a channel channelRoutes.put( - "/channel/update", + "/:id", describeRoute({ description: "Update an existing channel", responses: { @@ -163,7 +172,19 @@ channelRoutes.put( }), zValidator("json", updateChannelSchema), async (c) => { + const id = c.req.param("id"); const data = c.req.valid("json") as UpdateChannelInput; + + // Ensure the ID in the path matches the one in the body + if (data.id && data.id !== id) { + return c.json({ error: "ID in path does not match ID in body" }, 400); + } + + // Set ID from path if not in body + if (!data.id) { + data.id = id; + } + const result = await updateExistingChannel(data); if (result) { return c.json(result); @@ -173,8 +194,9 @@ channelRoutes.put( } ); +// Delete a specific channel channelRoutes.delete( - "/channel/delete", + "/:id", describeRoute({ description: "Delete an existing channel", responses: { @@ -206,7 +228,14 @@ channelRoutes.delete( }), zValidator("json", deleteChannelSchema), async (c) => { + const id = c.req.param("id"); const data = c.req.valid("json") as DeleteChannelInput; + + // Ensure the ID in the path matches the one in the body + if (data.id !== id) { + return c.json({ error: "ID in path does not match ID in body" }, 400); + } + const result = await deleteExistingChannel(data); if (result) { return c.json({ success: true }); @@ -216,8 +245,9 @@ channelRoutes.delete( } ); +// Delete all channels by category ID channelRoutes.delete( - "/channels/delete-by-category", + "/category/:categoryId", describeRoute({ description: "Delete all channels by category id", responses: { @@ -249,7 +279,14 @@ channelRoutes.delete( }), zValidator("json", deleteChannelsByCategoryIdSchema), async (c) => { + const categoryId = c.req.param("categoryId"); const data = c.req.valid("json") as DeleteChannelsByCategoryIdInput; + + // Ensure the categoryId in the path matches the one in the body + if (data.categoryId !== categoryId) { + return c.json({ error: "Category ID in path does not match Category ID in body" }, 400); + } + const result = await deleteAllChannelsByCategory(data); if (result) { return c.json({ success: true }); @@ -259,6 +296,4 @@ channelRoutes.delete( } ) - - -export default channelRoutes ; \ No newline at end of file +export { channelRoutes }; \ No newline at end of file diff --git a/concord-server/src/routes/index.ts b/concord-server/src/routes/index.ts index 97440a1..84ef367 100644 --- a/concord-server/src/routes/index.ts +++ b/concord-server/src/routes/index.ts @@ -2,8 +2,9 @@ import { Hono } from "hono"; import userRoutes from "./userRoutes"; import messageRoutes from "./messageRoutes"; -import channelRoutes from "./channelRoutes"; +import { channelRoutes } from "./channelRoutes"; import instanceRoutes from "./instanceRoutes"; +import { categoryRoutes } from "./categoryRoutes"; const routes = new Hono(); @@ -11,5 +12,6 @@ routes.route("/user", userRoutes); routes.route("/message", messageRoutes); routes.route("/channel", channelRoutes); routes.route("/instance", instanceRoutes); +routes.route("/category", categoryRoutes); export default routes;