// 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")
}

generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["filteredRelationCount", "extendedWhereUnique"]
  //provider = "prisma-dbml-generator"
}

generator json {
  provider = "prisma-json-types-generator"
  // namespace = "PrismaJson"
  // clientOutput = "<finds it automatically>"
  // (./ -> relative to schema, or an importable path to require() it)
  // useType = "MyType"
  // In case you need to use a type, export it inside the namespace and we will add a index signature to it
  // (e.g.  export namespace PrismaJson { export type MyType = {a: 1, b: 2} }; will generate namespace.MyType["TYPE HERE"])
}

enum PipelineTriggers {
  responseCreated
  responseUpdated
  responseFinished
}

model Webhook {
  id            String             @id @default(cuid())
  createdAt     DateTime           @default(now()) @map(name: "created_at")
  updatedAt     DateTime           @updatedAt @map(name: "updated_at")
  url           String
  environment   Environment        @relation(fields: [environmentId], references: [id], onDelete: Cascade)
  environmentId String
  triggers      PipelineTriggers[]
}

model Attribute {
  id               String         @id @default(cuid())
  createdAt        DateTime       @default(now()) @map(name: "created_at")
  updatedAt        DateTime       @updatedAt @map(name: "updated_at")
  attributeClass   AttributeClass @relation(fields: [attributeClassId], references: [id], onDelete: Cascade)
  attributeClassId String
  person           Person         @relation(fields: [personId], references: [id], onDelete: Cascade)
  personId         String
  value            String

  @@unique([attributeClassId, personId])
}

enum AttributeType {
  code
  noCode
  automatic
}

model AttributeClass {
  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             AttributeType
  environment      Environment             @relation(fields: [environmentId], references: [id], onDelete: Cascade)
  environmentId    String
  attributes       Attribute[]
  attributeFilters SurveyAttributeFilter[]

  @@unique([name, environmentId])
}

model Person {
  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[]
  sessions      Session[]
  attributes    Attribute[]
  displays      Display[]
}

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?
  /// [ResponseData]
  data      Json     @default("{}")
  /// [ResponseMeta]
  meta      Json     @default("{}")
}

enum SurveyStatus {
  draft
  inProgress
  paused
  completed
  archived
}

enum DisplayStatus {
  seen
  responded
}

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
  person    Person?       @relation(fields: [personId], references: [id], onDelete: Cascade)
  personId  String?
  status    DisplayStatus @default(seen)
}

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
  eventClass   EventClass @relation(fields: [eventClassId], references: [id], onDelete: Cascade)
  eventClassId String

  @@unique([surveyId, eventClassId])
}

enum SurveyAttributeFilterCondition {
  equals
  notEquals
}

model SurveyAttributeFilter {
  id               String                         @id @default(cuid())
  createdAt        DateTime                       @default(now()) @map(name: "created_at")
  updatedAt        DateTime                       @updatedAt @map(name: "updated_at")
  attributeClass   AttributeClass                 @relation(fields: [attributeClassId], references: [id], onDelete: Cascade)
  attributeClassId String
  survey           Survey                         @relation(fields: [surveyId], references: [id], onDelete: Cascade)
  surveyId         String
  condition        SurveyAttributeFilterCondition
  value            String

  @@unique([surveyId, attributeClassId])
}

enum SurveyType {
  email
  link
  mobile
  web
}

enum displayOptions {
  displayOnce
  displayMultiple
  respondMultiple
}

model Survey {
  id               String                  @id @default(cuid())
  createdAt        DateTime                @default(now()) @map(name: "created_at")
  updatedAt        DateTime                @updatedAt @map(name: "updated_at")
  name             String
  type             SurveyType              @default(web)
  environment      Environment             @relation(fields: [environmentId], references: [id], onDelete: Cascade)
  environmentId    String
  status           SurveyStatus            @default(draft)
  /// [SurveyQuestions]
  questions        Json                    @default("[]")
  /// [SurveyThankYouCard]
  thankYouCard     Json                    @default("{\"enabled\": false}")
  responses        Response[]
  displayOption    displayOptions          @default(displayOnce)
  recontactDays    Int?
  triggers         SurveyTrigger[]
  attributeFilters SurveyAttributeFilter[]
  displays         Display[]
  autoClose        Int?
  delay            Int                     @default(0)
}

model Event {
  id           String      @id @default(cuid())
  createdAt    DateTime    @default(now()) @map(name: "created_at")
  eventClass   EventClass? @relation(fields: [eventClassId], references: [id])
  eventClassId String?
  session      Session     @relation(fields: [sessionId], references: [id], onDelete: Cascade)
  sessionId    String
  /// [EventProperties]
  properties   Json        @default("{}")
}

