fix: add maxnum of folders to env (#6628)

* fix: add maxnum of folders to env

* fix: 知识库文件夹上限数量结构调整

* fix
This commit is contained in:
gaga0714
2026-03-25 13:59:18 +08:00
committed by GitHub
parent 2e84a1f2c9
commit bb8852d82b
8 changed files with 86 additions and 2 deletions
@@ -13,6 +13,7 @@ export enum TeamErrEnum {
appAmountNotEnough = 'appAmountNotEnough',
pluginAmountNotEnough = 'pluginAmountNotEnough',
appFolderAmountNotEnough = 'appFolderAmountNotEnough',
datasetFolderAmountNotEnough = 'datasetFolderAmountNotEnough',
websiteSyncNotEnough = 'websiteSyncNotEnough',
reRankNotEnough = 'reRankNotEnough',
ticketNotAvailable = 'ticketNotAvailable',
@@ -145,6 +146,10 @@ const teamErr = [
{
statusText: TeamErrEnum.tooManyInvitations,
message: i18nT('common:code_error.team_error.too_many_invitations')
},
{
statusText: TeamErrEnum.datasetFolderAmountNotEnough,
message: i18nT('common:code_error.team_error.dataset_folder_amount_not_enough')
}
];
+4 -1
View File
@@ -32,7 +32,10 @@ export const env = createEnv({
TRACING_ENABLE_OTEL: BoolSchema.default(false),
TRACING_OTEL_SERVICE_NAME: z.string().default('fastgpt-client'),
TRACING_OTEL_URL: z.url().optional(),
TRACING_OTEL_SAMPLE_RATIO: z.coerce.number().min(0).max(1).optional()
TRACING_OTEL_SAMPLE_RATIO: z.coerce.number().min(0).max(1).optional(),
APP_FOLDER_MAX_AMOUNT: z.coerce.number().int().positive().default(1000),
DATASET_FOLDER_MAX_AMOUNT: z.coerce.number().int().positive().default(1000)
},
emptyStringAsUndefined: true,
runtimeEnv: process.env,
@@ -8,6 +8,7 @@ import { AppTypeEnum, ToolTypeList, AppFolderTypeList } from '@fastgpt/global/co
import { MongoTeamMember } from '../user/team/teamMemberSchema';
import { TeamMemberStatusEnum } from '@fastgpt/global/support/user/team/constant';
import { getVectorCountByTeamId } from '../../common/vectorDB/controller';
import { env } from '../../env';
export const checkTeamAIPoints = async (teamId: string) => {
if (!global.subPlans?.standard) return;
@@ -40,6 +41,22 @@ export const checkTeamMemberLimit = async (teamId: string, newCount: number) =>
}
};
export const checkTeamDatasetFolderLimit = async ({
teamId,
amount = 1
}: {
teamId: string;
amount?: number;
}) => {
const folderCount = await MongoDataset.countDocuments({
teamId,
type: DatasetTypeEnum.folder
});
if (folderCount + amount > env.DATASET_FOLDER_MAX_AMOUNT) {
return Promise.reject(TeamErrEnum.datasetFolderAmountNotEnough);
}
};
export const checkTeamAppTypeLimit = async ({
teamId,
appCheckType,
@@ -93,7 +110,7 @@ export const checkTeamAppTypeLimit = async ({
$in: AppFolderTypeList
}
});
const maxAppFolderAmount = 1000;
const maxAppFolderAmount = env.APP_FOLDER_MAX_AMOUNT;
if (folderCount + amount > maxAppFolderAmount) {
return Promise.reject(TeamErrEnum.appFolderAmountNotEnough);
}
+1
View File
@@ -171,6 +171,7 @@
"code_error.team_error.cannot_modify_root_org": "Cannot modify root organization",
"code_error.team_error.cannot_move_to_sub_path": "Cannot move to same or subdirectory",
"code_error.team_error.dataset_amount_not_enough": "Dataset Limit Reached",
"code_error.team_error.dataset_folder_amount_not_enough": "Knowledge base folder limit reached",
"code_error.team_error.dataset_size_not_enough": "Insufficient Dataset Capacity, Please Expand",
"code_error.team_error.group_name_duplicate": "Duplicate group name",
"code_error.team_error.group_name_empty": "Group name cannot be empty",
+1
View File
@@ -171,6 +171,7 @@
"code_error.team_error.cannot_modify_root_org": "不能修改根部门",
"code_error.team_error.cannot_move_to_sub_path": "不能移动到相同或子目录",
"code_error.team_error.dataset_amount_not_enough": "知识库数量已达上限~",
"code_error.team_error.dataset_folder_amount_not_enough": "知识库文件夹数量已达上限~",
"code_error.team_error.dataset_size_not_enough": "知识库容量不足,请先扩容~",
"code_error.team_error.group_name_duplicate": "群组名称重复",
"code_error.team_error.group_name_empty": "群组名称不能为空",
+1
View File
@@ -169,6 +169,7 @@
"code_error.team_error.cannot_modify_root_org": "無法修改根組織",
"code_error.team_error.cannot_move_to_sub_path": "無法移動到相同或子目錄",
"code_error.team_error.dataset_amount_not_enough": "已達知識庫數量上限",
"code_error.team_error.dataset_folder_amount_not_enough": "已達知識庫資料夾數量上限",
"code_error.team_error.dataset_size_not_enough": "知識庫容量不足,請先擴充容量",
"code_error.team_error.group_name_duplicate": "群組名稱重複",
"code_error.team_error.group_name_empty": "群組名稱不能為空",
@@ -12,6 +12,7 @@ import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
import { MongoDataset } from '@fastgpt/service/core/dataset/schema';
import { createResourceDefaultCollaborators } from '@fastgpt/service/support/permission/controller';
import { authDataset } from '@fastgpt/service/support/permission/dataset/auth';
import { checkTeamDatasetFolderLimit } from '@fastgpt/service/support/permission/teamLimit';
import { authUserPer } from '@fastgpt/service/support/permission/user/auth';
import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next';
import { addAuditLog } from '@fastgpt/service/support/user/audit/util';
@@ -48,6 +49,8 @@ async function handler(
per: TeamDatasetCreatePermissionVal
});
await checkTeamDatasetFolderLimit({ teamId });
await mongoSessionRun(async (session) => {
const dataset = await MongoDataset.create({
...parseParentIdInMongo(parentId),
@@ -3,6 +3,7 @@ import {
checkTeamAIPoints,
checkTeamMemberLimit,
checkTeamAppTypeLimit,
checkTeamDatasetFolderLimit,
checkDatasetIndexLimit,
checkTeamDatasetLimit,
checkTeamDatasetSyncPermission
@@ -412,6 +413,58 @@ describe('checkTeamAppTypeLimit', () => {
});
});
describe('checkTeamDatasetFolderLimit', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('当知识库文件夹数量未超限时正常通过', async () => {
vi.spyOn(MongoDataset, 'countDocuments').mockResolvedValue(500);
await expect(
checkTeamDatasetFolderLimit({
teamId: mockTeamId,
amount: 100
})
).resolves.toBeUndefined();
});
it('当知识库文件夹数量超过上限时抛出错误', async () => {
vi.spyOn(MongoDataset, 'countDocuments').mockResolvedValue(950);
await expect(
checkTeamDatasetFolderLimit({
teamId: mockTeamId,
amount: 100
})
).rejects.toBe(TeamErrEnum.datasetFolderAmountNotEnough);
});
it('当知识库文件夹数量刚好达到上限时正常通过', async () => {
vi.spyOn(MongoDataset, 'countDocuments').mockResolvedValue(999);
await expect(
checkTeamDatasetFolderLimit({
teamId: mockTeamId,
amount: 1
})
).resolves.toBeUndefined();
});
it('查询时只统计知识库 folder 类型', async () => {
const countSpy = vi.spyOn(MongoDataset, 'countDocuments').mockResolvedValue(0);
await checkTeamDatasetFolderLimit({
teamId: mockTeamId
});
expect(countSpy).toHaveBeenCalledWith({
teamId: mockTeamId,
type: DatasetTypeEnum.folder
});
});
});
describe('checkDatasetIndexLimit', () => {
beforeEach(() => {
vi.clearAllMocks();