generator client {
  provider   = "prisma-client-js"
  engineType = "binary"
}

datasource db {
  provider = "postgresql"
  url      = env("PG_DATABASE_URL")
}

generator nestgraphql {
  provider           = "node node_modules/prisma-nestjs-graphql"
  output             = "../../src/core/@generated"
  noAtomicOperations = true

  // field validator
  fields_Validator_input  = true
  fields_Validator_output = true
  fields_Validator_model  = true
  fields_Validator_from   = "class-validator"

  // All relations, only allow connect
  decorate_all_type      = "!(ActivityTarget*Input|UserSettingsUpdateOneRequiredWithoutUserNestedInput)"
  decorate_all_field     = "*(create|connectOrCreate|update|upsert|delete|createMany|updateMany|deleteMany)"
  decorate_all_name      = "HideField"
  decorate_all_from      = "@nestjs/graphql"
  decorate_all_arguments = "[]"

  // Activity: Only Allow targets createOrConnect / createMany
  decorate_activityTargets_type      = "*ActivityTarget*Input"
  decorate_activityTargets_field     = "*(update|upsert|updateMany)"
  decorate_activityTargets_name      = "HideField"
  decorate_activityTargets_from      = "@nestjs/graphql"
  decorate_activityTargets_arguments = "[]"

  // User Settings: Only Allow targets createOrConnect / createMany
  decorate_userSettings_type      = "*UserSettingsUpdateOneRequiredWithoutUserNestedInput"
  decorate_userSettings_field     = "!(update)"
  decorate_userSettings_name      = "HideField"
  decorate_userSettings_from      = "@nestjs/graphql"
  decorate_userSettings_arguments = "[]"

  // Disable _count on all models except Aggregation use case
  decorate_count_type      = "!(*Aggregate*|*GroupBy*|*OrderBy*)"
  decorate_count_field     = "_count"
  decorate_count_name      = "HideField"
  decorate_count_from      = "@nestjs/graphql"
  decorate_count_arguments = "[]"

  // create data validator
  decorate_classValidator_type      = "@(Create|Update|Upsert)*Args"
  decorate_classValidator_field     = "@(data|[A-Z]*)"
  decorate_classValidator_name      = ValidateNested
  decorate_classValidator_from      = "class-validator"
  decorate_classValidator_arguments = "['{each: true}']"

  // create data transformer
  decorate_classTransformer_type      = "@(Create|Update|Upsert)*Args"
  decorate_classTransformer_field     = "@(data|[A-Z]*)"
  decorate_classTransformer_from      = "class-transformer"
  decorate_classTransformer_arguments = "['() => {propertyType.0}']"
  decorate_classTransformer_name      = Type
}

model User {
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  id             String    @id @default(uuid())
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  firstName      String?
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  lastName       String?
  /// @Validator.IsEmail()
  /// @Validator.IsOptional()
  email          String    @unique
  /// @Validator.IsBoolean()
  /// @Validator.IsOptional()
  emailVerified  Boolean   @default(false)
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  avatarUrl      String?
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  locale         String
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  phoneNumber    String?
  /// @Validator.IsDate()
  /// @Validator.IsOptional()
  lastSeen       DateTime?
  /// @Validator.IsBoolean()
  /// @Validator.IsOptional()
  disabled       Boolean   @default(false)
  /// @TypeGraphQL.omit(input: true, output: true)
  passwordHash   String?
  /// @Validator.IsJSON()
  /// @Validator.IsOptional()
  metadata       Json?
  /// @Validator.IsBoolean()
  /// @Validator.IsOptional()
  canImpersonate Boolean   @default(false)

  companies          Company[]
  /// @TypeGraphQL.omit(input: true, output: true)
  refreshTokens      RefreshToken[]
  comments           Comment[]
  defaultWorkspaceId String?

  authoredActivities  Activity[]   @relation(name: "authoredActivities")
  assignedActivities  Activity[]   @relation(name: "assignedActivities")
  authoredAttachments Attachment[] @relation(name: "authoredAttachments")

  /// @TypeGraphQL.omit(input: true, output: true)
  deletedAt DateTime?

  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@map("users")
}