enum EventType {
  code
  noCode
  automatic
}

model EventClass {
  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          EventType
  events        Event[]
  /// [EventClassNoCodeConfig]
  noCodeConfig  Json?
  environment   Environment     @relation(fields: [environmentId], references: [id], onDelete: Cascade)
  environmentId String
  surveys       SurveyTrigger[]

  @@unique([name, environmentId])
}

model Session {
  id        String   @id @default(cuid())
  createdAt DateTime @default(now()) @map(name: "created_at")
  updatedAt DateTime @updatedAt @map(name: "updated_at")
  person    Person   @relation(fields: [personId], references: [id], onDelete: Cascade)
  personId  String
  events    Event[]
}

enum EnvironmentType {
  production
  development
}

model Environment {
  id                   String           @id @default(cuid())
  createdAt            DateTime         @default(now()) @map(name: "created_at")
  updatedAt            DateTime         @updatedAt @map(name: "updated_at")
  type                 EnvironmentType
  product              Product          @relation(fields: [productId], references: [id], onDelete: Cascade)
  productId            String
  widgetSetupCompleted Boolean          @default(false)
  surveys              Survey[]
  people               Person[]
  eventClasses         EventClass[]
  attributeClasses     AttributeClass[]
  apiKeys              ApiKey[]
  webhooks             Webhook[]
}

model Product {
  id                  String        @id @default(cuid())
  createdAt           DateTime      @default(now()) @map(name: "created_at")
  updatedAt           DateTime      @updatedAt @map(name: "updated_at")
  name                String
  team                Team          @relation(fields: [teamId], references: [id], onDelete: Cascade)
  teamId              String
  environments        Environment[]
  brandColor          String        @default("#64748b")
  recontactDays       Int           @default(7)
  formbricksSignature Boolean       @default(true)
}

enum Plan {
  free
  pro
}

model Team {
  id               String       @id @default(cuid())
  createdAt        DateTime     @default(now()) @map(name: "created_at")
  updatedAt        DateTime     @updatedAt @map(name: "updated_at")
  name             String
  memberships      Membership[]
  products         Product[]
  plan             Plan         @default(free)
  stripeCustomerId String?
  invites          Invite[]
}

enum MembershipRole {
  owner
  admin
  editor
  developer
  viewer
}

model Membership {
  team     Team           @relation(fields: [teamId], references: [id], onDelete: Cascade)
  teamId   String
  user     User           @relation(fields: [userId], references: [id], onDelete: Cascade)
  userId   String
  accepted Boolean        @default(false)
  role     MembershipRole

  @@id([userId, teamId])
}

model Invite {
  id         String         @id @default(uuid())
  email      String
  name       String?
  team       Team           @relation(fields: [teamId], references: [id], onDelete: Cascade)
  teamId     String
  creator    User           @relation("inviteCreatedBy", fields: [creatorId], references: [id])
  creatorId  String
  acceptor   User?          @relation("inviteAcceptedBy", fields: [acceptorId], references: [id], onDelete: Cascade)
  acceptorId String?
  accepted   Boolean        @default(false)
  createdAt  DateTime       @default(now())
  expiresAt  DateTime
  role       MembershipRole @default(admin)

  @@index([email, teamId], name: "email_teamId_unique")
}

model ApiKey {
  id            String      @id @unique @default(cuid())
  createdAt     DateTime    @default(now())
  lastUsedAt    DateTime?
  label         String?
  hashedKey     String      @unique()
  environment   Environment @relation(fields: [environmentId], references: [id], onDelete: Cascade)
  environmentId String
}

enum IdentityProvider {
  email
  github
  google
}

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?
  token_type        String?
  scope             String?
  id_token          String?  @db.Text
  session_state     String?

  @@unique([provider, providerAccountId])
}

enum Role {
  project_manager
  engineer
  founder
  marketing_specialist
  other
}

enum Objective {
  increase_conversion
  improve_user_retention
  increase_user_adoption
  sharpen_marketing_messaging
  support_sales
  other
}

enum Intention {
  survey_user_segments
  survey_at_specific_point_in_user_journey
  enrich_customer_profiles
  collect_all_user_feedback_on_one_platform
  other
}

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")
  password                  String?
  onboardingCompleted       Boolean          @default(false)
  identityProvider          IdentityProvider @default(email)
  identityProviderAccountId String?
  memberships               Membership[]
  accounts                  Account[]
  groupId                   String?
  invitesCreated            Invite[]         @relation("inviteCreatedBy")
  invitesAccepted           Invite[]         @relation("inviteAcceptedBy")
  role                      Role?
  objective                 Objective?
  /// [UserNotificationSettings]
  notificationSettings      Json             @default("{}")
}
