mirror of
https://github.com/formbricks/formbricks.git
synced 2026-01-08 00:40:09 -06:00
fix: sync call gets called by other functions (#823)
* fix: sync call gets called by other functions * fix: sync call gets called by other functions * remove unused imports * remove unused import * fix userId update
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
import { getUpdatedState } from "@/app/api/v1/js/sync/lib/sync";
|
||||
import { responses } from "@/lib/api/response";
|
||||
import { transformErrorToDetails } from "@/lib/api/validator";
|
||||
import { prisma } from "@formbricks/database";
|
||||
import { WEBAPP_URL } from "@formbricks/lib/constants";
|
||||
import { createAttributeClass, getAttributeClassByNameCached } from "@formbricks/lib/services/attributeClass";
|
||||
import { getPersonCached } from "@formbricks/lib/services/person";
|
||||
import { TJsState, ZJsPeopleAttributeInput } from "@formbricks/types/v1/js";
|
||||
import { ZJsPeopleAttributeInput } from "@formbricks/types/v1/js";
|
||||
import { revalidateTag } from "next/cache";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
@@ -76,21 +76,7 @@ export async function POST(req: Request, { params }): Promise<NextResponse> {
|
||||
// revalidate person
|
||||
revalidateTag(personId);
|
||||
|
||||
const syncRes = await fetch(`${WEBAPP_URL}/api/v1/js/sync`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
environmentId,
|
||||
personId,
|
||||
sessionId,
|
||||
}),
|
||||
});
|
||||
|
||||
if (!syncRes.ok) {
|
||||
throw new Error("Unable to get latest state from sync");
|
||||
}
|
||||
|
||||
const syncJson = await syncRes.json();
|
||||
const state: TJsState = syncJson.data;
|
||||
const state = await getUpdatedState(environmentId, personId, sessionId);
|
||||
|
||||
return responses.successResponse({ ...state }, true);
|
||||
} catch (error) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { getUpdatedState } from "@/app/api/v1/js/sync/lib/sync";
|
||||
import { responses } from "@/lib/api/response";
|
||||
import { transformErrorToDetails } from "@/lib/api/validator";
|
||||
import { prisma } from "@formbricks/database";
|
||||
import { WEBAPP_URL } from "@formbricks/lib/constants";
|
||||
import { deletePerson, selectPerson, transformPrismaPerson } from "@formbricks/lib/services/person";
|
||||
import { TJsState, ZJsPeopleUserIdInput } from "@formbricks/types/v1/js";
|
||||
import { ZJsPeopleUserIdInput } from "@formbricks/types/v1/js";
|
||||
import { revalidateTag } from "next/cache";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
@@ -97,21 +97,7 @@ export async function POST(req: Request, { params }): Promise<NextResponse> {
|
||||
revalidateTag(person.id);
|
||||
}
|
||||
|
||||
const syncRes = await fetch(`${WEBAPP_URL}/api/v1/js/sync`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
environmentId,
|
||||
personId,
|
||||
sessionId,
|
||||
}),
|
||||
});
|
||||
|
||||
if (!syncRes.ok) {
|
||||
throw new Error("Unable to get latest state from sync");
|
||||
}
|
||||
|
||||
const syncJson = await syncRes.json();
|
||||
const state: TJsState = syncJson.data;
|
||||
const state = await getUpdatedState(environmentId, person.id, sessionId);
|
||||
|
||||
return responses.successResponse({ ...state }, true);
|
||||
} catch (error) {
|
||||
|
||||
99
apps/web/app/api/v1/js/sync/lib/sync.ts
Normal file
99
apps/web/app/api/v1/js/sync/lib/sync.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
import { getSurveysCached } from "@/app/api/v1/js/surveys";
|
||||
import { getActionClassesCached } from "@formbricks/lib/services/actionClass";
|
||||
import { getEnvironmentCached } from "@formbricks/lib/services/environment";
|
||||
import { createPerson, getPersonCached } from "@formbricks/lib/services/person";
|
||||
import { getProductByEnvironmentIdCached } from "@formbricks/lib/services/product";
|
||||
import { createSession, extendSession, getSessionCached } from "@formbricks/lib/services/session";
|
||||
import { captureTelemetry } from "@formbricks/lib/telemetry";
|
||||
import { TEnvironment } from "@formbricks/types/v1/environment";
|
||||
import { TJsState } from "@formbricks/types/v1/js";
|
||||
import { TPerson } from "@formbricks/types/v1/people";
|
||||
import { TSession } from "@formbricks/types/v1/sessions";
|
||||
|
||||
const captureNewSessionTelemetry = async (jsVersion?: string): Promise<void> => {
|
||||
await captureTelemetry("session created", { jsVersion: jsVersion ?? "unknown" });
|
||||
};
|
||||
|
||||
export const getUpdatedState = async (
|
||||
environmentId: string,
|
||||
personId?: string,
|
||||
sessionId?: string,
|
||||
jsVersion?: string
|
||||
): Promise<TJsState> => {
|
||||
let environment: TEnvironment | null;
|
||||
let person: TPerson;
|
||||
let session: TSession | null;
|
||||
|
||||
// check if environment exists
|
||||
environment = await getEnvironmentCached(environmentId);
|
||||
|
||||
if (!environment) {
|
||||
throw new Error("Environment does not exist");
|
||||
}
|
||||
|
||||
if (!personId) {
|
||||
// create a new person
|
||||
person = await createPerson(environmentId);
|
||||
// create a new session
|
||||
session = await createSession(person.id);
|
||||
} else {
|
||||
// check if person exists
|
||||
const existingPerson = await getPersonCached(personId);
|
||||
if (!existingPerson) {
|
||||
// create a new person
|
||||
person = await createPerson(environmentId);
|
||||
} else {
|
||||
person = existingPerson;
|
||||
}
|
||||
}
|
||||
if (!sessionId) {
|
||||
// create a new session
|
||||
session = await createSession(person.id);
|
||||
} else {
|
||||
// check validity of person & session
|
||||
session = await getSessionCached(sessionId);
|
||||
if (!session) {
|
||||
// create a new session
|
||||
session = await createSession(person.id);
|
||||
captureNewSessionTelemetry(jsVersion);
|
||||
} else {
|
||||
// check if session is expired
|
||||
if (session.expiresAt < new Date()) {
|
||||
// create a new session
|
||||
session = await createSession(person.id);
|
||||
captureNewSessionTelemetry(jsVersion);
|
||||
} else {
|
||||
// extend session (if about to expire)
|
||||
const isSessionAboutToExpire =
|
||||
new Date(session.expiresAt).getTime() - new Date().getTime() < 1000 * 60 * 10;
|
||||
|
||||
if (isSessionAboutToExpire) {
|
||||
session = await extendSession(sessionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// we now have a valid person & session
|
||||
|
||||
// get/create rest of the state
|
||||
const [surveys, noCodeActionClasses, product] = await Promise.all([
|
||||
getSurveysCached(environmentId, person),
|
||||
getActionClassesCached(environmentId),
|
||||
getProductByEnvironmentIdCached(environmentId),
|
||||
]);
|
||||
|
||||
if (!product) {
|
||||
throw new Error("Product not found");
|
||||
}
|
||||
|
||||
// return state
|
||||
const state: TJsState = {
|
||||
person: person!,
|
||||
session,
|
||||
surveys,
|
||||
noCodeActionClasses: noCodeActionClasses.filter((actionClass) => actionClass.type === "noCode"),
|
||||
product,
|
||||
};
|
||||
|
||||
return state;
|
||||
};
|
||||
@@ -1,21 +1,9 @@
|
||||
import { getSurveysCached } from "@/app/api/v1/js/surveys";
|
||||
import { getUpdatedState } from "@/app/api/v1/js/sync/lib/sync";
|
||||
import { responses } from "@/lib/api/response";
|
||||
import { transformErrorToDetails } from "@/lib/api/validator";
|
||||
import { getActionClassesCached } from "@formbricks/lib/services/actionClass";
|
||||
import { getEnvironmentCached } from "@formbricks/lib/services/environment";
|
||||
import { createPerson, getPersonCached } from "@formbricks/lib/services/person";
|
||||
import { getProductByEnvironmentIdCached } from "@formbricks/lib/services/product";
|
||||
import { createSession, extendSession, getSessionCached } from "@formbricks/lib/services/session";
|
||||
import { captureTelemetry } from "@formbricks/lib/telemetry";
|
||||
import { TJsState, ZJsSyncInput } from "@formbricks/types/v1/js";
|
||||
import { TPerson } from "@formbricks/types/v1/people";
|
||||
import { TSession } from "@formbricks/types/v1/sessions";
|
||||
import { ZJsSyncInput } from "@formbricks/types/v1/js";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
const captureNewSessionTelemetry = async (jsVersion?: string): Promise<void> => {
|
||||
await captureTelemetry("session created", { jsVersion: jsVersion ?? "unknown" });
|
||||
};
|
||||
|
||||
export async function OPTIONS(): Promise<NextResponse> {
|
||||
return responses.successResponse({}, true);
|
||||
}
|
||||
@@ -37,152 +25,8 @@ export async function POST(req: Request): Promise<NextResponse> {
|
||||
|
||||
const { environmentId, personId, sessionId } = inputValidation.data;
|
||||
|
||||
// check if environment exists
|
||||
const environment = await getEnvironmentCached(environmentId);
|
||||
const state = await getUpdatedState(environmentId, personId, sessionId, inputValidation.data.jsVersion);
|
||||
|
||||
if (!environment) {
|
||||
return responses.badRequestResponse(
|
||||
"Environment does not exist",
|
||||
{ environmentId: "Environment with this ID does not exist" },
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
if (!personId) {
|
||||
// create a new person
|
||||
const person = await createPerson(environmentId);
|
||||
|
||||
// create a new session
|
||||
const session = await createSession(person.id);
|
||||
|
||||
// get/create rest of the state
|
||||
|
||||
const [surveys, noCodeActionClasses, product] = await Promise.all([
|
||||
getSurveysCached(environmentId, person),
|
||||
getActionClassesCached(environmentId),
|
||||
getProductByEnvironmentIdCached(environmentId),
|
||||
]);
|
||||
|
||||
captureNewSessionTelemetry(inputValidation.data.jsVersion);
|
||||
|
||||
if (!product) {
|
||||
return responses.notFoundResponse("ProductByEnvironmentId", environmentId, true);
|
||||
}
|
||||
|
||||
// return state
|
||||
const state: TJsState = {
|
||||
person,
|
||||
session,
|
||||
surveys,
|
||||
noCodeActionClasses: noCodeActionClasses.filter((actionClass) => actionClass.type === "noCode"),
|
||||
product,
|
||||
};
|
||||
return responses.successResponse({ ...state }, true);
|
||||
}
|
||||
|
||||
if (!sessionId) {
|
||||
let person: TPerson | null;
|
||||
// check if person exists
|
||||
|
||||
person = await getPersonCached(personId);
|
||||
if (!person) {
|
||||
// create a new person
|
||||
person = await createPerson(environmentId);
|
||||
}
|
||||
|
||||
// create a new session
|
||||
const session = await createSession(person.id);
|
||||
|
||||
const [surveys, noCodeActionClasses, product] = await Promise.all([
|
||||
getSurveysCached(environmentId, person),
|
||||
getActionClassesCached(environmentId),
|
||||
getProductByEnvironmentIdCached(environmentId),
|
||||
]);
|
||||
|
||||
if (!product) {
|
||||
return responses.notFoundResponse("ProductByEnvironmentId", environmentId, true);
|
||||
}
|
||||
|
||||
captureNewSessionTelemetry(inputValidation.data.jsVersion);
|
||||
|
||||
// return state
|
||||
const state: TJsState = {
|
||||
person,
|
||||
session,
|
||||
surveys,
|
||||
noCodeActionClasses: noCodeActionClasses.filter((actionClass) => actionClass.type === "noCode"),
|
||||
product,
|
||||
};
|
||||
|
||||
return responses.successResponse({ ...state }, true);
|
||||
}
|
||||
// person & session exists
|
||||
|
||||
// check if session exists
|
||||
let person: TPerson | null;
|
||||
let session: TSession | null;
|
||||
|
||||
session = await getSessionCached(sessionId);
|
||||
|
||||
if (!session) {
|
||||
// check if person exits
|
||||
|
||||
person = await getPersonCached(personId);
|
||||
|
||||
if (!person) {
|
||||
// create a new person
|
||||
person = await createPerson(environmentId);
|
||||
}
|
||||
// create a new session
|
||||
session = await createSession(person.id);
|
||||
captureNewSessionTelemetry(inputValidation.data.jsVersion);
|
||||
} else {
|
||||
// session exists
|
||||
// check if person exists (should always exist, but just in case)
|
||||
|
||||
person = await getPersonCached(personId);
|
||||
if (!person) {
|
||||
// create a new person & session
|
||||
person = await createPerson(environmentId);
|
||||
session = await createSession(person.id);
|
||||
} else {
|
||||
// check if session is expired
|
||||
if (session.expiresAt < new Date()) {
|
||||
// create a new session
|
||||
session = await createSession(person.id);
|
||||
captureNewSessionTelemetry(inputValidation.data.jsVersion);
|
||||
} else {
|
||||
// extend session
|
||||
|
||||
const isSessionAboutToExpire =
|
||||
new Date(session.expiresAt).getTime() - new Date().getTime() < 1000 * 60 * 10;
|
||||
|
||||
if (isSessionAboutToExpire) {
|
||||
session = await extendSession(sessionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get/create rest of the state
|
||||
const [surveys, noCodeActionClasses, product] = await Promise.all([
|
||||
getSurveysCached(environmentId, person),
|
||||
getActionClassesCached(environmentId),
|
||||
getProductByEnvironmentIdCached(environmentId),
|
||||
]);
|
||||
|
||||
if (!product) {
|
||||
return responses.notFoundResponse("ProductByEnvironmentId", environmentId, true);
|
||||
}
|
||||
|
||||
// return state
|
||||
const state: TJsState = {
|
||||
person,
|
||||
session,
|
||||
surveys,
|
||||
noCodeActionClasses: noCodeActionClasses.filter((actionClass) => actionClass.type === "noCode"),
|
||||
product,
|
||||
};
|
||||
return responses.successResponse({ ...state }, true);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
||||
Reference in New Issue
Block a user