enum ColorScheme {
  Light
  Dark
  System
}

model UserSettings {
  id          String      @id @default(uuid())
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  colorScheme ColorScheme @default(System)
  /// @Validator.IsString()
  locale      String

  WorkspaceMember WorkspaceMember[]

  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@map("user_settings")
}

/// @TypeGraphQL.omit(input: true)
model Workspace {
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  id          String  @id @default(uuid())
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  domainName  String?
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  displayName String?
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  logo        String?
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  inviteHash  String?

  workspaceMember    WorkspaceMember[]
  companies          Company[]
  people             Person[]
  activities         Activity[]
  comments           Comment[]
  pipelines          Pipeline[]
  pipelineStages     PipelineStage[]
  pipelineProgresses PipelineProgress[]
  activityTargets    ActivityTarget[]
  apiKeys            ApiKey[]
  webHooks           WebHook[]

  /// @TypeGraphQL.omit(input: true, output: true)
  deletedAt DateTime?

  createdAt  DateTime     @default(now())
  updatedAt  DateTime     @updatedAt
  Attachment Attachment[]

  @@map("workspaces")
}

model WorkspaceMember {
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  id                 String  @id @default(uuid())
  /// @Validator.IsBoolean()
  /// @Validator.IsOptional()
  allowImpersonation Boolean @default(true)

  userId      String    @unique
  /// @TypeGraphQL.omit(input: true, output: false)
  workspace   Workspace @relation(fields: [workspaceId], references: [id])
  /// @TypeGraphQL.omit(input: true, output: true)
  workspaceId String

  /// @TypeGraphQL.omit(input: true, output: true)
  deletedAt DateTime?

  createdAt DateTime   @default(now())
  updatedAt DateTime   @updatedAt
  Favorite  Favorite[]

  authoredActivities  Activity[]    @relation(name: "authoredActivities")
  assignedActivities  Activity[]    @relation(name: "assignedActivities")
  authoredAttachments Attachment[]  @relation(name: "authoredAttachments")
  settings            UserSettings? @relation(fields: [settingsId], references: [id])
  settingsId          String?

  companies Company[]
  comments  Comment[]

  @@map("workspace_members")
}

model Company {
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  id                     String  @id @default(uuid())
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  name                   String
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  domainName             String
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  linkedinUrl            String?
  /// @Validator.IsNumber()
  /// @Validator.IsOptional()
  annualRecurringRevenue Int?
  /// @Validator.IsBoolean()
  /// @Validator.IsOptional()
  idealCustomerProfile   Boolean @default(false)
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  xUrl                   String?
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  address                String
  /// @Validator.IsNumber()
  /// @Validator.IsOptional()
  employees              Int?

  people                        Person[]
  accountOwner                  User?            @relation(fields: [accountOwnerId], references: [id], onDelete: SetNull)
  accountOwnerId                String?
  workspaceMemberAccountOwner   WorkspaceMember? @relation(fields: [workspaceMemberAccountOwnerId], references: [id], onDelete: SetNull)
  workspaceMemberAccountOwnerId String?
  /// @TypeGraphQL.omit(input: true, output: true)
  workspace                     Workspace        @relation(fields: [workspaceId], references: [id])
  /// @TypeGraphQL.omit(input: true, output: true)
  workspaceId                   String

  /// @TypeGraphQL.omit(input: true, output: true)
  deletedAt DateTime?

  createdAt        DateTime           @default(now())
  updatedAt        DateTime           @updatedAt
  ActivityTarget   ActivityTarget[]
  PipelineProgress PipelineProgress[]
  Favorite         Favorite[]
  Attachment       Attachment[]

  @@map("companies")
}

