Files
mrp/server/prisma/schema.prisma
2026-03-15 22:17:58 -05:00

822 lines
29 KiB
Plaintext

generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "debian-openssl-3.0.x"]
}
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
model User {
id String @id @default(cuid())
email String @unique
passwordHash String
firstName String
lastName String
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
userRoles UserRole[]
authSessions AuthSession[] @relation("AuthSessionUser")
revokedAuthSessions AuthSession[] @relation("AuthSessionRevokedBy")
contactEntries CrmContactEntry[]
inventoryTransactions InventoryTransaction[]
purchaseReceipts PurchaseReceipt[]
ownedProjects Project[] @relation("ProjectOwner")
workOrderMaterialIssues WorkOrderMaterialIssue[]
workOrderCompletions WorkOrderCompletion[]
approvedSalesQuotes SalesQuote[] @relation("SalesQuoteApprovedBy")
approvedSalesOrders SalesOrder[] @relation("SalesOrderApprovedBy")
salesQuoteRevisionsCreated SalesQuoteRevision[] @relation("SalesQuoteRevisionCreatedBy")
salesOrderRevisionsCreated SalesOrderRevision[] @relation("SalesOrderRevisionCreatedBy")
purchaseOrderRevisionsCreated PurchaseOrderRevision[]
inventoryTransfersCreated InventoryTransfer[] @relation("InventoryTransferCreatedBy")
auditEvents AuditEvent[]
}
model Role {
id String @id @default(cuid())
name String @unique
description String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
userRoles UserRole[]
rolePermissions RolePermission[]
}
model Permission {
id String @id @default(cuid())
key String @unique
description String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
rolePermissions RolePermission[]
}
model UserRole {
userId String
roleId String
assignedAt DateTime @default(now())
assignedBy String?
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@id([userId, roleId])
}
model RolePermission {
roleId String
permissionId String
grantedAt DateTime @default(now())
permission Permission @relation(fields: [permissionId], references: [id], onDelete: Cascade)
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
@@id([roleId, permissionId])
}
model AuthSession {
id String @id @default(cuid())
userId String
expiresAt DateTime
lastSeenAt DateTime @default(now())
ipAddress String?
userAgent String?
revokedAt DateTime?
revokedById String?
revokedReason String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation("AuthSessionUser", fields: [userId], references: [id], onDelete: Cascade)
revokedBy User? @relation("AuthSessionRevokedBy", fields: [revokedById], references: [id], onDelete: SetNull)
@@index([userId, createdAt])
@@index([expiresAt])
@@index([revokedAt])
}
model CompanyProfile {
id String @id @default(cuid())
companyName String
legalName String
email String
phone String
website String
taxId String
addressLine1 String
addressLine2 String
city String
state String
postalCode String
country String
primaryColor String @default("#185ADB")
accentColor String @default("#00A6A6")
surfaceColor String @default("#F4F7FB")
fontFamily String @default("Manrope")
logoFileId String? @unique
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
logoFile FileAttachment? @relation("CompanyLogo", fields: [logoFileId], references: [id], onDelete: SetNull)
}
model FileAttachment {
id String @id @default(cuid())
originalName String
storedName String
mimeType String
sizeBytes Int
relativePath String
ownerType String
ownerId String
createdById String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
companyLogoFor CompanyProfile? @relation("CompanyLogo")
}
model InventoryItem {
id String @id @default(cuid())
sku String @unique
skuFamilyId String?
skuNodeId String?
skuSequenceNumber Int?
name String
description String
type String
status String
unitOfMeasure String
isSellable Boolean @default(true)
isPurchasable Boolean @default(true)
preferredVendorId String?
defaultCost Float?
defaultPrice Float?
notes String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
bomLines InventoryBomLine[] @relation("InventoryBomParent")
usedInBomLines InventoryBomLine[] @relation("InventoryBomComponent")
inventoryTransactions InventoryTransaction[]
salesQuoteLines SalesQuoteLine[]
salesOrderLines SalesOrderLine[]
purchaseOrderLines PurchaseOrderLine[]
workOrders WorkOrder[]
workOrderMaterialIssues WorkOrderMaterialIssue[]
operations InventoryItemOperation[]
reservations InventoryReservation[]
transfers InventoryTransfer[]
preferredVendor Vendor? @relation(fields: [preferredVendorId], references: [id], onDelete: SetNull)
skuFamily InventorySkuFamily? @relation(fields: [skuFamilyId], references: [id], onDelete: SetNull)
skuNode InventorySkuNode? @relation(fields: [skuNodeId], references: [id], onDelete: SetNull)
@@index([preferredVendorId])
@@index([skuFamilyId])
@@index([skuNodeId])
}
model InventorySkuFamily {
id String @id @default(cuid())
code String @unique
sequenceCode String @unique
name String
description String
nextSequenceNumber Int @default(1)
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
nodes InventorySkuNode[]
items InventoryItem[]
}
model InventorySkuNode {
id String @id @default(cuid())
familyId String
parentNodeId String?
code String
label String
description String
path String
level Int
sortOrder Int @default(0)
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
family InventorySkuFamily @relation(fields: [familyId], references: [id], onDelete: Cascade)
parentNode InventorySkuNode? @relation("InventorySkuNodeTree", fields: [parentNodeId], references: [id], onDelete: Cascade)
childNodes InventorySkuNode[] @relation("InventorySkuNodeTree")
items InventoryItem[]
@@unique([familyId, path])
@@index([familyId, parentNodeId, sortOrder])
}
model Warehouse {
id String @id @default(cuid())
code String @unique
name String
notes String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
locations WarehouseLocation[]
inventoryTransactions InventoryTransaction[]
purchaseReceipts PurchaseReceipt[]
workOrders WorkOrder[]
workOrderMaterialIssues WorkOrderMaterialIssue[]
reservations InventoryReservation[]
transferSources InventoryTransfer[] @relation("InventoryTransferFromWarehouse")
transferDestinations InventoryTransfer[] @relation("InventoryTransferToWarehouse")
}
model Customer {
id String @id @default(cuid())
name String
email String
phone String
addressLine1 String
addressLine2 String
city String
state String
postalCode String
country String
status String @default("ACTIVE")
lifecycleStage String @default("ACTIVE")
isReseller Boolean @default(false)
resellerDiscountPercent Float @default(0)
parentCustomerId String?
paymentTerms String?
currencyCode String? @default("USD")
taxExempt Boolean @default(false)
creditHold Boolean @default(false)
preferredAccount Boolean @default(false)
strategicAccount Boolean @default(false)
requiresApproval Boolean @default(false)
blockedAccount Boolean @default(false)
notes String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
contactEntries CrmContactEntry[]
contacts CrmContact[]
parentCustomer Customer? @relation("CustomerHierarchy", fields: [parentCustomerId], references: [id], onDelete: SetNull)
childCustomers Customer[] @relation("CustomerHierarchy")
salesQuotes SalesQuote[]
salesOrders SalesOrder[]
projects Project[]
}
model InventoryBomLine {
id String @id @default(cuid())
parentItemId String
componentItemId String
quantity Float
unitOfMeasure String
notes String
position Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
parentItem InventoryItem @relation("InventoryBomParent", fields: [parentItemId], references: [id], onDelete: Cascade)
componentItem InventoryItem @relation("InventoryBomComponent", fields: [componentItemId], references: [id], onDelete: Restrict)
@@index([parentItemId, position])
@@index([componentItemId])
}
model WarehouseLocation {
id String @id @default(cuid())
warehouseId String
code String
name String
notes String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
warehouse Warehouse @relation(fields: [warehouseId], references: [id], onDelete: Cascade)
inventoryTransactions InventoryTransaction[]
purchaseReceipts PurchaseReceipt[]
workOrders WorkOrder[]
workOrderMaterialIssues WorkOrderMaterialIssue[]
reservations InventoryReservation[]
transferSourceLocations InventoryTransfer[] @relation("InventoryTransferFromLocation")
transferDestinationLocations InventoryTransfer[] @relation("InventoryTransferToLocation")
@@unique([warehouseId, code])
@@index([warehouseId])
}
model InventoryTransaction {
id String @id @default(cuid())
itemId String
warehouseId String
locationId String
transactionType String
quantity Int
reference String
notes String
createdById String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
item InventoryItem @relation(fields: [itemId], references: [id], onDelete: Cascade)
warehouse Warehouse @relation(fields: [warehouseId], references: [id], onDelete: Restrict)
location WarehouseLocation @relation(fields: [locationId], references: [id], onDelete: Restrict)
createdBy User? @relation(fields: [createdById], references: [id], onDelete: SetNull)
@@index([itemId, createdAt])
@@index([warehouseId, createdAt])
@@index([locationId, createdAt])
}
model InventoryTransfer {
id String @id @default(cuid())
itemId String
fromWarehouseId String
fromLocationId String
toWarehouseId String
toLocationId String
quantity Int
notes String
createdById String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
item InventoryItem @relation(fields: [itemId], references: [id], onDelete: Cascade)
fromWarehouse Warehouse @relation("InventoryTransferFromWarehouse", fields: [fromWarehouseId], references: [id], onDelete: Restrict)
fromLocation WarehouseLocation @relation("InventoryTransferFromLocation", fields: [fromLocationId], references: [id], onDelete: Restrict)
toWarehouse Warehouse @relation("InventoryTransferToWarehouse", fields: [toWarehouseId], references: [id], onDelete: Restrict)
toLocation WarehouseLocation @relation("InventoryTransferToLocation", fields: [toLocationId], references: [id], onDelete: Restrict)
createdBy User? @relation("InventoryTransferCreatedBy", fields: [createdById], references: [id], onDelete: SetNull)
@@index([itemId, createdAt])
}
model InventoryReservation {
id String @id @default(cuid())
itemId String
warehouseId String?
locationId String?
workOrderId String?
sourceType String
sourceId String?
quantity Int
status String @default("ACTIVE")
notes String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
item InventoryItem @relation(fields: [itemId], references: [id], onDelete: Cascade)
warehouse Warehouse? @relation(fields: [warehouseId], references: [id], onDelete: SetNull)
location WarehouseLocation? @relation(fields: [locationId], references: [id], onDelete: SetNull)
workOrder WorkOrder? @relation(fields: [workOrderId], references: [id], onDelete: Cascade)
@@index([itemId, status, createdAt])
@@index([warehouseId, locationId, status])
@@index([workOrderId, status])
}
model Vendor {
id String @id @default(cuid())
name String
email String
phone String
addressLine1 String
addressLine2 String
city String
state String
postalCode String
country String
status String @default("ACTIVE")
lifecycleStage String @default("ACTIVE")
paymentTerms String?
currencyCode String? @default("USD")
taxExempt Boolean @default(false)
creditHold Boolean @default(false)
preferredAccount Boolean @default(false)
strategicAccount Boolean @default(false)
requiresApproval Boolean @default(false)
blockedAccount Boolean @default(false)
notes String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
contactEntries CrmContactEntry[]
contacts CrmContact[]
purchaseOrders PurchaseOrder[]
preferredSupplyItems InventoryItem[]
}
model CrmContactEntry {
id String @id @default(cuid())
type String @default("NOTE")
summary String
body String
contactAt DateTime
customerId String?
vendorId String?
createdById String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
customer Customer? @relation(fields: [customerId], references: [id], onDelete: Cascade)
vendor Vendor? @relation(fields: [vendorId], references: [id], onDelete: Cascade)
createdBy User? @relation(fields: [createdById], references: [id], onDelete: SetNull)
}
model CrmContact {
id String @id @default(cuid())
fullName String
role String @default("OTHER")
email String
phone String
isPrimary Boolean @default(false)
customerId String?
vendorId String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
customer Customer? @relation(fields: [customerId], references: [id], onDelete: Cascade)
vendor Vendor? @relation(fields: [vendorId], references: [id], onDelete: Cascade)
}
model SalesQuote {
id String @id @default(cuid())
documentNumber String @unique
customerId String
status String
issueDate DateTime
expiresAt DateTime?
approvedAt DateTime?
approvedById String?
discountPercent Float @default(0)
taxPercent Float @default(0)
freightAmount Float @default(0)
notes String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
customer Customer @relation(fields: [customerId], references: [id], onDelete: Restrict)
approvedBy User? @relation("SalesQuoteApprovedBy", fields: [approvedById], references: [id], onDelete: SetNull)
lines SalesQuoteLine[]
projects Project[]
revisions SalesQuoteRevision[]
}
model SalesQuoteLine {
id String @id @default(cuid())
quoteId String
itemId String
description String
quantity Int
unitOfMeasure String
unitPrice Float
position Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
quote SalesQuote @relation(fields: [quoteId], references: [id], onDelete: Cascade)
item InventoryItem @relation(fields: [itemId], references: [id], onDelete: Restrict)
@@index([quoteId, position])
}
model SalesOrder {
id String @id @default(cuid())
documentNumber String @unique
customerId String
status String
issueDate DateTime
approvedAt DateTime?
approvedById String?
discountPercent Float @default(0)
taxPercent Float @default(0)
freightAmount Float @default(0)
notes String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
customer Customer @relation(fields: [customerId], references: [id], onDelete: Restrict)
approvedBy User? @relation("SalesOrderApprovedBy", fields: [approvedById], references: [id], onDelete: SetNull)
lines SalesOrderLine[]
shipments Shipment[]
projects Project[]
revisions SalesOrderRevision[]
workOrders WorkOrder[]
purchaseOrderLines PurchaseOrderLine[]
}
model SalesOrderLine {
id String @id @default(cuid())
orderId String
itemId String
description String
quantity Int
unitOfMeasure String
unitPrice Float
position Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
order SalesOrder @relation(fields: [orderId], references: [id], onDelete: Cascade)
item InventoryItem @relation(fields: [itemId], references: [id], onDelete: Restrict)
workOrders WorkOrder[]
purchaseOrderLines PurchaseOrderLine[]
@@index([orderId, position])
}
model SalesQuoteRevision {
id String @id @default(cuid())
quoteId String
revisionNumber Int
reason String
snapshot String
createdById String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
quote SalesQuote @relation(fields: [quoteId], references: [id], onDelete: Cascade)
createdBy User? @relation("SalesQuoteRevisionCreatedBy", fields: [createdById], references: [id], onDelete: SetNull)
@@unique([quoteId, revisionNumber])
@@index([quoteId, createdAt])
}
model SalesOrderRevision {
id String @id @default(cuid())
orderId String
revisionNumber Int
reason String
snapshot String
createdById String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
order SalesOrder @relation(fields: [orderId], references: [id], onDelete: Cascade)
createdBy User? @relation("SalesOrderRevisionCreatedBy", fields: [createdById], references: [id], onDelete: SetNull)
@@unique([orderId, revisionNumber])
@@index([orderId, createdAt])
}
model Shipment {
id String @id @default(cuid())
shipmentNumber String @unique
salesOrderId String
status String
shipDate DateTime?
carrier String
serviceLevel String
trackingNumber String
packageCount Int @default(1)
notes String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
salesOrder SalesOrder @relation(fields: [salesOrderId], references: [id], onDelete: Restrict)
projects Project[]
@@index([salesOrderId, createdAt])
}
model Project {
id String @id @default(cuid())
projectNumber String @unique
name String
status String
priority String
customerId String
salesQuoteId String?
salesOrderId String?
shipmentId String?
ownerId String?
dueDate DateTime?
notes String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
customer Customer @relation(fields: [customerId], references: [id], onDelete: Restrict)
salesQuote SalesQuote? @relation(fields: [salesQuoteId], references: [id], onDelete: SetNull)
salesOrder SalesOrder? @relation(fields: [salesOrderId], references: [id], onDelete: SetNull)
shipment Shipment? @relation(fields: [shipmentId], references: [id], onDelete: SetNull)
owner User? @relation("ProjectOwner", fields: [ownerId], references: [id], onDelete: SetNull)
workOrders WorkOrder[]
@@index([customerId, createdAt])
@@index([ownerId, dueDate])
@@index([status, priority])
}
model WorkOrder {
id String @id @default(cuid())
workOrderNumber String @unique
itemId String
projectId String?
salesOrderId String?
salesOrderLineId String?
warehouseId String
locationId String
status String
quantity Int
completedQuantity Int @default(0)
dueDate DateTime?
notes String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
item InventoryItem @relation(fields: [itemId], references: [id], onDelete: Restrict)
project Project? @relation(fields: [projectId], references: [id], onDelete: SetNull)
salesOrder SalesOrder? @relation(fields: [salesOrderId], references: [id], onDelete: SetNull)
salesOrderLine SalesOrderLine? @relation(fields: [salesOrderLineId], references: [id], onDelete: SetNull)
warehouse Warehouse @relation(fields: [warehouseId], references: [id], onDelete: Restrict)
location WarehouseLocation @relation(fields: [locationId], references: [id], onDelete: Restrict)
operations WorkOrderOperation[]
materialIssues WorkOrderMaterialIssue[]
completions WorkOrderCompletion[]
reservations InventoryReservation[]
@@index([itemId, createdAt])
@@index([projectId, dueDate])
@@index([salesOrderId, dueDate])
@@index([salesOrderLineId, dueDate])
@@index([status, dueDate])
@@index([warehouseId, createdAt])
}
model ManufacturingStation {
id String @id @default(cuid())
code String @unique
name String
description String
queueDays Int @default(0)
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
itemOperations InventoryItemOperation[]
workOrderOperations WorkOrderOperation[]
}
model InventoryItemOperation {
id String @id @default(cuid())
itemId String
stationId String
setupMinutes Int @default(0)
runMinutesPerUnit Int @default(0)
moveMinutes Int @default(0)
notes String
position Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
item InventoryItem @relation(fields: [itemId], references: [id], onDelete: Cascade)
station ManufacturingStation @relation(fields: [stationId], references: [id], onDelete: Restrict)
@@index([itemId, position])
@@index([stationId])
}
model WorkOrderOperation {
id String @id @default(cuid())
workOrderId String
stationId String
sequence Int
setupMinutes Int @default(0)
runMinutesPerUnit Int @default(0)
moveMinutes Int @default(0)
plannedMinutes Int @default(0)
plannedStart DateTime
plannedEnd DateTime
notes String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
workOrder WorkOrder @relation(fields: [workOrderId], references: [id], onDelete: Cascade)
station ManufacturingStation @relation(fields: [stationId], references: [id], onDelete: Restrict)
@@index([workOrderId, sequence])
@@index([stationId, plannedStart])
}
model WorkOrderMaterialIssue {
id String @id @default(cuid())
workOrderId String
componentItemId String
warehouseId String
locationId String
quantity Int
notes String
createdById String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
workOrder WorkOrder @relation(fields: [workOrderId], references: [id], onDelete: Cascade)
componentItem InventoryItem @relation(fields: [componentItemId], references: [id], onDelete: Restrict)
warehouse Warehouse @relation(fields: [warehouseId], references: [id], onDelete: Restrict)
location WarehouseLocation @relation(fields: [locationId], references: [id], onDelete: Restrict)
createdBy User? @relation(fields: [createdById], references: [id], onDelete: SetNull)
@@index([workOrderId, createdAt])
@@index([componentItemId, createdAt])
}
model WorkOrderCompletion {
id String @id @default(cuid())
workOrderId String
quantity Int
notes String
createdById String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
workOrder WorkOrder @relation(fields: [workOrderId], references: [id], onDelete: Cascade)
createdBy User? @relation(fields: [createdById], references: [id], onDelete: SetNull)
@@index([workOrderId, createdAt])
}
model PurchaseOrder {
id String @id @default(cuid())
documentNumber String @unique
vendorId String
status String
issueDate DateTime
taxPercent Float @default(0)
freightAmount Float @default(0)
notes String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
vendor Vendor @relation(fields: [vendorId], references: [id], onDelete: Restrict)
lines PurchaseOrderLine[]
receipts PurchaseReceipt[]
revisions PurchaseOrderRevision[]
}
model PurchaseOrderLine {
id String @id @default(cuid())
purchaseOrderId String
itemId String
salesOrderId String?
salesOrderLineId String?
description String
quantity Int
unitOfMeasure String
unitCost Float
position Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
purchaseOrder PurchaseOrder @relation(fields: [purchaseOrderId], references: [id], onDelete: Cascade)
item InventoryItem @relation(fields: [itemId], references: [id], onDelete: Restrict)
salesOrder SalesOrder? @relation(fields: [salesOrderId], references: [id], onDelete: SetNull)
salesOrderLine SalesOrderLine? @relation(fields: [salesOrderLineId], references: [id], onDelete: SetNull)
receiptLines PurchaseReceiptLine[]
@@index([purchaseOrderId, position])
@@index([salesOrderId, position])
@@index([salesOrderLineId, position])
}
model PurchaseReceipt {
id String @id @default(cuid())
receiptNumber String @unique
purchaseOrderId String
warehouseId String
locationId String
receivedAt DateTime
notes String
createdById String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
purchaseOrder PurchaseOrder @relation(fields: [purchaseOrderId], references: [id], onDelete: Cascade)
warehouse Warehouse @relation(fields: [warehouseId], references: [id], onDelete: Restrict)
location WarehouseLocation @relation(fields: [locationId], references: [id], onDelete: Restrict)
createdBy User? @relation(fields: [createdById], references: [id], onDelete: SetNull)
lines PurchaseReceiptLine[]
@@index([purchaseOrderId, createdAt])
@@index([warehouseId, createdAt])
@@index([locationId, createdAt])
}
model PurchaseReceiptLine {
id String @id @default(cuid())
purchaseReceiptId String
purchaseOrderLineId String
quantity Int
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
purchaseReceipt PurchaseReceipt @relation(fields: [purchaseReceiptId], references: [id], onDelete: Cascade)
purchaseOrderLine PurchaseOrderLine @relation(fields: [purchaseOrderLineId], references: [id], onDelete: Restrict)
@@index([purchaseReceiptId])
@@index([purchaseOrderLineId])
}
model PurchaseOrderRevision {
id String @id @default(cuid())
purchaseOrderId String
revisionNumber Int
reason String
snapshot String
createdById String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
purchaseOrder PurchaseOrder @relation(fields: [purchaseOrderId], references: [id], onDelete: Cascade)
createdBy User? @relation(fields: [createdById], references: [id], onDelete: SetNull)
@@unique([purchaseOrderId, revisionNumber])
@@index([purchaseOrderId, createdAt])
}
model AuditEvent {
id String @id @default(cuid())
actorId String?
entityType String
entityId String?
action String
summary String
metadataJson String
createdAt DateTime @default(now())
actor User? @relation(fields: [actorId], references: [id], onDelete: SetNull)
@@index([createdAt])
@@index([entityType, entityId, createdAt])
@@index([actorId, createdAt])
}