feat(F-004,F-005): complete Quest and remaining domain schemas
Some checks failed
Build and Deploy / deploy (push) Blocked by required conditions
Build and Deploy / build (push) Has been cancelled

Quest Domain Complete (F-004):
- quest_account_request: new user registration requests
- quest_notification + alert reads: notification/alert system
- quest_email_event + subscriptions: email event management
- quest_email_log: email tracking
- quest_plant + inventory_type + inventory_plant: plant/inventory configuration
- quest_processed_order_acknowledgement_email: duplicate prevention

Remaining Domains Complete (F-005):

Shipment Requests:
- ship_request + ship_request_detail: shipment request cart workflow

Allocation Requests:
- alloc_request + alloc_request_detail + alloc_plant: coil allocation workflow

Invoice Management:
- inv_upload + inv_upload_entry + inv_upload_status: invoice upload/processing

Finance/AP:
- finance_ap_check_processing_batch + status: AP check processing

Paint Schedule:
- paint_plant + paint_line + paint_line_type + paint_plant_line + paint_schedule

Documentation:
- doc_category + doc_article + doc_article_permission_group: knowledge base

Wave/EDI:
- wave_process + wave_process_history: EDI processing

Task Scheduler:
- lts_task + lts_task_type + lts_task_schedule + lts_task_execution

Total: 60+ tables, 600+ columns across all domains. All migrations applied successfully.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Lorentz 2026-02-16 02:16:28 +00:00
parent e643af1fe6
commit d8af580d93
4 changed files with 1378 additions and 18 deletions

View file

