diff --git a/apps/web/app/(app)/environments/[environmentId]/components/WidgetStatusIndicator.tsx b/apps/web/app/(app)/environments/[environmentId]/components/WidgetStatusIndicator.tsx index 677338e30d..9111def780 100644 --- a/apps/web/app/(app)/environments/[environmentId]/components/WidgetStatusIndicator.tsx +++ b/apps/web/app/(app)/environments/[environmentId]/components/WidgetStatusIndicator.tsx @@ -1,4 +1,4 @@ -import { getActionsByEnvironmentId } from "@formbricks/lib/action/service"; +import { getLatestActionByEnvironmentId } from "@formbricks/lib/action/service"; import { getEnvironment, updateEnvironment } from "@formbricks/lib/environment/service"; import { timeSince } from "@formbricks/lib/time"; import { ArrowDownIcon, CheckIcon, ExclamationTriangleIcon } from "@heroicons/react/24/solid"; @@ -11,11 +11,10 @@ interface WidgetStatusIndicatorProps { } export default async function WidgetStatusIndicator({ environmentId, type }: WidgetStatusIndicatorProps) { - const [environment, actions] = await Promise.all([ + const [environment, latestAction] = await Promise.all([ getEnvironment(environmentId), - getActionsByEnvironmentId(environmentId, 1), + getLatestActionByEnvironmentId(environmentId), ]); - const latestAction = actions.length > 0 ? actions[0] : null; if (!environment?.widgetSetupCompleted && latestAction) { await updateEnvironment(environment.id, { widgetSetupCompleted: true }); diff --git a/packages/lib/action/service.ts b/packages/lib/action/service.ts index b530ef5503..198c57e082 100644 --- a/packages/lib/action/service.ts +++ b/packages/lib/action/service.ts @@ -15,14 +15,65 @@ import { createActionClass, getActionClassByEnvironmentIdAndName } from "../acti import { validateInputs } from "../utils/validate"; import { actionCache } from "./cache"; -export const getActionsByEnvironmentId = async ( - environmentId: string, - limit?: number, - page?: number -): Promise => { +export const getLatestActionByEnvironmentId = async (environmentId: string): Promise => { + const action = await unstable_cache( + async () => { + validateInputs([environmentId, ZId]); + + try { + const actionPrisma = await prisma.event.findFirst({ + where: { + eventClass: { + environmentId: environmentId, + }, + }, + orderBy: { + createdAt: "desc", + }, + include: { + eventClass: true, + }, + }); + if (!actionPrisma) { + return null; + } + const action: TAction = { + id: actionPrisma.id, + createdAt: actionPrisma.createdAt, + sessionId: actionPrisma.sessionId, + properties: actionPrisma.properties, + actionClass: actionPrisma.eventClass, + }; + return action; + } catch (error) { + if (error instanceof Prisma.PrismaClientKnownRequestError) { + throw new DatabaseError("Database operation failed"); + } + + throw error; + } + }, + [`getLastestActionByEnvironmentId-${environmentId}`], + { + tags: [actionCache.tag.byEnvironmentId(environmentId)], + revalidate: SERVICES_REVALIDATION_INTERVAL, + } + )(); + + // since the unstable_cache function does not support deserialization of dates, we need to manually deserialize them + // https://github.com/vercel/next.js/issues/51613 + return action + ? { + ...action, + createdAt: new Date(action.createdAt), + } + : action; +}; + +export const getActionsByEnvironmentId = async (environmentId: string, page?: number): Promise => { const actions = await unstable_cache( async () => { - validateInputs([environmentId, ZId], [limit, ZOptionalNumber], [page, ZOptionalNumber]); + validateInputs([environmentId, ZId], [page, ZOptionalNumber]); try { const actionsPrisma = await prisma.event.findMany({ @@ -54,7 +105,7 @@ export const getActionsByEnvironmentId = async ( return actions; } catch (error) { if (error instanceof Prisma.PrismaClientKnownRequestError) { - throw new DatabaseError(error.message); + throw new DatabaseError("Database operation failed"); } throw error;