Skip to content

Commit

Permalink
fix: add data-migration fixing invalid jump end jump destination (for…
Browse files Browse the repository at this point in the history
  • Loading branch information
mattinannt authored Aug 7, 2024
1 parent 53fb976 commit 32b3a7d
Show file tree
Hide file tree
Showing 40 changed files with 235 additions and 1,077 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,5 @@ Zone.Identifier
packages/lib/uploads

# Vite Timestamps
vite.config.*.timestamp-*
*vite.config.*.timestamp-*

16 changes: 8 additions & 8 deletions apps/docs/app/self-hosting/migration-guide/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,12 @@ docker compose up -d
<CodeGroup title="Migrate the data">

```bash
docker pull ghcr.io/formbricks/data-migrations:latest && \
docker pull ghcr.io/formbricks/data-migrations:v2.3.0 && \
docker run --rm \
--network=formbricks_default \
-e DATABASE_URL="postgresql://postgres:postgres@postgres:5432/formbricks?schema=public" \
-e UPGRADE_TO_VERSION="v2.3" \
ghcr.io/formbricks/data-migrations:latest
ghcr.io/formbricks/data-migrations:v2.3.0
```

</CodeGroup>
Expand Down Expand Up @@ -286,12 +286,12 @@ docker compose up -d
<CodeGroup title="Migrate the data">

```bash
docker pull ghcr.io/formbricks/data-migrations:latest && \
docker pull ghcr.io/formbricks/data-migrations:v2.2 && \
docker run --rm \
--network=formbricks_default \
-e DATABASE_URL="postgresql://postgres:postgres@postgres:5432/formbricks?schema=public" \
-e UPGRADE_TO_VERSION="v2.2" \
ghcr.io/formbricks/data-migrations:latest
ghcr.io/formbricks/data-migrations:v2.2
```

</CodeGroup>
Expand Down Expand Up @@ -390,12 +390,12 @@ docker compose up -d
<CodeGroup title="Migrate the data">

```bash
docker pull ghcr.io/formbricks/data-migrations:latest && \
docker pull ghcr.io/formbricks/data-migrations:v2.1.0 && \
docker run --rm \
--network=formbricks_default \
-e DATABASE_URL="postgresql://postgres:postgres@postgres:5432/formbricks?schema=public" \
-e UPGRADE_TO_VERSION="v2.1" \
ghcr.io/formbricks/data-migrations:latest
ghcr.io/formbricks/data-migrations:v2.1.0
```

</CodeGroup>
Expand Down Expand Up @@ -504,12 +504,12 @@ docker compose up -d
<CodeGroup title="Migrate the data">

```bash
docker pull ghcr.io/formbricks/data-migrations:latest && \
docker pull ghcr.io/formbricks/data-migrations:v2.0.3 && \
docker run --rm \
--network=formbricks_default \
-e DATABASE_URL="postgresql://postgres:postgres@postgres:5432/formbricks?schema=public" \
-e UPGRADE_TO_VERSION="v2.0" \
ghcr.io/formbricks/data-migrations:latest
ghcr.io/formbricks/data-migrations:v2.0.3
```

</CodeGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ export const ConnectWithFormbricks = ({
</div>
<Button
id="finishOnboarding"
className="text-slate-400 hover:text-slate-700"
variant={widgetSetupCompleted ? "primary" : "minimal"}
onClick={handleFinishOnboarding}
EndIcon={ArrowRight}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { createId } from "@paralleldrive/cuid2";
import React, { SetStateAction, useEffect, useMemo, useState } from "react";
import toast from "react-hot-toast";
import { MultiLanguageCard } from "@formbricks/ee/multi-language/components/multi-language-card";
import { extractLanguageCodes, getLocalizedValue, translateQuestion } from "@formbricks/lib/i18n/utils";
import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
import { structuredClone } from "@formbricks/lib/pollyfills/structuredClone";
import { getDefaultEndingCard } from "@formbricks/lib/templates";
import { checkForEmptyFallBackValue, extractRecallInfo } from "@formbricks/lib/utils/recall";
Expand Down Expand Up @@ -258,18 +258,16 @@ export const QuestionsView = ({
toast.success("Question duplicated.");
};

const addQuestion = (question: any, index?: number) => {
const addQuestion = (question: TSurveyQuestion, index?: number) => {
const updatedSurvey = { ...localSurvey };
if (backButtonLabel) {
question.backButtonLabel = backButtonLabel;
}
const languageSymbols = extractLanguageCodes(localSurvey.languages);
const translatedQuestion = translateQuestion(question, languageSymbols);

if (index) {
updatedSurvey.questions.splice(index, 0, { ...translatedQuestion, isDraft: true });
updatedSurvey.questions.splice(index, 0, { ...question, isDraft: true });
} else {
updatedSurvey.questions.push({ ...translatedQuestion, isDraft: true });
updatedSurvey.questions.push({ ...question, isDraft: true });
}

setLocalSurvey(updatedSurvey);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@ import {
} from "@formbricks/lib/posthogServer";
import { getProductByEnvironmentId } from "@formbricks/lib/product/service";
import { COLOR_DEFAULTS } from "@formbricks/lib/styling/constants";
import { getSyncSurveys, transformToLegacySurvey } from "@formbricks/lib/survey/service";
import { getSyncSurveys } from "@formbricks/lib/survey/service";
import { transformToLegacySurvey } from "@formbricks/lib/survey/utils";
import { isVersionGreaterThanOrEqualTo } from "@formbricks/lib/utils/version";
import { TJsAppLegacyStateSync, TJsAppStateSync, ZJsPeopleUserIdInput } from "@formbricks/types/js";
import { TLegacySurvey } from "@formbricks/types/legacy-surveys";
import { TProductLegacy } from "@formbricks/types/product";
import { TJsAppStateSync, ZJsPeopleUserIdInput } from "@formbricks/types/js";
import { TSurvey } from "@formbricks/types/surveys/types";

export const OPTIONS = async (): Promise<Response> => {
Expand Down Expand Up @@ -181,7 +180,7 @@ export const GET = async (
throw new Error("Product not found");
}

const updatedProduct: TProductLegacy = {
const updatedProduct: any = {
...product,
brandColor: product.styling.brandColor?.light ?? COLOR_DEFAULTS.brandColor,
...(product.styling.highlightBorderColor?.light && {
Expand All @@ -194,10 +193,10 @@ export const GET = async (

// Scenario 1: Multi language and updated trigger action classes supported.
// Use the surveys as they are.
let transformedSurveys: TLegacySurvey[] | TSurvey[] = surveys;
let transformedSurveys: TSurvey[] = surveys;

// creating state object
let state: TJsAppStateSync | TJsAppLegacyStateSync = {
let state: TJsAppStateSync = {
surveys: !isMonthlyResponsesLimitReached
? transformedSurveys.map((survey) => replaceAttributeRecall(survey, attributes))
: [],
Expand All @@ -212,13 +211,13 @@ export const GET = async (
// Convert to legacy surveys with default language
// convert triggers to array of actionClasses Names
transformedSurveys = await Promise.all(
surveys.map((survey: TSurvey | TLegacySurvey) => {
surveys.map((survey) => {
const languageCode = "default";
return transformToLegacySurvey(survey as TSurvey, languageCode);
})
);

state = {
const legacyState: any = {
surveys: !isMonthlyResponsesLimitReached
? transformedSurveys.map((survey) => replaceAttributeRecallInLegacySurveys(survey, attributes))
: [],
Expand All @@ -227,6 +226,7 @@ export const GET = async (
language,
product: updatedProduct,
};
return responses.successResponse({ ...legacyState }, true);
}

return responses.successResponse({ ...state }, true);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { parseRecallInfo } from "@formbricks/lib/utils/recall";
import { TAttributes } from "@formbricks/types/attributes";
import { TLegacySurvey } from "@formbricks/types/legacy-surveys";
import { TSurvey } from "@formbricks/types/surveys/types";

export const replaceAttributeRecall = (survey: TSurvey, attributes: TAttributes): TSurvey => {
Expand Down Expand Up @@ -42,10 +41,7 @@ export const replaceAttributeRecall = (survey: TSurvey, attributes: TAttributes)
return surveyTemp;
};

export const replaceAttributeRecallInLegacySurveys = (
survey: TLegacySurvey,
attributes: TAttributes
): TLegacySurvey => {
export const replaceAttributeRecallInLegacySurveys = (survey: any, attributes: TAttributes): any => {
const surveyTemp = structuredClone(survey);
surveyTemp.questions.forEach((question) => {
if (question.headline.includes("recall:")) {
Expand Down
20 changes: 12 additions & 8 deletions apps/web/app/api/v1/client/[environmentId]/website/sync/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@ import {
} from "@formbricks/lib/posthogServer";
import { getProductByEnvironmentId } from "@formbricks/lib/product/service";
import { COLOR_DEFAULTS } from "@formbricks/lib/styling/constants";
import { getSurveys, transformToLegacySurvey } from "@formbricks/lib/survey/service";
import { getSurveys } from "@formbricks/lib/survey/service";
import { transformToLegacySurvey } from "@formbricks/lib/survey/utils";
import { isVersionGreaterThanOrEqualTo } from "@formbricks/lib/utils/version";
import { TJsWebsiteLegacyStateSync, TJsWebsiteStateSync, ZJsWebsiteSyncInput } from "@formbricks/types/js";
import { TLegacySurvey } from "@formbricks/types/legacy-surveys";
import { TProductLegacy } from "@formbricks/types/product";
import { TJsWebsiteStateSync, ZJsWebsiteSyncInput } from "@formbricks/types/js";
import { TSurvey } from "@formbricks/types/surveys/types";

export const OPTIONS = async (): Promise<Response> => {
Expand Down Expand Up @@ -122,7 +121,7 @@ export const GET = async (
// && (!survey.segment || survey.segment.filters.length === 0)
);

const updatedProduct: TProductLegacy = {
const updatedProduct: any = {
...product,
brandColor: product.styling.brandColor?.light ?? COLOR_DEFAULTS.brandColor,
...(product.styling.highlightBorderColor?.light && {
Expand All @@ -133,8 +132,8 @@ export const GET = async (
const noCodeActionClasses = actionClasses.filter((actionClass) => actionClass.type === "noCode");

// Define 'transformedSurveys' which can be an array of either TLegacySurvey or TSurvey.
let transformedSurveys: TLegacySurvey[] | TSurvey[] = filteredSurveys;
let state: TJsWebsiteStateSync | TJsWebsiteLegacyStateSync = {
let transformedSurveys: TSurvey[] = filteredSurveys;
let state: TJsWebsiteStateSync = {
surveys: !isWebsiteSurveyResponseLimitReached ? transformedSurveys : [],
actionClasses,
product: updatedProduct,
Expand All @@ -152,11 +151,16 @@ export const GET = async (
})
);

state = {
const legacyState: any = {
surveys: isWebsiteSurveyResponseLimitReached ? [] : transformedSurveys,
noCodeActionClasses,
product: updatedProduct,
};
return responses.successResponse(
{ ...legacyState },
true,
"public, s-maxage=600, max-age=840, stale-while-revalidate=600, stale-if-error=600"
);
}

return responses.successResponse(
Expand Down
8 changes: 0 additions & 8 deletions apps/web/app/api/v1/management/surveys/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { authenticateRequest } from "@/app/api/v1/auth";
import { responses } from "@/app/lib/api/response";
import { transformErrorToDetails } from "@/app/lib/api/validator";
import { translateSurvey } from "@formbricks/lib/i18n/utils";
import { createSurvey, getSurveys } from "@formbricks/lib/survey/service";
import { DatabaseError } from "@formbricks/types/errors";
import { ZSurveyCreateInput } from "@formbricks/types/surveys/types";
Expand Down Expand Up @@ -38,13 +37,6 @@ export const POST = async (request: Request): Promise<Response> => {
return responses.badRequestResponse("Malformed JSON input, please check your request body");
}

if (surveyInput?.questions && surveyInput.questions[0].headline) {
const questionHeadline = surveyInput.questions[0].headline;
if (typeof questionHeadline === "string") {
// its a legacy survey
surveyInput = translateSurvey(surveyInput, []);
}
}
const inputValidation = ZSurveyCreateInput.safeParse(surveyInput);

if (!inputValidation.success) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable -- leacy support workaround for now to avoid rewrite after eslint rules have been changed */
// migration script to translate surveys where thankYouCard buttonLabel is a string or question subheaders are strings
import { PrismaClient } from "@prisma/client";
import { hasStringSubheaders, translateSurvey } from "./lib/i18n";
Expand All @@ -8,7 +9,7 @@ const main = async () => {
await prisma.$transaction(
async (tx) => {
// Translate Surveys
const surveys = await tx.survey.findMany({
const surveys: any = await tx.survey.findMany({
select: {
id: true,
questions: true,
Expand All @@ -17,11 +18,6 @@ const main = async () => {
},
});

if (!surveys) {
// stop the migration if there are no surveys
return;
}

for (const survey of surveys) {
if (typeof survey.thankYouCard.buttonLabel === "string" || hasStringSubheaders(survey.questions)) {
const translatedSurvey = translateSurvey(survey, []);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable -- leacy support workaround for now to avoid rewrite after eslint rules have been changed */
// migration script to convert range field in rating question from string to number
import { PrismaClient } from "@prisma/client";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable -- leacy support workaround for now to avoid rewrite after eslint rules have been changed */
// migration script to add empty strings to welcome card headline in default language, if it does not exist
// WelcomeCard.headline = {} -> WelcomeCard.headline = {"default":""}
import { PrismaClient } from "@prisma/client";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable -- leacy support workaround for now to avoid rewrite after eslint rules have been changed */
import { PrismaClient } from "@prisma/client";
import { AttributeType } from "@prisma/client";
import { translateSurvey } from "./lib/i18n";
Expand Down
Loading

0 comments on commit 32b3a7d

Please sign in to comment.