-
+
+
+
+
+
+ {tooltipContent}
+
+
{displayIdentifier}
diff --git a/packages/database/jsonTypes.ts b/packages/database/jsonTypes.ts
index c74ac0b041..1ec9b86da4 100644
--- a/packages/database/jsonTypes.ts
+++ b/packages/database/jsonTypes.ts
@@ -1,5 +1,5 @@
import { TEventClassNoCodeConfig } from "@formbricks/types/v1/eventClasses";
-import { TResponseData } from "@formbricks/types/v1/responses";
+import { TResponsePersonAttributes, TResponseData } from "@formbricks/types/v1/responses";
import { TSurveyQuestions, TSurveyThankYouCard } from "@formbricks/types/v1/surveys";
import { TUserNotificationSettings } from "@formbricks/types/v1/users";
@@ -9,6 +9,7 @@ declare global {
export type EventClassNoCodeConfig = TEventClassNoCodeConfig;
export type ResponseData = TResponseData;
export type ResponseMeta = { [key: string]: string };
+ export type ResponsePersonAttributes = TResponsePersonAttributes;
export type SurveyQuestions = TSurveyQuestions;
export type SurveyThankYouCard = TSurveyThankYouCard;
export type UserNotificationSettings = TUserNotificationSettings;
diff --git a/packages/database/migrations/20230618112915_person_attributes/migration.sql b/packages/database/migrations/20230618112915_person_attributes/migration.sql
new file mode 100644
index 0000000000..c2c3c39fd1
--- /dev/null
+++ b/packages/database/migrations/20230618112915_person_attributes/migration.sql
@@ -0,0 +1,2 @@
+-- AlterTable
+ALTER TABLE "Response" ADD COLUMN "personAttributes" JSONB;
diff --git a/packages/database/schema.prisma b/packages/database/schema.prisma
index 6b01b30de3..d443073b06 100644
--- a/packages/database/schema.prisma
+++ b/packages/database/schema.prisma
@@ -87,21 +87,24 @@ model Person {
}
model Response {
- id String @id @default(cuid())
- createdAt DateTime @default(now()) @map(name: "created_at")
- updatedAt DateTime @updatedAt @map(name: "updated_at")
- finished Boolean @default(false)
- survey Survey @relation(fields: [surveyId], references: [id], onDelete: Cascade)
- surveyId String
- person Person? @relation(fields: [personId], references: [id], onDelete: Cascade)
- personId String?
- responseNotes ResponseNote[]
- /// @zod.custom(imports.ZResponseData)
+ id String @id @default(cuid())
+ createdAt DateTime @default(now()) @map(name: "created_at")
+ updatedAt DateTime @updatedAt @map(name: "updated_at")
+ finished Boolean @default(false)
+ survey Survey @relation(fields: [surveyId], references: [id], onDelete: Cascade)
+ surveyId String
+ person Person? @relation(fields: [personId], references: [id], onDelete: Cascade)
+ personId String?
+ responseNotes ResponseNote[]
+ /// @zod.custom(imports.ZResponsePersonAttributes)
+ /// [ResponsePersonAttributes]
+ personAttributes Json?
+ /// @zod.custom(imports.ZResponseData)
/// [ResponseData]
- data Json @default("{}")
+ data Json @default("{}")
/// @zod.custom(imports.ZResponseMeta)
/// [ResponseMeta]
- meta Json @default("{}")
+ meta Json @default("{}")
}
model ResponseNote {
diff --git a/packages/database/zod-utils.ts b/packages/database/zod-utils.ts
index 1d9f8cecfd..1e17d99712 100644
--- a/packages/database/zod-utils.ts
+++ b/packages/database/zod-utils.ts
@@ -3,7 +3,7 @@ import z from "zod";
export const ZEventProperties = z.record(z.string());
export { ZEventClassNoCodeConfig } from "@formbricks/types/v1/eventClasses";
-export { ZResponseData } from "@formbricks/types/v1/responses";
+export { ZResponseData, ZResponsePersonAttributes } from "@formbricks/types/v1/responses";
export const ZResponseMeta = z.record(z.union([z.string(), z.number()]));
export { ZSurveyQuestions, ZSurveyThankYouCard } from "@formbricks/types/v1/surveys";
diff --git a/packages/lib/services/person.ts b/packages/lib/services/person.ts
index d910523bd6..96d6335975 100644
--- a/packages/lib/services/person.ts
+++ b/packages/lib/services/person.ts
@@ -13,7 +13,7 @@ type TransformPersonInput = {
}[];
};
-type TransformPersonOutput = {
+export type TransformPersonOutput = {
id: string;
attributes: Record
;
};
diff --git a/packages/lib/services/response.ts b/packages/lib/services/response.ts
index ce00d50a5a..4d3cc62ab5 100644
--- a/packages/lib/services/response.ts
+++ b/packages/lib/services/response.ts
@@ -2,10 +2,16 @@ import { prisma } from "@formbricks/database";
import { TResponse, TResponseInput, TResponseUpdateInput } from "@formbricks/types/v1/responses";
import { Prisma } from "@prisma/client";
import { DatabaseError, ResourceNotFoundError } from "@formbricks/errors";
-import { transformPrismaPerson } from "./person";
+import { getPerson, TransformPersonOutput, transformPrismaPerson } from "./person";
export const createResponse = async (responseInput: TResponseInput): Promise => {
try {
+ let person: TransformPersonOutput | null = null;
+
+ if (responseInput.personId) {
+ person = await getPerson(responseInput.personId);
+ }
+
const responsePrisma = await prisma.response.create({
data: {
survey: {
@@ -21,6 +27,7 @@ export const createResponse = async (responseInput: TResponseInput): Promise
surveyId: true,
finished: true,
data: true,
+ personAttributes: true,
person: {
select: {
id: true,
@@ -100,6 +93,7 @@ export const getResponse = async (responseId: string): Promise
const response: TResponse = {
...responsePrisma,
+ personAttributes: responsePrisma.personAttributes as Record,
person: transformPrismaPerson(responsePrisma.person),
};
diff --git a/packages/types/v1/people.ts b/packages/types/v1/people.ts
index e5cb6baa3c..b0a19febfd 100644
--- a/packages/types/v1/people.ts
+++ b/packages/types/v1/people.ts
@@ -1,8 +1,11 @@
import z from "zod";
+export const ZPersonAttributes = z.record(z.union([z.string(), z.number()]));
+export type TPersonAttributes = z.infer;
+
export const ZPerson = z.object({
id: z.string().cuid2(),
- attributes: z.record(z.union([z.string(), z.number()])),
+ attributes: ZPersonAttributes,
});
export type TPerson = z.infer;
diff --git a/packages/types/v1/responses.ts b/packages/types/v1/responses.ts
index 3304cb642c..04b179a9cd 100644
--- a/packages/types/v1/responses.ts
+++ b/packages/types/v1/responses.ts
@@ -1,9 +1,14 @@
import { z } from "zod";
+import { ZPersonAttributes } from "./people";
export const ZResponseData = z.record(z.union([z.string(), z.number(), z.array(z.string())]));
export type TResponseData = z.infer;
+export const ZResponsePersonAttributes = ZPersonAttributes.optional();
+
+export type TResponsePersonAttributes = z.infer;
+
const ZResponse = z.object({
id: z.string().cuid2(),
createdAt: z.date(),
@@ -15,6 +20,7 @@ const ZResponse = z.object({
attributes: z.record(z.union([z.string(), z.number()])),
})
.nullable(),
+ personAttributes: ZResponsePersonAttributes,
finished: z.boolean(),
data: ZResponseData,
});