model Person {
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  id          String  @id @default(uuid())
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  firstName   String?
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  lastName    String?
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  email       String?
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  linkedinUrl String?
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  xUrl        String?
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  jobTitle    String?
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  phone       String?
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  city        String?
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  avatarUrl   String?

  company                   Company?           @relation(fields: [companyId], references: [id], onDelete: SetNull)
  companyId                 String?
  /// @TypeGraphQL.omit(input: true, output: true)
  workspace                 Workspace          @relation(fields: [workspaceId], references: [id])
  /// @TypeGraphQL.omit(input: true, output: true)
  workspaceId               String
  contactPipelineProgresses PipelineProgress[] @relation("PointOfContactPipelineProgress")

  /// @TypeGraphQL.omit(input: true, output: true)
  deletedAt DateTime?

  createdAt        DateTime           @default(now())
  updatedAt        DateTime           @updatedAt
  ActivityTarget   ActivityTarget[]
  PipelineProgress PipelineProgress[]
  Favorite         Favorite[]
  Attachment       Attachment[]

  @@map("people")
}

model RefreshToken {
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  id String @id @default(uuid())

  /// @TypeGraphQL.omit(input: true, output: true)
  user   User   @relation(fields: [userId], references: [id])
  /// @TypeGraphQL.omit(input: true, output: true)
  userId String

  expiresAt DateTime
  /// @TypeGraphQL.omit(input: true, output: true)
  deletedAt DateTime?
  /// @TypeGraphQL.omit(input: true, output: true)
  revokedAt DateTime?

  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@map("refresh_tokens")
}

enum ActivityType {
  Note
  Task
}

model Activity {
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  id          String       @id @default(uuid())
  body        String?
  title       String?
  type        ActivityType @default(Note)
  reminderAt  DateTime?
  dueAt       DateTime?
  completedAt DateTime?

  activityTargets ActivityTarget[]
  comments        Comment[]
  attachments     Attachment[]
  author          User             @relation(fields: [authorId], references: [id], name: "authoredActivities", onDelete: Cascade)
  authorId        String

  workspaceMemberAuthor   WorkspaceMember? @relation(fields: [workspaceMemberAuthorId], references: [id], name: "authoredActivities", onDelete: Cascade)
  workspaceMemberAuthorId String?

  assignee   User?   @relation(fields: [assigneeId], references: [id], name: "assignedActivities", onDelete: SetNull)
  assigneeId String?

  workspaceMemberAssignee   WorkspaceMember? @relation(fields: [workspaceMemberAssigneeId], references: [id], name: "assignedActivities", onDelete: SetNull)
  workspaceMemberAssigneeId String?

  /// @TypeGraphQL.omit(input: true, output: true)
  workspace   Workspace @relation(fields: [workspaceId], references: [id])
  /// @TypeGraphQL.omit(input: true, output: true)
  workspaceId String

  /// @TypeGraphQL.omit(input: true, output: true)
  deletedAt DateTime?

  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@map("activities")
}

model Comment {
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  id   String @id @default(uuid())
  /// @Validator.IsString()
  body String

  author   User   @relation(fields: [authorId], references: [id], onDelete: Cascade)
  authorId String

  workspaceMemberAuthor   WorkspaceMember? @relation(fields: [workspaceMemberAuthorId], references: [id], onDelete: Cascade)
  workspaceMemberAuthorId String?

  activity        Activity? @relation(fields: [activityId], references: [id], onDelete: Cascade)
  activityId      String?
  commentThreadId String?
  /// @TypeGraphQL.omit(input: true, output: true)
  workspace       Workspace @relation(fields: [workspaceId], references: [id])
  /// @TypeGraphQL.omit(input: true, output: true)
  workspaceId     String

  /// @TypeGraphQL.omit(input: true, output: true)
  deletedAt DateTime?

  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@map("comments")
}

model ActivityTarget {
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  id String @id @default(uuid())

  activity    Activity  @relation(fields: [activityId], references: [id], onDelete: Cascade)
  activityId  String
  /// @TypeGraphQL.omit(input: true, output: true)
  workspace   Workspace @relation(fields: [workspaceId], references: [id])
  /// @TypeGraphQL.omit(input: true, output: true)
  workspaceId String

  personId String?
  person   Person? @relation(fields: [personId], references: [id], onDelete: Cascade)

  companyId String?
  company   Company? @relation(fields: [companyId], references: [id], onDelete: Cascade)

  /// @TypeGraphQL.omit(input: true, output: true)
  deletedAt DateTime?

  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@map("activity_targets")
}

