feat: category and channel endpoints

This commit is contained in:
PrimarchPaul
2025-09-27 20:45:36 -04:00
parent 9b46852e20
commit d1273ca4ec
10 changed files with 1156 additions and 1 deletions

View 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);
}

View 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);
}

View 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 };

View 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 ;

View File

@@ -2,10 +2,12 @@
import { Hono } from "hono";
import userRoutes from "./userRoutes";
import messageRoutes from "./messageRoutes";
import channelRoutes from "./channelRoutes";
const routes = new Hono();
routes.route("/user", userRoutes);
routes.route("/message", messageRoutes);
routes.route("/channel", channelRoutes);
export default routes;

View 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;
}
}

View File

@@ -1,3 +1,4 @@
import {
Message,
MessagePing,

View 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>

View 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>

View File

@@ -7,7 +7,7 @@ export const queryUserByIdSchema = z.object({
export const queryAllUsersByInstanceId = z.object({
instanceId: z.uuidv7(),
});
import { is } from 'zod/v4/locales';
export const createUserSchema = z.object({
username: z.string().min(3).max(30),
nickname: z.string().min(1).max(30).optional(),