355 lines
10 KiB
Plaintext
355 lines
10 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
model Org {
|
|
id String @id @default(uuid())
|
|
name String
|
|
slug String @unique
|
|
createdAt DateTime @default(now())
|
|
|
|
members OrgUser[]
|
|
sessions Session[]
|
|
machines Machine[]
|
|
heartbeats MachineHeartbeat[]
|
|
kpiSnapshots MachineKpiSnapshot[]
|
|
events MachineEvent[]
|
|
workOrders MachineWorkOrder[]
|
|
settings OrgSettings?
|
|
shifts OrgShift[]
|
|
machineSettings MachineSettings[]
|
|
settingsAudits SettingsAudit[]
|
|
invites OrgInvite[]
|
|
}
|
|
|
|
model User {
|
|
id String @id @default(uuid())
|
|
email String @unique
|
|
name String?
|
|
passwordHash String
|
|
isActive Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
emailVerifiedAt DateTime? @map("email_verified_at")
|
|
emailVerificationToken String? @unique @map("email_verification_token")
|
|
emailVerificationExpiresAt DateTime? @map("email_verification_expires_at")
|
|
|
|
orgs OrgUser[]
|
|
sessions Session[]
|
|
sentInvites OrgInvite[] @relation("OrgInviteInviter")
|
|
}
|
|
|
|
model OrgUser {
|
|
id String @id @default(uuid())
|
|
orgId String
|
|
userId String
|
|
role String @default("MEMBER") // OWNER | ADMIN | MEMBER
|
|
createdAt DateTime @default(now())
|
|
|
|
org Org @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([orgId, userId])
|
|
@@index([userId])
|
|
@@index([orgId])
|
|
}
|
|
|
|
model OrgInvite {
|
|
id String @id @default(uuid())
|
|
orgId String @map("org_id")
|
|
email String
|
|
role String @default("MEMBER") // OWNER | ADMIN | MEMBER
|
|
token String @unique
|
|
invitedBy String? @map("invited_by")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
expiresAt DateTime @map("expires_at")
|
|
acceptedAt DateTime? @map("accepted_at")
|
|
revokedAt DateTime? @map("revoked_at")
|
|
|
|
org Org @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
inviter User? @relation("OrgInviteInviter", fields: [invitedBy], references: [id], onDelete: SetNull)
|
|
|
|
@@index([orgId])
|
|
@@index([orgId, email])
|
|
@@index([expiresAt])
|
|
@@map("org_invites")
|
|
}
|
|
|
|
model Session {
|
|
id String @id @default(uuid()) // cookie value
|
|
orgId String
|
|
userId String
|
|
createdAt DateTime @default(now())
|
|
lastSeenAt DateTime @default(now())
|
|
expiresAt DateTime
|
|
revokedAt DateTime?
|
|
ip String?
|
|
userAgent String?
|
|
|
|
org Org @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([userId])
|
|
@@index([orgId])
|
|
@@index([expiresAt])
|
|
}
|
|
|
|
model Machine {
|
|
id String @id @default(uuid())
|
|
orgId String
|
|
name String
|
|
apiKey String? @unique
|
|
code String?
|
|
location String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
tsDevice DateTime @default(now()) @map("ts")
|
|
tsServer DateTime @default(now()) @map("ts_server")
|
|
schemaVersion String? @map("schema_version")
|
|
seq BigInt? @map("seq")
|
|
pairingCode String? @unique @map("pairing_code")
|
|
pairingCodeExpiresAt DateTime? @map("pairing_code_expires_at")
|
|
pairingCodeUsedAt DateTime? @map("pairing_code_used_at")
|
|
|
|
org Org @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
heartbeats MachineHeartbeat[]
|
|
kpiSnapshots MachineKpiSnapshot[]
|
|
events MachineEvent[]
|
|
cycles MachineCycle[]
|
|
workOrders MachineWorkOrder[]
|
|
settings MachineSettings?
|
|
settingsAudits SettingsAudit[]
|
|
|
|
@@unique([orgId, name])
|
|
@@index([orgId])
|
|
}
|
|
|
|
model MachineHeartbeat {
|
|
id String @id @default(uuid())
|
|
orgId String
|
|
machineId String
|
|
ts DateTime @default(now())
|
|
tsServer DateTime @default(now()) @map("ts_server")
|
|
schemaVersion String? @map("schema_version")
|
|
seq BigInt? @map("seq")
|
|
|
|
status String
|
|
message String?
|
|
ip String?
|
|
fwVersion String?
|
|
|
|
org Org @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
machine Machine @relation(fields: [machineId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([orgId, machineId, ts])
|
|
}
|
|
|
|
model MachineKpiSnapshot {
|
|
id String @id @default(uuid())
|
|
orgId String
|
|
machineId String
|
|
ts DateTime @default(now())
|
|
|
|
workOrderId String?
|
|
sku String?
|
|
|
|
target Int?
|
|
good Int?
|
|
scrap Int?
|
|
cycleCount Int?
|
|
goodParts Int?
|
|
scrapParts Int?
|
|
cavities Int?
|
|
cycleTime Float? // theoretical/target
|
|
actualCycle Float? // if you want (optional)
|
|
|
|
availability Float?
|
|
performance Float?
|
|
quality Float?
|
|
oee Float?
|
|
|
|
trackingEnabled Boolean?
|
|
productionStarted Boolean?
|
|
tsServer DateTime @default(now()) @map("ts_server")
|
|
schemaVersion String? @map("schema_version")
|
|
seq BigInt? @map("seq")
|
|
|
|
org Org @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
machine Machine @relation(fields: [machineId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([orgId, machineId, ts])
|
|
}
|
|
|
|
model MachineEvent {
|
|
id String @id @default(uuid())
|
|
orgId String
|
|
machineId String
|
|
ts DateTime @default(now())
|
|
|
|
topic String // "anomaly-detected"
|
|
eventType String // "slow-cycle"
|
|
severity String // "critical"
|
|
requiresAck Boolean @default(false)
|
|
title String
|
|
description String?
|
|
tsServer DateTime @default(now()) @map("ts_server")
|
|
schemaVersion String? @map("schema_version")
|
|
seq BigInt? @map("seq")
|
|
|
|
// store the raw data blob so we don't lose fields
|
|
data Json?
|
|
|
|
workOrderId String?
|
|
sku String?
|
|
|
|
org Org @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
machine Machine @relation(fields: [machineId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([orgId, machineId, ts])
|
|
@@index([orgId, machineId, eventType, ts])
|
|
}
|
|
|
|
model MachineCycle {
|
|
id String @id @default(uuid())
|
|
orgId String
|
|
machineId String
|
|
ts DateTime @default(now())
|
|
|
|
cycleCount Int?
|
|
actualCycleTime Float
|
|
theoreticalCycleTime Float?
|
|
|
|
workOrderId String?
|
|
sku String?
|
|
|
|
cavities Int?
|
|
goodDelta Int?
|
|
scrapDelta Int?
|
|
tsServer DateTime @default(now()) @map("ts_server")
|
|
schemaVersion String? @map("schema_version")
|
|
seq BigInt? @map("seq")
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
machine Machine @relation(fields: [machineId], references: [id])
|
|
|
|
@@index([orgId, machineId, ts])
|
|
@@index([orgId, machineId, cycleCount])
|
|
}
|
|
|
|
model MachineWorkOrder {
|
|
id String @id @default(uuid())
|
|
orgId String
|
|
machineId String
|
|
workOrderId String
|
|
sku String?
|
|
targetQty Int?
|
|
cycleTime Float?
|
|
status String @default("PENDING")
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
org Org @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
machine Machine @relation(fields: [machineId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([machineId, workOrderId])
|
|
@@index([orgId, machineId])
|
|
@@index([orgId, workOrderId])
|
|
@@map("machine_work_orders")
|
|
}
|
|
|
|
model IngestLog {
|
|
id String @id @default(uuid())
|
|
orgId String?
|
|
machineId String?
|
|
endpoint String
|
|
schemaVersion String?
|
|
seq BigInt?
|
|
tsDevice DateTime?
|
|
tsServer DateTime @default(now())
|
|
|
|
ok Boolean
|
|
status Int
|
|
errorCode String?
|
|
errorMsg String?
|
|
body Json?
|
|
ip String?
|
|
userAgent String?
|
|
|
|
@@index([endpoint, tsServer])
|
|
@@index([machineId, tsServer])
|
|
@@index([machineId, seq])
|
|
}
|
|
|
|
model OrgSettings {
|
|
orgId String @id @map("org_id")
|
|
timezone String @default("UTC")
|
|
shiftChangeCompMin Int @default(10) @map("shift_change_comp_min")
|
|
lunchBreakMin Int @default(30) @map("lunch_break_min")
|
|
stoppageMultiplier Float @default(1.5) @map("stoppage_multiplier")
|
|
oeeAlertThresholdPct Float @default(90) @map("oee_alert_threshold_pct")
|
|
macroStoppageMultiplier Float @default(5) @map("macro_stoppage_multiplier")
|
|
performanceThresholdPct Float @default(85) @map("performance_threshold_pct")
|
|
qualitySpikeDeltaPct Float @default(5) @map("quality_spike_delta_pct")
|
|
alertsJson Json? @map("alerts_json")
|
|
defaultsJson Json? @map("defaults_json")
|
|
version Int @default(1)
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
updatedBy String? @map("updated_by")
|
|
|
|
org Org @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
|
|
@@map("org_settings")
|
|
}
|
|
|
|
model OrgShift {
|
|
id String @id @default(uuid())
|
|
orgId String @map("org_id")
|
|
name String
|
|
startTime String @map("start_time")
|
|
endTime String @map("end_time")
|
|
sortOrder Int @map("sort_order")
|
|
enabled Boolean @default(true)
|
|
|
|
org Org @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([orgId])
|
|
@@index([orgId, sortOrder])
|
|
@@map("org_shifts")
|
|
}
|
|
|
|
model MachineSettings {
|
|
machineId String @id @map("machine_id")
|
|
orgId String @map("org_id")
|
|
overridesJson Json? @map("overrides_json")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
updatedBy String? @map("updated_by")
|
|
|
|
org Org @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
machine Machine @relation(fields: [machineId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([orgId])
|
|
@@map("machine_settings")
|
|
}
|
|
|
|
model SettingsAudit {
|
|
id String @id @default(uuid())
|
|
orgId String @map("org_id")
|
|
machineId String? @map("machine_id")
|
|
actorId String? @map("actor_id")
|
|
source String
|
|
payloadJson Json @map("payload_json")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
org Org @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
machine Machine? @relation(fields: [machineId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([orgId, createdAt])
|
|
@@index([machineId, createdAt])
|
|
@@map("settings_audit")
|
|
}
|