init-source
This commit is contained in:
@@ -0,0 +1,433 @@
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
// ─── USERS & AUTH ─────────────────────────────────────────────────────────────
|
||||
|
||||
enum Role {
|
||||
ADMIN
|
||||
QC
|
||||
PRODUCTION
|
||||
MANAGEMENT
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
email String @unique
|
||||
name String
|
||||
password String
|
||||
role Role @default(PRODUCTION)
|
||||
department String?
|
||||
active Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
sessions Session[]
|
||||
capasOwned CAPA[] @relation("CAPAOwner")
|
||||
capasRaised CAPA[] @relation("CAPARaisedBy")
|
||||
auditsLed Audit[] @relation("AuditLead")
|
||||
ncrsRaised NCR[] @relation("NCRRaisedBy")
|
||||
submissions FormSubmission[]
|
||||
auditLogs AuditLog[]
|
||||
notifications Notification[]
|
||||
}
|
||||
|
||||
model Session {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
token String @unique
|
||||
expiresAt DateTime
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
||||
// ─── AUDIT TRAIL ──────────────────────────────────────────────────────────────
|
||||
|
||||
model AuditLog {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
action String
|
||||
entity String
|
||||
entityId String
|
||||
before Json?
|
||||
after Json?
|
||||
createdAt DateTime @default(now())
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
|
||||
@@index([entity, entityId])
|
||||
@@index([userId])
|
||||
@@index([createdAt])
|
||||
}
|
||||
|
||||
// ─── NOTIFICATIONS ────────────────────────────────────────────────────────────
|
||||
|
||||
enum NotifType {
|
||||
CAPA_OVERDUE
|
||||
CAPA_ASSIGNED
|
||||
AUDIT_DUE
|
||||
NCR_ESCALATED
|
||||
FORM_REVIEW_READY
|
||||
DOC_EXPIRING
|
||||
STANDARD_APPROVED
|
||||
}
|
||||
|
||||
model Notification {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
type NotifType
|
||||
title String
|
||||
body String
|
||||
read Boolean @default(false)
|
||||
link String?
|
||||
createdAt DateTime @default(now())
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([userId, read])
|
||||
}
|
||||
|
||||
// ─── CAPA ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
enum CAPAPriority {
|
||||
CRITICAL
|
||||
HIGH
|
||||
MEDIUM
|
||||
LOW
|
||||
}
|
||||
|
||||
enum CAPAStatus {
|
||||
OPEN
|
||||
IN_PROGRESS
|
||||
OVERDUE
|
||||
CLOSED
|
||||
}
|
||||
|
||||
model CAPA {
|
||||
id String @id @default(cuid())
|
||||
ref String @unique
|
||||
title String
|
||||
description String?
|
||||
priority CAPAPriority @default(MEDIUM)
|
||||
status CAPAStatus @default(OPEN)
|
||||
progress Int @default(0)
|
||||
ownerId String
|
||||
raisedById String
|
||||
dueDate DateTime
|
||||
closedAt DateTime?
|
||||
rootCause String?
|
||||
corrAction String?
|
||||
prevAction String?
|
||||
department String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
owner User @relation("CAPAOwner", fields: [ownerId], references: [id])
|
||||
raisedBy User @relation("CAPARaisedBy", fields: [raisedById], references: [id])
|
||||
timeline CAPAEvent[]
|
||||
|
||||
@@index([status])
|
||||
@@index([ownerId])
|
||||
@@index([dueDate])
|
||||
}
|
||||
|
||||
model CAPAEvent {
|
||||
id String @id @default(cuid())
|
||||
capaId String
|
||||
event String
|
||||
note String?
|
||||
createdAt DateTime @default(now())
|
||||
capa CAPA @relation(fields: [capaId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([capaId])
|
||||
}
|
||||
|
||||
// ─── AUDITS ───────────────────────────────────────────────────────────────────
|
||||
|
||||
enum AuditType {
|
||||
INTERNAL
|
||||
SUPPLIER
|
||||
EXTERNAL
|
||||
}
|
||||
|
||||
enum AuditStatus {
|
||||
SCHEDULED
|
||||
IN_PROGRESS
|
||||
COMPLETED
|
||||
CANCELLED
|
||||
}
|
||||
|
||||
model Audit {
|
||||
id String @id @default(cuid())
|
||||
ref String @unique
|
||||
name String
|
||||
type AuditType @default(INTERNAL)
|
||||
status AuditStatus @default(SCHEDULED)
|
||||
leadId String
|
||||
scope String?
|
||||
scheduledAt DateTime
|
||||
completedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
lead User @relation("AuditLead", fields: [leadId], references: [id])
|
||||
findings Finding[]
|
||||
|
||||
@@index([status])
|
||||
@@index([scheduledAt])
|
||||
}
|
||||
|
||||
enum FindingSeverity {
|
||||
OBSERVATION
|
||||
MINOR
|
||||
MAJOR
|
||||
CRITICAL
|
||||
}
|
||||
|
||||
enum FindingStatus {
|
||||
OPEN
|
||||
IN_PROGRESS
|
||||
CLOSED
|
||||
}
|
||||
|
||||
model Finding {
|
||||
id String @id @default(cuid())
|
||||
auditId String
|
||||
description String
|
||||
severity FindingSeverity @default(MINOR)
|
||||
status FindingStatus @default(OPEN)
|
||||
category String?
|
||||
dueDate DateTime?
|
||||
closedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
audit Audit @relation(fields: [auditId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([auditId])
|
||||
}
|
||||
|
||||
// ─── NCR ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
enum NCRSeverity {
|
||||
OBSERVATION
|
||||
MINOR
|
||||
MAJOR
|
||||
}
|
||||
|
||||
enum NCRStatus {
|
||||
OPEN
|
||||
INVESTIGATING
|
||||
ESCALATED
|
||||
RESOLVED
|
||||
}
|
||||
|
||||
model NCR {
|
||||
id String @id @default(cuid())
|
||||
ref String @unique
|
||||
description String
|
||||
source String?
|
||||
severity NCRSeverity @default(MINOR)
|
||||
status NCRStatus @default(OPEN)
|
||||
raisedById String
|
||||
resolvedAt DateTime?
|
||||
resolution String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
raisedBy User @relation("NCRRaisedBy", fields: [raisedById], references: [id])
|
||||
|
||||
@@index([status])
|
||||
@@index([createdAt])
|
||||
}
|
||||
|
||||
// ─── DOCUMENTS ────────────────────────────────────────────────────────────────
|
||||
|
||||
enum DocStatus {
|
||||
CURRENT
|
||||
PENDING_REVIEW
|
||||
EXPIRED
|
||||
ARCHIVED
|
||||
}
|
||||
|
||||
enum DocCategory {
|
||||
SOP
|
||||
POLICY
|
||||
FORM
|
||||
WORK_INSTRUCTION
|
||||
RECORD
|
||||
}
|
||||
|
||||
model Document {
|
||||
id String @id @default(cuid())
|
||||
ref String @unique
|
||||
title String
|
||||
category DocCategory @default(SOP)
|
||||
revision String @default("A")
|
||||
status DocStatus @default(CURRENT)
|
||||
fileUrl String?
|
||||
ownerId String?
|
||||
reviewDate DateTime?
|
||||
approvedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([status])
|
||||
@@index([category])
|
||||
}
|
||||
|
||||
// ─── RISK REGISTER ────────────────────────────────────────────────────────────
|
||||
|
||||
enum RiskLevel {
|
||||
LOW
|
||||
MEDIUM
|
||||
HIGH
|
||||
CRITICAL
|
||||
}
|
||||
|
||||
model Risk {
|
||||
id String @id @default(cuid())
|
||||
title String
|
||||
description String?
|
||||
likelihood Int @default(1)
|
||||
impact Int @default(1)
|
||||
score Int @default(1)
|
||||
level RiskLevel @default(LOW)
|
||||
owner String?
|
||||
controls String?
|
||||
reviewDate DateTime?
|
||||
accepted Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([level])
|
||||
}
|
||||
|
||||
// ─── SUPPLIERS ────────────────────────────────────────────────────────────────
|
||||
|
||||
enum SupplierStatus {
|
||||
APPROVED
|
||||
UNDER_REVIEW
|
||||
SUSPENDED
|
||||
INACTIVE
|
||||
}
|
||||
|
||||
enum SupplierTier {
|
||||
TIER_1
|
||||
TIER_2
|
||||
TIER_3
|
||||
}
|
||||
|
||||
model Supplier {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
category String?
|
||||
tier SupplierTier @default(TIER_2)
|
||||
status SupplierStatus @default(UNDER_REVIEW)
|
||||
score Float?
|
||||
contact String?
|
||||
email String?
|
||||
lastAudit DateTime?
|
||||
nextAudit DateTime?
|
||||
notes String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([status])
|
||||
}
|
||||
|
||||
// ─── FIRST BUILD FORMS ────────────────────────────────────────────────────────
|
||||
|
||||
enum FieldType {
|
||||
SHORT_TEXT
|
||||
LONG_TEXT
|
||||
NUMBER
|
||||
DATE
|
||||
SINGLE_CHOICE
|
||||
MULTI_CHOICE
|
||||
RATING
|
||||
PHOTO
|
||||
}
|
||||
|
||||
enum FormStatus {
|
||||
DRAFT
|
||||
ACTIVE
|
||||
SUSPENDED
|
||||
REVIEW_READY
|
||||
STANDARD_SET
|
||||
ARCHIVED
|
||||
}
|
||||
|
||||
model BuildForm {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
product String?
|
||||
description String?
|
||||
status FormStatus @default(DRAFT)
|
||||
minSubmissions Int @default(10)
|
||||
createdById String?
|
||||
publishedAt DateTime?
|
||||
suspendedAt DateTime?
|
||||
archivedAt DateTime?
|
||||
clonedFromId String?
|
||||
clonedFromName String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
fields FormField[]
|
||||
submissions FormSubmission[]
|
||||
standard QualityStandard?
|
||||
|
||||
@@index([status])
|
||||
}
|
||||
|
||||
model FormField {
|
||||
id String @id @default(cuid())
|
||||
formId String
|
||||
label String
|
||||
type FieldType @default(SHORT_TEXT)
|
||||
hint String?
|
||||
options String[]
|
||||
required Boolean @default(false)
|
||||
trackStd Boolean @default(true)
|
||||
order Int @default(0)
|
||||
form BuildForm @relation(fields: [formId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([formId])
|
||||
}
|
||||
|
||||
model FormSubmission {
|
||||
id String @id @default(cuid())
|
||||
formId String
|
||||
submittedBy String
|
||||
data Json
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
form BuildForm @relation(fields: [formId], references: [id])
|
||||
user User @relation(fields: [submittedBy], references: [id])
|
||||
|
||||
@@index([formId])
|
||||
@@index([createdAt])
|
||||
}
|
||||
|
||||
model QualityStandard {
|
||||
id String @id @default(cuid())
|
||||
formId String @unique
|
||||
title String
|
||||
specs Json
|
||||
status String @default("DRAFT")
|
||||
approvedBy String?
|
||||
approvedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
form BuildForm @relation(fields: [formId], references: [id])
|
||||
}
|
||||
|
||||
// ─── SETTINGS ─────────────────────────────────────────────────────────────────
|
||||
|
||||
model Setting {
|
||||
key String @id
|
||||
value String
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
Reference in New Issue
Block a user