This commit is contained in:
Kevin Puig
2025-09-27 21:30:08 -04:00
parent 83718a0dec
commit 11f25ca915
3 changed files with 121 additions and 41 deletions

View File

@@ -9,8 +9,16 @@ import {
import { import {
createCategorySchema, createCategorySchema,
getCategorySchema,
getCategoriesByInstanceIdSchema,
updateCategorySchema,
deleteCategorySchema,
deleteCategoriesByInstanceIdSchema,
CreateCategoryInput, CreateCategoryInput,
GetCategoryInput,
GetCategoriesByInstanceIdInput,
UpdateCategoryInput, UpdateCategoryInput,
DeleteCategoryInput,
DeleteCategoriesByInstanceIdInput, DeleteCategoriesByInstanceIdInput,
} from "../validators/categoryValidator"; } from "../validators/categoryValidator";
import { zValidator } from "@hono/zod-validator"; import { zValidator } from "@hono/zod-validator";
@@ -18,8 +26,9 @@ import { Hono } from "hono";
import { describeRoute, resolver } from "hono-openapi"; import { describeRoute, resolver } from "hono-openapi";
const categoryRoutes = new Hono() const categoryRoutes = new Hono()
// Create a new category
categoryRoutes.post( categoryRoutes.post(
"", "/",
describeRoute({ describeRoute({
description: "Create a new category", description: "Create a new category",
responses: { responses: {
@@ -61,6 +70,7 @@ categoryRoutes.post(
} }
) )
// Get a category by ID
categoryRoutes.get( categoryRoutes.get(
"/:id", "/:id",
describeRoute({ describeRoute({
@@ -69,13 +79,13 @@ categoryRoutes.get(
200: { 200: {
description: "Success getting category", description: "Success getting category",
content: { content: {
"application/json": { schema: resolver(createCategorySchema) }, "application/json": { schema: resolver(getCategorySchema) },
}, },
}, },
404: { 404: {
description: "Category id not found", description: "Category id not found",
content: { content: {
"application/json": { schema: resolver(createCategorySchema) }, "application/json": { schema: resolver(getCategorySchema) },
}, },
}, },
}, },
@@ -91,22 +101,28 @@ categoryRoutes.get(
} }
); );
// Get all categories by instance ID
categoryRoutes.get( categoryRoutes.get(
"", "/instance/:instanceId",
describeRoute({ describeRoute({
description: "Get all categories by instance id", description: "Get all categories by instance id",
responses: { responses: {
200: { 200: {
description: "Success getting all categories in instance", description: "Success getting all categories in instance",
content: { 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) => { async (c) => {
const instanceId = c.req.query("instanceId"); const instanceId = c.req.param("instanceId");
if (!instanceId) { if (!instanceId) {
return c.json({ error: "No instance id provided" }, 400); return c.json({ error: "No instance id provided" }, 400);
} }
@@ -120,40 +136,53 @@ categoryRoutes.get(
} }
); );
// Update a category
categoryRoutes.put( categoryRoutes.put(
"", "/:id",
describeRoute({ describeRoute({
description: "Update an existing category", description: "Update an existing category",
responses: { responses: {
200: { 200: {
description: "Success updating category", description: "Success updating category",
content: { content: {
"application/json": { schema: resolver(createCategorySchema) }, "application/json": { schema: resolver(updateCategorySchema) },
}, },
}, },
400: { 400: {
description: "Bad Request - Invalid input data", description: "Bad Request - Invalid input data",
content: { content: {
"application/json": { schema: resolver(createCategorySchema)}, "application/json": { schema: resolver(updateCategorySchema)},
}, },
}, },
401: { 401: {
description: "Unauthorized - Admin access required", description: "Unauthorized - Admin access required",
content: { content: {
"application/json": { schema: resolver(createCategorySchema)}, "application/json": { schema: resolver(updateCategorySchema)},
}, },
}, },
404: { 404: {
description: "Category id or User Id not found", description: "Category id or User Id not found",
content: { content: {
"application/json": { schema: resolver(createCategorySchema)}, "application/json": { schema: resolver(updateCategorySchema)},
}, },
}, },
}, },
}), }),
zValidator("json", createCategorySchema), zValidator("json", updateCategorySchema),
async (c) => { async (c) => {
const id = c.req.param("id");
const data = c.req.valid("json") as UpdateCategoryInput; 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); const categoryData = await updateExistingCategory(data);
if (categoryData) { if (categoryData) {
return c.json(categoryData); return c.json(categoryData);
@@ -163,40 +192,48 @@ categoryRoutes.put(
} }
); );
// Delete a specific category
categoryRoutes.delete( categoryRoutes.delete(
"", "/:id",
describeRoute({ describeRoute({
description: "Delete an existing category", description: "Delete an existing category",
responses: { responses: {
200: { 200: {
description: "Success deleting category", description: "Success deleting category",
content: { content: {
"application/json": { schema: resolver(createCategorySchema) }, "application/json": { schema: resolver(deleteCategorySchema) },
}, },
}, },
400: { 400: {
description: "Bad Request - Invalid input data", description: "Bad Request - Invalid input data",
content: { content: {
"application/json": { schema: resolver(createCategorySchema)}, "application/json": { schema: resolver(deleteCategorySchema)},
}, },
}, },
401: { 401: {
description: "Unauthorized - Admin access required", description: "Unauthorized - Admin access required",
content: { content: {
"application/json": { schema: resolver(createCategorySchema)}, "application/json": { schema: resolver(deleteCategorySchema)},
}, },
}, },
404: { 404: {
description: "Category id or User Id not found", description: "Category id or User Id not found",
content: { content: {
"application/json": { schema: resolver(createCategorySchema)}, "application/json": { schema: resolver(deleteCategorySchema)},
}, },
}, },
}, },
}), }),
zValidator("json", createCategorySchema), zValidator("json", deleteCategorySchema),
async (c) => { 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); const categoryData = await deleteExistingCategory(data);
if (categoryData) { if (categoryData) {
return c.json(categoryData); return c.json(categoryData);
@@ -206,40 +243,48 @@ categoryRoutes.delete(
} }
) )
// Delete all categories by instance ID
categoryRoutes.delete( categoryRoutes.delete(
"/:id/:userId", "/instance/:instanceId",
describeRoute({ describeRoute({
description: "Delete all categories by instance id", description: "Delete all categories by instance id",
responses: { responses: {
200: { 200: {
description: "Success deleting all categories in instance", description: "Success deleting all categories in instance",
content: { content: {
"application/json": { schema: resolver(createCategorySchema) }, "application/json": { schema: resolver(deleteCategoriesByInstanceIdSchema) },
}, },
}, },
400: { 400: {
description: "Bad Request - Invalid input data", description: "Bad Request - Invalid input data",
content: { content: {
"application/json": { schema: resolver(createCategorySchema)}, "application/json": { schema: resolver(deleteCategoriesByInstanceIdSchema)},
}, },
}, },
401: { 401: {
description: "Unauthorized - Admin access required", description: "Unauthorized - Admin access required",
content: { content: {
"application/json": { schema: resolver(createCategorySchema)}, "application/json": { schema: resolver(deleteCategoriesByInstanceIdSchema)},
}, },
}, },
404: { 404: {
description: "Instance id or User Id not found", description: "Instance id or User Id not found",
content: { content: {
"application/json": { schema: resolver(createCategorySchema)}, "application/json": { schema: resolver(deleteCategoriesByInstanceIdSchema)},
}, },
}, },
}, },
}), }),
zValidator("json", createCategorySchema), zValidator("json", deleteCategoriesByInstanceIdSchema),
async (c) => { async (c) => {
const instanceId = c.req.param("instanceId");
const data = c.req.valid("json") as DeleteCategoriesByInstanceIdInput; 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); const categoryData = await deleteAllCategoriesByInstance(data);
if (categoryData) { if (categoryData) {
return c.json(categoryData); return c.json(categoryData);
@@ -249,6 +294,4 @@ categoryRoutes.delete(
} }
) )
export { categoryRoutes }; export { categoryRoutes };

View File

@@ -28,8 +28,9 @@ import { describeRoute, resolver } from "hono-openapi";
const channelRoutes = new Hono() const channelRoutes = new Hono()
// Create a new channel
channelRoutes.post( channelRoutes.post(
"/channel/create", "/",
describeRoute({ describeRoute({
description: "Create a new channel", description: "Create a new channel",
responses: { responses: {
@@ -71,6 +72,7 @@ channelRoutes.post(
} }
) )
// Get a channel by ID
channelRoutes.get( channelRoutes.get(
"/:id", "/:id",
describeRoute({ describeRoute({
@@ -101,8 +103,9 @@ channelRoutes.get(
} }
); );
// Get all channels by category ID
channelRoutes.get( channelRoutes.get(
"", "/category/:categoryId",
describeRoute({ describeRoute({
description: "Get all channels by category id", description: "Get all channels by category id",
responses: { responses: {
@@ -112,11 +115,16 @@ channelRoutes.get(
"application/json": { schema: resolver(getChannelsByCategoryIdSchema) }, "application/json": { schema: resolver(getChannelsByCategoryIdSchema) },
}, },
}, },
400: {
description: "Bad Request - Missing category ID",
content: {
"application/json": { schema: resolver(getChannelsByCategoryIdSchema) },
},
},
}, },
}), }),
zValidator("query", getChannelsByCategoryIdSchema),
async (c) => { async (c) => {
const categoryId = c.req.query("categoryId"); const categoryId = c.req.param("categoryId");
if (!categoryId) { if (!categoryId) {
return c.json({ error: "No category id provided" }, 400); return c.json({ error: "No category id provided" }, 400);
} }
@@ -130,8 +138,9 @@ channelRoutes.get(
} }
); );
// Update a channel
channelRoutes.put( channelRoutes.put(
"/channel/update", "/:id",
describeRoute({ describeRoute({
description: "Update an existing channel", description: "Update an existing channel",
responses: { responses: {
@@ -163,7 +172,19 @@ channelRoutes.put(
}), }),
zValidator("json", updateChannelSchema), zValidator("json", updateChannelSchema),
async (c) => { async (c) => {
const id = c.req.param("id");
const data = c.req.valid("json") as UpdateChannelInput; 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); const result = await updateExistingChannel(data);
if (result) { if (result) {
return c.json(result); return c.json(result);
@@ -173,8 +194,9 @@ channelRoutes.put(
} }
); );
// Delete a specific channel
channelRoutes.delete( channelRoutes.delete(
"/channel/delete", "/:id",
describeRoute({ describeRoute({
description: "Delete an existing channel", description: "Delete an existing channel",
responses: { responses: {
@@ -206,7 +228,14 @@ channelRoutes.delete(
}), }),
zValidator("json", deleteChannelSchema), zValidator("json", deleteChannelSchema),
async (c) => { async (c) => {
const id = c.req.param("id");
const data = c.req.valid("json") as DeleteChannelInput; 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); const result = await deleteExistingChannel(data);
if (result) { if (result) {
return c.json({ success: true }); return c.json({ success: true });
@@ -216,8 +245,9 @@ channelRoutes.delete(
} }
); );
// Delete all channels by category ID
channelRoutes.delete( channelRoutes.delete(
"/channels/delete-by-category", "/category/:categoryId",
describeRoute({ describeRoute({
description: "Delete all channels by category id", description: "Delete all channels by category id",
responses: { responses: {
@@ -249,7 +279,14 @@ channelRoutes.delete(
}), }),
zValidator("json", deleteChannelsByCategoryIdSchema), zValidator("json", deleteChannelsByCategoryIdSchema),
async (c) => { async (c) => {
const categoryId = c.req.param("categoryId");
const data = c.req.valid("json") as DeleteChannelsByCategoryIdInput; 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); const result = await deleteAllChannelsByCategory(data);
if (result) { if (result) {
return c.json({ success: true }); return c.json({ success: true });
@@ -259,6 +296,4 @@ channelRoutes.delete(
} }
) )
export { channelRoutes };
export default channelRoutes ;

View File

@@ -2,8 +2,9 @@
import { Hono } from "hono"; import { Hono } from "hono";
import userRoutes from "./userRoutes"; import userRoutes from "./userRoutes";
import messageRoutes from "./messageRoutes"; import messageRoutes from "./messageRoutes";
import channelRoutes from "./channelRoutes"; import { channelRoutes } from "./channelRoutes";
import instanceRoutes from "./instanceRoutes"; import instanceRoutes from "./instanceRoutes";
import { categoryRoutes } from "./categoryRoutes";
const routes = new Hono(); const routes = new Hono();
@@ -11,5 +12,6 @@ routes.route("/user", userRoutes);
routes.route("/message", messageRoutes); routes.route("/message", messageRoutes);
routes.route("/channel", channelRoutes); routes.route("/channel", channelRoutes);
routes.route("/instance", instanceRoutes); routes.route("/instance", instanceRoutes);
routes.route("/category", categoryRoutes);
export default routes; export default routes;