@lead-routing/cli 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +763 -623
- package/dist/prisma/migrations/20260310300000_make_branch_assignment_type_nullable/migration.sql +2 -0
- package/dist/prisma/migrations/20260311000000_add_integration_fields/migration.sql +6 -0
- package/dist/prisma/migrations/20260312000000_add_trigger_conditions/migration.sql +20 -0
- package/dist/prisma/migrations/20260312100000_add_ai_fields/migration.sql +7 -0
- package/dist/prisma/migrations/20260312120000_add_fuzzy_matching/migration.sql +26 -0
- package/dist/prisma/migrations/migration_lock.toml +3 -0
- package/dist/prisma/schema.prisma +76 -11
- package/package.json +1 -1
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
-- AlterTable
|
|
2
|
+
ALTER TABLE "organizations" ADD COLUMN "packageDeployedAt" TIMESTAMP(3);
|
|
3
|
+
ALTER TABLE "organizations" ADD COLUMN "packageDeployId" TEXT;
|
|
4
|
+
ALTER TABLE "organizations" ADD COLUMN "packageVersion" TEXT;
|
|
5
|
+
ALTER TABLE "organizations" ADD COLUMN "objectConfig" JSONB;
|
|
6
|
+
ALTER TABLE "organizations" ADD COLUMN "fieldsSyncedAt" TIMESTAMP(3);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
-- CreateTable
|
|
2
|
+
CREATE TABLE "trigger_conditions" (
|
|
3
|
+
"id" TEXT NOT NULL,
|
|
4
|
+
"ruleId" TEXT NOT NULL,
|
|
5
|
+
"groupId" TEXT NOT NULL,
|
|
6
|
+
"fieldName" TEXT NOT NULL,
|
|
7
|
+
"fieldType" TEXT NOT NULL DEFAULT 'TEXT',
|
|
8
|
+
"operator" TEXT NOT NULL,
|
|
9
|
+
"value" TEXT,
|
|
10
|
+
"sortOrder" INTEGER NOT NULL DEFAULT 0,
|
|
11
|
+
|
|
12
|
+
CONSTRAINT "trigger_conditions_pkey" PRIMARY KEY ("id")
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
-- AddForeignKey
|
|
16
|
+
ALTER TABLE "trigger_conditions" ADD CONSTRAINT "trigger_conditions_ruleId_fkey" FOREIGN KEY ("ruleId") REFERENCES "routing_rules"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
17
|
+
|
|
18
|
+
-- AlterTable: add criteriaSyncedAt and triggerName to routing_rules
|
|
19
|
+
ALTER TABLE "routing_rules" ADD COLUMN "criteriaSyncedAt" TIMESTAMP(3);
|
|
20
|
+
ALTER TABLE "routing_rules" ADD COLUMN "triggerName" TEXT NOT NULL DEFAULT '';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
-- AlterTable
|
|
2
|
+
ALTER TABLE "organizations" ADD COLUMN "aiProvider" TEXT;
|
|
3
|
+
ALTER TABLE "organizations" ADD COLUMN "aiApiKey" TEXT;
|
|
4
|
+
ALTER TABLE "organizations" ADD COLUMN "aiModelName" TEXT;
|
|
5
|
+
ALTER TABLE "organizations" ADD COLUMN "aiBaseUrl" TEXT;
|
|
6
|
+
ALTER TABLE "organizations" ADD COLUMN "aiCustomHeaders" JSONB;
|
|
7
|
+
ALTER TABLE "organizations" ADD COLUMN "aiChatCount" INTEGER NOT NULL DEFAULT 0;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
-- AlterTable: add fuzzy matching columns to route_match_configs
|
|
2
|
+
ALTER TABLE "route_match_configs" ADD COLUMN "matchCompanyName" BOOLEAN NOT NULL DEFAULT false;
|
|
3
|
+
ALTER TABLE "route_match_configs" ADD COLUMN "fuzzyMatchMode" TEXT NOT NULL DEFAULT 'STRICT';
|
|
4
|
+
|
|
5
|
+
-- CreateTable: company_aliases for caching AI similarity results
|
|
6
|
+
CREATE TABLE "company_aliases" (
|
|
7
|
+
"id" TEXT NOT NULL,
|
|
8
|
+
"orgId" TEXT NOT NULL,
|
|
9
|
+
"nameA" TEXT NOT NULL,
|
|
10
|
+
"nameB" TEXT NOT NULL,
|
|
11
|
+
"isSimilar" BOOLEAN NOT NULL,
|
|
12
|
+
"confidence" DOUBLE PRECISION,
|
|
13
|
+
"source" TEXT NOT NULL DEFAULT 'AI',
|
|
14
|
+
"hitCount" INTEGER NOT NULL DEFAULT 1,
|
|
15
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
16
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
17
|
+
CONSTRAINT "company_aliases_pkey" PRIMARY KEY ("id")
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
-- CreateIndex
|
|
21
|
+
CREATE UNIQUE INDEX "company_aliases_orgId_nameA_nameB_key" ON "company_aliases"("orgId", "nameA", "nameB");
|
|
22
|
+
CREATE INDEX "company_aliases_orgId_nameA_idx" ON "company_aliases"("orgId", "nameA");
|
|
23
|
+
CREATE INDEX "company_aliases_orgId_nameB_idx" ON "company_aliases"("orgId", "nameB");
|
|
24
|
+
|
|
25
|
+
-- AddForeignKey
|
|
26
|
+
ALTER TABLE "company_aliases" ADD CONSTRAINT "company_aliases_orgId_fkey" FOREIGN KEY ("orgId") REFERENCES "organizations"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
@@ -78,6 +78,12 @@ model Organization {
|
|
|
78
78
|
oauthAccessToken String? // null until CRM is connected
|
|
79
79
|
oauthRefreshToken String? // null until CRM is connected
|
|
80
80
|
webhookSecret String // HMAC secret for verifying Apex trigger payloads
|
|
81
|
+
// Integration / package deploy tracking
|
|
82
|
+
packageDeployedAt DateTime?
|
|
83
|
+
packageDeployId String?
|
|
84
|
+
packageVersion String?
|
|
85
|
+
objectConfig Json? // e.g. { "Lead": { enabled: true }, "Contact": { enabled: true } }
|
|
86
|
+
fieldsSyncedAt DateTime?
|
|
81
87
|
plan Plan @default(FREE)
|
|
82
88
|
isActive Boolean @default(true)
|
|
83
89
|
seatsPurchased Int @default(5)
|
|
@@ -86,6 +92,13 @@ model Organization {
|
|
|
86
92
|
quotaResetAt DateTime @default(now())
|
|
87
93
|
onboardingDone Boolean @default(false)
|
|
88
94
|
notificationWebhookUrl String?
|
|
95
|
+
// AI Assistant (Pro feature)
|
|
96
|
+
aiProvider String? // "claude" | "openai" | "gemini" | "custom"
|
|
97
|
+
aiApiKey String? // AES-256-GCM encrypted
|
|
98
|
+
aiModelName String? // e.g. "claude-sonnet-4-5-20250514", "gpt-4o"
|
|
99
|
+
aiBaseUrl String? // custom endpoint URL (null = default)
|
|
100
|
+
aiCustomHeaders Json? // custom headers for self-hosted proxies
|
|
101
|
+
aiChatCount Int @default(0)
|
|
89
102
|
createdAt DateTime @default(now())
|
|
90
103
|
updatedAt DateTime @updatedAt
|
|
91
104
|
|
|
@@ -101,6 +114,7 @@ model Organization {
|
|
|
101
114
|
billingInfo BillingInfo?
|
|
102
115
|
routingDailyAggregates RoutingDailyAggregate[]
|
|
103
116
|
conversionTracking ConversionTracking[]
|
|
117
|
+
companyAliases CompanyAlias[]
|
|
104
118
|
|
|
105
119
|
@@map("organizations")
|
|
106
120
|
}
|
|
@@ -152,8 +166,10 @@ model User {
|
|
|
152
166
|
createdAt DateTime @default(now())
|
|
153
167
|
updatedAt DateTime @updatedAt
|
|
154
168
|
|
|
155
|
-
org
|
|
156
|
-
teamMemberships
|
|
169
|
+
org Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
170
|
+
teamMemberships TeamMember[]
|
|
171
|
+
branchAssignments RoutingBranch[] @relation("BranchAssigneeUser")
|
|
172
|
+
defaultOwnerRules RoutingRule[] @relation("DefaultOwnerUser")
|
|
157
173
|
|
|
158
174
|
@@unique([orgId, sfdcUserId])
|
|
159
175
|
@@map("users")
|
|
@@ -168,9 +184,11 @@ model RoundRobinTeam {
|
|
|
168
184
|
createdAt DateTime @default(now())
|
|
169
185
|
updatedAt DateTime @updatedAt
|
|
170
186
|
|
|
171
|
-
org
|
|
172
|
-
members
|
|
173
|
-
routingRules
|
|
187
|
+
org Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
188
|
+
members TeamMember[]
|
|
189
|
+
routingRules RoutingRule[] @relation("TeamRules")
|
|
190
|
+
branchAssignments RoutingBranch[] @relation("BranchAssigneeTeam")
|
|
191
|
+
defaultOwnerRules RoutingRule[] @relation("DefaultOwnerTeam")
|
|
174
192
|
|
|
175
193
|
@@map("round_robin_teams")
|
|
176
194
|
}
|
|
@@ -206,6 +224,8 @@ model RoutingRule {
|
|
|
206
224
|
assigneeTeamId String? // references RoundRobinTeam.id
|
|
207
225
|
assigneeQueueId String? // references SfdcQueue.id
|
|
208
226
|
isDryRun Boolean @default(false)
|
|
227
|
+
triggerName String @default("")
|
|
228
|
+
criteriaSyncedAt DateTime?
|
|
209
229
|
// Default owner: absolute catch-all for new Route Builder routes
|
|
210
230
|
defaultOwnerType AssignmentType?
|
|
211
231
|
defaultOwnerUserId String?
|
|
@@ -214,12 +234,16 @@ model RoutingRule {
|
|
|
214
234
|
createdAt DateTime @default(now())
|
|
215
235
|
updatedAt DateTime @updatedAt
|
|
216
236
|
|
|
217
|
-
org
|
|
218
|
-
team
|
|
219
|
-
queue
|
|
237
|
+
org Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
238
|
+
team RoundRobinTeam? @relation("TeamRules", fields: [assigneeTeamId], references: [id])
|
|
239
|
+
queue SfdcQueue? @relation(fields: [assigneeQueueId], references: [id])
|
|
240
|
+
defaultOwnerUser User? @relation("DefaultOwnerUser", fields: [defaultOwnerUserId], references: [id])
|
|
241
|
+
defaultOwnerTeam RoundRobinTeam? @relation("DefaultOwnerTeam", fields: [defaultOwnerTeamId], references: [id])
|
|
242
|
+
defaultOwnerQueue SfdcQueue? @relation("DefaultOwnerQueue", fields: [defaultOwnerQueueId], references: [id])
|
|
220
243
|
conditions RuleCondition[] // legacy conditions (old-style rules)
|
|
221
244
|
branches RoutingBranch[] // new Route Builder paths
|
|
222
245
|
matchConfig RouteMatchConfig?
|
|
246
|
+
triggerConditions TriggerCondition[]
|
|
223
247
|
|
|
224
248
|
@@map("routing_rules")
|
|
225
249
|
}
|
|
@@ -230,10 +254,13 @@ model RoutingBranch {
|
|
|
230
254
|
rule RoutingRule @relation(fields: [ruleId], references: [id], onDelete: Cascade)
|
|
231
255
|
label String?
|
|
232
256
|
priority Int @default(0)
|
|
233
|
-
assignmentType AssignmentType
|
|
257
|
+
assignmentType AssignmentType?
|
|
234
258
|
assigneeUserId String?
|
|
259
|
+
assigneeUser User? @relation("BranchAssigneeUser", fields: [assigneeUserId], references: [id])
|
|
235
260
|
assigneeTeamId String?
|
|
261
|
+
assigneeTeam RoundRobinTeam? @relation("BranchAssigneeTeam", fields: [assigneeTeamId], references: [id])
|
|
236
262
|
assigneeQueueId String?
|
|
263
|
+
assigneeQueue SfdcQueue? @relation("BranchAssigneeQueue", fields: [assigneeQueueId], references: [id])
|
|
237
264
|
createdAt DateTime @default(now())
|
|
238
265
|
updatedAt DateTime @updatedAt
|
|
239
266
|
|
|
@@ -257,6 +284,20 @@ model BranchCondition {
|
|
|
257
284
|
@@map("branch_conditions")
|
|
258
285
|
}
|
|
259
286
|
|
|
287
|
+
model TriggerCondition {
|
|
288
|
+
id String @id @default(cuid())
|
|
289
|
+
ruleId String
|
|
290
|
+
rule RoutingRule @relation(fields: [ruleId], references: [id], onDelete: Cascade)
|
|
291
|
+
groupId String
|
|
292
|
+
fieldName String
|
|
293
|
+
fieldType String @default("TEXT")
|
|
294
|
+
operator String
|
|
295
|
+
value String?
|
|
296
|
+
sortOrder Int @default(0)
|
|
297
|
+
|
|
298
|
+
@@map("trigger_conditions")
|
|
299
|
+
}
|
|
300
|
+
|
|
260
301
|
model RouteMatchConfig {
|
|
261
302
|
id String @id @default(cuid())
|
|
262
303
|
ruleId String @unique
|
|
@@ -271,6 +312,8 @@ model RouteMatchConfig {
|
|
|
271
312
|
matchEmail Boolean @default(true)
|
|
272
313
|
matchPhone Boolean @default(false)
|
|
273
314
|
matchDomain Boolean @default(false)
|
|
315
|
+
matchCompanyName Boolean @default(false)
|
|
316
|
+
fuzzyMatchMode String @default("STRICT") // "STRICT" | "FUZZY" | "AI_SMART"
|
|
274
317
|
|
|
275
318
|
// Lead match outcome
|
|
276
319
|
onLeadMatch LeadMatchAction @default(SFDC_MERGE)
|
|
@@ -373,8 +416,10 @@ model SfdcQueue {
|
|
|
373
416
|
name String
|
|
374
417
|
syncedAt DateTime @default(now())
|
|
375
418
|
|
|
376
|
-
org
|
|
377
|
-
routingRules
|
|
419
|
+
org Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
420
|
+
routingRules RoutingRule[]
|
|
421
|
+
branchAssignments RoutingBranch[] @relation("BranchAssigneeQueue")
|
|
422
|
+
defaultOwnerRules RoutingRule[] @relation("DefaultOwnerQueue")
|
|
378
423
|
|
|
379
424
|
@@unique([orgId, sfdcQueueId])
|
|
380
425
|
@@map("sfdc_queues")
|
|
@@ -484,3 +529,23 @@ model ConversionTracking {
|
|
|
484
529
|
@@index([orgId, sfdcLeadId])
|
|
485
530
|
@@map("conversion_tracking")
|
|
486
531
|
}
|
|
532
|
+
|
|
533
|
+
model CompanyAlias {
|
|
534
|
+
id String @id @default(cuid())
|
|
535
|
+
orgId String
|
|
536
|
+
nameA String // normalized company name A (alphabetically first)
|
|
537
|
+
nameB String // normalized company name B
|
|
538
|
+
isSimilar Boolean // LLM determination
|
|
539
|
+
confidence Float? // LLM confidence score (0-1)
|
|
540
|
+
source String @default("AI") // "AI" | "MANUAL" | "DICTIONARY"
|
|
541
|
+
hitCount Int @default(1)
|
|
542
|
+
createdAt DateTime @default(now())
|
|
543
|
+
updatedAt DateTime @updatedAt
|
|
544
|
+
|
|
545
|
+
org Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
546
|
+
|
|
547
|
+
@@unique([orgId, nameA, nameB])
|
|
548
|
+
@@index([orgId, nameA])
|
|
549
|
+
@@index([orgId, nameB])
|
|
550
|
+
@@map("company_aliases")
|
|
551
|
+
}
|