Skip to content

Commit 54d1b5e

Browse files
authored
feat(feedback): add validation for feedback creation and update (#4260)
* feat(feedback): add validation for feedback creation and update Introduced validation functions for feedback creation and update in the new validation service. Updated feedback controller to utilize these validation functions before processing requests. * refactor(feedback): update validation to return feedback object - Modified validateFeedbackExists to return the ChatMessageFeedback object instead of a boolean. - Updated validateFeedbackForUpdate to utilize the returned feedback object for setting default values.
1 parent 9d9b40a commit 54d1b5e

File tree

2 files changed

+130
-0
lines changed

2 files changed

+130
-0
lines changed

packages/server/src/controllers/feedback/index.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Request, Response, NextFunction } from 'express'
22
import feedbackService from '../../services/feedback'
3+
import { validateFeedbackForCreation, validateFeedbackForUpdate } from '../../services/feedback/validation'
34
import { InternalFlowiseError } from '../../errors/internalFlowiseError'
45
import { StatusCodes } from 'http-status-codes'
56

@@ -31,6 +32,7 @@ const createChatMessageFeedbackForChatflow = async (req: Request, res: Response,
3132
`Error: feedbackController.createChatMessageFeedbackForChatflow - body not provided!`
3233
)
3334
}
35+
await validateFeedbackForCreation(req.body)
3436
const apiResponse = await feedbackService.createChatMessageFeedbackForChatflow(req.body)
3537
return res.json(apiResponse)
3638
} catch (error) {
@@ -52,6 +54,7 @@ const updateChatMessageFeedbackForChatflow = async (req: Request, res: Response,
5254
`Error: feedbackController.updateChatMessageFeedbackForChatflow - id not provided!`
5355
)
5456
}
57+
await validateFeedbackForUpdate(req.params.id, req.body)
5558
const apiResponse = await feedbackService.updateChatMessageFeedbackForChatflow(req.params.id, req.body)
5659
return res.json(apiResponse)
5760
} catch (error) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import { StatusCodes } from 'http-status-codes'
2+
import { IChatMessageFeedback } from '../../Interface'
3+
import { InternalFlowiseError } from '../../errors/internalFlowiseError'
4+
import { getRunningExpressApp } from '../../utils/getRunningExpressApp'
5+
import { ChatMessage } from '../../database/entities/ChatMessage'
6+
import { ChatMessageFeedback } from '../../database/entities/ChatMessageFeedback'
7+
8+
/**
9+
* Validates that the message ID exists
10+
* @param {string} messageId
11+
*/
12+
export const validateMessageExists = async (messageId: string): Promise<ChatMessage> => {
13+
const appServer = getRunningExpressApp()
14+
const message = await appServer.AppDataSource.getRepository(ChatMessage).findOne({
15+
where: { id: messageId }
16+
})
17+
18+
if (!message) {
19+
throw new InternalFlowiseError(StatusCodes.NOT_FOUND, `Message with ID ${messageId} not found`)
20+
}
21+
22+
return message
23+
}
24+
25+
/**
26+
* Validates that the feedback ID exists
27+
* @param {string} feedbackId
28+
*/
29+
export const validateFeedbackExists = async (feedbackId: string): Promise<ChatMessageFeedback> => {
30+
const appServer = getRunningExpressApp()
31+
const feedbackExists = await appServer.AppDataSource.getRepository(ChatMessageFeedback).findOne({
32+
where: { id: feedbackId }
33+
})
34+
35+
if (!feedbackExists) {
36+
throw new InternalFlowiseError(StatusCodes.NOT_FOUND, `Feedback with ID ${feedbackId} not found`)
37+
}
38+
39+
return feedbackExists
40+
}
41+
42+
/**
43+
* Validates a feedback object for creation
44+
* @param {Partial<IChatMessageFeedback>} feedback
45+
*/
46+
export const validateFeedbackForCreation = async (feedback: Partial<IChatMessageFeedback>): Promise<Partial<IChatMessageFeedback>> => {
47+
// If messageId is provided, validate it exists and get the message
48+
let message: ChatMessage | null = null
49+
if (feedback.messageId) {
50+
message = await validateMessageExists(feedback.messageId)
51+
} else {
52+
throw new InternalFlowiseError(StatusCodes.BAD_REQUEST, 'Message ID is required')
53+
}
54+
55+
// If chatId is provided, validate it matches the message's chatId
56+
if (feedback.chatId) {
57+
if (message.chatId !== feedback.chatId) {
58+
throw new InternalFlowiseError(
59+
StatusCodes.BAD_REQUEST,
60+
`Inconsistent chat ID: message with ID ${message.id} does not belong to chat with ID ${feedback.chatId}`
61+
)
62+
}
63+
} else {
64+
// If not provided, use the message's chatId
65+
feedback.chatId = message.chatId
66+
}
67+
68+
// If chatflowid is provided, validate it matches the message's chatflowid
69+
if (feedback.chatflowid) {
70+
if (message.chatflowid !== feedback.chatflowid) {
71+
throw new InternalFlowiseError(
72+
StatusCodes.BAD_REQUEST,
73+
`Inconsistent chatflow ID: message with ID ${message.id} does not belong to chatflow with ID ${feedback.chatflowid}`
74+
)
75+
}
76+
} else {
77+
// If not provided, use the message's chatflowid
78+
feedback.chatflowid = message.chatflowid
79+
}
80+
81+
return feedback
82+
}
83+
84+
/**
85+
* Validates a feedback object for update
86+
* @param {string} feedbackId
87+
* @param {Partial<IChatMessageFeedback>} feedback
88+
*/
89+
export const validateFeedbackForUpdate = async (
90+
feedbackId: string,
91+
feedback: Partial<IChatMessageFeedback>
92+
): Promise<Partial<IChatMessageFeedback>> => {
93+
// First validate the feedback exists
94+
const existingFeedback = await validateFeedbackExists(feedbackId)
95+
96+
feedback.messageId = feedback.messageId ?? existingFeedback.messageId
97+
feedback.chatId = feedback.chatId ?? existingFeedback.chatId
98+
feedback.chatflowid = feedback.chatflowid ?? existingFeedback.chatflowid
99+
100+
// If messageId is provided, validate it exists and get the message
101+
let message: ChatMessage | null = null
102+
if (feedback.messageId) {
103+
message = await validateMessageExists(feedback.messageId)
104+
}
105+
106+
// If chatId is provided and we have a message, validate it matches the message's chatId
107+
if (feedback.chatId) {
108+
if (message?.chatId !== feedback.chatId) {
109+
throw new InternalFlowiseError(
110+
StatusCodes.BAD_REQUEST,
111+
`Inconsistent chat ID: message with ID ${message?.id} does not belong to chat with ID ${feedback.chatId}`
112+
)
113+
}
114+
}
115+
116+
// If chatflowid is provided and we have a message, validate it matches the message's chatflowid
117+
if (feedback.chatflowid && message) {
118+
if (message?.chatflowid !== feedback.chatflowid) {
119+
throw new InternalFlowiseError(
120+
StatusCodes.BAD_REQUEST,
121+
`Inconsistent chatflow ID: message with ID ${message?.id} does not belong to chatflow with ID ${feedback.chatflowid}`
122+
)
123+
}
124+
}
125+
126+
return feedback
127+
}

0 commit comments

Comments
 (0)