@ -0,0 +1,214 @@
-- CreateTable
CREATE TABLE "quest_account_request" (
"id" TEXT NOT NULL,
"first_name" TEXT NOT NULL,
"last_name" TEXT NOT NULL,
"email" TEXT NOT NULL,
"phone" TEXT,
"company_name" TEXT NOT NULL,
"epicor_cust_id" TEXT,
"message" TEXT,
"request_processed" BOOLEAN NOT NULL DEFAULT false,
"processed_at" TIMESTAMP(3),
"processed_by" TEXT,
"approved" BOOLEAN NOT NULL DEFAULT false,
"rejection_reason" TEXT,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "quest_account_request_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "quest_notification" (
"id" TEXT NOT NULL,
"title" TEXT NOT NULL,
"text" TEXT NOT NULL,
"is_alert" BOOLEAN NOT NULL DEFAULT false,
"display_date" TIMESTAMP(3) NOT NULL,
"display_time" TEXT,
"is_active" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "quest_notification_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "quest_user_notification_alert_read" (
"id" TEXT NOT NULL,
"quest_notification_id" TEXT NOT NULL,
"auth_user_id" TEXT NOT NULL,
"read_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "quest_user_notification_alert_read_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "quest_email_event" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT,
"is_active" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "quest_email_event_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "quest_user_email_event" (
"id" TEXT NOT NULL,
"auth_user_id" TEXT NOT NULL,
"quest_email_event_id" TEXT NOT NULL,
"subscribed" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "quest_user_email_event_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "quest_email_log" (
"id" TEXT NOT NULL,
"to_addresses" TEXT[],
"from_address" TEXT NOT NULL,
"subject" TEXT NOT NULL,
"body" TEXT NOT NULL,
"sent_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"status" TEXT NOT NULL DEFAULT 'sent',
"error_message" TEXT,
"quest_email_event_id" TEXT,
"auth_user_id" TEXT,
CONSTRAINT "quest_email_log_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "quest_plant" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"code" TEXT NOT NULL,
"is_active" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "quest_plant_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "quest_inventory_type" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"code" TEXT NOT NULL,
"description" TEXT,
"is_active" BOOLEAN NOT NULL DEFAULT true,
"sort_order" INTEGER NOT NULL DEFAULT 0,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "quest_inventory_type_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "quest_inventory_plant" (
"id" TEXT NOT NULL,
"quest_plant_id" TEXT NOT NULL,
"quest_inventory_type_id" TEXT NOT NULL,
"is_active" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "quest_inventory_plant_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "quest_processed_order_acknowledgement_email" (
"id" TEXT NOT NULL,
"epicor_order_num" INTEGER NOT NULL,
"epicor_cust_id" TEXT NOT NULL,
"epicor_po_num" TEXT,
"sent_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"quest_company_id" TEXT,
CONSTRAINT "quest_processed_order_acknowledgement_email_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE INDEX "quest_account_request_email_idx" ON "quest_account_request"("email");
-- CreateIndex
CREATE INDEX "quest_account_request_request_processed_idx" ON "quest_account_request"("request_processed");
-- CreateIndex
CREATE INDEX "quest_notification_is_alert_idx" ON "quest_notification"("is_alert");
-- CreateIndex
CREATE INDEX "quest_notification_display_date_idx" ON "quest_notification"("display_date");
-- CreateIndex
CREATE INDEX "quest_notification_is_active_idx" ON "quest_notification"("is_active");
-- CreateIndex
CREATE INDEX "quest_user_notification_alert_read_auth_user_id_idx" ON "quest_user_notification_alert_read"("auth_user_id");
-- CreateIndex
CREATE UNIQUE INDEX "quest_user_notification_alert_read_quest_notification_id_au_key" ON "quest_user_notification_alert_read"("quest_notification_id", "auth_user_id");
-- CreateIndex
CREATE UNIQUE INDEX "quest_email_event_name_key" ON "quest_email_event"("name");
-- CreateIndex
CREATE INDEX "quest_user_email_event_auth_user_id_idx" ON "quest_user_email_event"("auth_user_id");
-- CreateIndex
CREATE UNIQUE INDEX "quest_user_email_event_auth_user_id_quest_email_event_id_key" ON "quest_user_email_event"("auth_user_id", "quest_email_event_id");
-- CreateIndex
CREATE INDEX "quest_email_log_sent_at_idx" ON "quest_email_log"("sent_at");
-- CreateIndex
CREATE INDEX "quest_email_log_status_idx" ON "quest_email_log"("status");
-- CreateIndex
CREATE INDEX "quest_email_log_auth_user_id_idx" ON "quest_email_log"("auth_user_id");
-- CreateIndex
CREATE UNIQUE INDEX "quest_plant_name_key" ON "quest_plant"("name");
-- CreateIndex
CREATE UNIQUE INDEX "quest_plant_code_key" ON "quest_plant"("code");
-- CreateIndex
CREATE UNIQUE INDEX "quest_inventory_type_name_key" ON "quest_inventory_type"("name");
-- CreateIndex
CREATE UNIQUE INDEX "quest_inventory_type_code_key" ON "quest_inventory_type"("code");
-- CreateIndex
CREATE INDEX "quest_inventory_plant_quest_plant_id_idx" ON "quest_inventory_plant"("quest_plant_id");
-- CreateIndex
CREATE INDEX "quest_inventory_plant_quest_inventory_type_id_idx" ON "quest_inventory_plant"("quest_inventory_type_id");
-- CreateIndex
CREATE UNIQUE INDEX "quest_inventory_plant_quest_plant_id_quest_inventory_type_i_key" ON "quest_inventory_plant"("quest_plant_id", "quest_inventory_type_id");
-- CreateIndex
CREATE INDEX "quest_processed_order_acknowledgement_email_epicor_cust_id_idx" ON "quest_processed_order_acknowledgement_email"("epicor_cust_id");
-- CreateIndex
CREATE INDEX "quest_processed_order_acknowledgement_email_sent_at_idx" ON "quest_processed_order_acknowledgement_email"("sent_at");
-- CreateIndex
CREATE UNIQUE INDEX "quest_processed_order_acknowledgement_email_epicor_order_nu_key" ON "quest_processed_order_acknowledgement_email"("epicor_order_num", "epicor_cust_id");
-- AddForeignKey
ALTER TABLE "quest_user_notification_alert_read" ADD CONSTRAINT "quest_user_notification_alert_read_quest_notification_id_fkey" FOREIGN KEY ("quest_notification_id") REFERENCES "quest_notification"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "quest_user_email_event" ADD CONSTRAINT "quest_user_email_event_quest_email_event_id_fkey" FOREIGN KEY ("quest_email_event_id") REFERENCES "quest_email_event"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "quest_inventory_plant" ADD CONSTRAINT "quest_inventory_plant_quest_plant_id_fkey" FOREIGN KEY ("quest_plant_id") REFERENCES "quest_plant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "quest_inventory_plant" ADD CONSTRAINT "quest_inventory_plant_quest_inventory_type_id_fkey" FOREIGN KEY ("quest_inventory_type_id") REFERENCES "quest_inventory_type"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View file

@ -0,0 +1,519 @@
-- CreateTable
CREATE TABLE "ship_request" (
"id" TEXT NOT NULL,
"auth_user_id" TEXT NOT NULL,
"quest_company_id" TEXT NOT NULL,
"ship_to_address" TEXT NOT NULL,
"order_number" TEXT,
"po_number" TEXT,
"release_number" TEXT,
"pickup_date" TIMESTAMP(3),
"instructions" TEXT,
"email_recipients" TEXT[],
"is_submitted" BOOLEAN NOT NULL DEFAULT false,
"submitted_at" TIMESTAMP(3),
"is_cancelled" BOOLEAN NOT NULL DEFAULT false,
"cancelled_at" TIMESTAMP(3),
"cancelled_by" TEXT,
"last_cart_activity" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "ship_request_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "ship_request_detail" (
"id" TEXT NOT NULL,
"ship_request_id" TEXT NOT NULL,
"part_num" TEXT NOT NULL,
"lot_num" TEXT,
"plant" TEXT NOT NULL,
"warehouse" TEXT,
"quantity" DOUBLE PRECISION NOT NULL,
"notes" TEXT,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "ship_request_detail_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "alloc_request" (
"id" TEXT NOT NULL,
"auth_user_id" TEXT NOT NULL,
"quest_company_id" TEXT NOT NULL,
"job_number" TEXT NOT NULL,
"ship_to_address" TEXT NOT NULL,
"order_number" TEXT,
"po_number" TEXT,
"release_number" TEXT,
"pickup_date" TIMESTAMP(3),
"instructions" TEXT,
"email_recipients" TEXT[],
"is_submitted" BOOLEAN NOT NULL DEFAULT false,
"submitted_at" TIMESTAMP(3),
"is_cancelled" BOOLEAN NOT NULL DEFAULT false,
"cancelled_at" TIMESTAMP(3),
"cancelled_by" TEXT,
"last_cart_activity" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "alloc_request_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "alloc_request_detail" (
"id" TEXT NOT NULL,
"alloc_request_id" TEXT NOT NULL,
"part_num" TEXT NOT NULL,
"lot_num" TEXT,
"coil_number" TEXT,
"quantity" DOUBLE PRECISION NOT NULL,
"notes" TEXT,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "alloc_request_detail_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "alloc_plant" (
"id" TEXT NOT NULL,
"plant_code" TEXT NOT NULL,
"plant_name" TEXT NOT NULL,
"is_active" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "alloc_plant_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "inv_upload_status" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT,
"sort_order" INTEGER NOT NULL DEFAULT 0,
CONSTRAINT "inv_upload_status_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "inv_upload" (
"id" TEXT NOT NULL,
"auth_user_id" TEXT NOT NULL,
"original_filename" TEXT NOT NULL,
"storage_filename" TEXT NOT NULL,
"file_path" TEXT NOT NULL,
"file_size" INTEGER NOT NULL,
"total_pages" INTEGER,
"inv_upload_status_id" TEXT NOT NULL,
"upload_notes" TEXT,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"processed_at" TIMESTAMP(3),
CONSTRAINT "inv_upload_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "inv_upload_entry" (
"id" TEXT NOT NULL,
"inv_upload_id" TEXT NOT NULL,
"invoice_number" TEXT NOT NULL,
"epicor_cust_id" TEXT,
"quest_company_id" TEXT,
"job_number" TEXT,
"page_number" INTEGER,
"storage_filename" TEXT,
"file_path" TEXT,
"is_ignored" BOOLEAN NOT NULL DEFAULT false,
"is_replaced" BOOLEAN NOT NULL DEFAULT false,
"send_error" TEXT,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"sent_at" TIMESTAMP(3),
CONSTRAINT "inv_upload_entry_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "finance_ap_check_processing_status" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT,
"sort_order" INTEGER NOT NULL DEFAULT 0,
CONSTRAINT "finance_ap_check_processing_status_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "finance_ap_check_processing_batch" (
"id" TEXT NOT NULL,
"auth_user_id" TEXT NOT NULL,
"group_id" TEXT NOT NULL,
"original_filename" TEXT NOT NULL,
"generated_csv_filename" TEXT,
"generated_csv_path" TEXT,
"finance_ap_check_processing_status_id" TEXT NOT NULL,
"error_message" TEXT,
"record_count" INTEGER NOT NULL DEFAULT 0,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"processed_at" TIMESTAMP(3),
CONSTRAINT "finance_ap_check_processing_batch_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "paint_line_type" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT,
CONSTRAINT "paint_line_type_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "paint_plant" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"code" TEXT NOT NULL,
"is_active" BOOLEAN NOT NULL DEFAULT true,
CONSTRAINT "paint_plant_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "paint_line" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"paint_line_type_id" TEXT NOT NULL,
"is_active" BOOLEAN NOT NULL DEFAULT true,
CONSTRAINT "paint_line_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "paint_plant_line" (
"id" TEXT NOT NULL,
"paint_plant_id" TEXT NOT NULL,
"paint_line_id" TEXT NOT NULL,
"is_active" BOOLEAN NOT NULL DEFAULT true,
CONSTRAINT "paint_plant_line_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "paint_schedule" (
"id" TEXT NOT NULL,
"paint_line_id" TEXT NOT NULL,
"job_id" TEXT,
"part_description" TEXT,
"customer" TEXT,
"quantity" INTEGER,
"estimated_run_time" DOUBLE PRECISION,
"start_time" TIMESTAMP(3),
"notes" TEXT,
"is_complete" BOOLEAN NOT NULL DEFAULT false,
"line_speed" DOUBLE PRECISION,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "paint_schedule_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "doc_category" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT,
"icon" TEXT,
"sort_order" INTEGER NOT NULL DEFAULT 0,
"is_active" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "doc_category_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "doc_article" (
"id" TEXT NOT NULL,
"title" TEXT NOT NULL,
"content" TEXT NOT NULL,
"doc_category_id" TEXT NOT NULL,
"is_published" BOOLEAN NOT NULL DEFAULT false,
"sort_order" INTEGER NOT NULL DEFAULT 0,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
"created_by" TEXT,
"updated_by" TEXT,
CONSTRAINT "doc_article_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "doc_article_permission_group" (
"id" TEXT NOT NULL,
"doc_article_id" TEXT NOT NULL,
"auth_permission_group_id" TEXT NOT NULL,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "doc_article_permission_group_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "wave_process" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT,
"is_enabled" BOOLEAN NOT NULL DEFAULT true,
"schedule_cron" TEXT,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "wave_process_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "wave_process_history" (
"id" TEXT NOT NULL,
"wave_process_id" TEXT NOT NULL,
"started_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"completed_at" TIMESTAMP(3),
"status" TEXT NOT NULL DEFAULT 'running',
"result_message" TEXT,
"error_message" TEXT,
CONSTRAINT "wave_process_history_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "lts_task_type" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT,
CONSTRAINT "lts_task_type_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "lts_task" (
"id" TEXT NOT NULL,
"lts_task_type_id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT,
"command" TEXT NOT NULL,
"is_enabled" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "lts_task_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "lts_task_schedule" (
"id" TEXT NOT NULL,
"lts_task_id" TEXT NOT NULL,
"schedule_type" TEXT NOT NULL,
"schedule_value" TEXT NOT NULL,
"timezone" TEXT NOT NULL DEFAULT 'UTC',
"is_active" BOOLEAN NOT NULL DEFAULT true,
"next_run_at" TIMESTAMP(3),
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "lts_task_schedule_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "lts_task_execution" (
"id" TEXT NOT NULL,
"lts_task_id" TEXT NOT NULL,
"started_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"completed_at" TIMESTAMP(3),
"status" TEXT NOT NULL DEFAULT 'running',
"output" TEXT,
"error_message" TEXT,
"exit_code" INTEGER,
CONSTRAINT "lts_task_execution_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE INDEX "ship_request_auth_user_id_idx" ON "ship_request"("auth_user_id");
-- CreateIndex
CREATE INDEX "ship_request_quest_company_id_idx" ON "ship_request"("quest_company_id");
-- CreateIndex
CREATE INDEX "ship_request_is_submitted_idx" ON "ship_request"("is_submitted");
-- CreateIndex
CREATE INDEX "ship_request_is_cancelled_idx" ON "ship_request"("is_cancelled");
-- CreateIndex
CREATE INDEX "ship_request_detail_ship_request_id_idx" ON "ship_request_detail"("ship_request_id");
-- CreateIndex
CREATE INDEX "alloc_request_auth_user_id_idx" ON "alloc_request"("auth_user_id");
-- CreateIndex
CREATE INDEX "alloc_request_quest_company_id_idx" ON "alloc_request"("quest_company_id");
-- CreateIndex
CREATE INDEX "alloc_request_job_number_idx" ON "alloc_request"("job_number");
-- CreateIndex
CREATE INDEX "alloc_request_is_submitted_idx" ON "alloc_request"("is_submitted");
-- CreateIndex
CREATE INDEX "alloc_request_detail_alloc_request_id_idx" ON "alloc_request_detail"("alloc_request_id");
-- CreateIndex
CREATE UNIQUE INDEX "alloc_plant_plant_code_key" ON "alloc_plant"("plant_code");
-- CreateIndex
CREATE UNIQUE INDEX "inv_upload_status_name_key" ON "inv_upload_status"("name");
-- CreateIndex
CREATE INDEX "inv_upload_auth_user_id_idx" ON "inv_upload"("auth_user_id");
-- CreateIndex
CREATE INDEX "inv_upload_inv_upload_status_id_idx" ON "inv_upload"("inv_upload_status_id");
-- CreateIndex
CREATE INDEX "inv_upload_created_at_idx" ON "inv_upload"("created_at");
-- CreateIndex
CREATE INDEX "inv_upload_entry_inv_upload_id_idx" ON "inv_upload_entry"("inv_upload_id");
-- CreateIndex
CREATE INDEX "inv_upload_entry_invoice_number_idx" ON "inv_upload_entry"("invoice_number");
-- CreateIndex
CREATE INDEX "inv_upload_entry_epicor_cust_id_idx" ON "inv_upload_entry"("epicor_cust_id");
-- CreateIndex
CREATE INDEX "inv_upload_entry_quest_company_id_idx" ON "inv_upload_entry"("quest_company_id");
-- CreateIndex
CREATE UNIQUE INDEX "finance_ap_check_processing_status_name_key" ON "finance_ap_check_processing_status"("name");
-- CreateIndex
CREATE INDEX "finance_ap_check_processing_batch_auth_user_id_idx" ON "finance_ap_check_processing_batch"("auth_user_id");
-- CreateIndex
CREATE INDEX "finance_ap_check_processing_batch_group_id_idx" ON "finance_ap_check_processing_batch"("group_id");
-- CreateIndex
CREATE INDEX "finance_ap_check_processing_batch_finance_ap_check_processi_idx" ON "finance_ap_check_processing_batch"("finance_ap_check_processing_status_id");
-- CreateIndex
CREATE UNIQUE INDEX "paint_line_type_name_key" ON "paint_line_type"("name");
-- CreateIndex
CREATE UNIQUE INDEX "paint_plant_name_key" ON "paint_plant"("name");
-- CreateIndex
CREATE UNIQUE INDEX "paint_plant_code_key" ON "paint_plant"("code");
-- CreateIndex
CREATE UNIQUE INDEX "paint_line_name_key" ON "paint_line"("name");
-- CreateIndex
CREATE UNIQUE INDEX "paint_plant_line_paint_plant_id_paint_line_id_key" ON "paint_plant_line"("paint_plant_id", "paint_line_id");
-- CreateIndex
CREATE INDEX "paint_schedule_paint_line_id_idx" ON "paint_schedule"("paint_line_id");
-- CreateIndex
CREATE INDEX "paint_schedule_start_time_idx" ON "paint_schedule"("start_time");
-- CreateIndex
CREATE INDEX "paint_schedule_is_complete_idx" ON "paint_schedule"("is_complete");
-- CreateIndex
CREATE UNIQUE INDEX "doc_category_name_key" ON "doc_category"("name");
-- CreateIndex
CREATE INDEX "doc_article_doc_category_id_idx" ON "doc_article"("doc_category_id");
-- CreateIndex
CREATE INDEX "doc_article_is_published_idx" ON "doc_article"("is_published");
-- CreateIndex
CREATE UNIQUE INDEX "doc_article_permission_group_doc_article_id_auth_permission_key" ON "doc_article_permission_group"("doc_article_id", "auth_permission_group_id");
-- CreateIndex
CREATE UNIQUE INDEX "wave_process_name_key" ON "wave_process"("name");
-- CreateIndex
CREATE INDEX "wave_process_history_wave_process_id_idx" ON "wave_process_history"("wave_process_id");
-- CreateIndex
CREATE INDEX "wave_process_history_started_at_idx" ON "wave_process_history"("started_at");
-- CreateIndex
CREATE INDEX "wave_process_history_status_idx" ON "wave_process_history"("status");
-- CreateIndex
CREATE UNIQUE INDEX "lts_task_type_name_key" ON "lts_task_type"("name");
-- CreateIndex
CREATE INDEX "lts_task_schedule_lts_task_id_idx" ON "lts_task_schedule"("lts_task_id");
-- CreateIndex
CREATE INDEX "lts_task_schedule_next_run_at_idx" ON "lts_task_schedule"("next_run_at");
-- CreateIndex
CREATE INDEX "lts_task_execution_lts_task_id_idx" ON "lts_task_execution"("lts_task_id");
-- CreateIndex
CREATE INDEX "lts_task_execution_started_at_idx" ON "lts_task_execution"("started_at");
-- CreateIndex
CREATE INDEX "lts_task_execution_status_idx" ON "lts_task_execution"("status");
-- AddForeignKey
ALTER TABLE "ship_request_detail" ADD CONSTRAINT "ship_request_detail_ship_request_id_fkey" FOREIGN KEY ("ship_request_id") REFERENCES "ship_request"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "alloc_request_detail" ADD CONSTRAINT "alloc_request_detail_alloc_request_id_fkey" FOREIGN KEY ("alloc_request_id") REFERENCES "alloc_request"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "inv_upload" ADD CONSTRAINT "inv_upload_inv_upload_status_id_fkey" FOREIGN KEY ("inv_upload_status_id") REFERENCES "inv_upload_status"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "inv_upload_entry" ADD CONSTRAINT "inv_upload_entry_inv_upload_id_fkey" FOREIGN KEY ("inv_upload_id") REFERENCES "inv_upload"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "finance_ap_check_processing_batch" ADD CONSTRAINT "finance_ap_check_processing_batch_finance_ap_check_process_fkey" FOREIGN KEY ("finance_ap_check_processing_status_id") REFERENCES "finance_ap_check_processing_status"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "paint_line" ADD CONSTRAINT "paint_line_paint_line_type_id_fkey" FOREIGN KEY ("paint_line_type_id") REFERENCES "paint_line_type"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "paint_plant_line" ADD CONSTRAINT "paint_plant_line_paint_plant_id_fkey" FOREIGN KEY ("paint_plant_id") REFERENCES "paint_plant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "paint_plant_line" ADD CONSTRAINT "paint_plant_line_paint_line_id_fkey" FOREIGN KEY ("paint_line_id") REFERENCES "paint_line"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "paint_schedule" ADD CONSTRAINT "paint_schedule_paint_line_id_fkey" FOREIGN KEY ("paint_line_id") REFERENCES "paint_line"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "doc_article" ADD CONSTRAINT "doc_article_doc_category_id_fkey" FOREIGN KEY ("doc_category_id") REFERENCES "doc_category"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "doc_article_permission_group" ADD CONSTRAINT "doc_article_permission_group_doc_article_id_fkey" FOREIGN KEY ("doc_article_id") REFERENCES "doc_article"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "wave_process_history" ADD CONSTRAINT "wave_process_history_wave_process_id_fkey" FOREIGN KEY ("wave_process_id") REFERENCES "wave_process"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "lts_task" ADD CONSTRAINT "lts_task_lts_task_type_id_fkey" FOREIGN KEY ("lts_task_type_id") REFERENCES "lts_task_type"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "lts_task_schedule" ADD CONSTRAINT "lts_task_schedule_lts_task_id_fkey" FOREIGN KEY ("lts_task_id") REFERENCES "lts_task"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "lts_task_execution" ADD CONSTRAINT "lts_task_execution_lts_task_id_fkey" FOREIGN KEY ("lts_task_id") REFERENCES "lts_task"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

View file

@ -371,3 +371,630 @@ model quest_user_company {
@@index([quest_company_id])
@@map("quest_user_company")
}
// Account request for new user registration
model quest_account_request {
id String @id @default(cuid())
first_name String
last_name String
email String
phone String?
company_name String
epicor_cust_id String?
message String?
request_processed Boolean @default(false)
processed_at DateTime?
processed_by String?
approved Boolean @default(false)
rejection_reason String?
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@index([email])
@@index([request_processed])
@@map("quest_account_request")
}
// Notification/alert system
model quest_notification {
id String @id @default(cuid())
title String
text String
is_alert Boolean @default(false)
display_date DateTime
display_time String?
is_active Boolean @default(true)
created_at DateTime @default(now())
updated_at DateTime @updatedAt
alert_reads quest_user_notification_alert_read[]
@@index([is_alert])
@@index([display_date])
@@index([is_active])
@@map("quest_notification")
}
// Tracking which users have read alert notifications
model quest_user_notification_alert_read {
id String @id @default(cuid())
quest_notification_id String
auth_user_id String
read_at DateTime @default(now())
notification quest_notification @relation(fields: [quest_notification_id], references: [id], onDelete: Cascade)
@@unique([quest_notification_id, auth_user_id])
@@index([auth_user_id])
@@map("quest_user_notification_alert_read")
}
// Email event definitions (types of emails that can be sent)
model quest_email_event {
id String @id @default(cuid())
name String @unique
description String?
is_active Boolean @default(true)
created_at DateTime @default(now())
updated_at DateTime @updatedAt
user_subscriptions quest_user_email_event[]
@@map("quest_email_event")
}
// User subscriptions to email events (many-to-many)
model quest_user_email_event {
id String @id @default(cuid())
auth_user_id String
quest_email_event_id String
subscribed Boolean @default(true)
created_at DateTime @default(now())
email_event quest_email_event @relation(fields: [quest_email_event_id], references: [id], onDelete: Cascade)
@@unique([auth_user_id, quest_email_event_id])
@@index([auth_user_id])
@@map("quest_user_email_event")
}
// Email log for tracking sent emails
model quest_email_log {
id String @id @default(cuid())
to_addresses String[] // Array of recipient emails
from_address String
subject String
body String
sent_at DateTime @default(now())
status String @default("sent") // sent, failed, pending
error_message String?
quest_email_event_id String?
auth_user_id String?
@@index([sent_at])
@@index([status])
@@index([auth_user_id])
@@map("quest_email_log")
}
// Plant/facility definitions
model quest_plant {
id String @id @default(cuid())
name String @unique
code String @unique
is_active Boolean @default(true)
created_at DateTime @default(now())
updated_at DateTime @updatedAt
inventory_assignments quest_inventory_plant[]
@@map("quest_plant")
}
// Inventory type definitions (WIP, Finished Goods, etc.)
model quest_inventory_type {
id String @id @default(cuid())
name String @unique
code String @unique
description String?
is_active Boolean @default(true)
sort_order Int @default(0)
created_at DateTime @default(now())
updated_at DateTime @updatedAt
plant_assignments quest_inventory_plant[]
@@map("quest_inventory_type")
}
// Junction: which inventory types are available at which plants
model quest_inventory_plant {
id String @id @default(cuid())
quest_plant_id String
quest_inventory_type_id String
is_active Boolean @default(true)
created_at DateTime @default(now())
plant quest_plant @relation(fields: [quest_plant_id], references: [id], onDelete: Cascade)
inventory_type quest_inventory_type @relation(fields: [quest_inventory_type_id], references: [id], onDelete: Cascade)
@@unique([quest_plant_id, quest_inventory_type_id])
@@index([quest_plant_id])
@@index([quest_inventory_type_id])
@@map("quest_inventory_plant")
}
// Tracking processed order acknowledgement emails to prevent duplicates
model quest_processed_order_acknowledgement_email {
id String @id @default(cuid())
epicor_order_num Int
epicor_cust_id String
epicor_po_num String?
sent_at DateTime @default(now())
quest_company_id String?
@@unique([epicor_order_num, epicor_cust_id])
@@index([epicor_cust_id])
@@index([sent_at])
@@map("quest_processed_order_acknowledgement_email")
}
// =============================================================================
// SHIPMENT REQUEST DOMAIN
// =============================================================================
// Shipment request header
model ship_request {
id String @id @default(cuid())
auth_user_id String
quest_company_id String
ship_to_address String
order_number String?
po_number String?
release_number String?
pickup_date DateTime?
instructions String?
email_recipients String[] // Array of email addresses
is_submitted Boolean @default(false)
submitted_at DateTime?
is_cancelled Boolean @default(false)
cancelled_at DateTime?
cancelled_by String?
last_cart_activity DateTime @default(now())
created_at DateTime @default(now())
updated_at DateTime @updatedAt
details ship_request_detail[]
@@index([auth_user_id])
@@index([quest_company_id])
@@index([is_submitted])
@@index([is_cancelled])
@@map("ship_request")
}
// Shipment request line items
model ship_request_detail {
id String @id @default(cuid())
ship_request_id String
part_num String
lot_num String?
plant String
warehouse String?
quantity Float
notes String?
created_at DateTime @default(now())
request ship_request @relation(fields: [ship_request_id], references: [id], onDelete: Cascade)
@@index([ship_request_id])
@@map("ship_request_detail")
}
// =============================================================================
// ALLOCATION REQUEST DOMAIN
// =============================================================================
// Coil allocation request header
model alloc_request {
id String @id @default(cuid())
auth_user_id String
quest_company_id String
job_number String
ship_to_address String
order_number String?
po_number String?
release_number String?
pickup_date DateTime?
instructions String?
email_recipients String[] // Array of email addresses
is_submitted Boolean @default(false)
submitted_at DateTime?
is_cancelled Boolean @default(false)
cancelled_at DateTime?
cancelled_by String?
last_cart_activity DateTime @default(now())
created_at DateTime @default(now())
updated_at DateTime @updatedAt
details alloc_request_detail[]
@@index([auth_user_id])
@@index([quest_company_id])
@@index([job_number])
@@index([is_submitted])
@@map("alloc_request")
}
// Allocation request line items
model alloc_request_detail {
id String @id @default(cuid())
alloc_request_id String
part_num String
lot_num String?
coil_number String?
quantity Float
notes String?
created_at DateTime @default(now())
request alloc_request @relation(fields: [alloc_request_id], references: [id], onDelete: Cascade)
@@index([alloc_request_id])
@@map("alloc_request_detail")
}
// Allocation plant assignments (which plants can allocate)
model alloc_plant {
id String @id @default(cuid())
plant_code String @unique
plant_name String
is_active Boolean @default(true)
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@map("alloc_plant")
}
// =============================================================================
// INVOICE UPLOAD DOMAIN
// =============================================================================
// Invoice upload batch status
model inv_upload_status {
id String @id @default(cuid())
name String @unique
description String?
sort_order Int @default(0)
uploads inv_upload[]
@@map("inv_upload_status")
}
// Invoice upload batch
model inv_upload {
id String @id @default(cuid())
auth_user_id String
original_filename String
storage_filename String
file_path String
file_size Int
total_pages Int?
inv_upload_status_id String
upload_notes String?
created_at DateTime @default(now())
processed_at DateTime?
status inv_upload_status @relation(fields: [inv_upload_status_id], references: [id])
entries inv_upload_entry[]
@@index([auth_user_id])
@@index([inv_upload_status_id])
@@index([created_at])
@@map("inv_upload")
}
// Individual invoice entries from upload
model inv_upload_entry {
id String @id @default(cuid())
inv_upload_id String
invoice_number String
epicor_cust_id String?
quest_company_id String?
job_number String?
page_number Int?
storage_filename String?
file_path String?
is_ignored Boolean @default(false)
is_replaced Boolean @default(false)
send_error String?
created_at DateTime @default(now())
sent_at DateTime?
upload inv_upload @relation(fields: [inv_upload_id], references: [id], onDelete: Cascade)
@@index([inv_upload_id])
@@index([invoice_number])
@@index([epicor_cust_id])
@@index([quest_company_id])
@@map("inv_upload_entry")
}
// =============================================================================
// FINANCE/AP CHECK PROCESSING DOMAIN
// =============================================================================
// AP check processing status definitions
model finance_ap_check_processing_status {
id String @id @default(cuid())
name String @unique
description String?
sort_order Int @default(0)
batches finance_ap_check_processing_batch[]
@@map("finance_ap_check_processing_status")
}
// AP check processing batch tracking
model finance_ap_check_processing_batch {
id String @id @default(cuid())
auth_user_id String
group_id String
original_filename String
generated_csv_filename String?
generated_csv_path String?
finance_ap_check_processing_status_id String
error_message String?
record_count Int @default(0)
created_at DateTime @default(now())
processed_at DateTime?
status finance_ap_check_processing_status @relation(fields: [finance_ap_check_processing_status_id], references: [id])
@@index([auth_user_id])
@@index([group_id])
@@index([finance_ap_check_processing_status_id])
@@map("finance_ap_check_processing_batch")
}
// =============================================================================
// PAINT SCHEDULE DOMAIN
// =============================================================================
// Paint line types
model paint_line_type {
id String @id @default(cuid())
name String @unique
description String?
lines paint_line[]
@@map("paint_line_type")
}
// Paint plants
model paint_plant {
id String @id @default(cuid())
name String @unique
code String @unique
is_active Boolean @default(true)
plant_lines paint_plant_line[]
@@map("paint_plant")
}
// Paint lines
model paint_line {
id String @id @default(cuid())
name String @unique
paint_line_type_id String
is_active Boolean @default(true)
line_type paint_line_type @relation(fields: [paint_line_type_id], references: [id])
plant_lines paint_plant_line[]
schedules paint_schedule[]
@@map("paint_line")
}
// Junction: which lines are at which plants
model paint_plant_line {
id String @id @default(cuid())
paint_plant_id String
paint_line_id String
is_active Boolean @default(true)
plant paint_plant @relation(fields: [paint_plant_id], references: [id], onDelete: Cascade)
line paint_line @relation(fields: [paint_line_id], references: [id], onDelete: Cascade)
@@unique([paint_plant_id, paint_line_id])
@@map("paint_plant_line")
}
// Paint schedule entries
model paint_schedule {
id String @id @default(cuid())
paint_line_id String
job_id String?
part_description String?
customer String?
quantity Int?
estimated_run_time Float?
start_time DateTime?
notes String?
is_complete Boolean @default(false)
line_speed Float?
created_at DateTime @default(now())
updated_at DateTime @updatedAt
line paint_line @relation(fields: [paint_line_id], references: [id])
@@index([paint_line_id])
@@index([start_time])
@@index([is_complete])
@@map("paint_schedule")
}
// =============================================================================
// DOCUMENTATION/KNOWLEDGE BASE DOMAIN
// =============================================================================
// Documentation categories
model doc_category {
id String @id @default(cuid())
name String @unique
description String?
icon String?
sort_order Int @default(0)
is_active Boolean @default(true)
created_at DateTime @default(now())
updated_at DateTime @updatedAt
articles doc_article[]
@@map("doc_category")
}
// Documentation articles
model doc_article {
id String @id @default(cuid())
title String
content String
doc_category_id String
is_published Boolean @default(false)
sort_order Int @default(0)
created_at DateTime @default(now())
updated_at DateTime @updatedAt
created_by String?
updated_by String?
category doc_category @relation(fields: [doc_category_id], references: [id])
permission_groups doc_article_permission_group[]
@@index([doc_category_id])
@@index([is_published])
@@map("doc_article")
}
// Junction: which permission groups can see which articles
model doc_article_permission_group {
id String @id @default(cuid())
doc_article_id String
auth_permission_group_id String
created_at DateTime @default(now())
article doc_article @relation(fields: [doc_article_id], references: [id], onDelete: Cascade)
@@unique([doc_article_id, auth_permission_group_id])
@@map("doc_article_permission_group")
}
// =============================================================================
// WAVE/EDI PROCESSING DOMAIN
// =============================================================================
// Wave process definitions
model wave_process {
id String @id @default(cuid())
name String @unique
description String?
is_enabled Boolean @default(true)
schedule_cron String?
created_at DateTime @default(now())
updated_at DateTime @updatedAt
history wave_process_history[]
@@map("wave_process")
}
// Wave process execution history
model wave_process_history {
id String @id @default(cuid())
wave_process_id String
started_at DateTime @default(now())
completed_at DateTime?
status String @default("running") // running, success, failed
result_message String?
error_message String?
process wave_process @relation(fields: [wave_process_id], references: [id])
@@index([wave_process_id])
@@index([started_at])
@@index([status])
@@map("wave_process_history")
}
// =============================================================================
// LTS (LONG-TERM SCHEDULER) TASK DOMAIN
// =============================================================================
// Task types
model lts_task_type {
id String @id @default(cuid())
name String @unique
description String?
tasks lts_task[]
@@map("lts_task_type")
}
// Scheduled tasks
model lts_task {
id String @id @default(cuid())
lts_task_type_id String
name String
description String?
command String
is_enabled Boolean @default(true)
created_at DateTime @default(now())
updated_at DateTime @updatedAt
task_type lts_task_type @relation(fields: [lts_task_type_id], references: [id])
schedules lts_task_schedule[]
executions lts_task_execution[]
@@map("lts_task")
}
// Task schedule definitions
model lts_task_schedule {
id String @id @default(cuid())
lts_task_id String
schedule_type String // cron, interval, daily, weekly, monthly
schedule_value String // cron expression or interval value
timezone String @default("UTC")
is_active Boolean @default(true)
next_run_at DateTime?
created_at DateTime @default(now())
updated_at DateTime @updatedAt
task lts_task @relation(fields: [lts_task_id], references: [id], onDelete: Cascade)
@@index([lts_task_id])
@@index([next_run_at])
@@map("lts_task_schedule")
}
// Task execution log
model lts_task_execution {
id String @id @default(cuid())
lts_task_id String
started_at DateTime @default(now())
completed_at DateTime?
status String @default("running") // running, success, failed
output String?
error_message String?
exit_code Int?
task lts_task @relation(fields: [lts_task_id], references: [id])
@@index([lts_task_id])
@@index([started_at])
@@index([status])
@@map("lts_task_execution")
}