Final MVP valid
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "public"."User" ADD COLUMN "phone" TEXT;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "public"."alert_contacts" (
|
||||
"id" TEXT NOT NULL,
|
||||
"org_id" TEXT NOT NULL,
|
||||
"user_id" TEXT,
|
||||
"name" TEXT NOT NULL,
|
||||
"role_scope" TEXT NOT NULL,
|
||||
"email" TEXT,
|
||||
"phone" TEXT,
|
||||
"event_types" JSONB,
|
||||
"is_active" BOOLEAN NOT NULL DEFAULT true,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "alert_contacts_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "public"."alert_notifications" (
|
||||
"id" TEXT NOT NULL,
|
||||
"org_id" TEXT NOT NULL,
|
||||
"machine_id" TEXT NOT NULL,
|
||||
"event_id" TEXT NOT NULL,
|
||||
"event_type" TEXT NOT NULL,
|
||||
"rule_id" TEXT NOT NULL,
|
||||
"role" TEXT NOT NULL,
|
||||
"channel" TEXT NOT NULL,
|
||||
"contact_id" TEXT,
|
||||
"user_id" TEXT,
|
||||
"sent_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"status" TEXT NOT NULL,
|
||||
"error" TEXT,
|
||||
|
||||
CONSTRAINT "alert_notifications_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "public"."alert_policies" (
|
||||
"id" TEXT NOT NULL,
|
||||
"org_id" TEXT NOT NULL,
|
||||
"policy_json" JSONB NOT NULL,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_by" TEXT,
|
||||
|
||||
CONSTRAINT "alert_policies_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "alert_contacts_org_id_idx" ON "public"."alert_contacts"("org_id" ASC);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "alert_contacts_org_id_role_scope_idx" ON "public"."alert_contacts"("org_id" ASC, "role_scope" ASC);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "alert_contacts_org_id_user_id_key" ON "public"."alert_contacts"("org_id" ASC, "user_id" ASC);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "alert_notifications_contact_id_idx" ON "public"."alert_notifications"("contact_id" ASC);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "alert_notifications_org_event_role_channel_idx" ON "public"."alert_notifications"("org_id" ASC, "event_id" ASC, "role" ASC, "channel" ASC);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "alert_notifications_org_machine_sent_idx" ON "public"."alert_notifications"("org_id" ASC, "machine_id" ASC, "sent_at" ASC);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "alert_notifications_user_id_idx" ON "public"."alert_notifications"("user_id" ASC);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "alert_policies_org_id_idx" ON "public"."alert_policies"("org_id" ASC);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "alert_policies_org_id_key" ON "public"."alert_policies"("org_id" ASC);
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."alert_contacts" ADD CONSTRAINT "alert_contacts_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "public"."Org"("id") ON DELETE CASCADE ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."alert_contacts" ADD CONSTRAINT "alert_contacts_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."User"("id") ON DELETE SET NULL ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."alert_notifications" ADD CONSTRAINT "alert_notifications_contact_id_fkey" FOREIGN KEY ("contact_id") REFERENCES "public"."alert_contacts"("id") ON DELETE SET NULL ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."alert_notifications" ADD CONSTRAINT "alert_notifications_machine_id_fkey" FOREIGN KEY ("machine_id") REFERENCES "public"."Machine"("id") ON DELETE CASCADE ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."alert_notifications" ADD CONSTRAINT "alert_notifications_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "public"."Org"("id") ON DELETE CASCADE ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."alert_notifications" ADD CONSTRAINT "alert_notifications_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."User"("id") ON DELETE SET NULL ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."alert_policies" ADD CONSTRAINT "alert_policies_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "public"."Org"("id") ON DELETE CASCADE ON UPDATE NO ACTION;
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "alert_contacts" DROP CONSTRAINT "alert_contacts_org_id_fkey";
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "alert_contacts" DROP CONSTRAINT "alert_contacts_user_id_fkey";
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "alert_notifications" DROP CONSTRAINT "alert_notifications_contact_id_fkey";
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "alert_notifications" DROP CONSTRAINT "alert_notifications_machine_id_fkey";
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "alert_notifications" DROP CONSTRAINT "alert_notifications_org_id_fkey";
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "alert_notifications" DROP CONSTRAINT "alert_notifications_user_id_fkey";
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "alert_policies" DROP CONSTRAINT "alert_policies_org_id_fkey";
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "alert_contacts" ALTER COLUMN "updated_at" DROP DEFAULT;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "alert_policies" ALTER COLUMN "updated_at" DROP DEFAULT;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ReasonEntry" (
|
||||
"id" TEXT NOT NULL,
|
||||
"orgId" TEXT NOT NULL,
|
||||
"machineId" TEXT NOT NULL,
|
||||
"reasonId" TEXT NOT NULL,
|
||||
"kind" TEXT NOT NULL,
|
||||
"episodeId" TEXT,
|
||||
"durationSeconds" INTEGER,
|
||||
"episodeEndTs" TIMESTAMP(3),
|
||||
"scrapEntryId" TEXT,
|
||||
"scrapQty" INTEGER,
|
||||
"scrapUnit" TEXT,
|
||||
"reasonCode" TEXT NOT NULL,
|
||||
"reasonLabel" TEXT,
|
||||
"reasonText" TEXT,
|
||||
"capturedAt" TIMESTAMP(3) NOT NULL,
|
||||
"workOrderId" TEXT,
|
||||
"meta" JSONB,
|
||||
"schemaVersion" INTEGER NOT NULL DEFAULT 1,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "ReasonEntry_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ReasonEntry_reasonId_key" ON "ReasonEntry"("reasonId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ReasonEntry_orgId_machineId_capturedAt_idx" ON "ReasonEntry"("orgId", "machineId", "capturedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ReasonEntry_orgId_kind_capturedAt_idx" ON "ReasonEntry"("orgId", "kind", "capturedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ReasonEntry_orgId_kind_episodeId_key" ON "ReasonEntry"("orgId", "kind", "episodeId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ReasonEntry_orgId_kind_scrapEntryId_key" ON "ReasonEntry"("orgId", "kind", "scrapEntryId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "alert_policies" ADD CONSTRAINT "alert_policies_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "Org"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "alert_contacts" ADD CONSTRAINT "alert_contacts_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "Org"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "alert_contacts" ADD CONSTRAINT "alert_contacts_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "alert_notifications" ADD CONSTRAINT "alert_notifications_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "Org"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "alert_notifications" ADD CONSTRAINT "alert_notifications_machine_id_fkey" FOREIGN KEY ("machine_id") REFERENCES "Machine"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "alert_notifications" ADD CONSTRAINT "alert_notifications_contact_id_fkey" FOREIGN KEY ("contact_id") REFERENCES "alert_contacts"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "alert_notifications" ADD CONSTRAINT "alert_notifications_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ReasonEntry" ADD CONSTRAINT "ReasonEntry_orgId_fkey" FOREIGN KEY ("orgId") REFERENCES "Org"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ReasonEntry" ADD CONSTRAINT "ReasonEntry_machineId_fkey" FOREIGN KEY ("machineId") REFERENCES "Machine"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- RenameIndex
|
||||
ALTER INDEX "alert_notifications_org_event_role_channel_idx" RENAME TO "alert_notifications_org_id_event_id_role_channel_idx";
|
||||
|
||||
-- RenameIndex
|
||||
ALTER INDEX "alert_notifications_org_machine_sent_idx" RENAME TO "alert_notifications_org_id_machine_id_sent_at_idx";
|
||||
@@ -0,0 +1,53 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "downtime_actions" (
|
||||
"id" TEXT NOT NULL,
|
||||
"org_id" TEXT NOT NULL,
|
||||
"machine_id" TEXT,
|
||||
"reason_code" TEXT,
|
||||
"hm_day" INTEGER,
|
||||
"hm_hour" INTEGER,
|
||||
"title" TEXT NOT NULL,
|
||||
"notes" TEXT,
|
||||
"status" TEXT NOT NULL DEFAULT 'open',
|
||||
"priority" TEXT NOT NULL DEFAULT 'medium',
|
||||
"due_date" TIMESTAMP(3),
|
||||
"reminder_at" TIMESTAMP(3),
|
||||
"last_reminder_at" TIMESTAMP(3),
|
||||
"completed_at" TIMESTAMP(3),
|
||||
"owner_user_id" TEXT,
|
||||
"created_by" TEXT,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "downtime_actions_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "downtime_actions_org_id_idx" ON "downtime_actions"("org_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "downtime_actions_org_id_machine_id_idx" ON "downtime_actions"("org_id", "machine_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "downtime_actions_org_id_reason_code_idx" ON "downtime_actions"("org_id", "reason_code");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "downtime_actions_org_id_hm_day_hm_hour_idx" ON "downtime_actions"("org_id", "hm_day", "hm_hour");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "downtime_actions_org_id_status_due_date_idx" ON "downtime_actions"("org_id", "status", "due_date");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "downtime_actions_owner_user_id_idx" ON "downtime_actions"("owner_user_id");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "downtime_actions" ADD CONSTRAINT "downtime_actions_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "Org"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "downtime_actions" ADD CONSTRAINT "downtime_actions_machine_id_fkey" FOREIGN KEY ("machine_id") REFERENCES "Machine"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "downtime_actions" ADD CONSTRAINT "downtime_actions_owner_user_id_fkey" FOREIGN KEY ("owner_user_id") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "downtime_actions" ADD CONSTRAINT "downtime_actions_created_by_fkey" FOREIGN KEY ("created_by") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "downtime_actions" ADD COLUMN "reminder_stage" TEXT;
|
||||
@@ -32,6 +32,9 @@ model Org {
|
||||
locationFinancialOverrides LocationFinancialOverride[]
|
||||
machineFinancialOverrides MachineFinancialOverride[]
|
||||
productCostOverrides ProductCostOverride[]
|
||||
reasonEntries ReasonEntry[]
|
||||
downtimeActions DowntimeAction[]
|
||||
|
||||
}
|
||||
|
||||
model User {
|
||||
@@ -51,6 +54,8 @@ model User {
|
||||
sentInvites OrgInvite[] @relation("OrgInviteInviter")
|
||||
alertContacts AlertContact[]
|
||||
alertNotifications AlertNotification[]
|
||||
downtimeActionsOwned DowntimeAction[] @relation("DowntimeActionOwner")
|
||||
downtimeActionsCreated DowntimeAction[] @relation("DowntimeActionCreator")
|
||||
}
|
||||
|
||||
model OrgUser {
|
||||
@@ -135,6 +140,9 @@ model Machine {
|
||||
settingsAudits SettingsAudit[]
|
||||
alertNotifications AlertNotification[]
|
||||
financialOverrides MachineFinancialOverride[]
|
||||
reasonEntries ReasonEntry[]
|
||||
downtimeActions DowntimeAction[]
|
||||
|
||||
|
||||
@@unique([orgId, name])
|
||||
@@index([orgId])
|
||||
@@ -517,3 +525,83 @@ model SettingsAudit {
|
||||
@@index([machineId, createdAt])
|
||||
@@map("settings_audit")
|
||||
}
|
||||
|
||||
model ReasonEntry {
|
||||
id String @id @default(uuid())
|
||||
orgId String
|
||||
machineId String
|
||||
|
||||
// idempotency key from Edge (rsn_<ulid>)
|
||||
reasonId String @unique
|
||||
|
||||
// "downtime" | "scrap"
|
||||
kind String
|
||||
|
||||
// For downtime reasons
|
||||
episodeId String?
|
||||
durationSeconds Int?
|
||||
episodeEndTs DateTime?
|
||||
|
||||
// For scrap reasons
|
||||
scrapEntryId String?
|
||||
scrapQty Int?
|
||||
scrapUnit String?
|
||||
|
||||
// Required reason
|
||||
reasonCode String
|
||||
reasonLabel String?
|
||||
reasonText String?
|
||||
|
||||
capturedAt DateTime
|
||||
workOrderId String?
|
||||
meta Json?
|
||||
schemaVersion Int @default(1)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
org Org @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
||||
machine Machine @relation(fields: [machineId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([orgId, machineId, capturedAt])
|
||||
@@index([orgId, kind, capturedAt])
|
||||
@@unique([orgId, kind, episodeId])
|
||||
@@unique([orgId, kind, scrapEntryId])
|
||||
}
|
||||
|
||||
model DowntimeAction {
|
||||
id String @id @default(uuid())
|
||||
orgId String @map("org_id")
|
||||
machineId String? @map("machine_id")
|
||||
reasonCode String? @map("reason_code")
|
||||
hmDay Int? @map("hm_day")
|
||||
hmHour Int? @map("hm_hour")
|
||||
|
||||
title String
|
||||
notes String?
|
||||
status String @default("open")
|
||||
priority String @default("medium")
|
||||
dueDate DateTime? @map("due_date")
|
||||
reminderAt DateTime? @map("reminder_at")
|
||||
lastReminderAt DateTime? @map("last_reminder_at")
|
||||
reminderStage String? @map("reminder_stage")
|
||||
completedAt DateTime? @map("completed_at")
|
||||
|
||||
ownerUserId String? @map("owner_user_id")
|
||||
createdBy String? @map("created_by")
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
org Org @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
||||
machine Machine? @relation(fields: [machineId], references: [id], onDelete: SetNull)
|
||||
ownerUser User? @relation("DowntimeActionOwner", fields: [ownerUserId], references: [id], onDelete: SetNull)
|
||||
creator User? @relation("DowntimeActionCreator", fields: [createdBy], references: [id], onDelete: SetNull)
|
||||
|
||||
@@index([orgId])
|
||||
@@index([orgId, machineId])
|
||||
@@index([orgId, reasonCode])
|
||||
@@index([orgId, hmDay, hmHour])
|
||||
@@index([orgId, status, dueDate])
|
||||
@@index([ownerUserId])
|
||||
@@map("downtime_actions")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user