Files
optima/api/prisma/schema.prisma
T

542 lines
12 KiB
Plaintext

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
datasource db {
provider = "postgresql"
}
enum PhoneType {
DIRECT
MOBILE
HOME
COMPANY // Main company line, not direct to contact
SITE // Main site line, not direct to contact
}
enum FaxType {
FAX // Direct fax line to contact
COMPANY // Main company fax line, not direct to contact
SITE // Main site fax line, not direct to contact
}
// By human nature, there are only two genders.
enum GenderType {
MALE
FEMALE
}
enum USState {
AL
AK
AZ
AR
CA
CO
CT
DE
FL
GA
HI
ID
IL
IN
IA
KS
KY
LA
ME
MD
MA
MI
MN
MS
MO
MT
NE
NV
NH
NJ
NM
NY
NC
ND
OH
OK
OR
PA
RI
SC
SD
TN
TX
UT
VT
VA
WA
WV
WI
WY
}
enum Country {
US
}
enum OpportunityInterest {
HOT
WARM
COLD
}
model Session {
id String @id @default(uuid())
sessionKey String @unique @default(cuid())
userId String
expires DateTime
refreshTokenGenerated Boolean @default(false)
refreshedAt DateTime?
invalidatedAt DateTime?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model User {
id String @id @default(cuid())
roles Role[]
permissions String?
login String @unique
name String?
email String @unique
emailVerified DateTime?
image String?
active Boolean @default(true)
hidden Boolean @default(false)
cwIdentifier String? @unique
userId String @unique
token String?
sessions Session[]
companiesDeleted Company[] @relation("DeletedBy")
companiesEntered Company[] @relation("EnteredBy")
opportunities Opportunity[] @relation("PrimarySalesRep")
opportunitiesSecondary Opportunity[] @relation("SecondarySalesRep")
generatedQuotes GeneratedQuotes[]
companyAddresses CompanyAddress[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Role {
id String @id @default(uuid())
title String
moniker String @unique // e.g. admin, super_admin, moderator
permissions String
users User[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model CorporateLocation {
id Int @unique
uid String @id @default(uuid())
name String
description String?
updatedById String?
addressLine1 String?
addressLine2 String?
city String?
state USState?
zipCode String?
country Country?
inactiveFlag Boolean @default(false) // Optima Only field, not synced to CW
opportunities Opportunity[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model InternalDepartment {
id Int @unique
uid String @id @default(uuid())
name String
description String? // Optima Only field, not synced to CW
createdById String?
updatedById String?
opportunities Opportunity[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model UnifiSite {
id String @id @default(cuid())
name String
siteId String @unique
companyId Int?
company Company? @relation(fields: [companyId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Company {
id Int @unique
uid String @id @default(uuid())
name String
phone String?
website String?
deleteFlag Boolean @default(false)
dateDeleted DateTime?
taxId String?
taxExempt Boolean @default(false) // Optima Only field, not synced to CW
enteredById String?
deletedById String?
contacts Contact[]
companyAddresses CompanyAddress[]
credentials Credential[]
unifiSites UnifiSite[]
opportunities Opportunity[]
deletedBy User? @relation("DeletedBy", fields: [deletedById], references: [cwIdentifier])
enteredBy User? @relation("EnteredBy", fields: [enteredById], references: [cwIdentifier])
enteredAt DateTime @default(now())
deletedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model CompanyAddress {
id Int @unique
uid String @id @default(uuid())
name String
description String?
addressLine1 String?
addressLine2 String?
city String?
state USState?
zipCode String?
country Country?
phone String?
fax String?
inactiveFlag Boolean @default(false)
defaultFlag Boolean @default(false)
defaultMailFlag Boolean @default(false)
defaultBillFlag Boolean @default(false)
defaultShipFlag Boolean @default(false)
updatedById String?
updatedBy User? @relation(fields: [updatedById], references: [cwIdentifier])
companyId Int
company Company @relation(fields: [companyId], references: [id])
contacts Contact[]
oppportunities Opportunity[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Contact {
id Int @unique
uid String @id @default(uuid())
active Boolean @default(true)
default Boolean @default(false)
firstName String
lastName String
nickname String?
title String?
gender GenderType?
birthday DateTime?
email String?
phone String?
phoneExtension String?
phoneType PhoneType?
companyAddressId Int?
companyAddress CompanyAddress? @relation(fields: [companyAddressId], references: [id])
memberId Int?
companyId Int?
company Company? @relation(fields: [companyId], references: [id])
opportunities Opportunity[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model CatalogItem {
id String @id @default(cuid())
cwCatalogId Int @unique
identifier String? @unique
name String
description String?
customerDescription String?
internalNotes String?
linkedItems CatalogItem[] @relation("LinkedItems")
linkedTo CatalogItem[] @relation("LinkedItems")
category String?
categoryCwId Int?
subcategory String?
subcategoryCwId Int?
manufacturer String?
manufactureCwId Int?
partNumber String?
vendorName String?
vendorSku String?
vendorCwId Int?
price Float
cost Float
inactive Boolean @default(false)
salesTaxable Boolean @default(true)
onHand Int @default(0)
cwLastUpdated DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model OpportunityType {
id Int @unique
uid String @id @default(uuid())
name String
description String? // Optima Only field, not synced to CW
inactiveFlag Boolean @default(false)
opportunities Opportunity[]
updatedById String?
createdById String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model OpportunityStatus {
id Int @unique
uid String @id @default(uuid())
name String
description String? // Optima Only field, not synced to CW
inactiveFlag Boolean @default(false)
defaultFlag Boolean @default(false)
wonFlag Boolean @default(false)
lostFlag Boolean @default(false)
closeFlag Boolean @default(false)
updatedById String?
createdById String?
opportunities Opportunity[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Opportunity {
id Int @unique
uid String @id @default(uuid())
name String
notes String?
generatedQuotes GeneratedQuotes[]
typeId Int
type OpportunityType @relation(fields: [typeId], references: [id])
stageName String?
stageCwId Int?
statusId Int?
status OpportunityStatus? @relation(fields: [statusId], references: [id])
interest OpportunityInterest?
probability Float @default(0)
source String?
// Sales rep references
primarySalesRepId String?
primarySalesRep User? @relation("PrimarySalesRep", fields: [primarySalesRepId], references: [cwIdentifier])
secondarySalesRepId String?
secondarySalesRep User? @relation("SecondarySalesRep", fields: [secondarySalesRepId], references: [cwIdentifier])
// Company / contact / site
companyId Int?
company Company? @relation(fields: [companyId], references: [id])
contactId Int?
contact Contact? @relation(fields: [contactId], references: [id])
siteId Int?
site CompanyAddress? @relation(fields: [siteId], references: [id])
customerPO String?
// Location / department
locationId Int?
location CorporateLocation? @relation(fields: [locationId], references: [id])
departmentId Int?
department InternalDepartment? @relation(fields: [departmentId], references: [id])
// Dates
expectedCloseDate DateTime?
pipelineChangeDate DateTime?
dateBecameLead DateTime?
closedDate DateTime?
closedFlag Boolean @default(false)
closedById String?
// Local product sequence — array of CW forecast item IDs in display order.
// When present, fetchProducts() uses this order instead of CW sequenceNumber.
productSequence Int[] @default([])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model CredentialType {
id String @id @default(cuid())
name String @unique
permissionScope String
icon String?
fields Json
credentials Credential[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model SecureValue {
id String @id @default(cuid())
name String
content String // Encrypted content
hash String // Hash of the original content for integrity verification and Search
credentialId String
credential Credential @relation(fields: [credentialId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Credential {
id String @id @default(cuid())
name String
notes String?
subCredentialOfId String?
subCredentialOf Credential? @relation("SubCredentials", fields: [subCredentialOfId], references: [id], onDelete: Cascade)
subCredentials Credential[] @relation("SubCredentials")
typeId String
type CredentialType @relation(fields: [typeId], references: [id], onDelete: Cascade)
fields Json
companyId String
company Company @relation(fields: [companyId], references: [uid], onDelete: Cascade)
securevalues SecureValue[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model GeneratedQuotes {
id String @id @default(uuid())
quoteRegenData Json @default("{}") // Store any additional data needed for quote regeneration, such as product details, pricing, etc.
quoteRegenParams Json @default("{}") // Store parameters used for quote regeneration, such as template ID, formatting options, etc.
quoteRegenHash String @unique @default("")
downloads Json @default("[]") // Array of download records with timestamp and user info
quoteFile Bytes
quoteFileName String
opportunityId String
opportunity Opportunity @relation(fields: [opportunityId], references: [uid], onDelete: Cascade)
createdById String?
createdBy User? @relation(fields: [createdById], references: [id], onDelete: SetNull)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model CwMember {
id String @id @default(cuid())
cwMemberId Int @unique
identifier String @unique
firstName String
lastName String
officeEmail String?
inactiveFlag Boolean @default(false)
apiKey String?
cwLastUpdated DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}