// All of the world's currently active currencies based on the ISO 4217 standard
enum CurrencyCode {
  AED
  AFN
  ALL
  AMD
  ANG
  AOA
  ARS
  AUD
  AWG
  AZN
  BAM
  BBD
  BDT
  BGN
  BHD
  BIF
  BMD
  BND
  BOB
  BOV
  BRL
  BSD
  BTN
  BWP
  BYN
  BZD
  CAD
  CDF
  CHF
  CLF
  CLP
  CNY
  COP
  COU
  CRC
  CUC
  CUP
  CVE
  CZK
  DJF
  DKK
  DOP
  DZD
  EGP
  ERN
  ETB
  EUR
  FJD
  FKP
  GBP
  GEL
  GHS
  GIP
  GMD
  GNF
  GTQ
  GYD
  HKD
  HNL
  HRK
  HTG
  HUF
  IDR
  ILS
  INR
  IQD
  IRR
  ISK
  JMD
  JOD
  JPY
  KES
  KGS
  KHR
  KMF
  KPW
  KRW
  KWD
  KYD
  KZT
  LAK
  LBP
  LKR
  LRD
  LSL
  LYD
  MAD
  MDL
  MGA
  MKD
  MMK
  MNT
  MOP
  MRO
  MRU
  MUR
  MVR
  MWK
  MXN
  MXV
  MYR
  MZN
  NAD
  NGN
  NIO
  NOK
  NPR
  NZD
  OMR
  PAB
  PEN
  PGK
  PHP
  PKR
  PLN
  PYG
  QAR
  RON
  RSD
  RUB
  RWF
  SAR
  SBD
  SCR
  SDD
  SDG
  SEK
  SGD
  SHP
  SLL
  SOS
  SRD
  SSP
  STD
  STN
  SVC
  SYP
  SZL
  THB
  TJS
  TMM
  TMT
  TND
  TOP
  TRY
  TTD
  TWD
  TZS
  UAH
  UGX
  USD
  UYU
  UZS
  VEF
  VES
  VND
  VUV
  WST
  XAF
  XCD
  XOF
  XPF
  XSU
  XUA
  YER
  ZAR
  ZMW
  ZWL

  @@map("CurrencyCode")
}

model Pipeline {
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  id   String @id @default(uuid())
  /// @Validator.IsString()
  name String
  /// @Validator.IsString()
  icon String

  pipelineStages           PipelineStage[]
  pipelineProgresses       PipelineProgress[]
  pipelineProgressableType PipelineProgressableType @default(Company)
  /// @TypeGraphQL.omit(input: true, output: true)
  workspace                Workspace                @relation(fields: [workspaceId], references: [id])
  /// @TypeGraphQL.omit(input: true, output: true)
  workspaceId              String

  /// @TypeGraphQL.omit(input: true, output: true)
  deletedAt DateTime?

  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  currency CurrencyCode @default(USD)

  @@map("pipelines")
}

model PipelineStage {
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  id       String @id @default(uuid())
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  name     String
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  type     String
  /// @Validator.IsOptional()
  /// @Validator.IsString()
  color    String
  /// @Validator.IsNumber()
  /// @Validator.IsOptional()
  position Int?

  pipelineProgresses PipelineProgress[]
  /// 
  pipeline           Pipeline           @relation(fields: [pipelineId], references: [id], onDelete: Cascade)
  pipelineId         String
  /// @TypeGraphQL.omit(input: true, output: true)
  workspace          Workspace          @relation(fields: [workspaceId], references: [id])
  /// @TypeGraphQL.omit(input: true, output: true)
  workspaceId        String

  /// @TypeGraphQL.omit(input: true, output: true)
  deletedAt DateTime?

  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@map("pipeline_stages")
}

enum PipelineProgressableType {
  Person
  Company
}

model PipelineProgress {
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  id          String    @id @default(uuid())
  amount      Int?
  closeDate   DateTime?
  probability Int?

  pipeline         Pipeline      @relation(fields: [pipelineId], references: [id], onDelete: Cascade)
  pipelineId       String
  pipelineStage    PipelineStage @relation(fields: [pipelineStageId], references: [id], onDelete: Cascade)
  pipelineStageId  String
  pointOfContact   Person?       @relation("PointOfContactPipelineProgress", fields: [pointOfContactId], references: [id], onDelete: SetNull)
  pointOfContactId String?

  /// @TypeGraphQL.omit(input: true, output: true)
  workspace   Workspace @relation(fields: [workspaceId], references: [id])
  /// @TypeGraphQL.omit(input: true, output: true)
  workspaceId String

  /// @TypeGraphQL.omit(input: true, output: true)
  deletedAt DateTime?

  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  companyId String?
  company   Company? @relation(fields: [companyId], references: [id], onDelete: Cascade)

  personId String?
  person   Person? @relation(fields: [personId], references: [id], onDelete: Cascade)

  @@map("pipeline_progresses")
}

enum AttachmentType {
  Image
  Audio
  Video
  TextDocument
  Spreadsheet
  Archive
  Other
}

model Attachment {
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  id String @id @default(uuid())

  fullPath String
  type     AttachmentType
  name     String

  /// @TypeGraphQL.omit(input: true, output: true)
  workspaceId String

  author   User   @relation(fields: [authorId], references: [id], name: "authoredAttachments", onDelete: Cascade)
  authorId String

  workspaceMemberAuthor   WorkspaceMember? @relation(fields: [workspaceMemberAuthorId], references: [id], name: "authoredAttachments", onDelete: Cascade)
  workspaceMemberAuthorId String?

  activity   Activity? @relation(fields: [activityId], references: [id], onDelete: Cascade)
  activityId String?

  /// @TypeGraphQL.omit(input: true, output: false)
  person    Person?  @relation(fields: [personId], references: [id], onDelete: Cascade)
  personId  String?
  /// @TypeGraphQL.omit(input: true, output: false)
  company   Company? @relation(fields: [companyId], references: [id], onDelete: Cascade)
  companyId String?

  /// @TypeGraphQL.omit(input: true, output: false)
  workspace Workspace @relation(fields: [workspaceId], references: [id])
  /// @TypeGraphQL.omit(input: true, output: true)
  deletedAt DateTime?
  createdAt DateTime  @default(now())
  updatedAt DateTime  @updatedAt

  @@map("attachments")
}

model Favorite {
  id                String           @id @default(uuid())
  workspaceId       String?
  /// @TypeGraphQL.omit(input: true, output: false)
  person            Person?          @relation(fields: [personId], references: [id], onDelete: Cascade)
  personId          String?
  /// @TypeGraphQL.omit(input: true, output: false)
  company           Company?         @relation(fields: [companyId], references: [id], onDelete: Cascade)
  companyId         String?
  /// @TypeGraphQL.omit(input: true, output: false)
  workspaceMember   WorkspaceMember? @relation(fields: [workspaceMemberId], references: [id])
  workspaceMemberId String?
  position          Float

  @@map("favorites")
}

enum ViewType {
  Table
  Pipeline
}

model ApiKey {
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  id          String    @id @default(uuid())
  name        String
  /// @TypeGraphQL.omit(input: true, output: true)
  workspace   Workspace @relation(fields: [workspaceId], references: [id])
  /// @TypeGraphQL.omit(input: true, output: true)
  workspaceId String
  expiresAt   DateTime?
  createdAt   DateTime  @default(now())
  updatedAt   DateTime  @updatedAt
  /// @TypeGraphQL.omit(input: true, output: true)
  deletedAt   DateTime?
  /// @TypeGraphQL.omit(input: true, output: true)
  revokedAt   DateTime?

  @@map("api_keys")
}

model WebHook {
  /// @Validator.IsString()
  /// @Validator.IsOptional()
  id          String    @id @default(uuid())
  /// @TypeGraphQL.omit(input: true, output: true)
  workspace   Workspace @relation(fields: [workspaceId], references: [id])
  /// @TypeGraphQL.omit(input: true, output: true)
  workspaceId String
  targetUrl   String
  operation   String
  createdAt   DateTime  @default(now())
  updatedAt   DateTime  @updatedAt
  /// @TypeGraphQL.omit(input: true, output: true)
  deletedAt   DateTime?

  @@map("web_hooks")
}
