feat: add number library routing and cdr location support

This commit is contained in:
hectorzhao
2026-06-24 11:39:32 +08:00
parent 5fa1bd35e9
commit 7057fd3c42
63 changed files with 6361 additions and 566 deletions
@@ -0,0 +1,139 @@
-- CreateTable
CREATE TABLE `geo_cities` (
`code` VARCHAR(12) NOT NULL,
`province_code` VARCHAR(12) NOT NULL,
`province_name` VARCHAR(80) NOT NULL,
`city_code` VARCHAR(12) NOT NULL,
`city_name` VARCHAR(80) NOT NULL,
`city_level` VARCHAR(32) NOT NULL,
`status` ENUM('ENABLED', 'DISABLED') NOT NULL DEFAULT 'ENABLED',
`effective_from` DATETIME(3) NULL,
`effective_to` DATETIME(3) NULL,
`created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updated_at` DATETIME(3) NOT NULL,
`created_by` VARCHAR(32) NULL,
`updated_by` VARCHAR(32) NULL,
`version` INTEGER NOT NULL DEFAULT 1,
`deleted_at` DATETIME(3) NULL,
UNIQUE INDEX `geo_cities_city_code_key`(`city_code`),
INDEX `geo_cities_province_code_idx`(`province_code`),
INDEX `geo_cities_province_name_city_name_idx`(`province_name`, `city_name`),
INDEX `geo_cities_status_idx`(`status`),
INDEX `geo_cities_deleted_at_idx`(`deleted_at`),
PRIMARY KEY (`code`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `phone_number_segments` (
`segment7` CHAR(7) NOT NULL,
`city_code` VARCHAR(12) NOT NULL,
`province_name` VARCHAR(80) NOT NULL,
`city_name` VARCHAR(80) NOT NULL,
`carrier` ENUM('MOBILE', 'UNICOM', 'TELECOM', 'BROADCAST', 'MVNO', 'UNKNOWN') NOT NULL DEFAULT 'UNKNOWN',
`source` VARCHAR(120) NULL,
`batch_id` VARCHAR(64) NULL,
`effective_from` DATETIME(3) NULL,
`effective_to` DATETIME(3) NULL,
`created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updated_at` DATETIME(3) NOT NULL,
`created_by` VARCHAR(32) NULL,
`updated_by` VARCHAR(32) NULL,
`version` INTEGER NOT NULL DEFAULT 1,
`deleted_at` DATETIME(3) NULL,
INDEX `phone_number_segments_city_code_idx`(`city_code`),
INDEX `phone_number_segments_carrier_idx`(`carrier`),
INDEX `phone_number_segments_batch_id_idx`(`batch_id`),
INDEX `phone_number_segments_deleted_at_idx`(`deleted_at`),
PRIMARY KEY (`segment7`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `phone_area_codes` (
`area_code` VARCHAR(8) NOT NULL,
`city_code` VARCHAR(12) NOT NULL,
`province_name` VARCHAR(80) NOT NULL,
`city_name` VARCHAR(80) NOT NULL,
`source` VARCHAR(120) NULL,
`batch_id` VARCHAR(64) NULL,
`created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updated_at` DATETIME(3) NOT NULL,
`created_by` VARCHAR(32) NULL,
`updated_by` VARCHAR(32) NULL,
`version` INTEGER NOT NULL DEFAULT 1,
`deleted_at` DATETIME(3) NULL,
INDEX `phone_area_codes_city_code_idx`(`city_code`),
INDEX `phone_area_codes_batch_id_idx`(`batch_id`),
INDEX `phone_area_codes_deleted_at_idx`(`deleted_at`),
PRIMARY KEY (`area_code`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `carrier_prefix_rules` (
`prefix` VARCHAR(4) NOT NULL,
`carrier` ENUM('MOBILE', 'UNICOM', 'TELECOM', 'BROADCAST', 'MVNO', 'UNKNOWN') NOT NULL,
`priority` INTEGER NOT NULL DEFAULT 100,
`source` VARCHAR(120) NULL,
`batch_id` VARCHAR(64) NULL,
`effective_from` DATETIME(3) NULL,
`effective_to` DATETIME(3) NULL,
`created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updated_at` DATETIME(3) NOT NULL,
`created_by` VARCHAR(32) NULL,
`updated_by` VARCHAR(32) NULL,
`version` INTEGER NOT NULL DEFAULT 1,
`deleted_at` DATETIME(3) NULL,
INDEX `carrier_prefix_rules_carrier_idx`(`carrier`),
INDEX `carrier_prefix_rules_priority_idx`(`priority`),
INDEX `carrier_prefix_rules_batch_id_idx`(`batch_id`),
INDEX `carrier_prefix_rules_deleted_at_idx`(`deleted_at`),
PRIMARY KEY (`prefix`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `vendor_gateway_blocked_regions` (
`id` VARCHAR(32) NOT NULL,
`vendor_gateway_id` VARCHAR(32) NOT NULL,
`region_scope` ENUM('PROVINCE', 'CITY') NOT NULL,
`province_code` VARCHAR(12) NULL,
`province_name` VARCHAR(80) NULL,
`city_code` VARCHAR(12) NULL,
`city_name` VARCHAR(80) NULL,
`created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`created_by` VARCHAR(32) NULL,
INDEX `vendor_gateway_blocked_regions_vendor_gateway_id_idx`(`vendor_gateway_id`),
INDEX `vendor_gateway_blocked_regions_province_code_idx`(`province_code`),
INDEX `vendor_gateway_blocked_regions_city_code_idx`(`city_code`),
UNIQUE INDEX `vendor_gateway_blocked_regions_vendor_gateway_id_region_scope_province_code_city_code_key`(`vendor_gateway_id`, `region_scope`, `province_code`, `city_code`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- AlterTable
ALTER TABLE `raw_cdrs`
ADD COLUMN `callee_city_code` VARCHAR(12) NULL,
ADD COLUMN `callee_city_name` VARCHAR(80) NULL,
ADD COLUMN `callee_province_name` VARCHAR(80) NULL,
ADD COLUMN `callee_operator` ENUM('MOBILE', 'UNICOM', 'TELECOM', 'BROADCAST', 'MVNO', 'UNKNOWN') NOT NULL DEFAULT 'UNKNOWN',
ADD COLUMN `callee_number_type` ENUM('MOBILE', 'LANDLINE', 'INTERNATIONAL', 'UNKNOWN') NOT NULL DEFAULT 'UNKNOWN';
-- CreateIndex
CREATE INDEX `raw_cdrs_callee_city_code_started_at_idx` ON `raw_cdrs`(`callee_city_code`, `started_at`);
-- CreateIndex
CREATE INDEX `raw_cdrs_callee_operator_started_at_idx` ON `raw_cdrs`(`callee_operator`, `started_at`);
-- AddForeignKey
ALTER TABLE `phone_number_segments` ADD CONSTRAINT `phone_number_segments_city_code_fkey` FOREIGN KEY (`city_code`) REFERENCES `geo_cities`(`city_code`) ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `phone_area_codes` ADD CONSTRAINT `phone_area_codes_city_code_fkey` FOREIGN KEY (`city_code`) REFERENCES `geo_cities`(`city_code`) ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `vendor_gateway_blocked_regions` ADD CONSTRAINT `vendor_gateway_blocked_regions_vendor_gateway_id_fkey` FOREIGN KEY (`vendor_gateway_id`) REFERENCES `vendor_gateways`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `vendor_gateway_blocked_regions` ADD CONSTRAINT `vendor_gateway_blocked_regions_city_code_fkey` FOREIGN KEY (`city_code`) REFERENCES `geo_cities`(`city_code`) ON DELETE RESTRICT ON UPDATE CASCADE;
+483 -329
View File
@@ -52,6 +52,33 @@ enum PrefixRuleDirection {
@@map("prefix_rule_direction")
}
enum NumberCarrier {
MOBILE
UNICOM
TELECOM
BROADCAST
MVNO
UNKNOWN
@@map("number_carrier")
}
enum PhoneNumberType {
MOBILE
LANDLINE
INTERNATIONAL
UNKNOWN
@@map("phone_number_type")
}
enum RegionScope {
PROVINCE
CITY
@@map("region_scope")
}
enum CdrRatingStatus {
UNRATED
RATED
@@ -104,30 +131,30 @@ enum IdempotencyStatus {
}
model Customer {
id String @id @db.VarChar(32)
name String @unique @db.VarChar(120)
contactName String? @map("contact_name") @db.VarChar(80)
phone String? @db.VarChar(32)
email String? @db.VarChar(160)
domain String? @unique @db.VarChar(160)
status EntityStatus @default(ENABLED)
billingMode CustomerBillingMode @default(PREPAID) @map("billing_mode")
balance Decimal @default(0) @db.Decimal(20, 6)
creditLimit Decimal @default(0) @map("credit_limit") @db.Decimal(20, 6)
minBalance Decimal @default(0) @map("min_balance") @db.Decimal(20, 6)
notes String? @db.VarChar(500)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
deletedAt DateTime? @map("deleted_at") @db.DateTime(3)
id String @id @db.VarChar(32)
name String @unique @db.VarChar(120)
contactName String? @map("contact_name") @db.VarChar(80)
phone String? @db.VarChar(32)
email String? @db.VarChar(160)
domain String? @unique @db.VarChar(160)
status EntityStatus @default(ENABLED)
billingMode CustomerBillingMode @default(PREPAID) @map("billing_mode")
balance Decimal @default(0) @db.Decimal(20, 6)
creditLimit Decimal @default(0) @map("credit_limit") @db.Decimal(20, 6)
minBalance Decimal @default(0) @map("min_balance") @db.Decimal(20, 6)
notes String? @db.VarChar(500)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
deletedAt DateTime? @map("deleted_at") @db.DateTime(3)
gateways CustomerGateway[]
policies CustomerGatewayPolicy[]
recharges CustomerRecharge[]
rawCdrs RawCdr[]
samplingRules QualitySamplingRule[]
gateways CustomerGateway[]
policies CustomerGatewayPolicy[]
recharges CustomerRecharge[]
rawCdrs RawCdr[]
samplingRules QualitySamplingRule[]
@@index([status])
@@index([deletedAt])
@@ -135,25 +162,25 @@ model Customer {
}
model CustomerGateway {
id String @id @db.VarChar(32)
customerId String @map("customer_id") @db.VarChar(32)
name String @db.VarChar(120)
authMode GatewayAuthMode @map("auth_mode")
sourceIp String? @map("source_ip") @db.VarChar(45)
sipUsername String? @map("sip_username") @db.VarChar(120)
sipDomain String? @map("sip_domain") @db.VarChar(160)
sipHa1 String? @map("sip_ha1") @db.VarChar(128)
status EntityStatus @default(ENABLED)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
deletedAt DateTime? @map("deleted_at") @db.DateTime(3)
id String @id @db.VarChar(32)
customerId String @map("customer_id") @db.VarChar(32)
name String @db.VarChar(120)
authMode GatewayAuthMode @map("auth_mode")
sourceIp String? @map("source_ip") @db.VarChar(45)
sipUsername String? @map("sip_username") @db.VarChar(120)
sipDomain String? @map("sip_domain") @db.VarChar(160)
sipHa1 String? @map("sip_ha1") @db.VarChar(128)
status EntityStatus @default(ENABLED)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
deletedAt DateTime? @map("deleted_at") @db.DateTime(3)
customer Customer @relation(fields: [customerId], references: [id], onDelete: Restrict)
policies CustomerGatewayPolicy[]
rawCdrs RawCdr[]
customer Customer @relation(fields: [customerId], references: [id], onDelete: Restrict)
policies CustomerGatewayPolicy[]
rawCdrs RawCdr[]
@@unique([customerId, name])
@@unique([sipUsername, sipDomain])
@@ -164,28 +191,28 @@ model CustomerGateway {
}
model CustomerGatewayPolicy {
id String @id @db.VarChar(32)
customerId String @map("customer_id") @db.VarChar(32)
gatewayId String @map("gateway_id") @db.VarChar(32)
lineGroupId String @map("line_group_id") @db.VarChar(32)
name String @db.VarChar(120)
priority Int
callerMode MatchMode @default(ANY) @map("caller_mode")
callerValue String? @map("caller_value") @db.VarChar(64)
calleeMode MatchMode @default(ANY) @map("callee_mode")
calleeValue String? @map("callee_value") @db.VarChar(64)
status EntityStatus @default(ENABLED)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
deletedAt DateTime? @map("deleted_at") @db.DateTime(3)
id String @id @db.VarChar(32)
customerId String @map("customer_id") @db.VarChar(32)
gatewayId String @map("gateway_id") @db.VarChar(32)
lineGroupId String @map("line_group_id") @db.VarChar(32)
name String @db.VarChar(120)
priority Int
callerMode MatchMode @default(ANY) @map("caller_mode")
callerValue String? @map("caller_value") @db.VarChar(64)
calleeMode MatchMode @default(ANY) @map("callee_mode")
calleeValue String? @map("callee_value") @db.VarChar(64)
status EntityStatus @default(ENABLED)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
deletedAt DateTime? @map("deleted_at") @db.DateTime(3)
customer Customer @relation(fields: [customerId], references: [id], onDelete: Restrict)
gateway CustomerGateway @relation(fields: [gatewayId], references: [id], onDelete: Restrict)
lineGroup LandingLineGroup @relation(fields: [lineGroupId], references: [id], onDelete: Restrict)
rawCdrs RawCdr[]
customer Customer @relation(fields: [customerId], references: [id], onDelete: Restrict)
gateway CustomerGateway @relation(fields: [gatewayId], references: [id], onDelete: Restrict)
lineGroup LandingLineGroup @relation(fields: [lineGroupId], references: [id], onDelete: Restrict)
rawCdrs RawCdr[]
@@unique([gatewayId, priority])
@@index([customerId, status])
@@ -195,45 +222,45 @@ model CustomerGatewayPolicy {
}
model CustomerRecharge {
id String @id @db.VarChar(40)
customerId String @map("customer_id") @db.VarChar(32)
amount Decimal @db.Decimal(20, 6)
beforeBalance Decimal @map("before_balance") @db.Decimal(20, 6)
afterBalance Decimal @map("after_balance") @db.Decimal(20, 6)
idempotencyKey String @unique @map("idempotency_key") @db.VarChar(128)
remark String? @db.VarChar(500)
status RechargeStatus @default(SUCCEEDED)
occurredAt DateTime @default(now()) @map("occurred_at") @db.DateTime(3)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
id String @id @db.VarChar(40)
customerId String @map("customer_id") @db.VarChar(32)
amount Decimal @db.Decimal(20, 6)
beforeBalance Decimal @map("before_balance") @db.Decimal(20, 6)
afterBalance Decimal @map("after_balance") @db.Decimal(20, 6)
idempotencyKey String @unique @map("idempotency_key") @db.VarChar(128)
remark String? @db.VarChar(500)
status RechargeStatus @default(SUCCEEDED)
occurredAt DateTime @default(now()) @map("occurred_at") @db.DateTime(3)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
customer Customer @relation(fields: [customerId], references: [id], onDelete: Restrict)
customer Customer @relation(fields: [customerId], references: [id], onDelete: Restrict)
@@index([customerId, occurredAt])
@@map("customer_recharges")
}
model Vendor {
id String @id @db.VarChar(32)
name String @unique @db.VarChar(120)
contactName String? @map("contact_name") @db.VarChar(80)
phone String? @db.VarChar(32)
email String? @db.VarChar(160)
status EntityStatus @default(ENABLED)
balance Decimal @default(0) @db.Decimal(20, 6)
creditLimit Decimal @default(0) @map("credit_limit") @db.Decimal(20, 6)
settlement String? @db.VarChar(80)
notes String? @db.VarChar(500)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
deletedAt DateTime? @map("deleted_at") @db.DateTime(3)
id String @id @db.VarChar(32)
name String @unique @db.VarChar(120)
contactName String? @map("contact_name") @db.VarChar(80)
phone String? @db.VarChar(32)
email String? @db.VarChar(160)
status EntityStatus @default(ENABLED)
balance Decimal @default(0) @db.Decimal(20, 6)
creditLimit Decimal @default(0) @map("credit_limit") @db.Decimal(20, 6)
settlement String? @db.VarChar(80)
notes String? @db.VarChar(500)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
deletedAt DateTime? @map("deleted_at") @db.DateTime(3)
gateways VendorGateway[]
recharges VendorRecharge[]
rawCdrs RawCdr[]
gateways VendorGateway[]
recharges VendorRecharge[]
rawCdrs RawCdr[]
@@index([status])
@@index([deletedAt])
@@ -241,52 +268,53 @@ model Vendor {
}
model VendorRecharge {
id String @id @db.VarChar(40)
vendorId String @map("vendor_id") @db.VarChar(32)
amount Decimal @db.Decimal(20, 6)
beforeBalance Decimal @map("before_balance") @db.Decimal(20, 6)
afterBalance Decimal @map("after_balance") @db.Decimal(20, 6)
idempotencyKey String @unique @map("idempotency_key") @db.VarChar(128)
remark String? @db.VarChar(500)
status RechargeStatus @default(SUCCEEDED)
occurredAt DateTime @default(now()) @map("occurred_at") @db.DateTime(3)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
id String @id @db.VarChar(40)
vendorId String @map("vendor_id") @db.VarChar(32)
amount Decimal @db.Decimal(20, 6)
beforeBalance Decimal @map("before_balance") @db.Decimal(20, 6)
afterBalance Decimal @map("after_balance") @db.Decimal(20, 6)
idempotencyKey String @unique @map("idempotency_key") @db.VarChar(128)
remark String? @db.VarChar(500)
status RechargeStatus @default(SUCCEEDED)
occurredAt DateTime @default(now()) @map("occurred_at") @db.DateTime(3)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
vendor Vendor @relation(fields: [vendorId], references: [id], onDelete: Restrict)
vendor Vendor @relation(fields: [vendorId], references: [id], onDelete: Restrict)
@@index([vendorId, occurredAt])
@@map("vendor_recharges")
}
model VendorGateway {
id String @id @db.VarChar(32)
vendorId String @map("vendor_id") @db.VarChar(32)
name String @db.VarChar(120)
authMode GatewayAuthMode @map("auth_mode")
host String @db.VarChar(160)
port Int @default(5060)
transport String @default("udp") @db.VarChar(16)
sipUsername String? @map("sip_username") @db.VarChar(120)
sipHa1 String? @map("sip_ha1") @db.VarChar(128)
cpsLimit Int @default(0) @map("cps_limit")
concurrencyLimit Int @default(0) @map("concurrency_limit")
billingCycleSec Int @default(60) @map("billing_cycle_sec")
cycleRate Decimal @default(0) @map("cycle_rate") @db.Decimal(20, 6)
status EntityStatus @default(ENABLED)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
deletedAt DateTime? @map("deleted_at") @db.DateTime(3)
id String @id @db.VarChar(32)
vendorId String @map("vendor_id") @db.VarChar(32)
name String @db.VarChar(120)
authMode GatewayAuthMode @map("auth_mode")
host String @db.VarChar(160)
port Int @default(5060)
transport String @default("udp") @db.VarChar(16)
sipUsername String? @map("sip_username") @db.VarChar(120)
sipHa1 String? @map("sip_ha1") @db.VarChar(128)
cpsLimit Int @default(0) @map("cps_limit")
concurrencyLimit Int @default(0) @map("concurrency_limit")
billingCycleSec Int @default(60) @map("billing_cycle_sec")
cycleRate Decimal @default(0) @map("cycle_rate") @db.Decimal(20, 6)
status EntityStatus @default(ENABLED)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
deletedAt DateTime? @map("deleted_at") @db.DateTime(3)
vendor Vendor @relation(fields: [vendorId], references: [id], onDelete: Restrict)
forbiddenPeriods VendorGatewayForbiddenPeriod[]
codecs VendorGatewayCodec[]
prefixRules VendorGatewayPrefixRule[]
lineGroupItems LandingLineGroupItem[]
rawCdrs RawCdr[]
vendor Vendor @relation(fields: [vendorId], references: [id], onDelete: Restrict)
forbiddenPeriods VendorGatewayForbiddenPeriod[]
blockedRegions VendorGatewayBlockedRegion[]
codecs VendorGatewayCodec[]
prefixRules VendorGatewayPrefixRule[]
lineGroupItems LandingLineGroupItem[]
rawCdrs RawCdr[]
@@unique([vendorId, name])
@@index([vendorId, status])
@@ -295,36 +323,155 @@ model VendorGateway {
@@map("vendor_gateways")
}
model VendorGatewayForbiddenPeriod {
id String @id @db.VarChar(32)
vendorGatewayId String @map("vendor_gateway_id") @db.VarChar(32)
weekdayMask Int @map("weekday_mask")
startTime String @map("start_time") @db.VarChar(8)
endTime String @map("end_time") @db.VarChar(8)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
model GeoCity {
code String @id @db.VarChar(12)
provinceCode String @map("province_code") @db.VarChar(12)
provinceName String @map("province_name") @db.VarChar(80)
cityCode String @unique @map("city_code") @db.VarChar(12)
cityName String @map("city_name") @db.VarChar(80)
cityLevel String @map("city_level") @db.VarChar(32)
status EntityStatus @default(ENABLED)
effectiveFrom DateTime? @map("effective_from") @db.DateTime(3)
effectiveTo DateTime? @map("effective_to") @db.DateTime(3)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
deletedAt DateTime? @map("deleted_at") @db.DateTime(3)
vendorGateway VendorGateway @relation(fields: [vendorGatewayId], references: [id], onDelete: Cascade)
phoneSegments PhoneNumberSegment[]
areaCodes PhoneAreaCode[]
blockedRegions VendorGatewayBlockedRegion[]
@@index([provinceCode])
@@index([provinceName, cityName])
@@index([status])
@@index([deletedAt])
@@map("geo_cities")
}
model PhoneNumberSegment {
segment7 String @id @map("segment7") @db.Char(7)
cityCode String @map("city_code") @db.VarChar(12)
provinceName String @map("province_name") @db.VarChar(80)
cityName String @map("city_name") @db.VarChar(80)
carrier NumberCarrier @default(UNKNOWN)
source String? @db.VarChar(120)
batchId String? @map("batch_id") @db.VarChar(64)
effectiveFrom DateTime? @map("effective_from") @db.DateTime(3)
effectiveTo DateTime? @map("effective_to") @db.DateTime(3)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
deletedAt DateTime? @map("deleted_at") @db.DateTime(3)
city GeoCity @relation(fields: [cityCode], references: [cityCode], onDelete: Restrict)
@@index([cityCode])
@@index([carrier])
@@index([batchId])
@@index([deletedAt])
@@map("phone_number_segments")
}
model PhoneAreaCode {
areaCode String @id @map("area_code") @db.VarChar(8)
cityCode String @map("city_code") @db.VarChar(12)
provinceName String @map("province_name") @db.VarChar(80)
cityName String @map("city_name") @db.VarChar(80)
source String? @db.VarChar(120)
batchId String? @map("batch_id") @db.VarChar(64)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
deletedAt DateTime? @map("deleted_at") @db.DateTime(3)
city GeoCity @relation(fields: [cityCode], references: [cityCode], onDelete: Restrict)
@@index([cityCode])
@@index([batchId])
@@index([deletedAt])
@@map("phone_area_codes")
}
model CarrierPrefixRule {
prefix String @id @db.VarChar(4)
carrier NumberCarrier
priority Int @default(100)
source String? @db.VarChar(120)
batchId String? @map("batch_id") @db.VarChar(64)
effectiveFrom DateTime? @map("effective_from") @db.DateTime(3)
effectiveTo DateTime? @map("effective_to") @db.DateTime(3)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
deletedAt DateTime? @map("deleted_at") @db.DateTime(3)
@@index([carrier])
@@index([priority])
@@index([batchId])
@@index([deletedAt])
@@map("carrier_prefix_rules")
}
model VendorGatewayBlockedRegion {
id String @id @db.VarChar(32)
vendorGatewayId String @map("vendor_gateway_id") @db.VarChar(32)
regionScope RegionScope @map("region_scope")
provinceCode String? @map("province_code") @db.VarChar(12)
provinceName String? @map("province_name") @db.VarChar(80)
cityCode String? @map("city_code") @db.VarChar(12)
cityName String? @map("city_name") @db.VarChar(80)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
vendorGateway VendorGateway @relation(fields: [vendorGatewayId], references: [id], onDelete: Cascade)
city GeoCity? @relation(fields: [cityCode], references: [cityCode], onDelete: Restrict)
@@unique([vendorGatewayId, regionScope, provinceCode, cityCode])
@@index([vendorGatewayId])
@@index([provinceCode])
@@index([cityCode])
@@map("vendor_gateway_blocked_regions")
}
model VendorGatewayForbiddenPeriod {
id String @id @db.VarChar(32)
vendorGatewayId String @map("vendor_gateway_id") @db.VarChar(32)
weekdayMask Int @map("weekday_mask")
startTime String @map("start_time") @db.VarChar(8)
endTime String @map("end_time") @db.VarChar(8)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
vendorGateway VendorGateway @relation(fields: [vendorGatewayId], references: [id], onDelete: Cascade)
@@index([vendorGatewayId])
@@map("vendor_gateway_forbidden_periods")
}
model VendorGatewayCodec {
id String @id @db.VarChar(32)
vendorGatewayId String @map("vendor_gateway_id") @db.VarChar(32)
codec String @db.VarChar(32)
id String @id @db.VarChar(32)
vendorGatewayId String @map("vendor_gateway_id") @db.VarChar(32)
codec String @db.VarChar(32)
priority Int
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
vendorGateway VendorGateway @relation(fields: [vendorGatewayId], references: [id], onDelete: Cascade)
vendorGateway VendorGateway @relation(fields: [vendorGatewayId], references: [id], onDelete: Cascade)
@@unique([vendorGatewayId, codec])
@@unique([vendorGatewayId, priority])
@@ -344,7 +491,7 @@ model VendorGatewayPrefixRule {
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
vendorGateway VendorGateway @relation(fields: [vendorGatewayId], references: [id], onDelete: Cascade)
vendorGateway VendorGateway @relation(fields: [vendorGatewayId], references: [id], onDelete: Cascade)
@@unique([vendorGatewayId, direction, priority])
@@index([vendorGatewayId, direction])
@@ -352,21 +499,21 @@ model VendorGatewayPrefixRule {
}
model LandingLineGroup {
id String @id @db.VarChar(32)
name String @unique @db.VarChar(120)
status EntityStatus @default(ENABLED)
notes String? @db.VarChar(500)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
deletedAt DateTime? @map("deleted_at") @db.DateTime(3)
id String @id @db.VarChar(32)
name String @unique @db.VarChar(120)
status EntityStatus @default(ENABLED)
notes String? @db.VarChar(500)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
deletedAt DateTime? @map("deleted_at") @db.DateTime(3)
items LandingLineGroupItem[]
policies CustomerGatewayPolicy[]
rawCdrs RawCdr[]
rules QualitySamplingRule[]
items LandingLineGroupItem[]
policies CustomerGatewayPolicy[]
rawCdrs RawCdr[]
rules QualitySamplingRule[]
@@index([status])
@@index([deletedAt])
@@ -374,21 +521,21 @@ model LandingLineGroup {
}
model LandingLineGroupItem {
id String @id @db.VarChar(32)
lineGroupId String @map("line_group_id") @db.VarChar(32)
vendorGatewayId String @map("vendor_gateway_id") @db.VarChar(32)
id String @id @db.VarChar(32)
lineGroupId String @map("line_group_id") @db.VarChar(32)
vendorGatewayId String @map("vendor_gateway_id") @db.VarChar(32)
priority Int
weight Int @default(1)
concurrencyCap Int @default(0) @map("concurrency_cap")
status EntityStatus @default(ENABLED)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
weight Int @default(1)
concurrencyCap Int @default(0) @map("concurrency_cap")
status EntityStatus @default(ENABLED)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
lineGroup LandingLineGroup @relation(fields: [lineGroupId], references: [id], onDelete: Cascade)
vendorGateway VendorGateway @relation(fields: [vendorGatewayId], references: [id], onDelete: Restrict)
lineGroup LandingLineGroup @relation(fields: [lineGroupId], references: [id], onDelete: Cascade)
vendorGateway VendorGateway @relation(fields: [vendorGatewayId], references: [id], onDelete: Restrict)
@@unique([lineGroupId, vendorGatewayId])
@@unique([lineGroupId, priority])
@@ -397,104 +544,111 @@ model LandingLineGroupItem {
}
model RawCdr {
id String @id @db.VarChar(40)
eventId String @unique @map("event_id") @db.VarChar(64)
callId String @map("call_id") @db.VarChar(255)
customerId String? @map("customer_id") @db.VarChar(32)
customerGatewayId String? @map("customer_gateway_id") @db.VarChar(32)
customerGatewayPolicyId String? @map("customer_gateway_policy_id") @db.VarChar(32)
sourceIp String? @map("source_ip") @db.VarChar(45)
caller String @db.VarChar(64)
callee String @db.VarChar(64)
vendorId String? @map("vendor_id") @db.VarChar(32)
vendorGatewayId String? @map("vendor_gateway_id") @db.VarChar(32)
lineGroupId String? @map("line_group_id") @db.VarChar(32)
startedAt DateTime @map("started_at") @db.DateTime(3)
answeredAt DateTime? @map("answered_at") @db.DateTime(3)
endedAt DateTime @map("ended_at") @db.DateTime(3)
durationSec Int @default(0) @map("duration_sec")
sipCode Int @map("sip_code")
hangupReason String? @map("hangup_reason") @db.VarChar(120)
recordingKey String? @map("recording_key") @db.VarChar(255)
configVersion Int? @map("config_version")
ratingStatus CdrRatingStatus @default(UNRATED) @map("rating_status")
id String @id @db.VarChar(40)
eventId String @unique @map("event_id") @db.VarChar(64)
callId String @map("call_id") @db.VarChar(255)
customerId String? @map("customer_id") @db.VarChar(32)
customerGatewayId String? @map("customer_gateway_id") @db.VarChar(32)
customerGatewayPolicyId String? @map("customer_gateway_policy_id") @db.VarChar(32)
sourceIp String? @map("source_ip") @db.VarChar(45)
caller String @db.VarChar(64)
callee String @db.VarChar(64)
calleeCityCode String? @map("callee_city_code") @db.VarChar(12)
calleeCityName String? @map("callee_city_name") @db.VarChar(80)
calleeProvinceName String? @map("callee_province_name") @db.VarChar(80)
calleeOperator NumberCarrier @default(UNKNOWN) @map("callee_operator")
calleeNumberType PhoneNumberType @default(UNKNOWN) @map("callee_number_type")
vendorId String? @map("vendor_id") @db.VarChar(32)
vendorGatewayId String? @map("vendor_gateway_id") @db.VarChar(32)
lineGroupId String? @map("line_group_id") @db.VarChar(32)
startedAt DateTime @map("started_at") @db.DateTime(3)
answeredAt DateTime? @map("answered_at") @db.DateTime(3)
endedAt DateTime @map("ended_at") @db.DateTime(3)
durationSec Int @default(0) @map("duration_sec")
sipCode Int @map("sip_code")
hangupReason String? @map("hangup_reason") @db.VarChar(120)
recordingKey String? @map("recording_key") @db.VarChar(255)
configVersion Int? @map("config_version")
ratingStatus CdrRatingStatus @default(UNRATED) @map("rating_status")
payload Json?
receivedAt DateTime @default(now()) @map("received_at") @db.DateTime(3)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
receivedAt DateTime @default(now()) @map("received_at") @db.DateTime(3)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
customer Customer? @relation(fields: [customerId], references: [id], onDelete: SetNull)
customerGateway CustomerGateway? @relation(fields: [customerGatewayId], references: [id], onDelete: SetNull)
customerGatewayPolicy CustomerGatewayPolicy? @relation(fields: [customerGatewayPolicyId], references: [id], onDelete: SetNull)
vendor Vendor? @relation(fields: [vendorId], references: [id], onDelete: SetNull)
vendorGateway VendorGateway? @relation(fields: [vendorGatewayId], references: [id], onDelete: SetNull)
lineGroup LandingLineGroup? @relation(fields: [lineGroupId], references: [id], onDelete: SetNull)
ratedCdr RatedCdr?
recording Recording?
customer Customer? @relation(fields: [customerId], references: [id], onDelete: SetNull)
customerGateway CustomerGateway? @relation(fields: [customerGatewayId], references: [id], onDelete: SetNull)
customerGatewayPolicy CustomerGatewayPolicy? @relation(fields: [customerGatewayPolicyId], references: [id], onDelete: SetNull)
vendor Vendor? @relation(fields: [vendorId], references: [id], onDelete: SetNull)
vendorGateway VendorGateway? @relation(fields: [vendorGatewayId], references: [id], onDelete: SetNull)
lineGroup LandingLineGroup? @relation(fields: [lineGroupId], references: [id], onDelete: SetNull)
ratedCdr RatedCdr?
recording Recording?
@@unique([callId, endedAt])
@@index([customerId, startedAt])
@@index([vendorId, startedAt])
@@index([calleeCityCode, startedAt])
@@index([calleeOperator, startedAt])
@@index([sipCode])
@@index([ratingStatus])
@@map("raw_cdrs")
}
model RatedCdr {
id String @id @db.VarChar(40)
rawCdrId String @unique @map("raw_cdr_id") @db.VarChar(40)
billSec Int @map("bill_sec")
customerFee Decimal @default(0) @map("customer_fee") @db.Decimal(20, 6)
vendorCost Decimal @default(0) @map("vendor_cost") @db.Decimal(20, 6)
grossProfit Decimal @default(0) @map("gross_profit") @db.Decimal(20, 6)
customerRate Json? @map("customer_rate")
vendorRate Json? @map("vendor_rate")
ratedAt DateTime @default(now()) @map("rated_at") @db.DateTime(3)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
id String @id @db.VarChar(40)
rawCdrId String @unique @map("raw_cdr_id") @db.VarChar(40)
billSec Int @map("bill_sec")
customerFee Decimal @default(0) @map("customer_fee") @db.Decimal(20, 6)
vendorCost Decimal @default(0) @map("vendor_cost") @db.Decimal(20, 6)
grossProfit Decimal @default(0) @map("gross_profit") @db.Decimal(20, 6)
customerRate Json? @map("customer_rate")
vendorRate Json? @map("vendor_rate")
ratedAt DateTime @default(now()) @map("rated_at") @db.DateTime(3)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
rawCdr RawCdr @relation(fields: [rawCdrId], references: [id], onDelete: Restrict)
rawCdr RawCdr @relation(fields: [rawCdrId], references: [id], onDelete: Restrict)
@@index([ratedAt])
@@map("rated_cdrs")
}
model Recording {
id String @id @db.VarChar(40)
rawCdrId String? @unique @map("raw_cdr_id") @db.VarChar(40)
storageKey String @unique @map("storage_key") @db.VarChar(255)
storagePath String @map("storage_path") @db.VarChar(500)
sha256 String? @db.Char(64)
bytes BigInt @default(0)
durationSec Int @default(0) @map("duration_sec")
status RecordingStatus @default(PENDING)
movedAt DateTime? @map("moved_at") @db.DateTime(3)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
id String @id @db.VarChar(40)
rawCdrId String? @unique @map("raw_cdr_id") @db.VarChar(40)
storageKey String @unique @map("storage_key") @db.VarChar(255)
storagePath String @map("storage_path") @db.VarChar(500)
sha256 String? @db.Char(64)
bytes BigInt @default(0)
durationSec Int @default(0) @map("duration_sec")
status RecordingStatus @default(PENDING)
movedAt DateTime? @map("moved_at") @db.DateTime(3)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
rawCdr RawCdr? @relation(fields: [rawCdrId], references: [id], onDelete: SetNull)
reviews QualityReview[]
rawCdr RawCdr? @relation(fields: [rawCdrId], references: [id], onDelete: SetNull)
reviews QualityReview[]
@@index([status, createdAt])
@@map("recordings")
}
model QualitySamplingRule {
id String @id @db.VarChar(32)
name String @db.VarChar(120)
customerId String? @map("customer_id") @db.VarChar(32)
lineGroupId String? @map("line_group_id") @db.VarChar(32)
ratio Decimal @db.Decimal(5, 2)
status EntityStatus @default(ENABLED)
effectiveAt DateTime @default(now()) @map("effective_at") @db.DateTime(3)
expiresAt DateTime? @map("expires_at") @db.DateTime(3)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
deletedAt DateTime? @map("deleted_at") @db.DateTime(3)
id String @id @db.VarChar(32)
name String @db.VarChar(120)
customerId String? @map("customer_id") @db.VarChar(32)
lineGroupId String? @map("line_group_id") @db.VarChar(32)
ratio Decimal @db.Decimal(5, 2)
status EntityStatus @default(ENABLED)
effectiveAt DateTime @default(now()) @map("effective_at") @db.DateTime(3)
expiresAt DateTime? @map("expires_at") @db.DateTime(3)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
deletedAt DateTime? @map("deleted_at") @db.DateTime(3)
customer Customer? @relation(fields: [customerId], references: [id], onDelete: SetNull)
lineGroup LandingLineGroup? @relation(fields: [lineGroupId], references: [id], onDelete: SetNull)
customer Customer? @relation(fields: [customerId], references: [id], onDelete: SetNull)
lineGroup LandingLineGroup? @relation(fields: [lineGroupId], references: [id], onDelete: SetNull)
@@index([customerId, status])
@@index([lineGroupId, status])
@@ -503,20 +657,20 @@ model QualitySamplingRule {
}
model QualityReview {
id String @id @db.VarChar(40)
recordingId String @map("recording_id") @db.VarChar(40)
reviewerId String @map("reviewer_id") @db.VarChar(32)
score Int?
result QualityReviewResult
issueTags Json? @map("issue_tags")
notes String? @db.VarChar(1000)
reviewedAt DateTime @default(now()) @map("reviewed_at") @db.DateTime(3)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
version Int @default(1)
id String @id @db.VarChar(40)
recordingId String @map("recording_id") @db.VarChar(40)
reviewerId String @map("reviewer_id") @db.VarChar(32)
score Int?
result QualityReviewResult
issueTags Json? @map("issue_tags")
notes String? @db.VarChar(1000)
reviewedAt DateTime @default(now()) @map("reviewed_at") @db.DateTime(3)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
version Int @default(1)
recording Recording @relation(fields: [recordingId], references: [id], onDelete: Restrict)
reviewer User @relation(fields: [reviewerId], references: [id], onDelete: Restrict)
recording Recording @relation(fields: [recordingId], references: [id], onDelete: Restrict)
reviewer User @relation(fields: [reviewerId], references: [id], onDelete: Restrict)
@@index([recordingId])
@@index([reviewerId, reviewedAt])
@@ -524,29 +678,29 @@ model QualityReview {
}
model User {
id String @id @db.VarChar(32)
username String @unique @db.VarChar(80)
displayName String @map("display_name") @db.VarChar(80)
phone String? @db.VarChar(32)
email String? @unique @db.VarChar(160)
passwordHash String? @map("password_hash") @db.VarChar(255)
passwordAlgo String? @map("password_algo") @db.VarChar(32)
status EntityStatus @default(ENABLED)
failedLoginCount Int @default(0) @map("failed_login_count")
lockedUntil DateTime? @map("locked_until") @db.DateTime(3)
requirePasswordChange Boolean @default(false) @map("require_password_change")
lastLoginAt DateTime? @map("last_login_at") @db.DateTime(3)
lastLoginIp String? @map("last_login_ip") @db.VarChar(45)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
deletedAt DateTime? @map("deleted_at") @db.DateTime(3)
id String @id @db.VarChar(32)
username String @unique @db.VarChar(80)
displayName String @map("display_name") @db.VarChar(80)
phone String? @db.VarChar(32)
email String? @unique @db.VarChar(160)
passwordHash String? @map("password_hash") @db.VarChar(255)
passwordAlgo String? @map("password_algo") @db.VarChar(32)
status EntityStatus @default(ENABLED)
failedLoginCount Int @default(0) @map("failed_login_count")
lockedUntil DateTime? @map("locked_until") @db.DateTime(3)
requirePasswordChange Boolean @default(false) @map("require_password_change")
lastLoginAt DateTime? @map("last_login_at") @db.DateTime(3)
lastLoginIp String? @map("last_login_ip") @db.VarChar(45)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
deletedAt DateTime? @map("deleted_at") @db.DateTime(3)
userRoles UserRole[]
qualityReviews QualityReview[]
sessions UserSession[]
userRoles UserRole[]
qualityReviews QualityReview[]
sessions UserSession[]
@@index([status])
@@index([deletedAt])
@@ -565,7 +719,7 @@ model UserSession {
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId, createdAt])
@@index([expiresAt])
@@ -574,17 +728,17 @@ model UserSession {
}
model Role {
id String @id @db.VarChar(32)
name String @unique @db.VarChar(80)
description String? @db.VarChar(300)
builtIn Boolean @default(false) @map("built_in")
status EntityStatus @default(ENABLED)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
deletedAt DateTime? @map("deleted_at") @db.DateTime(3)
id String @id @db.VarChar(32)
name String @unique @db.VarChar(80)
description String? @db.VarChar(300)
builtIn Boolean @default(false) @map("built_in")
status EntityStatus @default(ENABLED)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
updatedBy String? @map("updated_by") @db.VarChar(32)
version Int @default(1)
deletedAt DateTime? @map("deleted_at") @db.DateTime(3)
userRoles UserRole[]
permissions RolePermission[]
@@ -595,14 +749,14 @@ model Role {
}
model Permission {
id String @id @db.VarChar(80)
module String @db.VarChar(80)
action String @db.VarChar(80)
description String? @db.VarChar(300)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
id String @id @db.VarChar(80)
module String @db.VarChar(80)
action String @db.VarChar(80)
description String? @db.VarChar(300)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
updatedAt DateTime @updatedAt @map("updated_at") @db.DateTime(3)
roles RolePermission[]
roles RolePermission[]
@@unique([module, action])
@@map("permissions")
@@ -614,8 +768,8 @@ model UserRole {
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
@@id([userId, roleId])
@@index([roleId])
@@ -623,13 +777,13 @@ model UserRole {
}
model RolePermission {
roleId String @map("role_id") @db.VarChar(32)
permissionId String @map("permission_id") @db.VarChar(80)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
roleId String @map("role_id") @db.VarChar(32)
permissionId String @map("permission_id") @db.VarChar(80)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
createdBy String? @map("created_by") @db.VarChar(32)
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
permission Permission @relation(fields: [permissionId], references: [id], onDelete: Cascade)
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
permission Permission @relation(fields: [permissionId], references: [id], onDelete: Cascade)
@@id([roleId, permissionId])
@@index([permissionId])
@@ -637,22 +791,22 @@ model RolePermission {
}
model AuditLog {
id String @id @db.VarChar(40)
requestId String @map("request_id") @db.VarChar(64)
userId String? @map("user_id") @db.VarChar(32)
username String? @db.VarChar(80)
roleNames String? @map("role_names") @db.VarChar(300)
ip String? @db.VarChar(45)
userAgent String? @map("user_agent") @db.VarChar(500)
module String @db.VarChar(80)
action String @db.VarChar(80)
objectType String @map("object_type") @db.VarChar(80)
objectId String? @map("object_id") @db.VarChar(80)
beforeSummary Json? @map("before_summary")
afterSummary Json? @map("after_summary")
result AuditResult
errorCode String? @map("error_code") @db.VarChar(80)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
id String @id @db.VarChar(40)
requestId String @map("request_id") @db.VarChar(64)
userId String? @map("user_id") @db.VarChar(32)
username String? @db.VarChar(80)
roleNames String? @map("role_names") @db.VarChar(300)
ip String? @db.VarChar(45)
userAgent String? @map("user_agent") @db.VarChar(500)
module String @db.VarChar(80)
action String @db.VarChar(80)
objectType String @map("object_type") @db.VarChar(80)
objectId String? @map("object_id") @db.VarChar(80)
beforeSummary Json? @map("before_summary")
afterSummary Json? @map("after_summary")
result AuditResult
errorCode String? @map("error_code") @db.VarChar(80)
createdAt DateTime @default(now()) @map("created_at") @db.DateTime(3)
@@index([userId, createdAt])
@@index([module, action, createdAt])
+12 -1
View File
@@ -4,6 +4,8 @@ const prisma = new PrismaClient();
const permissions = [
['dashboard.view', 'dashboard', 'view', '查看 Dashboard 指标'],
['active_calls.view', 'active_calls', 'view', '查看当前通话'],
['active_calls.manage', 'active_calls', 'manage', '强制挂断当前通话'],
['customers.view', 'customers', 'view', '查看客户'],
['customers.manage', 'customers', 'manage', '管理客户'],
['customer_gateways.view', 'customer_gateways', 'view', '查看客户网关'],
@@ -14,6 +16,8 @@ const permissions = [
['vendor_gateways.manage', 'vendor_gateways', 'manage', '管理落地网关'],
['line_groups.view', 'line_groups', 'view', '查看落地线路组'],
['line_groups.manage', 'line_groups', 'manage', '管理落地线路组'],
['number_library.view', 'number_library', 'view', '查看号码库'],
['number_library.manage', 'number_library', 'manage', '管理号码库'],
['recharges.view', 'recharges', 'view', '查看充值流水'],
['recharges.manage', 'recharges', 'manage', '执行客户或供应商充值'],
['cdr.view', 'cdr', 'view', '查看话单'],
@@ -40,6 +44,7 @@ const roles = [
description: '客户、网关、线路和话单运营',
permissionIds: [
'dashboard.view',
'active_calls.view',
'customers.view',
'customers.manage',
'customer_gateways.view',
@@ -48,6 +53,8 @@ const roles = [
'vendor_gateways.view',
'line_groups.view',
'line_groups.manage',
'number_library.view',
'number_library.manage',
'cdr.view',
'recordings.play'
]
@@ -75,9 +82,13 @@ const roles = [
'vendor_gateways.view',
'vendor_gateways.manage',
'line_groups.view',
'number_library.view',
'number_library.manage',
'cdr.view',
'recordings.play',
'audit.view'
'audit.view',
'active_calls.view',
'active_calls.manage'
]
}
];