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

@ -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")
}