generator client { provider = "prisma-client-js" } datasource db { provider = "mysql" url = env("DATABASE_URL") } model SysUser { id BigInt @id @default(autoincrement()) @db.UnsignedBigInt userId String @unique @map("user_id") @db.VarChar(32) customerId String? @unique @map("customer_id") @db.VarChar(32) username String @unique @db.VarChar(64) passwordHash String @map("password_hash") @db.VarChar(255) role String @db.VarChar(16) isDeleted Boolean @default(false) @map("is_deleted") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") @@map("sys_user") } model QuoteRecord { id BigInt @id @default(autoincrement()) @db.UnsignedBigInt quoteId String @unique @map("quote_id") @db.VarChar(32) requestId String @map("request_id") @db.VarChar(36) customerId String @map("customer_id") @db.VarChar(32) cargoHash String @map("cargo_hash") @db.Char(32) status String @default("processing") @db.VarChar(16) sourceType String? @map("source_type") @db.VarChar(16) isRealtime Boolean @default(true) @map("is_realtime") confidenceScore Decimal? @map("confidence_score") @db.Decimal(3, 2) currency String @default("USD") @db.VarChar(8) pickupJson Json @map("pickup_json") deliveryJson Json @map("delivery_json") weightLb Decimal @map("weight_lb") @db.Decimal(12, 2) dimLIn Decimal @map("dim_l_in") @db.Decimal(8, 2) dimWIn Decimal @map("dim_w_in") @db.Decimal(8, 2) dimHIn Decimal @map("dim_h_in") @db.Decimal(8, 2) palletCount Int @map("pallet_count") cargoType String @map("cargo_type") @db.VarChar(32) quotesJson Json? @map("quotes_json") markupPercent Decimal @default(0.0) @map("markup_percent") @db.Decimal(5, 2) validUntil DateTime? @map("valid_until") errorCode String? @map("error_code") @db.VarChar(32) errorMessage String? @map("error_message") @db.VarChar(512) ccCustomerId String? @map("cc_customer_id") @db.VarChar(32) forecastId String? @map("forecast_id") @db.VarChar(32) isDeleted Boolean @default(false) @map("is_deleted") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") @@index([customerId, createdAt], map: "idx_customer_created") @@index([cargoHash], map: "idx_cargo_hash") @@index([requestId], map: "idx_request") @@map("quote_record") } model IdempotencyRecord { id BigInt @id @default(autoincrement()) @db.UnsignedBigInt requestId String @unique @map("request_id") @db.VarChar(36) customerId String @map("customer_id") @db.VarChar(32) quoteId String @map("quote_id") @db.VarChar(32) expireAt DateTime @map("expire_at") createdAt DateTime @default(now()) @map("created_at") @@map("idempotency_record") } model QuoteCacheMeta { id BigInt @id @default(autoincrement()) @db.UnsignedBigInt cargoHash String @unique @map("cargo_hash") @db.Char(32) rawTotalStandard Decimal @map("raw_total_standard") @db.Decimal(12, 2) rawTotalGuaranteed Decimal @map("raw_total_guaranteed") @db.Decimal(12, 2) lastQuotesJson Json @map("last_quotes_json") refreshedAt DateTime @default(now()) @map("refreshed_at") @@map("quote_cache_meta") } model MarkupConfig { id BigInt @id @default(autoincrement()) @db.UnsignedBigInt customerId String @unique @map("customer_id") @db.VarChar(32) markupType String @default("percent") @map("markup_type") @db.VarChar(16) markupPercent Decimal @map("markup_percent") @db.Decimal(5, 2) markupFixedAmount Decimal? @map("markup_fixed_amount") @db.Decimal(12, 2) operatorId String @map("operator_id") @db.VarChar(32) remark String? @db.VarChar(255) isDeleted Boolean @default(false) @map("is_deleted") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") @@map("markup_config") } model AlertLog { id BigInt @id @default(autoincrement()) @db.UnsignedBigInt alertType String @map("alert_type") @db.VarChar(32) quoteId String? @map("quote_id") @db.VarChar(32) cargoHash String? @map("cargo_hash") @db.Char(32) detailJson Json? @map("detail_json") status String @default("open") @db.VarChar(16) resolverId String? @map("resolver_id") @db.VarChar(32) resolvedAt DateTime? @map("resolved_at") createdAt DateTime @default(now()) @map("created_at") @@index([alertType, status], map: "idx_type_status") @@index([createdAt], map: "idx_created") @@map("alert_log") } model AuditLog { id BigInt @id @default(autoincrement()) @db.UnsignedBigInt action String @db.VarChar(64) actorId String @map("actor_id") @db.VarChar(32) resource String? @db.VarChar(128) detailJson Json? @map("detail_json") createdAt DateTime @default(now()) @map("created_at") @@index([actorId, createdAt], map: "idx_actor_created") @@index([action, createdAt], map: "idx_action_created") @@map("audit_log") } model HostCustomer { id BigInt @id @default(autoincrement()) @db.UnsignedBigInt customerId String @unique @map("customer_id") @db.VarChar(32) name String @db.VarChar(128) status String @default("active") @db.VarChar(16) remark String? @db.VarChar(255) embedPasswordHash String? @map("embed_password_hash") @db.VarChar(255) isDeleted Boolean @default(false) @map("is_deleted") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") apiKeys ServiceApiKey[] @@index([status, isDeleted], map: "idx_host_customer_status") @@map("host_customer") } model ServiceApiKey { id BigInt @id @default(autoincrement()) @db.UnsignedBigInt keyId String @unique @map("key_id") @db.VarChar(32) customerId String @map("customer_id") @db.VarChar(32) tokenHash String @unique @map("token_hash") @db.Char(64) tokenCiphertext String? @map("token_ciphertext") @db.Text keyPrefix String @map("key_prefix") @db.VarChar(16) permissions Json isActive Boolean @default(true) @map("is_active") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") customer HostCustomer @relation(fields: [customerId], references: [customerId]) @@index([customerId, isActive], map: "idx_service_api_key_customer") @@map("service_api_key") } model QuoteQueryLog { id BigInt @id @default(autoincrement()) @db.UnsignedBigInt quoteId String @unique @map("quote_id") @db.VarChar(32) requestId String @map("request_id") @db.VarChar(36) customerId String @map("customer_id") @db.VarChar(32) pickupJson Json @map("pickup_json") deliveryJson Json @map("delivery_json") cargoJson Json @map("cargo_json") outcome String @default("processing") @db.VarChar(16) failureReason String? @map("failure_reason") @db.VarChar(512) errorCode String? @map("error_code") @db.VarChar(32) sourceType String? @map("source_type") @db.VarChar(16) tierCount Int? @map("tier_count") createdAt DateTime @default(now()) @map("created_at") completedAt DateTime? @map("completed_at") @@index([createdAt], map: "idx_query_log_created") @@index([customerId, createdAt], map: "idx_query_log_customer") @@map("quote_query_log") } /** 客户级承运商官网登录账密(密码 AES-GCM 密文) */ model CustomerProviderCredential { id BigInt @id @default(autoincrement()) @db.UnsignedBigInt customerId String @map("customer_id") @db.VarChar(32) provider String @db.VarChar(16) loginEmail String @map("login_email") @db.VarChar(255) passwordCiphertext String @map("password_ciphertext") @db.Text updatedBy String? @map("updated_by") @db.VarChar(32) isDeleted Boolean @default(false) @map("is_deleted") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") @@unique([customerId, provider], map: "uq_customer_provider") @@index([customerId, isDeleted], map: "idx_cpc_customer") @@map("customer_provider_credential") }