feat(knowledge): validate required fields based on plugin schema

Add business-agnostic validation for knowledge base creation:
- Backend: dynamically validate required fields from plugin's creation_schema
  and retrieval_schema, with support for show_if conditional fields
- Frontend: expose validation function from DynamicFormComponent and
  validate before KBForm submission
- Add i18n translations for validation error messages

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
huanghuoguoguo
2026-05-10 18:25:28 +08:00
parent aedc097188
commit 0ceab3f6a5
5 changed files with 162 additions and 4 deletions
@@ -57,7 +57,6 @@ const getFormSchema = (t: (key: string) => string) =>
* Parse creation schema from Knowledge Engine to IDynamicFormItemSchema[]
*/
function parseCreationSchema(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
schemaItems: any | any[] | undefined,
): IDynamicFormItemSchema[] {
if (!schemaItems) return [];
@@ -107,6 +106,10 @@ export default function KBForm({
const savedSnapshotRef = useRef<string>('');
const isInitializing = useRef(true);
// Refs to store validation functions from dynamic forms
const configValidateRef = useRef<(() => Promise<boolean>) | null>(null);
const retrievalValidateRef = useRef<(() => Promise<boolean>) | null>(null);
const formSchema = getFormSchema(t);
const form = useForm<z.infer<typeof formSchema>>({
@@ -235,7 +238,24 @@ export default function KBForm({
}
};
const onSubmit = (data: z.infer<typeof formSchema>) => {
const onSubmit = async (data: z.infer<typeof formSchema>) => {
// Validate dynamic forms before submission
if (configValidateRef.current) {
const configValid = await configValidateRef.current();
if (!configValid) {
toast.error(t('knowledge.engineSettingsInvalid'));
return;
}
}
if (retrievalValidateRef.current) {
const retrievalValid = await retrievalValidateRef.current();
if (!retrievalValid) {
toast.error(t('knowledge.retrievalSettingsInvalid'));
return;
}
}
const kbData: KnowledgeBase = {
name: data.name,
description: data.description ?? '',
@@ -490,6 +510,9 @@ export default function KBForm({
}
isEditing={isEditing}
externalDependentValues={retrievalSettings}
onValidate={(validateFn) =>
(configValidateRef.current = validateFn)
}
/>
</CardContent>
</Card>
@@ -512,6 +535,9 @@ export default function KBForm({
setRetrievalSettings(val as Record<string, unknown>)
}
externalDependentValues={configSettings}
onValidate={(validateFn) =>
(retrievalValidateRef.current = validateFn)
}
/>
</CardContent>
</Card>