From 284ca367aabca735c58c49199329e7affcc85508 Mon Sep 17 00:00:00 2001 From: heheer Date: Fri, 19 Dec 2025 11:33:49 +0800 Subject: [PATCH] app update time --- packages/service/core/app/controller.ts | 24 ++++++++++++++ packages/service/core/chat/saveChat.ts | 14 -------- projects/app/src/pages/api/core/app/create.ts | 6 ++++ .../pages/api/core/app/httpTools/update.ts | 7 ++++ .../src/pages/api/core/app/mcpTools/update.ts | 7 ++++ projects/app/src/pages/api/core/app/update.ts | 23 ++++++++++++- .../src/pages/api/core/app/version/publish.ts | 11 +++++++ .../app/src/pages/api/core/chat/chatTest.ts | 1 - .../app/src/pages/api/v1/chat/completions.ts | 2 -- .../app/src/pages/api/v2/chat/completions.ts | 2 -- projects/app/src/service/core/app/utils.ts | 1 - projects/app/src/service/support/mcp/utils.ts | 1 - test/cases/service/core/chat/saveChat.test.ts | 33 +------------------ 13 files changed, 78 insertions(+), 54 deletions(-) diff --git a/packages/service/core/app/controller.ts b/packages/service/core/app/controller.ts index fb07552a2..1facc88e2 100644 --- a/packages/service/core/app/controller.ts +++ b/packages/service/core/app/controller.ts @@ -204,3 +204,27 @@ export const deleteAppsImmediate = async ({ ).lean(); await Promise.all(evalJobs.map((evalJob) => removeEvaluationJob(evalJob._id))); }; + +export async function updateParentFoldersUpdateTime({ + parentId, + session +}: { + parentId?: string | null; + session?: ClientSession; +}): Promise { + if (!parentId) return; + + const parentApp = await MongoApp.findById(parentId).lean(); + if (!parentApp) return; + + // Only update if parent is a folder + if (AppFolderTypeList.includes(parentApp.type)) { + await MongoApp.findByIdAndUpdate(parentId, { updateTime: new Date() }, { session }); + } + + // Recursively update parent folders + await updateParentFoldersUpdateTime({ + parentId: parentApp.parentId, + session + }); +} diff --git a/packages/service/core/chat/saveChat.ts b/packages/service/core/chat/saveChat.ts index f427a40b1..a18773fa1 100644 --- a/packages/service/core/chat/saveChat.ts +++ b/packages/service/core/chat/saveChat.ts @@ -35,7 +35,6 @@ export type Props = { nodes: StoreNodeItemType[]; appChatConfig?: AppChatConfigType; variables?: Record; - isUpdateUseTime: boolean; newTitle: string; source: `${ChatSourceEnum}`; sourceName?: string; @@ -219,7 +218,6 @@ export async function saveChat(props: Props) { nodes, appChatConfig, variables, - isUpdateUseTime, newTitle, source, sourceName, @@ -393,18 +391,6 @@ export async function saveChat(props: Props) { } catch (error) { addLog.error('Push chat log error', error); } - - if (isUpdateUseTime) { - await MongoApp.updateOne( - { _id: appId }, - { - updateTime: new Date() - }, - { - ...writePrimary - } - ).catch(); - } } catch (error) { addLog.error(`update chat history error`, error); } diff --git a/projects/app/src/pages/api/core/app/create.ts b/projects/app/src/pages/api/core/app/create.ts index ea9265c5f..8246df691 100644 --- a/projects/app/src/pages/api/core/app/create.ts +++ b/projects/app/src/pages/api/core/app/create.ts @@ -33,6 +33,7 @@ import { isS3ObjectKey } from '@fastgpt/service/common/s3/utils'; import { MongoAppTemplate } from '@fastgpt/service/core/app/templates/templateSchema'; import { getNanoid } from '@fastgpt/global/common/string/tools'; import path from 'node:path'; +import { updateParentFoldersUpdateTime } from '@fastgpt/service/core/app/controller'; export type CreateAppBody = { parentId?: ParentIdType; @@ -243,6 +244,11 @@ export const onCreateApp = async ({ await getS3AvatarSource().refreshAvatar(_avatar, undefined, session); + await updateParentFoldersUpdateTime({ + parentId, + session + }); + (async () => { addAuditLog({ tmbId, diff --git a/projects/app/src/pages/api/core/app/httpTools/update.ts b/projects/app/src/pages/api/core/app/httpTools/update.ts index 6ee3a5cc9..344bbf2f4 100644 --- a/projects/app/src/pages/api/core/app/httpTools/update.ts +++ b/projects/app/src/pages/api/core/app/httpTools/update.ts @@ -10,6 +10,7 @@ import { MongoApp } from '@fastgpt/service/core/app/schema'; import type { StoreSecretValueType } from '@fastgpt/global/common/secret/type'; import { storeSecretValue } from '@fastgpt/service/common/secret/utils'; import { MongoAppVersion } from '@fastgpt/service/core/app/version/schema'; +import { updateParentFoldersUpdateTime } from '@fastgpt/service/core/app/controller'; export type UpdateHttpPluginBody = { appId: string; @@ -50,6 +51,12 @@ async function handler(req: ApiRequestProps, res: NextApiR }, { session } ); + + await updateParentFoldersUpdateTime({ + parentId: app.parentId, + session + }); + await MongoAppVersion.updateOne( { appId }, { diff --git a/projects/app/src/pages/api/core/app/mcpTools/update.ts b/projects/app/src/pages/api/core/app/mcpTools/update.ts index df0cca86f..555a3646d 100644 --- a/projects/app/src/pages/api/core/app/mcpTools/update.ts +++ b/projects/app/src/pages/api/core/app/mcpTools/update.ts @@ -10,6 +10,7 @@ import { getMCPToolSetRuntimeNode } from '@fastgpt/global/core/app/tool/mcpTool/ import { MongoAppVersion } from '@fastgpt/service/core/app/version/schema'; import { type StoreSecretValueType } from '@fastgpt/global/common/secret/type'; import { storeSecretValue } from '@fastgpt/service/common/secret/utils'; +import { updateParentFoldersUpdateTime } from '@fastgpt/service/core/app/controller'; export type updateMCPToolsQuery = {}; @@ -51,6 +52,12 @@ async function handler( }, { session } ); + + await updateParentFoldersUpdateTime({ + parentId: app.parentId, + session + }); + await MongoAppVersion.updateOne( { appId }, { diff --git a/projects/app/src/pages/api/core/app/update.ts b/projects/app/src/pages/api/core/app/update.ts index 68a20455a..358045ec7 100644 --- a/projects/app/src/pages/api/core/app/update.ts +++ b/projects/app/src/pages/api/core/app/update.ts @@ -27,6 +27,7 @@ import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants'; import { getI18nAppType } from '@fastgpt/service/support/user/audit/util'; import { i18nT } from '@fastgpt/web/i18n/utils'; import { getS3AvatarSource } from '@fastgpt/service/common/s3/sources/avatar'; +import { updateParentFoldersUpdateTime } from '@fastgpt/service/core/app/controller'; export type AppUpdateQuery = { appId: string; @@ -117,7 +118,7 @@ async function handler(req: ApiRequestProps) { await getS3AvatarSource().refreshAvatar(avatar, app.avatar, session); - return MongoApp.findByIdAndUpdate( + const result = await MongoApp.findByIdAndUpdate( appId, { ...parseParentIdInMongo(parentId), @@ -137,6 +138,26 @@ async function handler(req: ApiRequestProps) { }, { session } ); + + if (isMove) { + // Update both old and new parent folders + await updateParentFoldersUpdateTime({ + parentId: app.parentId, + session + }); + await updateParentFoldersUpdateTime({ + parentId, + session + }); + } else { + // Update current parent folder + await updateParentFoldersUpdateTime({ + parentId: parentId || app.parentId, + session + }); + } + + return result; }; // Move diff --git a/projects/app/src/pages/api/core/app/version/publish.ts b/projects/app/src/pages/api/core/app/version/publish.ts index 6d804a085..ce3dc632d 100644 --- a/projects/app/src/pages/api/core/app/version/publish.ts +++ b/projects/app/src/pages/api/core/app/version/publish.ts @@ -13,6 +13,7 @@ import { addAuditLog } from '@fastgpt/service/support/user/audit/util'; import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants'; import { getI18nAppType } from '@fastgpt/service/support/user/audit/util'; import { i18nT } from '@fastgpt/web/i18n/utils'; +import { updateParentFoldersUpdateTime } from '@fastgpt/service/core/app/controller'; async function handler(req: ApiRequestProps, res: NextApiResponse) { const { appId } = req.query as { appId: string }; @@ -61,6 +62,11 @@ async function handler(req: ApiRequestProps, res: NextApiRe session } ); + + await updateParentFoldersUpdateTime({ + parentId: app.parentId, + session + }); }); addAuditLog({ @@ -122,6 +128,11 @@ async function handler(req: ApiRequestProps, res: NextApiRe session } ); + + await updateParentFoldersUpdateTime({ + parentId: app.parentId, + session + }); }); (async () => { diff --git a/projects/app/src/pages/api/core/chat/chatTest.ts b/projects/app/src/pages/api/core/chat/chatTest.ts index 8c934d397..c035395b1 100644 --- a/projects/app/src/pages/api/core/chat/chatTest.ts +++ b/projects/app/src/pages/api/core/chat/chatTest.ts @@ -248,7 +248,6 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { nodes, appChatConfig: chatConfig, variables: newVariables, - isUpdateUseTime: false, // owner update use time newTitle, source: ChatSourceEnum.test, userContent: userQuestion, diff --git a/projects/app/src/pages/api/v1/chat/completions.ts b/projects/app/src/pages/api/v1/chat/completions.ts index 68e9387e3..2df434716 100644 --- a/projects/app/src/pages/api/v1/chat/completions.ts +++ b/projects/app/src/pages/api/v1/chat/completions.ts @@ -326,7 +326,6 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { })(); // save chat - const isOwnerUse = !shareId && !spaceTeamId && String(tmbId) === String(app.tmbId); const source = (() => { if (shareId) { return ChatSourceEnum.share; @@ -363,7 +362,6 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { nodes, appChatConfig: chatConfig, variables: newVariables, - isUpdateUseTime: isOwnerUse && source === ChatSourceEnum.online, // owner update use time newTitle, shareId, outLinkUid: outLinkUserId, diff --git a/projects/app/src/pages/api/v2/chat/completions.ts b/projects/app/src/pages/api/v2/chat/completions.ts index 8cfde3e15..b1d14e471 100644 --- a/projects/app/src/pages/api/v2/chat/completions.ts +++ b/projects/app/src/pages/api/v2/chat/completions.ts @@ -328,7 +328,6 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { })(); // save chat - const isOwnerUse = !shareId && !spaceTeamId && String(tmbId) === String(app.tmbId); const source = (() => { if (shareId) { return ChatSourceEnum.share; @@ -365,7 +364,6 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { nodes, appChatConfig: chatConfig, variables: newVariables, - isUpdateUseTime: isOwnerUse && source === ChatSourceEnum.online, // owner update use time newTitle, shareId, outLinkUid: outLinkUserId, diff --git a/projects/app/src/service/core/app/utils.ts b/projects/app/src/service/core/app/utils.ts index e8f6685e5..cde645cab 100644 --- a/projects/app/src/service/core/app/utils.ts +++ b/projects/app/src/service/core/app/utils.ts @@ -101,7 +101,6 @@ export const getScheduleTriggerApp = async () => { nodes, appChatConfig: chatConfig, variables: {}, - isUpdateUseTime: false, // owner update use time newTitle: 'Cron Job', source: ChatSourceEnum.cronJob, userContent: { diff --git a/projects/app/src/service/support/mcp/utils.ts b/projects/app/src/service/support/mcp/utils.ts index 0eca67f80..fbf2645cd 100644 --- a/projects/app/src/service/support/mcp/utils.ts +++ b/projects/app/src/service/support/mcp/utils.ts @@ -257,7 +257,6 @@ export const callMcpServerTool = async ({ key, toolName, inputs }: toolCallProps nodes, appChatConfig: chatConfig, variables: newVariables, - isUpdateUseTime: false, // owner update use time newTitle, source: ChatSourceEnum.mcp, userContent: userQuestion, diff --git a/test/cases/service/core/chat/saveChat.test.ts b/test/cases/service/core/chat/saveChat.test.ts index 5fade7cf1..9c1308b93 100644 --- a/test/cases/service/core/chat/saveChat.test.ts +++ b/test/cases/service/core/chat/saveChat.test.ts @@ -31,7 +31,6 @@ const createMockProps = ( outputs: [] } ], - isUpdateUseTime: true, newTitle: 'Test Chat', source: 'online' as any, userContent: { @@ -228,7 +227,7 @@ describe('saveChat', () => { collectionId: 'collection-1', sourceId: 'source-1', sourceName: 'doc.pdf', - score: [{ type: 'embedding', value: 0.95, index: 0 }], + score: [{ type: 'embedding' as const, value: 0.95, index: 0 }], q: 'What is AI?', a: 'AI stands for Artificial Intelligence...', updateTime: new Date() @@ -283,36 +282,6 @@ describe('saveChat', () => { } }); - it('should update app use time when isUpdateUseTime is true', async () => { - const beforeTime = new Date(); - - const props = createMockProps( - { isUpdateUseTime: true }, - { appId: testAppId, teamId: testTeamId, tmbId: testTmbId } - ); - - await saveChat(props); - - const app = await MongoApp.findById(testAppId); - expect(app?.updateTime).toBeDefined(); - expect(app!.updateTime.getTime()).toBeGreaterThanOrEqual(beforeTime.getTime()); - }); - - it('should not update app use time when isUpdateUseTime is false', async () => { - const app = await MongoApp.findById(testAppId); - const originalUpdateTime = app!.updateTime; - - const props = createMockProps( - { isUpdateUseTime: false }, - { appId: testAppId, teamId: testTeamId, tmbId: testTmbId } - ); - - await saveChat(props); - - const updatedApp = await MongoApp.findById(testAppId); - expect(updatedApp!.updateTime.getTime()).toBe(originalUpdateTime.getTime()); - }); - it('should create chat data log with error count when response has error', async () => { const props = createMockProps( {