Fix chatflow's type null or blank (#5065)

* fix(entities/ChatFlow.ts): make type column non-nullable with default value

* fix(postgres/ModifyChatflowType): set default type and make column non-nullable

* fix(sqlite/ModifyChatflowType): set default type and make column non-nullable

* fix(mysql/ModifyChatflowType): set default type and make column non-nullable

* chore(sqlite/ModifyChatflowType): standardize type column to VARCHAR(20)

* chore(postgres/ModifyChatflowType): standardize type column to VARCHAR(20)

* fix(mariadb/ModifyChatflowType): set default type and make column non-nullable

* chore: rename ChatflowType to EnumChatflowType and update references

* feat(chatflows): add chatflow type validation

* fix(chatflows): empty string bypassing type validation on update
This commit is contained in:
Ong Chung Yau
2025-08-15 19:25:54 +08:00
committed by GitHub
parent 44087bc706
commit 4ce0851858
10 changed files with 180 additions and 73 deletions
@@ -2,6 +2,13 @@
import { Entity, Column, CreateDateColumn, UpdateDateColumn, PrimaryGeneratedColumn } from 'typeorm'
import { ChatflowType, IChatFlow } from '../../Interface'
export enum EnumChatflowType {
CHATFLOW = 'CHATFLOW',
AGENTFLOW = 'AGENTFLOW',
MULTIAGENT = 'MULTIAGENT',
ASSISTANT = 'ASSISTANT'
}
@Entity()
export class ChatFlow implements IChatFlow {
@PrimaryGeneratedColumn('uuid')
@@ -40,7 +47,7 @@ export class ChatFlow implements IChatFlow {
@Column({ nullable: true, type: 'text' })
category?: string
@Column({ nullable: true, type: 'text' })
@Column({ type: 'varchar', length: 20, default: EnumChatflowType.CHATFLOW })
type?: ChatflowType
@Column({ type: 'timestamp' })
@@ -0,0 +1,15 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
import { EnumChatflowType } from '../../entities/ChatFlow'
export class ModifyChatflowType1755066758601 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
UPDATE \`chat_flow\` SET \`type\` = '${EnumChatflowType.CHATFLOW}' WHERE \`type\` IS NULL OR \`type\` = '';
`)
await queryRunner.query(`
ALTER TABLE \`chat_flow\` MODIFY COLUMN \`type\` VARCHAR(20) NOT NULL DEFAULT '${EnumChatflowType.CHATFLOW}';
`)
}
public async down(): Promise<void> {}
}
@@ -36,6 +36,7 @@ import { AddExecutionEntity1738090872625 } from './1738090872625-AddExecutionEnt
import { FixOpenSourceAssistantTable1743758056188 } from './1743758056188-FixOpenSourceAssistantTable'
import { AddErrorToEvaluationRun1744964560174 } from './1744964560174-AddErrorToEvaluationRun'
import { ModifyExecutionDataColumnType1747902489801 } from './1747902489801-ModifyExecutionDataColumnType'
import { ModifyChatflowType1755066758601 } from './1755066758601-ModifyChatflowType'
import { AddAuthTables1720230151482 } from '../../../enterprise/database/migrations/mariadb/1720230151482-AddAuthTables'
import { AddWorkspace1725437498242 } from '../../../enterprise/database/migrations/mariadb/1725437498242-AddWorkspace'
@@ -98,5 +99,6 @@ export const mariadbMigrations = [
FixOpenSourceAssistantTable1743758056188,
AddErrorToEvaluationRun1744964560174,
ExecutionLinkWorkspaceId1746862866554,
ModifyExecutionDataColumnType1747902489801
ModifyExecutionDataColumnType1747902489801,
ModifyChatflowType1755066758601
]
@@ -0,0 +1,15 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
import { EnumChatflowType } from '../../entities/ChatFlow'
export class ModifyChatflowType1755066758601 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
UPDATE \`chat_flow\` SET \`type\` = '${EnumChatflowType.CHATFLOW}' WHERE \`type\` IS NULL OR \`type\` = '';
`)
await queryRunner.query(`
ALTER TABLE \`chat_flow\` MODIFY COLUMN \`type\` VARCHAR(20) NOT NULL DEFAULT '${EnumChatflowType.CHATFLOW}';
`)
}
public async down(): Promise<void> {}
}
@@ -37,6 +37,7 @@ import { FixOpenSourceAssistantTable1743758056188 } from './1743758056188-FixOpe
import { AddErrorToEvaluationRun1744964560174 } from './1744964560174-AddErrorToEvaluationRun'
import { FixErrorsColumnInEvaluationRun1746437114935 } from './1746437114935-FixErrorsColumnInEvaluationRun'
import { ModifyExecutionDataColumnType1747902489801 } from './1747902489801-ModifyExecutionDataColumnType'
import { ModifyChatflowType1755066758601 } from './1755066758601-ModifyChatflowType'
import { AddAuthTables1720230151482 } from '../../../enterprise/database/migrations/mysql/1720230151482-AddAuthTables'
import { AddWorkspace1720230151484 } from '../../../enterprise/database/migrations/mysql/1720230151484-AddWorkspace'
@@ -100,5 +101,6 @@ export const mysqlMigrations = [
AddErrorToEvaluationRun1744964560174,
FixErrorsColumnInEvaluationRun1746437114935,
ExecutionLinkWorkspaceId1746862866554,
ModifyExecutionDataColumnType1747902489801
ModifyExecutionDataColumnType1747902489801,
ModifyChatflowType1755066758601
]
@@ -0,0 +1,21 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
import { EnumChatflowType } from '../../entities/ChatFlow'
export class ModifyChatflowType1755066758601 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
UPDATE "chat_flow" SET "type" = '${EnumChatflowType.CHATFLOW}' WHERE "type" IS NULL OR "type" = '';
`)
await queryRunner.query(`
ALTER TABLE "chat_flow" ALTER COLUMN "type" SET DEFAULT '${EnumChatflowType.CHATFLOW}';
`)
await queryRunner.query(`
ALTER TABLE "chat_flow" ALTER COLUMN "type" TYPE VARCHAR(20);
`)
await queryRunner.query(`
ALTER TABLE "chat_flow" ALTER COLUMN "type" SET NOT NULL;
`)
}
public async down(): Promise<void> {}
}
@@ -36,6 +36,7 @@ import { AddExecutionEntity1738090872625 } from './1738090872625-AddExecutionEnt
import { FixOpenSourceAssistantTable1743758056188 } from './1743758056188-FixOpenSourceAssistantTable'
import { AddErrorToEvaluationRun1744964560174 } from './1744964560174-AddErrorToEvaluationRun'
import { ModifyExecutionSessionIdFieldType1748450230238 } from './1748450230238-ModifyExecutionSessionIdFieldType'
import { ModifyChatflowType1755066758601 } from './1755066758601-ModifyChatflowType'
import { AddAuthTables1720230151482 } from '../../../enterprise/database/migrations/postgres/1720230151482-AddAuthTables'
import { AddWorkspace1720230151484 } from '../../../enterprise/database/migrations/postgres/1720230151484-AddWorkspace'
@@ -98,5 +99,6 @@ export const postgresMigrations = [
FixOpenSourceAssistantTable1743758056188,
AddErrorToEvaluationRun1744964560174,
ExecutionLinkWorkspaceId1746862866554,
ModifyExecutionSessionIdFieldType1748450230238
ModifyExecutionSessionIdFieldType1748450230238,
ModifyChatflowType1755066758601
]
@@ -0,0 +1,40 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
import { EnumChatflowType } from '../../entities/ChatFlow'
export class ModifyChatflowType1755066758601 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
CREATE TABLE "temp_chat_flow" (
"id" varchar PRIMARY KEY NOT NULL,
"name" varchar NOT NULL,
"flowData" text NOT NULL,
"deployed" boolean,
"isPublic" boolean,
"apikeyid" varchar,
"chatbotConfig" text,
"createdDate" datetime NOT NULL DEFAULT (datetime('now')),
"updatedDate" datetime NOT NULL DEFAULT (datetime('now')),
"apiConfig" TEXT,
"analytic" TEXT,
"category" TEXT,
"speechToText" TEXT,
"type" VARCHAR(20) NOT NULL DEFAULT '${EnumChatflowType.CHATFLOW}',
"workspaceId" TEXT,
"followUpPrompts" TEXT,
FOREIGN KEY ("workspaceId") REFERENCES "workspace"("id")
);
`)
await queryRunner.query(`
INSERT INTO "temp_chat_flow" ("id", "name", "flowData", "deployed", "isPublic", "apikeyid", "chatbotConfig", "createdDate", "updatedDate", "apiConfig", "analytic", "category", "speechToText", "type", "workspaceId", "followUpPrompts")
SELECT "id", "name", "flowData", "deployed", "isPublic", "apikeyid", "chatbotConfig", "createdDate", "updatedDate", "apiConfig", "analytic", "category", "speechToText",
CASE WHEN "type" IS NULL OR "type" = '' THEN '${EnumChatflowType.CHATFLOW}' ELSE "type" END, "workspaceId", "followUpPrompts" FROM "chat_flow";
`)
await queryRunner.query(`DROP TABLE "chat_flow";`)
await queryRunner.query(`ALTER TABLE "temp_chat_flow" RENAME TO "chat_flow";`)
}
public async down(): Promise<void> {}
}
@@ -34,6 +34,7 @@ import { AddSeqNoToDatasetRow1733752119696 } from './1733752119696-AddSeqNoToDat
import { AddExecutionEntity1738090872625 } from './1738090872625-AddExecutionEntity'
import { FixOpenSourceAssistantTable1743758056188 } from './1743758056188-FixOpenSourceAssistantTable'
import { AddErrorToEvaluationRun1744964560174 } from './1744964560174-AddErrorToEvaluationRun'
import { ModifyChatflowType1755066758601 } from './1755066758601-ModifyChatflowType'
import { AddAuthTables1720230151482 } from '../../../enterprise/database/migrations/sqlite/1720230151482-AddAuthTables'
import { AddWorkspace1720230151484 } from '../../../enterprise/database/migrations/sqlite/1720230151484-AddWorkspace'
@@ -94,5 +95,6 @@ export const sqliteMigrations = [
AddExecutionEntity1738090872625,
FixOpenSourceAssistantTable1743758056188,
AddErrorToEvaluationRun1744964560174,
ExecutionLinkWorkspaceId1746862866554
ExecutionLinkWorkspaceId1746862866554,
ModifyChatflowType1755066758601
]