mirror of
https://github.com/formbricks/formbricks.git
synced 2026-04-16 19:15:05 -05:00
docs: add system architecture and cluster setup details (#4761)
This commit is contained in:
203
docs/development/technical-handbook/database-model.mdx
Normal file
203
docs/development/technical-handbook/database-model.mdx
Normal file
@@ -0,0 +1,203 @@
|
||||
---
|
||||
title: "Database Model"
|
||||
description: "Overview of the Formbricks database schema and relationships"
|
||||
icon: "database"
|
||||
---
|
||||
|
||||
Formbricks uses PostgreSQL as its primary database and [Prisma](https://www.prisma.io/) as the Object-Relational Mapping (ORM) tool. The database schema is designed to support multi-tenancy, survey management, and response collection while maintaining data isolation between organizations.
|
||||
|
||||
## Entity Relationship Diagram
|
||||
|
||||
The following diagram shows the core entities and their relationships in the Formbricks database:
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
Organization ||--o{ Project : "has many"
|
||||
Organization ||--o{ Membership : "has many"
|
||||
Organization ||--o{ Team : "has many"
|
||||
Organization ||--o{ Invite : "sends"
|
||||
|
||||
Project ||--o{ Environment : "has two"
|
||||
Project ||--o{ Language : "supports"
|
||||
Project ||--o{ ProjectTeam : "has"
|
||||
|
||||
Environment ||--o{ Survey : "contains"
|
||||
Environment ||--o{ Contact : "tracks"
|
||||
Environment ||--o{ ActionClass : "defines"
|
||||
Environment ||--o{ ApiKey : "has"
|
||||
Environment ||--o{ Integration : "configures"
|
||||
|
||||
Survey ||--o{ Response : "receives"
|
||||
Survey ||--o{ Display : "tracks"
|
||||
Survey ||--o{ SurveyTrigger : "configured by"
|
||||
Survey ||--o{ SurveyAttributeFilter : "filtered by"
|
||||
Survey ||--o{ SurveyLanguage : "translated to"
|
||||
|
||||
Contact ||--o{ Response : "provides"
|
||||
Contact ||--o{ Display : "sees"
|
||||
Contact ||--o{ ContactAttribute : "has"
|
||||
|
||||
User ||--o{ Membership : "belongs to"
|
||||
User ||--o{ Account : "has"
|
||||
User ||--o{ TeamUser : "member of"
|
||||
|
||||
Team ||--o{ TeamUser : "includes"
|
||||
Team ||--o{ ProjectTeam : "has access to"
|
||||
|
||||
Response ||--o{ ResponseNote : "has"
|
||||
Response ||--o{ TagsOnResponses : "tagged with"
|
||||
|
||||
Tag ||--o{ TagsOnResponses : "applied to"
|
||||
|
||||
ActionClass ||--o{ SurveyTrigger : "triggers"
|
||||
|
||||
ContactAttributeKey ||--o{ ContactAttribute : "defines"
|
||||
ContactAttributeKey ||--o{ SurveyAttributeFilter : "used in"
|
||||
```
|
||||
|
||||
## Core Models
|
||||
|
||||
### Organization & Project Management
|
||||
|
||||
1. **Organization**
|
||||
|
||||
- Top-level entity for multi-tenancy
|
||||
- Contains multiple projects and team members
|
||||
- Manages billing and whitelabel settings
|
||||
|
||||
2. **Project**
|
||||
|
||||
- Groups related surveys and configurations
|
||||
- Has two environments (production/development)
|
||||
- Controls branding and display settings
|
||||
|
||||
3. **Environment**
|
||||
- Isolates production and development resources
|
||||
- Contains surveys, contacts, and actions
|
||||
- Manages API keys and integrations
|
||||
|
||||
### Survey Management
|
||||
|
||||
1. **Survey**
|
||||
|
||||
- Central model for questionnaires
|
||||
- Configurable with multiple questions and display rules
|
||||
- Supports multiple languages and targeting filters
|
||||
|
||||
2. **Response**
|
||||
|
||||
- Records user answers to surveys
|
||||
- Links to contact information when available
|
||||
- Supports tagging and notes for analysis
|
||||
|
||||
3. **ActionClass**
|
||||
- Defines triggering points for surveys
|
||||
- Can be code-based or no-code configurations
|
||||
- Links surveys to specific user actions
|
||||
|
||||
### User Management
|
||||
|
||||
1. **User**
|
||||
|
||||
- Represents system users (admins/team members)
|
||||
- Manages authentication and preferences
|
||||
- Can belong to multiple organizations
|
||||
|
||||
2. **Contact**
|
||||
|
||||
- Represents survey respondents
|
||||
- Stores attributes for targeting
|
||||
- Tracks survey displays and responses
|
||||
|
||||
3. **Team**
|
||||
- Groups users within organizations
|
||||
- Controls project access permissions
|
||||
- Facilitates collaborative survey management
|
||||
|
||||
## Data Isolation
|
||||
|
||||
The database schema ensures proper data isolation through:
|
||||
|
||||
1. **Organization-level isolation**
|
||||
|
||||
- Each organization has its own projects
|
||||
- Users can belong to multiple organizations
|
||||
- Resources are scoped to organizations
|
||||
|
||||
2. **Environment-level isolation**
|
||||
|
||||
- Separate production and development environments
|
||||
- Independent surveys, contacts, and actions
|
||||
- Isolated API keys and integrations
|
||||
|
||||
3. **Project-level isolation**
|
||||
- Project-specific configurations
|
||||
- Separate language settings
|
||||
- Team-based access control
|
||||
|
||||
## Schema Management
|
||||
|
||||
The database schema is managed through Prisma, which provides:
|
||||
|
||||
- Type-safe database client
|
||||
- Automatic migration generation
|
||||
- Schema versioning
|
||||
- Data validation
|
||||
- Query optimization
|
||||
|
||||
For detailed information about specific models and their properties, refer to the [schema.prisma](https://github.com/formbricks/formbricks/blob/main/packages/database/schema.prisma) file in the repository.
|
||||
|
||||
## PostgreSQL Database Tables
|
||||
|
||||
Formbricks stores all data in PostgreSQL tables. Here's a comprehensive list of all database tables and their purposes:
|
||||
|
||||
| Table Name | Description |
|
||||
| --------------------- | ---------------------------------------------------------------------- |
|
||||
| Account | Stores third-party authentication accounts (OAuth) and their tokens |
|
||||
| ActionClass | Defines triggerable events that can launch surveys |
|
||||
| ApiKey | Stores API authentication keys for environment-specific access |
|
||||
| Contact | Records information about user that can receive and respond to surveys |
|
||||
| ContactAttribute | Stores attribute values for contacts (e.g., role, company size) |
|
||||
| ContactAttributeKey | Defines available attribute types for contacts |
|
||||
| DataMigration | Tracks the status of database schema migrations |
|
||||
| Display | Records when and to whom surveys were shown |
|
||||
| Document | Stores processed survey responses for analysis |
|
||||
| DocumentInsight | Links analyzed documents to derived insights |
|
||||
| Environment | Manages production/development environments within projects |
|
||||
| Insight | Contains analyzed patterns and information from responses |
|
||||
| Integration | Stores configuration for third-party service integrations |
|
||||
| Invite | Manages pending invitations to join organizations |
|
||||
| Language | Defines supported languages for multi-lingual surveys |
|
||||
| Membership | Links users to organizations with specific roles |
|
||||
| Organization | Top-level container for projects and team management |
|
||||
| Project | Groups related surveys and environments |
|
||||
| ProjectTeam | Manages team access permissions to projects |
|
||||
| Response | Stores survey responses and associated metadata |
|
||||
| ResponseNote | Contains team member comments on survey responses |
|
||||
| Segment | Defines groups of contacts based on attributes |
|
||||
| ShortUrl | Maps shortened URLs to their full destinations |
|
||||
| Survey | Stores survey configurations, questions, and display rules |
|
||||
| SurveyAttributeFilter | Defines targeting rules for surveys based on contact attributes |
|
||||
| SurveyFollowUp | Configures automated actions based on survey responses |
|
||||
| SurveyLanguage | Links surveys to their supported languages |
|
||||
| SurveyTrigger | Connects surveys to their triggering actions |
|
||||
| Tag | Stores labels for categorizing responses |
|
||||
| TagsOnResponses | Junction table linking tags to responses |
|
||||
| Team | Groups users within organizations |
|
||||
| TeamUser | Links users to teams with specific roles |
|
||||
| User | Stores user account information and preferences |
|
||||
| Webhook | Manages webhook endpoints for event notifications |
|
||||
|
||||
## Schema Reference
|
||||
|
||||
For detailed information about the database schema, including:
|
||||
|
||||
- Complete field definitions
|
||||
- Relationships between tables
|
||||
- Enums and custom types
|
||||
- Field constraints and indices
|
||||
- JSON field structures
|
||||
|
||||
Please refer to the [Prisma schema file](https://github.com/formbricks/formbricks/blob/main/packages/database/schema.prisma) in our GitHub repository.
|
||||
|
||||
The schema.prisma file contains extensive documentation comments for each model, making it the authoritative reference for the database structure.
|
||||
122
docs/development/technical-handbook/overview.mdx
Normal file
122
docs/development/technical-handbook/overview.mdx
Normal file
@@ -0,0 +1,122 @@
|
||||
---
|
||||
title: "Solution Overview"
|
||||
description: "High-level architecture and technical details of the Formbricks platform"
|
||||
icon: "presentation-screen"
|
||||
---
|
||||
|
||||
The Formbricks platform is designed with a modern, unified architecture that prioritizes developer experience and performance. This overview outlines the system's architecture, key technology choices, and how different components interact.
|
||||
|
||||
## System Architecture
|
||||
|
||||
Formbricks uses a unified architecture with Next.js at its core, serving both the frontend and backend capabilities. Here's an interactive overview of the system:
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph Users
|
||||
MU[Mobile User]
|
||||
WU[Web User]
|
||||
LSU[Link Survey User]
|
||||
AD[Admin]
|
||||
end
|
||||
|
||||
subgraph Client Applications
|
||||
MA[Mobile App\niOS/Android SDK]
|
||||
SW[Survey Widget\nJavaScript SDK]
|
||||
end
|
||||
|
||||
subgraph Formbricks Platform
|
||||
NS[Next.js Server\nAPI Routes + SSR\nBusiness Logic]
|
||||
|
||||
subgraph Storage
|
||||
DB[(PostgreSQL\nSurveys & Data)]
|
||||
RC[(Redis\nPerformance Cache)]
|
||||
FS[File Storage\nUploads]
|
||||
end
|
||||
end
|
||||
|
||||
MU --> |Uses| MA
|
||||
WU --> |Interacts| SW
|
||||
LSU --> |Direct Access| NS
|
||||
AD --> |Manages| NS
|
||||
|
||||
MA --> |REST API| NS
|
||||
SW --> |REST API| NS
|
||||
|
||||
NS --> |Cache Data| RC
|
||||
NS --> |Read/Write| DB
|
||||
NS --> |File Upload| FS
|
||||
|
||||
style DB fill:#00C4B8,color:#ffffff
|
||||
style RC fill:#00C4B8,color:#ffffff
|
||||
style FS fill:#00C4B8,color:#ffffff
|
||||
style NS fill:#0D9373,color:#ffffff
|
||||
style MA fill:#07C983,color:#ffffff
|
||||
style SW fill:#07C983,color:#ffffff
|
||||
|
||||
classDef user fill:#666,color:#fff,stroke:#333
|
||||
class MU,WU,LSU,AD user
|
||||
```
|
||||
|
||||
### Key Components
|
||||
|
||||
#### Users
|
||||
|
||||
- **Mobile Users**: Access surveys through native mobile applications
|
||||
- **Web Users**: Interact with embedded survey widgets on websites
|
||||
- **Link Survey Users**: Access surveys directly through shared URLs
|
||||
- **Admins**: Manage surveys and view responses through the web dashboard
|
||||
|
||||
#### Client Applications
|
||||
|
||||
- **Survey Widget**: A JavaScript component that can be embedded in web applications
|
||||
- **Mobile Application**: Native iOS/Android apps that integrate with the Formbricks SDK
|
||||
- **Web Dashboard**: The admin interface for managing surveys and viewing responses
|
||||
|
||||
#### Core Platform
|
||||
|
||||
- **Next.js Server**: The central component that handles:
|
||||
- Frontend rendering and SSR
|
||||
- API routes for client communication
|
||||
- Business logic implementation
|
||||
- Survey display and response collection
|
||||
|
||||
#### Data Storage
|
||||
|
||||
- **PostgreSQL Database**: Primary data store for:
|
||||
- Survey definitions
|
||||
- Response data
|
||||
- User and organization information
|
||||
- **Redis Cache**: Performance optimization through:
|
||||
- Caching frequently accessed data
|
||||
- Reducing database load
|
||||
- Improving response times
|
||||
|
||||
### Communication Flow
|
||||
|
||||
1. **Client Interaction**
|
||||
|
||||
- Web users interact with embedded survey widgets
|
||||
- Mobile users engage with surveys through native apps
|
||||
- Link survey users access surveys directly via URLs
|
||||
- Admins manage the system through the web dashboard
|
||||
|
||||
2. **Data Flow**
|
||||
|
||||
- Clients communicate with the Next.js server via REST APIs
|
||||
- Survey data is fetched and responses are submitted over HTTPS
|
||||
- The server processes requests and interacts with the database using Prisma ORM
|
||||
- Frequently accessed data is cached in Redis for performance
|
||||
|
||||
3. **Data Storage**
|
||||
- Persistent data is stored in PostgreSQL
|
||||
- Frequently accessed data is cached in Redis
|
||||
- File attachments are handled through the configured storage provider
|
||||
|
||||
## Technology Stack
|
||||
|
||||
- **Frontend**: React, TailwindCSS, Radix UI
|
||||
- **Backend**: Next.js App Router with API Routes
|
||||
- **Database**: PostgreSQL with Prisma ORM
|
||||
- **Caching**: Redis
|
||||
- **API**: REST with OpenAPI specification
|
||||
- **Testing**: Playwright for E2E, Vitest for unit tests
|
||||
@@ -174,6 +174,10 @@
|
||||
"development/local-setup/github-codespaces"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Technical Handbook",
|
||||
"pages": ["development/technical-handbook/overview", "development/technical-handbook/database-model"]
|
||||
},
|
||||
{
|
||||
"group": "Contribution",
|
||||
"pages": ["development/contribution/contribution"]
|
||||
@@ -692,14 +696,14 @@
|
||||
"name": "Self Hosting",
|
||||
"url": "self-hosting"
|
||||
},
|
||||
{
|
||||
"name": "Development",
|
||||
"url": "development"
|
||||
},
|
||||
{
|
||||
"name": "API Reference",
|
||||
"openapi": "/api-reference/openapi.json",
|
||||
"url": "api-reference"
|
||||
},
|
||||
{
|
||||
"name": "Development",
|
||||
"url": "development"
|
||||
}
|
||||
],
|
||||
"topbarCtaButton": {
|
||||
|
||||
@@ -1,42 +1,131 @@
|
||||
---
|
||||
title: 'Cluster Setup'
|
||||
title: "Cluster Setup"
|
||||
description: "How to set up Formbricks in a cluster"
|
||||
icon: "circle-nodes"
|
||||
---
|
||||
|
||||
<Note>
|
||||
Running Formbricks in a multi-instance cluster configuration is an Enterprise Edition feature and requires an enterprise license key.
|
||||
Running Formbricks in a multi-instance cluster configuration is an Enterprise Edition feature and requires
|
||||
an enterprise license key.
|
||||
</Note>
|
||||
|
||||
## Overview
|
||||
|
||||
Running Formbricks as a cluster of multiple instances offers several key advantages:
|
||||
|
||||
* **High Availability**: Ensure your surveys remain accessible even if some instances fail
|
||||
- **High Availability**: Ensure your surveys remain accessible even if some instances fail
|
||||
|
||||
* **Load Distribution**: Handle higher traffic by distributing requests across multiple instances
|
||||
- **Load Distribution**: Handle higher traffic by distributing requests across multiple instances
|
||||
|
||||
* **Scalability**: Easily scale horizontally by adding more instances as your needs grow
|
||||
- **Scalability**: Easily scale horizontally by adding more instances as your needs grow
|
||||
|
||||
* **Zero-Downtime Updates**: Rolling updates without service interruption
|
||||
- **Zero-Downtime Updates**: Rolling updates without service interruption
|
||||
|
||||
## Requirements
|
||||
|
||||
To run Formbricks in a cluster setup, you'll need:
|
||||
|
||||
* Enterprise Edition license key
|
||||
- Enterprise Edition license key
|
||||
|
||||
* Shared PostgreSQL database
|
||||
- Shared PostgreSQL database
|
||||
|
||||
* Shared Redis cache for session management and caching
|
||||
- Shared Redis cache for session management and caching
|
||||
|
||||
* Load balancer to distribute traffic
|
||||
- Load balancer to distribute traffic
|
||||
|
||||
## Architecture
|
||||
|
||||
The Formbricks cluster setup consists of multiple components working together to provide a scalable and highly available system. Here's a detailed overview of the architecture:
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph Load Balancer
|
||||
LB[Load Balancer/Ingress]
|
||||
end
|
||||
|
||||
subgraph Formbricks Cluster
|
||||
FB1[Formbricks Instance 1]
|
||||
FB2[Formbricks Instance 2]
|
||||
FB3[Formbricks Instance n]
|
||||
end
|
||||
|
||||
subgraph Data Storage
|
||||
subgraph PostgreSQL HA
|
||||
PSQL_P[(PostgreSQL Primary)]
|
||||
PSQL_R[(PostgreSQL Replica)]
|
||||
end
|
||||
|
||||
subgraph Redis Cluster
|
||||
RC_P[(Redis Primary)]
|
||||
RC_R[(Redis Replica)]
|
||||
end
|
||||
|
||||
S3[S3 Compatible Storage]
|
||||
end
|
||||
|
||||
%% Connections
|
||||
LB --> FB1
|
||||
LB --> FB2
|
||||
LB --> FB3
|
||||
|
||||
FB1 --> PSQL_P
|
||||
FB2 --> PSQL_P
|
||||
FB3 --> PSQL_P
|
||||
PSQL_P --> PSQL_R
|
||||
|
||||
FB1 --> RC_P
|
||||
FB2 --> RC_P
|
||||
FB3 --> RC_P
|
||||
RC_P --> RC_R
|
||||
|
||||
FB1 --> S3
|
||||
FB2 --> S3
|
||||
FB3 --> S3
|
||||
|
||||
style PSQL_P fill:#00C4B8,color:#ffffff
|
||||
style PSQL_R fill:#00C4B8,color:#ffffff
|
||||
style RC_P fill:#FF6B6B,color:#ffffff
|
||||
style RC_R fill:#FF6B6B,color:#ffffff
|
||||
style S3 fill:#FFA94D,color:#ffffff
|
||||
style FB1,FB2,FB3 fill:#0D9373,color:#ffffff
|
||||
style LB fill:#4C6EF5,color:#ffffff
|
||||
```
|
||||
|
||||
### Component Description
|
||||
|
||||
1. **Formbricks Cluster**
|
||||
|
||||
- Multiple Formbricks instances (1..n) running in parallel
|
||||
- Each instance is stateless and can handle any incoming request
|
||||
- Automatic failover if any instance becomes unavailable
|
||||
|
||||
2. **PostgreSQL Database**
|
||||
|
||||
- Primary database storing all survey, response, and contact data
|
||||
- Optional high-availability setup with primary-replica configuration
|
||||
- Handles all persistent data storage needs
|
||||
|
||||
3. **Redis Cluster**
|
||||
|
||||
- Acts as a distributed cache layer
|
||||
- Improves performance by caching frequently accessed data
|
||||
- Can be configured in HA mode with primary-replica setup
|
||||
- Handles session management and real-time features
|
||||
|
||||
4. **S3 Compatible Storage**
|
||||
|
||||
- Stores file uploads and attachments
|
||||
- Can be any S3-compatible storage service (AWS S3, MinIO, etc.)
|
||||
- Provides reliable and scalable file storage
|
||||
|
||||
5. **Load Balancer**
|
||||
- Distributes incoming traffic across all Formbricks instances
|
||||
- Performs health checks and removes unhealthy instances
|
||||
- Ensures even load distribution and high availability
|
||||
|
||||
## Redis Configuration
|
||||
|
||||
<Note>
|
||||
Redis integration is an Enterprise Edition feature and requires an enterprise license key.
|
||||
</Note>
|
||||
<Note>Redis integration is an Enterprise Edition feature and requires an enterprise license key.</Note>
|
||||
|
||||
Configure Redis by adding the following environment variables to your instances:
|
||||
|
||||
@@ -45,16 +134,66 @@ REDIS_URL=redis://your-redis-host:6379
|
||||
REDIS_HTTP_URL=http://your-redis-host:8000
|
||||
```
|
||||
|
||||
## Coming Soon
|
||||
## S3 Configuration
|
||||
|
||||
We're working on comprehensive Kubernetes deployment instructions to make cluster setup even easier. This will include:
|
||||
Configure S3 storage by adding the following environment variables to your instances:
|
||||
|
||||
* Kubernetes manifests
|
||||
```sh env
|
||||
# Required for file uploads in serverless environments
|
||||
S3_ACCESS_KEY=your-access-key
|
||||
S3_SECRET_KEY=your-secret-key
|
||||
S3_REGION=your-region
|
||||
S3_BUCKET_NAME=your-bucket-name
|
||||
|
||||
* Helm charts
|
||||
# For S3-compatible storage (e.g., StorJ, MinIO)
|
||||
# Leave empty for Amazon S3
|
||||
S3_ENDPOINT_URL=https://your-s3-compatible-endpoint
|
||||
|
||||
* Detailed scaling configurations
|
||||
# Enable for S3-compatible storage that requires path style
|
||||
# 0 for disabled, 1 for enabled
|
||||
S3_FORCE_PATH_STYLE=0
|
||||
```
|
||||
|
||||
* Production-ready deployment examples
|
||||
When using S3 in a cluster setup, ensure that:
|
||||
|
||||
Stay tuned for updates.
|
||||
- All Formbricks instances have access to the same S3 bucket
|
||||
- The bucket has appropriate CORS settings configured
|
||||
- IAM roles/users have sufficient permissions for read/write operations
|
||||
|
||||
## Kubernetes Setup
|
||||
|
||||
Formbricks provides an official Helm chart for deploying the entire cluster stack on Kubernetes. The Helm chart is available in the [Formbricks GitHub repository](https://github.com/formbricks/formbricks/tree/main/helm-chart).
|
||||
|
||||
### Features of the Helm Chart
|
||||
|
||||
The Helm chart provides a complete deployment solution that includes:
|
||||
- Formbricks application with configurable replicas
|
||||
- PostgreSQL database (with optional HA configuration)
|
||||
- Redis cluster for caching
|
||||
- Optional Traefik ingress controller for routing and SSL termination
|
||||
- Automatic configuration of dependencies and networking
|
||||
|
||||
### Installation Steps
|
||||
|
||||
1. Add the Formbricks Helm repository:
|
||||
```sh
|
||||
helm repo add formbricks https://raw.githubusercontent.com/formbricks/formbricks/main/helm-chart
|
||||
helm repo update
|
||||
```
|
||||
|
||||
2. Install the chart:
|
||||
```sh
|
||||
helm install formbricks formbricks/formbricks
|
||||
```
|
||||
|
||||
### Configuration Options
|
||||
|
||||
The Helm chart can be customized using a `values.yaml` file to configure:
|
||||
- Number of Formbricks replicas
|
||||
- Resource limits and requests
|
||||
- Database configuration
|
||||
- Redis settings
|
||||
- Ingress rules and TLS
|
||||
- Environment variables and secrets
|
||||
|
||||
Refer to the [Helm chart documentation](https://github.com/formbricks/formbricks/tree/main/helm-chart) for detailed configuration options and examples.
|
||||
|
||||
@@ -34,6 +34,16 @@ enum WebhookSource {
|
||||
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?
|
||||
@@ -49,6 +59,13 @@ model Webhook {
|
||||
@@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")
|
||||
@@ -68,6 +85,15 @@ enum ContactAttributeType {
|
||||
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")
|
||||
@@ -86,6 +112,15 @@ model ContactAttributeKey {
|
||||
@@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 userId - Optional external user identifier
|
||||
/// @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())
|
||||
userId String?
|
||||
@@ -100,10 +135,21 @@ model Contact {
|
||||
@@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 @updatedAt @map(name: "updated_at")
|
||||
updatedAt DateTime @default(now()) @map(name: "updated_at")
|
||||
finished Boolean @default(false)
|
||||
survey Survey @relation(fields: [surveyId], references: [id], onDelete: Cascade)
|
||||
surveyId String
|
||||
@@ -135,6 +181,15 @@ model Response {
|
||||
@@index([surveyId])
|
||||
}
|
||||
|
||||
/// Represents notes or comments added to survey responses by team members.
|
||||
/// Used for internal communication and response analysis.
|
||||
///
|
||||
/// @property id - Unique identifier for the note
|
||||
/// @property response - The associated survey response
|
||||
/// @property user - The team member who created the note
|
||||
/// @property text - Content of the note
|
||||
/// @property isResolved - Whether the note has been marked as resolved
|
||||
/// @property isEdited - Whether the note has been modified
|
||||
model ResponseNote {
|
||||
id String @id @default(cuid())
|
||||
createdAt DateTime @default(now()) @map(name: "created_at")
|
||||
@@ -150,6 +205,13 @@ model ResponseNote {
|
||||
@@index([responseId])
|
||||
}
|
||||
|
||||
/// 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")
|
||||
@@ -163,6 +225,11 @@ model Tag {
|
||||
@@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)
|
||||
@@ -186,6 +253,14 @@ enum DisplayStatus {
|
||||
responded
|
||||
}
|
||||
|
||||
/// 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 status - Whether the survey was just seen or responded to
|
||||
/// @property response - The associated response if one exists
|
||||
model Display {
|
||||
id String @id @default(cuid())
|
||||
createdAt DateTime @default(now()) @map(name: "created_at")
|
||||
@@ -202,6 +277,16 @@ model Display {
|
||||
@@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")
|
||||
@@ -220,6 +305,14 @@ enum SurveyAttributeFilterCondition {
|
||||
notEquals
|
||||
}
|
||||
|
||||
/// 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")
|
||||
@@ -250,6 +343,18 @@ enum displayOptions {
|
||||
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")
|
||||
@@ -317,6 +422,14 @@ model Survey {
|
||||
@@index([segmentId])
|
||||
}
|
||||
|
||||
/// 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")
|
||||
@@ -335,6 +448,15 @@ enum ActionType {
|
||||
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")
|
||||
@@ -366,6 +488,13 @@ enum IntegrationType {
|
||||
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
|
||||
@@ -384,6 +513,14 @@ enum DataMigrationStatus {
|
||||
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")
|
||||
@@ -392,6 +529,18 @@ model DataMigration {
|
||||
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 widgetSetupCompleted - Tracks initial widget setup status
|
||||
/// @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")
|
||||
@@ -424,6 +573,17 @@ enum WidgetPlacement {
|
||||
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")
|
||||
@@ -453,6 +613,17 @@ model Project {
|
||||
@@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")
|
||||
@@ -484,6 +655,14 @@ enum MembershipRole {
|
||||
viewer
|
||||
}
|
||||
|
||||
/// 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
|
||||
@@ -498,6 +677,19 @@ model Membership {
|
||||
@@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
|
||||
@@ -518,6 +710,14 @@ model Invite {
|
||||
@@index([organizationId])
|
||||
}
|
||||
|
||||
/// Represents API authentication keys.
|
||||
/// Used for authenticating API requests to Formbricks.
|
||||
///
|
||||
/// @property id - Unique identifier for the API key
|
||||
/// @property label - Optional descriptive name for the key
|
||||
/// @property hashedKey - Securely stored API key
|
||||
/// @property environment - The environment this key belongs to
|
||||
/// @property lastUsedAt - Timestamp of last usage
|
||||
model ApiKey {
|
||||
id String @id @unique @default(cuid())
|
||||
createdAt DateTime @default(now())
|
||||
@@ -538,6 +738,15 @@ enum IdentityProvider {
|
||||
openid
|
||||
}
|
||||
|
||||
/// 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")
|
||||
@@ -585,6 +794,17 @@ enum Intention {
|
||||
other
|
||||
}
|
||||
|
||||
/// 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 role - User's professional role
|
||||
/// @property objective - User's main goal with Formbricks
|
||||
/// @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")
|
||||
@@ -618,6 +838,11 @@ model User {
|
||||
@@index([email])
|
||||
}
|
||||
|
||||
/// Maps a short URL to its full destination.
|
||||
/// Used for creating memorable, shortened URLs for surveys.
|
||||
///
|
||||
/// @property id - Short identifier/slug for the URL
|
||||
/// @property url - The full destination URL
|
||||
model ShortUrl {
|
||||
id String @id // generate nanoId in service
|
||||
createdAt DateTime @default(now()) @map(name: "created_at")
|
||||
@@ -625,6 +850,14 @@ model ShortUrl {
|
||||
url String @unique
|
||||
}
|
||||
|
||||
/// 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")
|
||||
@@ -642,6 +875,13 @@ model Segment {
|
||||
@@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")
|
||||
@@ -655,6 +895,13 @@ model Language {
|
||||
@@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
|
||||
@@ -675,6 +922,14 @@ enum InsightCategory {
|
||||
other
|
||||
}
|
||||
|
||||
/// Stores analyzed insights from survey responses.
|
||||
/// Used for tracking patterns and extracting meaningful information.
|
||||
///
|
||||
/// @property id - Unique identifier for the insight
|
||||
/// @property category - Type of insight (feature request, complaint, etc.)
|
||||
/// @property title - Summary of the insight
|
||||
/// @property description - Detailed explanation
|
||||
/// @property vector - Embedding vector for similarity search
|
||||
model Insight {
|
||||
id String @id @default(cuid())
|
||||
createdAt DateTime @default(now()) @map(name: "created_at")
|
||||
@@ -688,6 +943,11 @@ model Insight {
|
||||
documentInsights DocumentInsight[]
|
||||
}
|
||||
|
||||
/// Links insights to source documents.
|
||||
/// Enables tracing insights back to original responses.
|
||||
///
|
||||
/// @property document - The source document
|
||||
/// @property insight - The derived insight
|
||||
model DocumentInsight {
|
||||
documentId String
|
||||
document Document @relation(fields: [documentId], references: [id], onDelete: Cascade)
|
||||
@@ -704,6 +964,15 @@ enum Sentiment {
|
||||
neutral
|
||||
}
|
||||
|
||||
/// Represents a processed text document from survey responses.
|
||||
/// Used for analysis and insight generation.
|
||||
///
|
||||
/// @property id - Unique identifier for the document
|
||||
/// @property survey - The associated survey
|
||||
/// @property response - The source response
|
||||
/// @property sentiment - Analyzed sentiment (positive, negative, neutral)
|
||||
/// @property text - The document content
|
||||
/// @property vector - Embedding vector for similarity search
|
||||
model Document {
|
||||
id String @id @default(cuid())
|
||||
createdAt DateTime @default(now()) @map(name: "created_at")
|
||||
@@ -725,6 +994,14 @@ model Document {
|
||||
@@index([createdAt])
|
||||
}
|
||||
|
||||
/// 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")
|
||||
@@ -743,6 +1020,12 @@ enum TeamUserRole {
|
||||
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")
|
||||
@@ -762,6 +1045,12 @@ enum ProjectTeamPermission {
|
||||
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")
|
||||
|
||||
Reference in New Issue
Block a user