feat: category and channel endpoints
This commit is contained in:
39
concord-server/src/controller/categoryController.ts
Normal file
39
concord-server/src/controller/categoryController.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import{
|
||||||
|
createCategory,
|
||||||
|
getCategory,
|
||||||
|
getCategoriesByInstance,
|
||||||
|
updateCategory,
|
||||||
|
deleteCategory,
|
||||||
|
deleteAllCategoriesFromInstance,
|
||||||
|
} from "../services/channelService";
|
||||||
|
import{
|
||||||
|
CreateCategoryInput,
|
||||||
|
UpdateCategoryInput,
|
||||||
|
DeleteCategoryInput,
|
||||||
|
DeleteCategoriesByInstanceIdInput
|
||||||
|
} from "../validators/categoryValidator";
|
||||||
|
|
||||||
|
export async function createNewCategory(data: CreateCategoryInput) {
|
||||||
|
return await createCategory(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchCategoryData(id: string) {
|
||||||
|
return await getCategory(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchCategoriesByInstance(instanceId: string) {
|
||||||
|
return await getCategoriesByInstance(instanceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function updateExistingCategory(data: UpdateCategoryInput) {
|
||||||
|
return await updateCategory(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteExistingCategory(data: DeleteCategoryInput) {
|
||||||
|
return await deleteCategory(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteAllCategoriesByInstance(data: DeleteCategoriesByInstanceIdInput) {
|
||||||
|
return await deleteAllCategoriesFromInstance(data);
|
||||||
|
}
|
||||||
|
|
||||||
38
concord-server/src/controller/channelController.ts
Normal file
38
concord-server/src/controller/channelController.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import{
|
||||||
|
createChannel,
|
||||||
|
getChannel,
|
||||||
|
getChannelsByCategory,
|
||||||
|
updateChannel,
|
||||||
|
deleteChannel,
|
||||||
|
deleteAllChannelsFromCategory
|
||||||
|
} from "../services/channelService";
|
||||||
|
import {
|
||||||
|
CreateChannelInput,
|
||||||
|
UpdateChannelInput,
|
||||||
|
DeleteChannelInput,
|
||||||
|
DeleteChannelsByCategoryIdInput
|
||||||
|
} from "../validators/channelValidator";
|
||||||
|
|
||||||
|
export async function createNewChannel(data: CreateChannelInput) {
|
||||||
|
return await createChannel(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchChannelData(id: string) {
|
||||||
|
return await getChannel(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchChannelsByCategory(categoryId: string) {
|
||||||
|
return await getChannelsByCategory(categoryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function updateExistingChannel(data: UpdateChannelInput) {
|
||||||
|
return await updateChannel(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteExistingChannel(data: DeleteChannelInput) {
|
||||||
|
return await deleteChannel(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteAllChannelsByCategory(data: DeleteChannelsByCategoryIdInput) {
|
||||||
|
return await deleteAllChannelsFromCategory(data);
|
||||||
|
}
|
||||||
254
concord-server/src/routes/categoryRoutes.ts
Normal file
254
concord-server/src/routes/categoryRoutes.ts
Normal file
@@ -0,0 +1,254 @@
|
|||||||
|
import {
|
||||||
|
createNewCategory,
|
||||||
|
fetchCategoryData,
|
||||||
|
fetchCategoriesByInstance,
|
||||||
|
updateExistingCategory,
|
||||||
|
deleteExistingCategory,
|
||||||
|
deleteAllCategoriesByInstance,
|
||||||
|
} from "../controller/categoryController";
|
||||||
|
|
||||||
|
import {
|
||||||
|
createCategorySchema,
|
||||||
|
CreateCategoryInput,
|
||||||
|
UpdateCategoryInput,
|
||||||
|
DeleteCategoriesByInstanceIdInput,
|
||||||
|
} from "../validators/categoryValidator";
|
||||||
|
import { zValidator } from "@hono/zod-validator";
|
||||||
|
import { Hono } from "hono";
|
||||||
|
import { describeRoute, resolver } from "hono-openapi";
|
||||||
|
const categoryRoutes = new Hono()
|
||||||
|
|
||||||
|
categoryRoutes.post(
|
||||||
|
"/category/create",
|
||||||
|
describeRoute({
|
||||||
|
description: "Create a new category",
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: "Success creating category",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createCategorySchema) },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
400: {
|
||||||
|
description: "Bad Request - Invalid input data",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createCategorySchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
401: {
|
||||||
|
description: "Unauthorized - Admin access required",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createCategorySchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
404: {
|
||||||
|
description: "User Id not found",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createCategorySchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
zValidator("json", createCategorySchema),
|
||||||
|
async (c) => {
|
||||||
|
const data = c.req.valid("json") as CreateCategoryInput;
|
||||||
|
const categoryData = await createNewCategory(data);
|
||||||
|
if (categoryData) {
|
||||||
|
return c.json(categoryData);
|
||||||
|
} else {
|
||||||
|
return c.json({ error: "Failed to create category" }, 400);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
categoryRoutes.get(
|
||||||
|
"/:id",
|
||||||
|
describeRoute({
|
||||||
|
description: "Get category by id",
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: "Success getting category",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createCategorySchema) },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
404: {
|
||||||
|
description: "Category id not found",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createCategorySchema) },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
async (c) => {
|
||||||
|
const id = c.req.param("id");
|
||||||
|
const categoryData = await fetchCategoryData(id);
|
||||||
|
if (categoryData) {
|
||||||
|
return c.json(categoryData);
|
||||||
|
} else {
|
||||||
|
return c.json({ error: "Category not found" }, 404);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
categoryRoutes.get(
|
||||||
|
"",
|
||||||
|
describeRoute({
|
||||||
|
description: "Get all categories by instance id",
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: "Success getting all categories in instance",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createCategorySchema) },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
zValidator("query", createCategorySchema),
|
||||||
|
async (c) => {
|
||||||
|
const instanceId = c.req.query("instanceId");
|
||||||
|
if (!instanceId) {
|
||||||
|
return c.json({ error: "No instance id provided" }, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
const categoryData = await fetchCategoriesByInstance(instanceId);
|
||||||
|
if (categoryData) {
|
||||||
|
return c.json(categoryData);
|
||||||
|
} else {
|
||||||
|
return c.json({ error: "Error getting all categories from instance" }, 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
categoryRoutes.put(
|
||||||
|
"/category/update",
|
||||||
|
describeRoute({
|
||||||
|
description: "Update an existing category",
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: "Success updating category",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createCategorySchema) },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
400: {
|
||||||
|
description: "Bad Request - Invalid input data",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createCategorySchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
401: {
|
||||||
|
description: "Unauthorized - Admin access required",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createCategorySchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
404: {
|
||||||
|
description: "Category id or User Id not found",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createCategorySchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
zValidator("json", createCategorySchema),
|
||||||
|
async (c) => {
|
||||||
|
const data = c.req.valid("json") as UpdateCategoryInput;
|
||||||
|
const categoryData = await updateExistingCategory(data);
|
||||||
|
if (categoryData) {
|
||||||
|
return c.json(categoryData);
|
||||||
|
} else {
|
||||||
|
return c.json({ error: "Failed to update category" }, 400);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
categoryRoutes.delete(
|
||||||
|
"/category/delete",
|
||||||
|
describeRoute({
|
||||||
|
description: "Delete an existing category",
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: "Success deleting category",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createCategorySchema) },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
400: {
|
||||||
|
description: "Bad Request - Invalid input data",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createCategorySchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
401: {
|
||||||
|
description: "Unauthorized - Admin access required",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createCategorySchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
404: {
|
||||||
|
description: "Category id or User Id not found",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createCategorySchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
zValidator("json", createCategorySchema),
|
||||||
|
async (c) => {
|
||||||
|
const data = c.req.valid("json") as UpdateCategoryInput;
|
||||||
|
const categoryData = await deleteExistingCategory(data);
|
||||||
|
if (categoryData) {
|
||||||
|
return c.json(categoryData);
|
||||||
|
} else {
|
||||||
|
return c.json({ error: "Failed to delete category" }, 400);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
categoryRoutes.delete(
|
||||||
|
"/categories/delete/:id",
|
||||||
|
describeRoute({
|
||||||
|
description: "Delete all categories by instance id",
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: "Success deleting all categories in instance",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createCategorySchema) },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
400: {
|
||||||
|
description: "Bad Request - Invalid input data",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createCategorySchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
401: {
|
||||||
|
description: "Unauthorized - Admin access required",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createCategorySchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
404: {
|
||||||
|
description: "Instance id or User Id not found",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createCategorySchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
zValidator("json", createCategorySchema),
|
||||||
|
async (c) => {
|
||||||
|
const data = c.req.valid("json") as DeleteCategoriesByInstanceIdInput;
|
||||||
|
const categoryData = await deleteAllCategoriesByInstance(data);
|
||||||
|
if (categoryData) {
|
||||||
|
return c.json(categoryData);
|
||||||
|
} else {
|
||||||
|
return c.json({ error: "Failed to delete categories" }, 400);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export { categoryRoutes };
|
||||||
264
concord-server/src/routes/channelRoutes.ts
Normal file
264
concord-server/src/routes/channelRoutes.ts
Normal file
@@ -0,0 +1,264 @@
|
|||||||
|
import {
|
||||||
|
createNewChannel,
|
||||||
|
fetchChannelData,
|
||||||
|
fetchChannelsByCategory,
|
||||||
|
updateExistingChannel,
|
||||||
|
deleteExistingChannel,
|
||||||
|
deleteAllChannelsByCategory,
|
||||||
|
} from "../controller/channelController";
|
||||||
|
|
||||||
|
import {
|
||||||
|
createChannelSchema,
|
||||||
|
getChannelSchema,
|
||||||
|
getChannelsByCategoryIdSchema,
|
||||||
|
updateChannelSchema,
|
||||||
|
deleteChannelSchema,
|
||||||
|
deleteChannelsByCategoryIdSchema,
|
||||||
|
|
||||||
|
CreateChannelInput,
|
||||||
|
GetChannelInput,
|
||||||
|
GetChannelsByCategoryIdInput,
|
||||||
|
UpdateChannelInput,
|
||||||
|
DeleteChannelInput,
|
||||||
|
DeleteChannelsByCategoryIdInput,
|
||||||
|
} from "../validators/channelValidator";
|
||||||
|
import { zValidator } from "@hono/zod-validator";
|
||||||
|
import { Hono } from "hono";
|
||||||
|
import { describeRoute, resolver } from "hono-openapi";
|
||||||
|
|
||||||
|
const channelRoutes = new Hono()
|
||||||
|
|
||||||
|
channelRoutes.post(
|
||||||
|
"/channel/create",
|
||||||
|
describeRoute({
|
||||||
|
description: "Create a new channel",
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: "Success creating channel",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createChannelSchema) },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
400: {
|
||||||
|
description: "Bad Request - Invalid input data",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createChannelSchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
401: {
|
||||||
|
description: "Unauthorized - Admin access required",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createChannelSchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
404: {
|
||||||
|
description: "User Id not found",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(createChannelSchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
zValidator("json", createChannelSchema),
|
||||||
|
async (c) => {
|
||||||
|
const data = c.req.valid("json") as CreateChannelInput;
|
||||||
|
const channelData = await createNewChannel(data);
|
||||||
|
if (channelData) {
|
||||||
|
return c.json(channelData);
|
||||||
|
} else {
|
||||||
|
return c.json({ error: "Failed to create channel" }, 400);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
channelRoutes.get(
|
||||||
|
"/:id",
|
||||||
|
describeRoute({
|
||||||
|
description: "Get channel by id",
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: "Success getting channel",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(getChannelSchema) },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
404: {
|
||||||
|
description: "Channel id not found",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(getChannelSchema) },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
async (c) => {
|
||||||
|
const id = c.req.param("id");
|
||||||
|
const channelData = await fetchChannelData(id);
|
||||||
|
if (channelData) {
|
||||||
|
return c.json(channelData);
|
||||||
|
} else {
|
||||||
|
return c.json({ error: "Channel not found" }, 404);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
channelRoutes.get(
|
||||||
|
"",
|
||||||
|
describeRoute({
|
||||||
|
description: "Get all channels by category id",
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: "Success getting all channels in category",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(getChannelsByCategoryIdSchema) },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
zValidator("query", getChannelsByCategoryIdSchema),
|
||||||
|
async (c) => {
|
||||||
|
const categoryId = c.req.query("categoryId");
|
||||||
|
if (!categoryId) {
|
||||||
|
return c.json({ error: "No category id provided" }, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
const channels = await fetchChannelsByCategory(categoryId);
|
||||||
|
if (channels) {
|
||||||
|
return c.json(channels);
|
||||||
|
} else {
|
||||||
|
return c.json({ error: "Error getting channels from category" }, 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
channelRoutes.put(
|
||||||
|
"/channel/update",
|
||||||
|
describeRoute({
|
||||||
|
description: "Update an existing channel",
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: "Success updating channel",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(updateChannelSchema) },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
400: {
|
||||||
|
description: "Bad Request - Invalid input data",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(updateChannelSchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
401: {
|
||||||
|
description: "Unauthorized - Admin access required",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(updateChannelSchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
404: {
|
||||||
|
description: "Channel id or User Id not found",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(updateChannelSchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
zValidator("json", updateChannelSchema),
|
||||||
|
async (c) => {
|
||||||
|
const data = c.req.valid("json") as UpdateChannelInput;
|
||||||
|
const result = await updateExistingChannel(data);
|
||||||
|
if (result) {
|
||||||
|
return c.json(result);
|
||||||
|
} else {
|
||||||
|
return c.json({ error: "Failed to update channel" }, 400);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
channelRoutes.delete(
|
||||||
|
"/channel/delete",
|
||||||
|
describeRoute({
|
||||||
|
description: "Delete an existing channel",
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: "Success deleting channel",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(deleteChannelSchema) },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
400: {
|
||||||
|
description: "Bad Request - Invalid input data",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(deleteChannelSchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
401: {
|
||||||
|
description: "Unauthorized - Admin access required",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(deleteChannelSchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
404: {
|
||||||
|
description: "Channel id or User Id not found",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(deleteChannelSchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
zValidator("json", deleteChannelSchema),
|
||||||
|
async (c) => {
|
||||||
|
const data = c.req.valid("json") as DeleteChannelInput;
|
||||||
|
const result = await deleteExistingChannel(data);
|
||||||
|
if (result) {
|
||||||
|
return c.json({ success: true });
|
||||||
|
} else {
|
||||||
|
return c.json({ error: "Failed to delete channel" }, 400);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
channelRoutes.delete(
|
||||||
|
"/channels/delete-by-category",
|
||||||
|
describeRoute({
|
||||||
|
description: "Delete all channels by category id",
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: "Success deleting all channels in category",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(deleteChannelsByCategoryIdSchema) },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
400: {
|
||||||
|
description: "Bad Request - Invalid input data",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(deleteChannelsByCategoryIdSchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
401: {
|
||||||
|
description: "Unauthorized - Admin access required",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(deleteChannelsByCategoryIdSchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
404: {
|
||||||
|
description: "Category id or User Id not found",
|
||||||
|
content: {
|
||||||
|
"application/json": { schema: resolver(deleteChannelsByCategoryIdSchema)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
zValidator("json", deleteChannelsByCategoryIdSchema),
|
||||||
|
async (c) => {
|
||||||
|
const data = c.req.valid("json") as DeleteChannelsByCategoryIdInput;
|
||||||
|
const result = await deleteAllChannelsByCategory(data);
|
||||||
|
if (result) {
|
||||||
|
return c.json({ success: true });
|
||||||
|
} else {
|
||||||
|
return c.json({ error: "Failed to delete channels" }, 400);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default channelRoutes ;
|
||||||
@@ -2,10 +2,12 @@
|
|||||||
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";
|
||||||
|
|
||||||
const routes = new Hono();
|
const routes = new Hono();
|
||||||
|
|
||||||
routes.route("/user", userRoutes);
|
routes.route("/user", userRoutes);
|
||||||
routes.route("/message", messageRoutes);
|
routes.route("/message", messageRoutes);
|
||||||
|
routes.route("/channel", channelRoutes);
|
||||||
|
|
||||||
export default routes;
|
export default routes;
|
||||||
|
|||||||
450
concord-server/src/services/channelService.ts
Normal file
450
concord-server/src/services/channelService.ts
Normal file
@@ -0,0 +1,450 @@
|
|||||||
|
import{
|
||||||
|
Channel,
|
||||||
|
Category
|
||||||
|
} from '@prisma/client';
|
||||||
|
import { PrismaClient } from "@prisma/client";
|
||||||
|
import { getUserInformation, getUserCredentials } from './userService';
|
||||||
|
import {
|
||||||
|
CreateChannelInput,
|
||||||
|
UpdateChannelInput,
|
||||||
|
DeleteChannelInput,
|
||||||
|
DeleteChannelsByCategoryIdInput
|
||||||
|
} from '../validators/channelValidator';
|
||||||
|
import{
|
||||||
|
UpdateCategoryInput,
|
||||||
|
DeleteCategoryInput,
|
||||||
|
DeleteCategoriesByInstanceIdInput,
|
||||||
|
CreateCategoryInput
|
||||||
|
} from '../validators/categoryValidator';
|
||||||
|
|
||||||
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
|
|
||||||
|
export async function createCategory(data: CreateCategoryInput): Promise<Category | null>{
|
||||||
|
try{
|
||||||
|
|
||||||
|
//Confirm if user exists and is admin
|
||||||
|
const requestingUser = await getUserInformation(data.requestingUserId);
|
||||||
|
const requestingUserCredentials = await getUserCredentials(
|
||||||
|
data.requestingUserId,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
!requestingUser ||
|
||||||
|
!requestingUserCredentials ||
|
||||||
|
!requestingUser.admin ||
|
||||||
|
requestingUserCredentials.token == null ||
|
||||||
|
data.requestingUserToken != requestingUserCredentials.token
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newCategory = await prisma.category.create({
|
||||||
|
data: {
|
||||||
|
name: data.name,
|
||||||
|
position: data.position
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(!newCategory){
|
||||||
|
throw new Error("could not create category");
|
||||||
|
}
|
||||||
|
|
||||||
|
let curInstance;
|
||||||
|
if(data.instanceId){
|
||||||
|
curInstance = await prisma.instance.findUnique({
|
||||||
|
where: {
|
||||||
|
id: data.instanceId
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
Category: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(!curInstance){
|
||||||
|
throw new Error("could not find instance to add category to");
|
||||||
|
}
|
||||||
|
|
||||||
|
await prisma.category.update({
|
||||||
|
where: {
|
||||||
|
id: newCategory.id
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
instanceId: curInstance.id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return newCategory;
|
||||||
|
}
|
||||||
|
|
||||||
|
return newCategory;
|
||||||
|
}catch(err){
|
||||||
|
console.log("services::channelService::createCategory - ", err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getCategory(
|
||||||
|
categoryId: string,
|
||||||
|
): Promise<Category | null>{
|
||||||
|
try{
|
||||||
|
const category = await prisma.category.findUnique({
|
||||||
|
where: {
|
||||||
|
id: categoryId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(!category){
|
||||||
|
throw new Error("could not find category");
|
||||||
|
}
|
||||||
|
|
||||||
|
return category;
|
||||||
|
}catch(err){
|
||||||
|
console.log("services::channelService::getCategory - ", err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getCategoriesByInstance(
|
||||||
|
instanceId: string
|
||||||
|
): Promise<Category[] | null>{
|
||||||
|
try{
|
||||||
|
const categories = await prisma.category.findMany({
|
||||||
|
where: {
|
||||||
|
instanceId: instanceId
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
Channel: true
|
||||||
|
},
|
||||||
|
orderBy: {
|
||||||
|
position: 'asc'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(!categories){
|
||||||
|
throw new Error("could not find categories for instance");
|
||||||
|
}
|
||||||
|
|
||||||
|
return categories;
|
||||||
|
}catch(err){
|
||||||
|
console.log("services::channelService::getCategoriesByInstance - ", err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function updateCategory(data: UpdateCategoryInput): Promise<Category | null>{
|
||||||
|
try{
|
||||||
|
|
||||||
|
//Confirm if user exists and is admin
|
||||||
|
const requestingUser = await getUserInformation(data.requestingUserId);
|
||||||
|
const requestingUserCredentials = await getUserCredentials(
|
||||||
|
data.requestingUserId,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
!requestingUser ||
|
||||||
|
!requestingUserCredentials ||
|
||||||
|
!requestingUser.admin ||
|
||||||
|
requestingUserCredentials.token == null ||
|
||||||
|
data.requestingUserToken != requestingUserCredentials.token
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedCategory = await prisma.category.update({
|
||||||
|
where: {
|
||||||
|
id: data.id
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
name: data.name,
|
||||||
|
position: data.position,
|
||||||
|
Channel: data.channels ? { set: data.channels } : undefined
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(!updatedCategory){
|
||||||
|
throw new Error("could not update category");
|
||||||
|
}
|
||||||
|
|
||||||
|
return updatedCategory;
|
||||||
|
}catch(err){
|
||||||
|
console.log("services::channelService::updateCategory - ", err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteCategory(data: DeleteCategoryInput): Promise<boolean | null>{
|
||||||
|
try{
|
||||||
|
|
||||||
|
//Confirm if user exists and is admin
|
||||||
|
const requestingUser = await getUserInformation(data.requestingUserId);
|
||||||
|
const requestingUserCredentials = await getUserCredentials(
|
||||||
|
data.requestingUserId,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
!requestingUser ||
|
||||||
|
!requestingUserCredentials ||
|
||||||
|
!requestingUser.admin ||
|
||||||
|
requestingUserCredentials.token == null ||
|
||||||
|
data.requestingUserToken != requestingUserCredentials.token
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteAllChannels = await prisma.channel.deleteMany({
|
||||||
|
where: {
|
||||||
|
categoryId: data.id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(deleteAllChannels.count === 0){
|
||||||
|
throw new Error("could not delete channels from category");
|
||||||
|
}
|
||||||
|
|
||||||
|
const deletedCategory = await prisma.category.delete({
|
||||||
|
where: {
|
||||||
|
id: data.id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(!deletedCategory){
|
||||||
|
throw new Error("could not delete category");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}catch(err){
|
||||||
|
console.log("services::channelService::deleteCategory - ", err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteAllCategoriesFromInstance(data: DeleteCategoriesByInstanceIdInput): Promise<boolean | null>{
|
||||||
|
try{
|
||||||
|
|
||||||
|
//Confirm if user exists and is admin
|
||||||
|
const requestingUser = await getUserInformation(data.requestingUserId);
|
||||||
|
const requestingUserCredentials = await getUserCredentials(
|
||||||
|
data.requestingUserId,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
!requestingUser ||
|
||||||
|
!requestingUserCredentials ||
|
||||||
|
!requestingUser.admin ||
|
||||||
|
requestingUserCredentials.token == null ||
|
||||||
|
data.requestingUserToken != requestingUserCredentials.token
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const deletedCategories = await prisma.category.deleteMany({
|
||||||
|
where: {
|
||||||
|
instanceId: data.instanceId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(deletedCategories.count === 0){
|
||||||
|
throw new Error("could not delete categories from instance");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}catch(err){
|
||||||
|
console.log("services::channelService::deleteAllCategoriesFromInstance - ", err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createChannel(data: CreateChannelInput): Promise<Channel | null>{
|
||||||
|
try{
|
||||||
|
|
||||||
|
//Confirm if user exists and is admin
|
||||||
|
const requestingUser = await getUserInformation(data.requestingUserId);
|
||||||
|
const requestingUserCredentials = await getUserCredentials(
|
||||||
|
data.requestingUserId,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
!requestingUser ||
|
||||||
|
!requestingUserCredentials ||
|
||||||
|
!requestingUser.admin ||
|
||||||
|
requestingUserCredentials.token == null ||
|
||||||
|
data.requestingUserToken != requestingUserCredentials.token
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newChannel = await prisma.channel.create({
|
||||||
|
data: {
|
||||||
|
type: data.type,
|
||||||
|
name: data.name,
|
||||||
|
description: data.description,
|
||||||
|
categoryId: data.categoryId ? data.categoryId : null
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(!newChannel){
|
||||||
|
throw new Error("could not create channel");
|
||||||
|
}
|
||||||
|
|
||||||
|
return newChannel;
|
||||||
|
}catch(err){
|
||||||
|
console.log("services::channelService::createChannel - ", err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getChannel(
|
||||||
|
channelId: string
|
||||||
|
): Promise<Channel | null>{
|
||||||
|
try{
|
||||||
|
const channel = await prisma.channel.findUnique({
|
||||||
|
where: {
|
||||||
|
id: channelId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(!channel){
|
||||||
|
throw new Error("could not find channel");
|
||||||
|
}
|
||||||
|
|
||||||
|
return channel;
|
||||||
|
}catch(err){
|
||||||
|
console.log("services::channelService::getChannel - ", err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getChannelsByCategory(
|
||||||
|
categoryId: string
|
||||||
|
): Promise<Channel[] | null>{
|
||||||
|
try{
|
||||||
|
const channels = await prisma.channel.findMany({
|
||||||
|
where: {
|
||||||
|
categoryId: categoryId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(!channels){
|
||||||
|
throw new Error("could not find channels for category");
|
||||||
|
}
|
||||||
|
return channels;
|
||||||
|
}
|
||||||
|
catch(err){
|
||||||
|
console.log("services::channelService::getChannelsByCategory - ", err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function updateChannel(data: UpdateChannelInput): Promise<Channel | null>{
|
||||||
|
try{
|
||||||
|
|
||||||
|
//Confirm if user exists and is admin
|
||||||
|
const requestingUser = await getUserInformation(data.requestingUserId);
|
||||||
|
const requestingUserCredentials = await getUserCredentials(
|
||||||
|
data.requestingUserId,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
!requestingUser ||
|
||||||
|
!requestingUserCredentials ||
|
||||||
|
!requestingUser.admin ||
|
||||||
|
requestingUserCredentials.token == null ||
|
||||||
|
data.requestingUserToken != requestingUserCredentials.token
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedChannel = await prisma.channel.update({
|
||||||
|
where: {
|
||||||
|
id: data.id
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
name: data.name,
|
||||||
|
description: data.description,
|
||||||
|
categoryId: data.categoryId ? data.categoryId : undefined
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(!updatedChannel){
|
||||||
|
throw new Error("could not update channel");
|
||||||
|
}
|
||||||
|
|
||||||
|
return updatedChannel;
|
||||||
|
}catch(err){
|
||||||
|
console.log("services::channelService::updateChannel - ", err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteChannel(data: DeleteChannelInput): Promise<boolean | null>{
|
||||||
|
try{
|
||||||
|
|
||||||
|
//Confirm if user exists and is admin
|
||||||
|
const requestingUser = await getUserInformation(data.requestingUserId);
|
||||||
|
const requestingUserCredentials = await getUserCredentials(
|
||||||
|
data.requestingUserId,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
!requestingUser ||
|
||||||
|
!requestingUserCredentials ||
|
||||||
|
!requestingUser.admin ||
|
||||||
|
requestingUserCredentials.token == null ||
|
||||||
|
data.requestingUserToken != requestingUserCredentials.token
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const deletedChannel = await prisma.channel.delete({
|
||||||
|
where: {
|
||||||
|
id: data.id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(!deletedChannel){
|
||||||
|
throw new Error("could not delete channel");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}catch(err){
|
||||||
|
console.log("services::channelService::deleteChannel - ", err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteAllChannelsFromCategory(data: DeleteChannelsByCategoryIdInput): Promise<boolean | null>
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
//Confirm if user exists and is admin
|
||||||
|
const requestingUser = await getUserInformation(data.requestingUserId);
|
||||||
|
const requestingUserCredentials = await getUserCredentials(
|
||||||
|
data.requestingUserId,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
!requestingUser ||
|
||||||
|
!requestingUserCredentials ||
|
||||||
|
!requestingUser.admin ||
|
||||||
|
requestingUserCredentials.token == null ||
|
||||||
|
data.requestingUserToken != requestingUserCredentials.token
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const deletedChannels = await prisma.channel.deleteMany({
|
||||||
|
where: {
|
||||||
|
categoryId: data.categoryId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(deletedChannels.count === 0){
|
||||||
|
throw new Error("could not delete channels from category");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}catch(err){
|
||||||
|
console.log("services::channelService::deleteAllChannelsFromCategory - ", err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
Message,
|
Message,
|
||||||
MessagePing,
|
MessagePing,
|
||||||
|
|||||||
55
concord-server/src/validators/categoryValidator.ts
Normal file
55
concord-server/src/validators/categoryValidator.ts
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
//category validators
|
||||||
|
|
||||||
|
export const createCategorySchema = z.object({
|
||||||
|
name: z.string().min(1).max(50),
|
||||||
|
position: z.number().min(0),
|
||||||
|
instanceId : z.uuidv7().optional(),
|
||||||
|
admin: z.boolean(),
|
||||||
|
requestingUserId: z.uuidv7(),
|
||||||
|
requestingUserToken: z.uuidv4()
|
||||||
|
})
|
||||||
|
|
||||||
|
export const getCategorySchema = z.object({
|
||||||
|
id: z.uuidv7()
|
||||||
|
})
|
||||||
|
|
||||||
|
export const getCategoriesByInstanceIdSchema = z.object({
|
||||||
|
instanceId: z.uuidv7()
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
export const updateCategorySchema = z.object({
|
||||||
|
id: z.uuidv7(),
|
||||||
|
name: z.string().min(1).max(50).optional(),
|
||||||
|
position: z.number().min(0).optional(),
|
||||||
|
channels: z.array(z.object({
|
||||||
|
id: z.string()
|
||||||
|
})).optional(),
|
||||||
|
admin: z.boolean(),
|
||||||
|
requestingUserId: z.uuidv7(),
|
||||||
|
requestingUserToken: z.uuidv4()
|
||||||
|
})
|
||||||
|
|
||||||
|
export const deleteCategorySchema = z.object({
|
||||||
|
id: z.uuidv7(),
|
||||||
|
admin: z.boolean(),
|
||||||
|
requestingUserId: z.uuidv7(),
|
||||||
|
requestingUserToken: z.uuidv4()
|
||||||
|
})
|
||||||
|
|
||||||
|
export const deleteCategoriesByInstanceIdSchema = z.object({
|
||||||
|
instanceId: z.uuidv7(),
|
||||||
|
admin: z.boolean(),
|
||||||
|
requestingUserId: z.uuidv7(),
|
||||||
|
requestingUserToken: z.uuidv4()
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
export type CreateCategoryInput = z.infer<typeof createCategorySchema>
|
||||||
|
export type GetCategoryInput = z.infer<typeof getCategorySchema>
|
||||||
|
export type GetCategoriesByInstanceIdInput = z.infer<typeof getCategoriesByInstanceIdSchema>
|
||||||
|
export type UpdateCategoryInput = z.infer<typeof updateCategorySchema>
|
||||||
|
export type DeleteCategoryInput = z.infer<typeof deleteCategorySchema>
|
||||||
|
export type DeleteCategoriesByInstanceIdInput = z.infer<typeof deleteCategoriesByInstanceIdSchema>
|
||||||
52
concord-server/src/validators/channelValidator.ts
Normal file
52
concord-server/src/validators/channelValidator.ts
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
//channel validators
|
||||||
|
|
||||||
|
export const createChannelSchema = z.object({
|
||||||
|
type: z.enum(['text', 'voice']),
|
||||||
|
name: z.string().min(1).max(50),
|
||||||
|
description: z.string().max(255),
|
||||||
|
categoryId: z.uuidv7().optional(),
|
||||||
|
admin: z.boolean(),
|
||||||
|
requestingUserId: z.uuidv7(),
|
||||||
|
requestingUserToken: z.uuidv4()
|
||||||
|
})
|
||||||
|
|
||||||
|
export const getChannelSchema = z.object({
|
||||||
|
id: z.uuidv7()
|
||||||
|
})
|
||||||
|
|
||||||
|
export const getChannelsByCategoryIdSchema = z.object({
|
||||||
|
categoryId: z.uuidv7()
|
||||||
|
})
|
||||||
|
|
||||||
|
export const updateChannelSchema = z.object({
|
||||||
|
id: z.uuidv7(),
|
||||||
|
name: z.string().min(1).max(50).optional(),
|
||||||
|
description: z.string().max(255).optional(),
|
||||||
|
categoryId: z.uuidv7().optional(),
|
||||||
|
admin: z.boolean(),
|
||||||
|
requestingUserId: z.uuidv7(),
|
||||||
|
requestingUserToken: z.uuidv4()
|
||||||
|
})
|
||||||
|
|
||||||
|
export const deleteChannelSchema = z.object({
|
||||||
|
id: z.uuidv7(),
|
||||||
|
admin: z.boolean(),
|
||||||
|
requestingUserId: z.uuidv7(),
|
||||||
|
requestingUserToken: z.uuidv4()
|
||||||
|
})
|
||||||
|
|
||||||
|
export const deleteChannelsByCategoryIdSchema = z.object({
|
||||||
|
categoryId: z.uuidv7(),
|
||||||
|
admin: z.boolean(),
|
||||||
|
requestingUserId: z.uuidv7(),
|
||||||
|
requestingUserToken: z.uuidv4()
|
||||||
|
})
|
||||||
|
|
||||||
|
export type CreateChannelInput = z.infer<typeof createChannelSchema>
|
||||||
|
export type GetChannelInput = z.infer<typeof getChannelSchema>
|
||||||
|
export type GetChannelsByCategoryIdInput = z.infer<typeof getChannelsByCategoryIdSchema>
|
||||||
|
export type UpdateChannelInput = z.infer<typeof updateChannelSchema>
|
||||||
|
export type DeleteChannelInput = z.infer<typeof deleteChannelSchema>
|
||||||
|
export type DeleteChannelsByCategoryIdInput = z.infer<typeof deleteChannelsByCategoryIdSchema>
|
||||||
@@ -7,7 +7,7 @@ export const queryUserByIdSchema = z.object({
|
|||||||
export const queryAllUsersByInstanceId = z.object({
|
export const queryAllUsersByInstanceId = z.object({
|
||||||
instanceId: z.uuidv7(),
|
instanceId: z.uuidv7(),
|
||||||
});
|
});
|
||||||
|
import { is } from 'zod/v4/locales';
|
||||||
export const createUserSchema = z.object({
|
export const createUserSchema = z.object({
|
||||||
username: z.string().min(3).max(30),
|
username: z.string().min(3).max(30),
|
||||||
nickname: z.string().min(1).max(30).optional(),
|
nickname: z.string().min(1).max(30).optional(),
|
||||||
|
|||||||
Reference in New Issue
Block a user