feat(F-004,F-005): complete Quest and remaining domain schemas
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:
parent
e643af1fe6
commit
d8af580d93
4 changed files with 1378 additions and 18 deletions
|
|
@ -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")
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue