mirror of
https://github.com/formbricks/formbricks.git
synced 2025-12-29 18:00:26 -06:00
Co-authored-by: pandeymangg <anshuman.pandey9999@gmail.com> Co-authored-by: Dhruwang <dhruwangjariwala18@gmail.com>
986 lines
37 KiB
Plaintext
986 lines
37 KiB
Plaintext
// This is your Prisma schema file,
|
|
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
extensions = [pgvector(map: "vector")]
|
|
}
|
|
|
|
generator client {
|
|
provider = "prisma-client-js"
|
|
previewFeatures = ["postgresqlExtensions"]
|
|
}
|
|
|
|
generator json {
|
|
provider = "prisma-json-types-generator"
|
|
}
|
|
|
|
enum PipelineTriggers {
|
|
responseCreated
|
|
responseUpdated
|
|
responseFinished
|
|
}
|
|
|
|
enum WebhookSource {
|
|
user
|
|
zapier
|
|
make
|
|
n8n
|
|
activepieces
|
|
}
|
|
|
|
/// Represents a webhook endpoint for receiving survey-related events.
|
|
/// Webhooks can be configured to receive notifications about response creation, updates, and completion.
|
|
///
|
|
/// @property id - Unique identifier for the webhook
|
|
/// @property name - Optional display name for the webhook
|
|
/// @property url - The endpoint URL where events will be sent
|
|
/// @property source - Origin of the webhook (user, zapier, make, etc.)
|
|
/// @property environment - Associated environment
|
|
/// @property triggers - Types of events that trigger this webhook
|
|
/// @property surveyIds - List of surveys this webhook is monitoring
|
|
model Webhook {
|
|
id String @id @default(cuid())
|
|
name String?
|
|
createdAt DateTime @default(now()) @map(name: "created_at")
|
|
updatedAt DateTime @default(now()) @updatedAt @map(name: "updated_at")
|
|
url String
|
|
source WebhookSource @default(user)
|
|
environment Environment @relation(fields: [environmentId], references: [id], onDelete: Cascade)
|
|
environmentId String
|
|
triggers PipelineTriggers[]
|
|
surveyIds String[]
|
|
|
|
@@index([environmentId])
|
|
}
|
|
|
|
/// Represents an attribute value associated with a contact.
|
|
/// Used to store custom properties and characteristics of contacts.
|
|
///
|
|
/// @property id - Unique identifier for the attribute
|
|
/// @property attributeKey - Reference to the attribute definition
|
|
/// @property contact - The contact this attribute belongs to
|
|
/// @property value - The actual value of the attribute
|
|
model ContactAttribute {
|
|
id String @id @default(cuid())
|
|
createdAt DateTime @default(now()) @map(name: "created_at")
|
|
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
|
attributeKey ContactAttributeKey @relation(fields: [attributeKeyId], references: [id], onDelete: Cascade)
|
|
attributeKeyId String
|
|
contact Contact @relation(fields: [contactId], references: [id], onDelete: Cascade)
|
|
contactId String
|
|
value String
|
|
|
|
@@unique([contactId, attributeKeyId])
|
|
@@index([attributeKeyId, value])
|
|
}
|
|
|
|
enum ContactAttributeType {
|
|
default
|
|
custom
|
|
}
|
|
|
|
/// Defines the possible attributes that can be assigned to contacts.
|
|
/// Acts as a schema for contact attributes within an environment.
|
|
///
|
|
/// @property id - Unique identifier for the attribute key
|
|
/// @property isUnique - Whether the attribute must have unique values across contacts
|
|
/// @property key - The attribute identifier used in the system
|
|
/// @property name - Display name for the attribute
|
|
/// @property type - Whether this is a default or custom attribute
|
|
/// @property environment - The environment this attribute belongs to
|
|
model ContactAttributeKey {
|
|
id String @id @default(cuid())
|
|
createdAt DateTime @default(now()) @map(name: "created_at")
|
|
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
|
isUnique Boolean @default(false)
|
|
key String
|
|
name String?
|
|
description String?
|
|
type ContactAttributeType @default(custom)
|
|
environment Environment @relation(fields: [environmentId], references: [id], onDelete: Cascade)
|
|
environmentId String
|
|
attributes ContactAttribute[]
|
|
attributeFilters SurveyAttributeFilter[]
|
|
|
|
@@unique([key, environmentId])
|
|
@@index([environmentId, createdAt])
|
|
}
|
|
|
|
/// Represents a person or user who can receive and respond to surveys.
|
|
/// Contacts are environment-specific and can have multiple attributes and responses.
|
|
///
|
|
/// @property id - Unique identifier for the contact
|
|
/// @property environment - The environment this contact belongs to
|
|
/// @property responses - Survey responses from this contact
|
|
/// @property attributes - Custom attributes associated with this contact
|
|
/// @property displays - Record of surveys shown to this contact
|
|
model Contact {
|
|
id String @id @default(cuid())
|
|
createdAt DateTime @default(now()) @map(name: "created_at")
|
|
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
|
environment Environment @relation(fields: [environmentId], references: [id], onDelete: Cascade)
|
|
environmentId String
|
|
responses Response[]
|
|
attributes ContactAttribute[]
|
|
displays Display[]
|
|
|
|
@@index([environmentId])
|
|
}
|
|
|
|
/// Stores a user's response to a survey, including their answers and metadata.
|
|
/// Each response is linked to a specific survey and optionally to a contact.
|
|
///
|
|
/// @property id - Unique identifier for the response
|
|
/// @property finished - Whether the survey was completed
|
|
/// @property survey - The associated survey
|
|
/// @property contact - The optional contact who provided the response
|
|
/// @property data - JSON object containing the actual response data
|
|
/// @property variables - Custom variables used in the response
|
|
/// @property ttc - Time to completion metrics
|
|
/// @property meta - Additional metadata about the response
|
|
model Response {
|
|
id String @id @default(cuid())
|
|
createdAt DateTime @default(now()) @map(name: "created_at")
|
|
updatedAt DateTime @default(now()) @updatedAt @map(name: "updated_at")
|
|
finished Boolean @default(false)
|
|
survey Survey @relation(fields: [surveyId], references: [id], onDelete: Cascade)
|
|
surveyId String
|
|
contact Contact? @relation(fields: [contactId], references: [id], onDelete: Cascade)
|
|
contactId String?
|
|
endingId String?
|
|
/// [ResponseData]
|
|
data Json @default("{}")
|
|
/// [ResponseVariables]
|
|
variables Json @default("{}")
|
|
/// [ResponseTtc]
|
|
ttc Json @default("{}")
|
|
/// [ResponseMeta]
|
|
meta Json @default("{}")
|
|
tags TagsOnResponses[]
|
|
quotaLinks ResponseQuotaLink[]
|
|
/// [ResponseContactAttributes]
|
|
contactAttributes Json?
|
|
// singleUseId, used to prevent multiple responses
|
|
singleUseId String?
|
|
language String?
|
|
displayId String? @unique
|
|
display Display? @relation(fields: [displayId], references: [id])
|
|
|
|
@@unique([surveyId, singleUseId])
|
|
@@index([createdAt])
|
|
@@index([surveyId, createdAt]) // to determine monthly response count
|
|
@@index([contactId, createdAt]) // to determine monthly identified users (persons)
|
|
@@index([surveyId])
|
|
}
|
|
|
|
/// Represents a label that can be applied to survey responses.
|
|
/// Used for categorizing and organizing responses within an environment.
|
|
///
|
|
/// @property id - Unique identifier for the tag
|
|
/// @property name - Display name of the tag
|
|
/// @property responses - Survey responses tagged with this label
|
|
/// @property environment - The environment this tag belongs to
|
|
model Tag {
|
|
id String @id @default(cuid())
|
|
createdAt DateTime @default(now()) @map(name: "created_at")
|
|
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
|
name String
|
|
responses TagsOnResponses[]
|
|
environmentId String
|
|
environment Environment @relation(fields: [environmentId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([environmentId, name])
|
|
@@index([environmentId])
|
|
}
|
|
|
|
/// Junction table linking tags to responses.
|
|
/// Enables many-to-many relationship between tags and responses.
|
|
///
|
|
/// @property response - The tagged response
|
|
/// @property tag - The tag applied to the response
|
|
model TagsOnResponses {
|
|
responseId String
|
|
response Response @relation(fields: [responseId], references: [id], onDelete: Cascade)
|
|
tagId String
|
|
tag Tag @relation(fields: [tagId], references: [id], onDelete: Cascade)
|
|
|
|
@@id([responseId, tagId])
|
|
@@index([responseId])
|
|
}
|
|
|
|
enum SurveyStatus {
|
|
draft
|
|
inProgress
|
|
paused
|
|
completed
|
|
}
|
|
|
|
/// Records when a survey is shown to a user.
|
|
/// Tracks survey display history and response status.
|
|
///
|
|
/// @property id - Unique identifier for the display event
|
|
/// @property survey - The survey that was displayed
|
|
/// @property contact - The contact who saw the survey
|
|
/// @property response - The associated response if one exists
|
|
model Display {
|
|
id String @id @default(cuid())
|
|
createdAt DateTime @default(now()) @map(name: "created_at")
|
|
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
|
survey Survey @relation(fields: [surveyId], references: [id], onDelete: Cascade)
|
|
surveyId String
|
|
contact Contact? @relation(fields: [contactId], references: [id], onDelete: Cascade)
|
|
contactId String?
|
|
response Response?
|
|
|
|
@@index([surveyId])
|
|
@@index([contactId, createdAt])
|
|
}
|
|
|
|
/// Links surveys to specific trigger actions.
|
|
/// Defines which user actions should cause a survey to be displayed.
|
|
/// This is the connection table between Surveys and ActionClasses that determines
|
|
/// when and under what conditions a survey should be triggered.
|
|
///
|
|
/// @property id - Unique identifier for the trigger
|
|
/// @property survey - The survey to be triggered
|
|
/// @property actionClass - The action that triggers the survey
|
|
/// @property createdAt - When the trigger was created
|
|
/// @property updatedAt - When the trigger was last modified
|
|
model SurveyTrigger {
|
|
id String @id @default(cuid())
|
|
createdAt DateTime @default(now()) @map(name: "created_at")
|
|
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
|
survey Survey @relation(fields: [surveyId], references: [id], onDelete: Cascade)
|
|
surveyId String
|
|
actionClass ActionClass @relation(fields: [actionClassId], references: [id], onDelete: Cascade)
|
|
actionClassId String
|
|
|
|
@@unique([surveyId, actionClassId])
|
|
@@index([surveyId])
|
|
}
|
|
|
|
enum SurveyAttributeFilterCondition {
|
|
equals
|
|
notEquals
|
|
}
|
|
|
|
enum SurveyQuotaAction {
|
|
endSurvey
|
|
continueSurvey
|
|
}
|
|
|
|
enum ResponseQuotaLinkStatus {
|
|
screenedIn
|
|
screenedOut
|
|
}
|
|
|
|
/// Defines targeting rules for surveys based on contact attributes.
|
|
/// Used to show surveys only to contacts matching specific criteria.
|
|
///
|
|
/// @property id - Unique identifier for the filter
|
|
/// @property attributeKey - The contact attribute to filter on
|
|
/// @property survey - The survey being filtered
|
|
/// @property condition - The comparison operator to use
|
|
/// @property value - The value to compare against
|
|
model SurveyAttributeFilter {
|
|
id String @id @default(cuid())
|
|
createdAt DateTime @default(now()) @map(name: "created_at")
|
|
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
|
attributeKey ContactAttributeKey @relation(fields: [attributeKeyId], references: [id], onDelete: Cascade)
|
|
attributeKeyId String
|
|
survey Survey @relation(fields: [surveyId], references: [id], onDelete: Cascade)
|
|
surveyId String
|
|
condition SurveyAttributeFilterCondition
|
|
value String
|
|
|
|
@@unique([surveyId, attributeKeyId])
|
|
@@index([surveyId])
|
|
@@index([attributeKeyId])
|
|
}
|
|
|
|
enum SurveyType {
|
|
link
|
|
app
|
|
}
|
|
|
|
enum displayOptions {
|
|
displayOnce
|
|
displayMultiple
|
|
displaySome
|
|
respondMultiple
|
|
}
|
|
|
|
/// Represents a complete survey configuration including questions, styling, and display rules.
|
|
/// Core model for the survey functionality in Formbricks.
|
|
///
|
|
/// @property id - Unique identifier for the survey
|
|
/// @property name - Display name of the survey
|
|
/// @property type - Survey delivery method (link, web, website, app)
|
|
/// @property status - Current state of the survey (draft, active, completed, etc)
|
|
/// @property environment - The environment this survey belongs to
|
|
/// @property questions - JSON array containing survey questions configuration
|
|
/// @property displayOption - Rules for how often the survey can be shown
|
|
/// @property triggers - Actions that can trigger this survey
|
|
/// @property attributeFilters - Rules for targeting specific contacts
|
|
model Survey {
|
|
id String @id @default(cuid())
|
|
createdAt DateTime @default(now()) @map(name: "created_at")
|
|
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
|
name String
|
|
redirectUrl String?
|
|
type SurveyType @default(app)
|
|
environment Environment @relation(fields: [environmentId], references: [id], onDelete: Cascade)
|
|
environmentId String
|
|
creator User? @relation(fields: [createdBy], references: [id])
|
|
createdBy String?
|
|
status SurveyStatus @default(draft)
|
|
/// [SurveyWelcomeCard]
|
|
welcomeCard Json @default("{\"enabled\": false}")
|
|
/// [SurveyQuestions]
|
|
questions Json @default("[]")
|
|
/// [SurveyBlocks]
|
|
blocks Json[] @default([])
|
|
/// [SurveyEnding]
|
|
endings Json[] @default([])
|
|
/// [SurveyHiddenFields]
|
|
hiddenFields Json @default("{\"enabled\": false}")
|
|
/// [SurveyVariables]
|
|
variables Json @default("[]")
|
|
responses Response[]
|
|
quotas SurveyQuota[]
|
|
displayOption displayOptions @default(displayOnce)
|
|
recontactDays Int?
|
|
displayLimit Int?
|
|
triggers SurveyTrigger[]
|
|
/// [SurveyInlineTriggers]
|
|
inlineTriggers Json?
|
|
attributeFilters SurveyAttributeFilter[]
|
|
displays Display[]
|
|
autoClose Int?
|
|
autoComplete Int?
|
|
delay Int @default(0)
|
|
/// [SurveyClosedMessage]
|
|
surveyClosedMessage Json?
|
|
segmentId String?
|
|
segment Segment? @relation(fields: [segmentId], references: [id])
|
|
|
|
/// [SurveyProjectOverwrites]
|
|
projectOverwrites Json?
|
|
|
|
/// [SurveyStyling]
|
|
styling Json?
|
|
|
|
/// [SurveySingleUse]
|
|
singleUse Json? @default("{\"enabled\": false, \"isEncrypted\": true}")
|
|
|
|
isVerifyEmailEnabled Boolean @default(false)
|
|
isSingleResponsePerEmailEnabled Boolean @default(false)
|
|
isBackButtonHidden Boolean @default(false)
|
|
pin String?
|
|
displayPercentage Decimal?
|
|
languages SurveyLanguage[]
|
|
showLanguageSwitch Boolean?
|
|
followUps SurveyFollowUp[]
|
|
/// [SurveyRecaptcha]
|
|
recaptcha Json? @default("{\"enabled\": false, \"threshold\":0.1}")
|
|
/// [SurveyLinkMetadata]
|
|
metadata Json @default("{}")
|
|
|
|
slug String? @unique
|
|
|
|
@@index([environmentId, updatedAt])
|
|
@@index([segmentId])
|
|
}
|
|
|
|
/// Represents a quota configuration for a survey.
|
|
/// Defines response limits and conditions for quota management.
|
|
///
|
|
/// @property id - Unique identifier for the quota
|
|
/// @property survey - The survey this quota belongs to
|
|
/// @property name - Display name for the quota
|
|
/// @property limit - Maximum number of responses allowed
|
|
/// @property conditions - JSON object containing quota conditions
|
|
/// @property action - Action to take when quota is reached
|
|
/// @property endingCardId - Optional ending card to show when quota is reached
|
|
model SurveyQuota {
|
|
id String @id @default(cuid())
|
|
createdAt DateTime @default(now()) @map(name: "created_at")
|
|
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
|
survey Survey @relation(fields: [surveyId], references: [id], onDelete: Cascade)
|
|
surveyId String
|
|
name String
|
|
limit Int
|
|
/// [SurveyQuotaLogic]
|
|
logic Json @default("{}")
|
|
action SurveyQuotaAction
|
|
endingCardId String?
|
|
quotaLinks ResponseQuotaLink[]
|
|
countPartialSubmissions Boolean @default(false)
|
|
|
|
@@unique([surveyId, name])
|
|
@@index([surveyId])
|
|
}
|
|
|
|
/// Junction table linking responses to quotas.
|
|
/// Tracks which responses counted towards specific quotas and their status.
|
|
///
|
|
/// @property response - The response that counted towards the quota
|
|
/// @property quota - The quota this response counted towards
|
|
/// @property status - Whether the response was screened in or out
|
|
model ResponseQuotaLink {
|
|
response Response @relation(fields: [responseId], references: [id], onDelete: Cascade)
|
|
responseId String
|
|
quota SurveyQuota @relation(fields: [quotaId], references: [id], onDelete: Cascade)
|
|
quotaId String
|
|
status ResponseQuotaLinkStatus
|
|
|
|
@@id([responseId, quotaId])
|
|
@@index([quotaId, status])
|
|
}
|
|
|
|
/// Defines follow-up actions for survey responses.
|
|
/// Enables automated actions based on specific survey response conditions.
|
|
///
|
|
/// @property id - Unique identifier for the follow-up
|
|
/// @property survey - The associated survey
|
|
/// @property name - Display name for the follow-up
|
|
/// @property trigger - Conditions that activate the follow-up
|
|
/// @property action - Actions to take when triggered
|
|
model SurveyFollowUp {
|
|
id String @id @default(cuid())
|
|
createdAt DateTime @default(now()) @map(name: "created_at")
|
|
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
|
survey Survey @relation(fields: [surveyId], references: [id], onDelete: Cascade)
|
|
surveyId String
|
|
name String
|
|
/// [SurveyFollowUpTrigger]
|
|
trigger Json
|
|
/// [SurveyFollowUpAction]
|
|
action Json
|
|
}
|
|
|
|
enum ActionType {
|
|
code
|
|
noCode
|
|
}
|
|
|
|
/// Represents a user action that can trigger surveys.
|
|
/// Used to define points in the user journey where surveys can be shown.
|
|
///
|
|
/// @property id - Unique identifier for the action
|
|
/// @property name - Display name of the action
|
|
/// @property type - Whether this is a code or no-code action
|
|
/// @property key - Unique identifier used in code implementation
|
|
/// @property noCodeConfig - Configuration for no-code setup
|
|
/// @property environment - The environment this action belongs to
|
|
model ActionClass {
|
|
id String @id @default(cuid())
|
|
createdAt DateTime @default(now()) @map(name: "created_at")
|
|
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
|
name String
|
|
description String?
|
|
type ActionType
|
|
key String?
|
|
/// [ActionClassNoCodeConfig]
|
|
noCodeConfig Json?
|
|
environment Environment @relation(fields: [environmentId], references: [id], onDelete: Cascade)
|
|
environmentId String
|
|
surveyTriggers SurveyTrigger[]
|
|
|
|
@@unique([key, environmentId])
|
|
@@unique([name, environmentId])
|
|
@@index([environmentId, createdAt])
|
|
}
|
|
|
|
enum EnvironmentType {
|
|
production
|
|
development
|
|
}
|
|
|
|
enum IntegrationType {
|
|
googleSheets
|
|
notion
|
|
airtable
|
|
slack
|
|
}
|
|
|
|
/// Represents third-party service integrations.
|
|
/// Enables data flow between Formbricks and external services.
|
|
///
|
|
/// @property id - Unique identifier for the integration
|
|
/// @property type - The service being integrated (Google Sheets, Notion, etc.)
|
|
/// @property environment - The environment this integration belongs to
|
|
/// @property config - Service-specific configuration details
|
|
model Integration {
|
|
id String @id @default(cuid())
|
|
type IntegrationType
|
|
environmentId String
|
|
/// [IntegrationConfig]
|
|
config Json
|
|
environment Environment @relation(fields: [environmentId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([type, environmentId])
|
|
@@index([environmentId])
|
|
}
|
|
|
|
enum DataMigrationStatus {
|
|
pending
|
|
applied
|
|
failed
|
|
}
|
|
|
|
/// Tracks database schema migrations.
|
|
/// Used to manage and track the state of data structure changes.
|
|
///
|
|
/// @property id - Unique identifier for the migration
|
|
/// @property name - Name of the migration
|
|
/// @property status - Current state of the migration (pending, applied, failed)
|
|
/// @property startedAt - When the migration began
|
|
/// @property finishedAt - When the migration completed
|
|
model DataMigration {
|
|
id String @id @default(cuid())
|
|
startedAt DateTime @default(now()) @map(name: "started_at")
|
|
finishedAt DateTime? @map(name: "finished_at")
|
|
name String @unique
|
|
status DataMigrationStatus
|
|
}
|
|
|
|
/// Represents either a production or development environment within a project.
|
|
/// Each project has exactly two environments, serving as the main reference point
|
|
/// for most Formbricks resources including surveys and actions.
|
|
///
|
|
/// @property id - Unique identifier for the environment
|
|
/// @property type - Either 'production' or 'development'
|
|
/// @property project - Reference to parent project
|
|
/// @property surveys - Collection of surveys in this environment
|
|
/// @property contacts - Collection of contacts/users tracked
|
|
/// @property actionClasses - Defined actions that can trigger surveys
|
|
/// @property attributeKeys - Custom attributes configuration
|
|
model Environment {
|
|
id String @id @default(cuid())
|
|
createdAt DateTime @default(now()) @map(name: "created_at")
|
|
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
|
type EnvironmentType
|
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
projectId String
|
|
appSetupCompleted Boolean @default(false)
|
|
surveys Survey[]
|
|
contacts Contact[]
|
|
actionClasses ActionClass[]
|
|
attributeKeys ContactAttributeKey[]
|
|
webhooks Webhook[]
|
|
tags Tag[]
|
|
segments Segment[]
|
|
integration Integration[]
|
|
ApiKeyEnvironment ApiKeyEnvironment[]
|
|
|
|
@@index([projectId])
|
|
}
|
|
|
|
enum WidgetPlacement {
|
|
bottomLeft
|
|
bottomRight
|
|
topLeft
|
|
topRight
|
|
center
|
|
}
|
|
|
|
/// Main grouping mechanism for resources in Formbricks.
|
|
/// Each organization can have multiple projects to separate different applications or products.
|
|
///
|
|
/// @property id - Unique identifier for the project
|
|
/// @property name - Display name of the project
|
|
/// @property organization - Reference to parent organization
|
|
/// @property environments - Development and production environments
|
|
/// @property styling - Project-wide styling configuration
|
|
/// @property config - Project-specific configuration
|
|
/// @property recontactDays - Default recontact delay for surveys
|
|
/// @property placement - Default widget placement for in-app surveys
|
|
model Project {
|
|
id String @id @default(cuid())
|
|
createdAt DateTime @default(now()) @map(name: "created_at")
|
|
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
|
name String
|
|
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
organizationId String
|
|
environments Environment[]
|
|
/// [Styling]
|
|
styling Json @default("{\"allowStyleOverwrite\":true}")
|
|
/// [ProjectConfig]
|
|
config Json @default("{}")
|
|
recontactDays Int @default(7)
|
|
linkSurveyBranding Boolean @default(true) // Determines if the survey branding should be displayed in link surveys
|
|
inAppSurveyBranding Boolean @default(true) // Determines if the survey branding should be displayed in in-app surveys
|
|
placement WidgetPlacement @default(bottomRight)
|
|
clickOutsideClose Boolean @default(true)
|
|
darkOverlay Boolean @default(false)
|
|
languages Language[]
|
|
/// [Logo]
|
|
logo Json?
|
|
projectTeams ProjectTeam[]
|
|
|
|
@@unique([organizationId, name])
|
|
@@index([organizationId])
|
|
}
|
|
|
|
/// Represents the top-level organizational hierarchy in Formbricks.
|
|
/// Self-hosting instances typically have a single organization, while Formbricks Cloud
|
|
/// supports multiple organizations with multi-tenancy.
|
|
///
|
|
/// @property id - Unique identifier for the organization
|
|
/// @property name - Display name of the organization
|
|
/// @property memberships - User memberships within the organization
|
|
/// @property projects - Collection of projects owned by the organization
|
|
/// @property billing - JSON field containing billing information
|
|
/// @property whitelabel - Whitelabel configuration for the organization
|
|
/// @property isAIEnabled - Controls access to AI-powered features
|
|
model Organization {
|
|
id String @id @default(cuid())
|
|
createdAt DateTime @default(now()) @map(name: "created_at")
|
|
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
|
name String
|
|
memberships Membership[]
|
|
projects Project[]
|
|
/// [OrganizationBilling]
|
|
billing Json
|
|
/// [OrganizationWhitelabel]
|
|
whitelabel Json @default("{}")
|
|
invites Invite[]
|
|
isAIEnabled Boolean @default(false)
|
|
teams Team[]
|
|
apiKeys ApiKey[]
|
|
}
|
|
|
|
enum OrganizationRole {
|
|
owner
|
|
manager
|
|
member
|
|
billing
|
|
}
|
|
|
|
/// Links users to organizations with specific roles.
|
|
/// Manages organization membership and permissions.
|
|
/// Core model for managing user access within organizations.
|
|
///
|
|
/// @property organization - The organization the user belongs to
|
|
/// @property user - The member user
|
|
/// @property accepted - Whether the user has accepted the membership
|
|
/// @property role - User's role within the organization (owner, manager, member, billing)
|
|
model Membership {
|
|
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
organizationId String
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
userId String
|
|
accepted Boolean @default(false)
|
|
role OrganizationRole @default(member)
|
|
|
|
@@id([userId, organizationId])
|
|
@@index([userId])
|
|
@@index([organizationId])
|
|
}
|
|
|
|
/// Represents pending invitations to join an organization.
|
|
/// Used to manage the process of adding new users to an organization.
|
|
/// Once accepted, invites are converted into memberships.
|
|
///
|
|
/// @property id - Unique identifier for the invite
|
|
/// @property email - Email address of the invited user
|
|
/// @property name - Optional display name for the invited user
|
|
/// @property organization - The organization sending the invite
|
|
/// @property creator - The user who created the invite
|
|
/// @property acceptor - The user who accepted the invite (if accepted)
|
|
/// @property expiresAt - When the invite becomes invalid
|
|
/// @property role - Intended role for the invited user
|
|
/// @property teamIds - Teams the user will be added to upon acceptance
|
|
model Invite {
|
|
id String @id @default(uuid())
|
|
email String
|
|
name String?
|
|
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
organizationId String
|
|
creator User @relation("inviteCreatedBy", fields: [creatorId], references: [id])
|
|
creatorId String
|
|
acceptor User? @relation("inviteAcceptedBy", fields: [acceptorId], references: [id], onDelete: Cascade)
|
|
acceptorId String?
|
|
createdAt DateTime @default(now())
|
|
expiresAt DateTime
|
|
role OrganizationRole @default(member)
|
|
teamIds String[] @default([])
|
|
|
|
@@index([email, organizationId])
|
|
@@index([organizationId])
|
|
}
|
|
|
|
/// Represents enhanced API authentication keys with organization-level ownership.
|
|
/// Used for authenticating API requests to Formbricks with more granular permissions.
|
|
///
|
|
/// @property id - Unique identifier for the API key
|
|
/// @property label - Optional descriptive name for the key
|
|
/// @property hashedKey - Securely stored API key
|
|
/// @property organization - The organization this key belongs to
|
|
/// @property createdBy - User ID who created this key
|
|
/// @property lastUsedAt - Timestamp of last usage
|
|
/// @property apiKeyEnvironments - Environments this key has access to
|
|
model ApiKey {
|
|
id String @id @default(cuid())
|
|
createdAt DateTime @default(now())
|
|
createdBy String?
|
|
lastUsedAt DateTime?
|
|
label String
|
|
hashedKey String
|
|
lookupHash String? @unique
|
|
organizationId String
|
|
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
apiKeyEnvironments ApiKeyEnvironment[]
|
|
/// [OrganizationAccess]
|
|
organizationAccess Json @default("{}")
|
|
|
|
@@index([organizationId])
|
|
}
|
|
|
|
/// Defines permission levels for API keys.
|
|
/// Controls what operations an API key can perform.
|
|
enum ApiKeyPermission {
|
|
read
|
|
write
|
|
manage
|
|
}
|
|
|
|
/// Links API keys to environments with specific permissions.
|
|
/// Enables granular access control for API keys across environments.
|
|
///
|
|
/// @property id - Unique identifier for the environment access entry
|
|
/// @property apiKey - The associated API key
|
|
/// @property environment - The environment being accessed
|
|
/// @property permission - Level of access granted
|
|
model ApiKeyEnvironment {
|
|
id String @id @default(cuid())
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
apiKeyId String
|
|
apiKey ApiKey @relation(fields: [apiKeyId], references: [id], onDelete: Cascade)
|
|
environmentId String
|
|
environment Environment @relation(fields: [environmentId], references: [id], onDelete: Cascade)
|
|
permission ApiKeyPermission
|
|
|
|
@@unique([apiKeyId, environmentId])
|
|
@@index([environmentId])
|
|
}
|
|
|
|
enum IdentityProvider {
|
|
email
|
|
github
|
|
google
|
|
azuread
|
|
openid
|
|
saml
|
|
}
|
|
|
|
/// Stores third-party authentication account information.
|
|
/// Enables OAuth and other external authentication methods.
|
|
///
|
|
/// @property id - Unique identifier for the account
|
|
/// @property user - The Formbricks user who owns this account
|
|
/// @property provider - The authentication provider (GitHub, Google, etc.)
|
|
/// @property providerAccountId - User ID from the provider
|
|
/// @property access_token - OAuth access token
|
|
/// @property refresh_token - OAuth refresh token
|
|
model Account {
|
|
id String @id @default(cuid())
|
|
createdAt DateTime @default(now()) @map(name: "created_at")
|
|
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
|
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
userId String
|
|
type String
|
|
provider String
|
|
providerAccountId String
|
|
access_token String? @db.Text
|
|
refresh_token String? @db.Text
|
|
expires_at Int?
|
|
ext_expires_in Int?
|
|
token_type String?
|
|
scope String?
|
|
id_token String? @db.Text
|
|
session_state String?
|
|
|
|
@@unique([provider, providerAccountId])
|
|
@@index([userId])
|
|
}
|
|
|
|
/// Represents a user in the Formbricks system.
|
|
/// Central model for user authentication and profile management.
|
|
///
|
|
/// @property id - Unique identifier for the user
|
|
/// @property name - Display name of the user
|
|
/// @property email - User's email address
|
|
/// @property twoFactorEnabled - Whether 2FA is active
|
|
/// @property memberships - Organizations the user belongs to
|
|
/// @property notificationSettings - User's notification preferences
|
|
model User {
|
|
id String @id @default(cuid())
|
|
createdAt DateTime @default(now()) @map(name: "created_at")
|
|
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
|
name String
|
|
email String @unique
|
|
emailVerified DateTime? @map(name: "email_verified")
|
|
|
|
twoFactorSecret String?
|
|
twoFactorEnabled Boolean @default(false)
|
|
backupCodes String?
|
|
password String?
|
|
identityProvider IdentityProvider @default(email)
|
|
identityProviderAccountId String?
|
|
memberships Membership[]
|
|
accounts Account[]
|
|
groupId String?
|
|
invitesCreated Invite[] @relation("inviteCreatedBy")
|
|
invitesAccepted Invite[] @relation("inviteAcceptedBy")
|
|
/// [UserNotificationSettings]
|
|
notificationSettings Json @default("{}")
|
|
/// [Locale]
|
|
locale String @default("en-US")
|
|
surveys Survey[]
|
|
teamUsers TeamUser[]
|
|
lastLoginAt DateTime?
|
|
isActive Boolean @default(true)
|
|
|
|
@@index([email])
|
|
}
|
|
|
|
/// Defines a segment of contacts based on attributes.
|
|
/// Used for targeting surveys to specific user groups.
|
|
///
|
|
/// @property id - Unique identifier for the segment
|
|
/// @property title - Display name of the segment
|
|
/// @property filters - Rules defining the segment
|
|
/// @property isPrivate - Whether the segment is private
|
|
/// @property environment - The environment this segment belongs to
|
|
model Segment {
|
|
id String @id @default(cuid())
|
|
createdAt DateTime @default(now()) @map(name: "created_at")
|
|
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
|
title String
|
|
description String?
|
|
isPrivate Boolean @default(true)
|
|
/// [SegmentFilter]
|
|
filters Json @default("[]")
|
|
environmentId String
|
|
environment Environment @relation(fields: [environmentId], references: [id], onDelete: Cascade)
|
|
surveys Survey[]
|
|
|
|
@@unique([environmentId, title])
|
|
@@index([environmentId])
|
|
}
|
|
|
|
/// Represents a supported language in the system.
|
|
/// Used for multilingual survey support.
|
|
///
|
|
/// @property id - Unique identifier for the language
|
|
/// @property code - Language code (e.g., 'en-US')
|
|
/// @property alias - Optional friendly name
|
|
/// @property project - The project this language is enabled for
|
|
model Language {
|
|
id String @id @default(cuid())
|
|
createdAt DateTime @default(now()) @map(name: "created_at")
|
|
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
|
code String
|
|
alias String?
|
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
projectId String
|
|
surveyLanguages SurveyLanguage[]
|
|
|
|
@@unique([projectId, code])
|
|
}
|
|
|
|
/// Links surveys to their supported languages.
|
|
/// Manages which languages are available for each survey.
|
|
///
|
|
/// @property language - The supported language
|
|
/// @property survey - The associated survey
|
|
/// @property default - Whether this is the default language
|
|
/// @property enabled - Whether this language is currently active
|
|
model SurveyLanguage {
|
|
language Language @relation(fields: [languageId], references: [id], onDelete: Cascade)
|
|
languageId String
|
|
surveyId String
|
|
survey Survey @relation(fields: [surveyId], references: [id], onDelete: Cascade)
|
|
default Boolean @default(false)
|
|
enabled Boolean @default(true)
|
|
|
|
@@id([languageId, surveyId])
|
|
@@index([surveyId])
|
|
@@index([languageId])
|
|
}
|
|
|
|
/// Represents a team within an organization.
|
|
/// Enables group-based access control and collaboration.
|
|
///
|
|
/// @property id - Unique identifier for the team
|
|
/// @property name - Display name of the team
|
|
/// @property organization - The parent organization
|
|
/// @property teamUsers - Users who are part of this team
|
|
/// @property projectTeams - Projects this team has access to
|
|
model Team {
|
|
id String @id @default(cuid())
|
|
createdAt DateTime @default(now()) @map(name: "created_at")
|
|
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
|
name String
|
|
organizationId String
|
|
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
teamUsers TeamUser[]
|
|
projectTeams ProjectTeam[]
|
|
|
|
@@unique([organizationId, name])
|
|
}
|
|
|
|
enum TeamUserRole {
|
|
admin
|
|
contributor
|
|
}
|
|
|
|
/// Links users to teams with specific roles.
|
|
/// Manages team membership and permissions.
|
|
///
|
|
/// @property team - The associated team
|
|
/// @property user - The team member
|
|
/// @property role - User's role within the team
|
|
model TeamUser {
|
|
createdAt DateTime @default(now()) @map(name: "created_at")
|
|
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
|
teamId String
|
|
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
|
userId String
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
role TeamUserRole
|
|
|
|
@@id([teamId, userId])
|
|
@@index([userId])
|
|
}
|
|
|
|
enum ProjectTeamPermission {
|
|
read
|
|
readWrite
|
|
manage
|
|
}
|
|
|
|
/// Defines team access to specific projects.
|
|
/// Manages project-level permissions for teams.
|
|
///
|
|
/// @property project - The accessed project
|
|
/// @property team - The team receiving access
|
|
/// @property permission - Level of access granted
|
|
model ProjectTeam {
|
|
createdAt DateTime @default(now()) @map(name: "created_at")
|
|
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
|
projectId String
|
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
teamId String
|
|
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
|
permission ProjectTeamPermission @default(read)
|
|
|
|
@@id([projectId, teamId])
|
|
@@index([teamId])
|
|
}
|