@lead-routing/cli 0.7.0 → 0.8.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 CHANGED
@@ -111,7 +111,7 @@ function bail2(value) {
111
111
  }
112
112
  throw new Error("Unexpected cancel");
113
113
  }
114
- async function collectConfig(opts = {}) {
114
+ async function collectConfig(opts = {}, authEmail) {
115
115
  const crmType = opts.crmType ?? "salesforce";
116
116
  note2(
117
117
  "You will need:\n \u2022 Public HTTPS URLs for the web app and routing engine",
@@ -152,16 +152,22 @@ async function collectConfig(opts = {}) {
152
152
  const redisPassword = generateSecret(16);
153
153
  const managedRedis = !opts.externalRedis;
154
154
  const redisUrl = opts.externalRedis ?? `redis://:${redisPassword}@redis:6379`;
155
- note2("This creates the first admin user for the web app.", "Admin Account");
156
- const adminEmail = await text2({
157
- message: "Admin email address",
158
- placeholder: "admin@acme.com",
159
- validate: (v) => {
160
- if (!v) return "Required";
161
- if (!v.includes("@")) return "Must be a valid email";
162
- }
163
- });
164
- if (isCancel2(adminEmail)) bail2(adminEmail);
155
+ let adminEmail;
156
+ if (authEmail) {
157
+ note2(`Using ${authEmail} as admin email`, "Admin Account");
158
+ adminEmail = authEmail;
159
+ } else {
160
+ note2("This creates the first admin user for the web app.", "Admin Account");
161
+ adminEmail = await text2({
162
+ message: "Admin email address",
163
+ placeholder: "admin@acme.com",
164
+ validate: (v) => {
165
+ if (!v) return "Required";
166
+ if (!v.includes("@")) return "Must be a valid email";
167
+ }
168
+ });
169
+ if (isCancel2(adminEmail)) bail2(adminEmail);
170
+ }
165
171
  const adminPassword = await password2({
166
172
  message: "Admin password (min 8 characters)",
167
173
  validate: (v) => {
@@ -173,35 +179,9 @@ async function collectConfig(opts = {}) {
173
179
  const sessionSecret = generateSecret(32);
174
180
  const engineWebhookSecret = generateSecret(32);
175
181
  const internalApiKey = generateSecret(32);
176
- let hubspotAppId;
177
- let hubspotClientId;
178
- let hubspotClientSecret;
179
- if (crmType === "hubspot") {
180
- note2(
181
- "Create a HubSpot app at https://developers.hubspot.com/\nYou will need the App ID, Client ID, and Client Secret.",
182
- "HubSpot Credentials"
183
- );
184
- const rawAppId = await text2({
185
- message: "HubSpot App ID",
186
- placeholder: "123456",
187
- validate: (v) => !v?.trim() ? "Required" : void 0
188
- });
189
- if (isCancel2(rawAppId)) bail2(rawAppId);
190
- hubspotAppId = rawAppId.trim();
191
- const rawClientId = await text2({
192
- message: "HubSpot Client ID",
193
- placeholder: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
194
- validate: (v) => !v?.trim() ? "Required" : void 0
195
- });
196
- if (isCancel2(rawClientId)) bail2(rawClientId);
197
- hubspotClientId = rawClientId.trim();
198
- const rawClientSecret = await password2({
199
- message: "HubSpot Client Secret",
200
- validate: (v) => !v?.trim() ? "Required" : void 0
201
- });
202
- if (isCancel2(rawClientSecret)) bail2(rawClientSecret);
203
- hubspotClientSecret = rawClientSecret.trim();
204
- }
182
+ const hubspotAppId = void 0;
183
+ const hubspotClientId = void 0;
184
+ const hubspotClientSecret = void 0;
205
185
  return {
206
186
  appUrl: appUrl.trim().replace(/\/+$/, ""),
207
187
  engineUrl: engineUrl.trim().replace(/\/+$/, ""),
@@ -389,9 +369,9 @@ function renderEnvWeb(c) {
389
369
  ...c.crmType === "hubspot" ? [
390
370
  ``,
391
371
  `# HubSpot`,
392
- `HUBSPOT_CLIENT_ID=${c.hubspotClientId ?? ""}`,
393
- `HUBSPOT_CLIENT_SECRET=${c.hubspotClientSecret ?? ""}`,
394
- `HUBSPOT_APP_ID=${c.hubspotAppId ?? ""}`,
372
+ `HUBSPOT_CLIENT_ID=${c.hubspotClientId ?? "c53f3d1c-ff03-4db7-875a-1ebe7b0f98cc"}`,
373
+ `HUBSPOT_CLIENT_SECRET=${c.hubspotClientSecret ?? "f95949ac-6464-40d3-bdaa-893c48749951"}`,
374
+ `HUBSPOT_APP_ID=${c.hubspotAppId ?? "35016223"}`,
395
375
  `HUBSPOT_REDIRECT_URI=${c.appUrl}/api/auth/hubspot/callback`
396
376
  ] : []
397
377
  ].join("\n");
@@ -427,6 +407,7 @@ function renderEnvEngine(c) {
427
407
  ...c.crmType === "hubspot" ? [
428
408
  ``,
429
409
  `# HubSpot`,
410
+ `HUBSPOT_CLIENT_ID=${c.hubspotClientId ?? ""}`,
430
411
  `HUBSPOT_CLIENT_SECRET=${c.hubspotClientSecret ?? ""}`
431
412
  ] : []
432
413
  ].join("\n");
@@ -1451,7 +1432,7 @@ Install URL: ${chalk2.cyan(MANAGED_PACKAGE_INSTALL_URL)}`,
1451
1432
  externalDb: options.externalDb,
1452
1433
  externalRedis: options.externalRedis,
1453
1434
  crmType
1454
- });
1435
+ }, auth.customer.email);
1455
1436
  await checkDnsResolvable(cfg.appUrl, cfg.engineUrl);
1456
1437
  log7.step("Step 6/9 Generating config files");
1457
1438
  const { dir } = generateFiles(cfg, sshCfg, {
@@ -1540,6 +1521,12 @@ Files created: docker-compose.yml, Caddyfile, .env.web, .env.engine, lead-routin
1540
1521
  log7.step("Retrying health check...");
1541
1522
  }
1542
1523
  }
1524
+ note3(
1525
+ `You can log in to the web app at ${chalk2.cyan(cfg.appUrl)} with:
1526
+ Email: ${cfg.adminEmail}
1527
+ Password: (the password you set during setup)`,
1528
+ "Admin Login"
1529
+ );
1543
1530
  try {
1544
1531
  const envWebPath = join5(dir, ".env.web");
1545
1532
  const envContent = readFileSync4(envWebPath, "utf-8");
@@ -140,7 +140,7 @@ model Organization {
140
140
  fieldsSyncedAt DateTime?
141
141
  plan Plan @default(FREE)
142
142
  isActive Boolean @default(true)
143
- seatsPurchased Int @default(5)
143
+ seatsPurchased Int @default(10)
144
144
  seatsUsed Int @default(0)
145
145
  routingQuotaUsed Int @default(0)
146
146
  quotaResetAt DateTime @default(now())
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lead-routing/cli",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Self-hosted deployment CLI for Lead Routing",
5
5
  "homepage": "https://github.com/lead-routing/lead-routing",
6
6
  "keywords": [
@@ -1,76 +0,0 @@
1
- -- CreateEnum
2
- CREATE TYPE "FlowStatus" AS ENUM ('DRAFT', 'ACTIVE', 'INACTIVE');
3
-
4
- -- CreateEnum
5
- CREATE TYPE "FlowNodeType" AS ENUM ('ENTRY', 'DECISION', 'BRANCH_DECISION', 'MATCH', 'ASSIGNMENT', 'UPDATE_FIELD', 'CREATE_TASK', 'FILTER', 'DEFAULT');
6
-
7
- -- AlterTable
8
- ALTER TABLE "organizations" ADD COLUMN "routingMode" JSONB;
9
-
10
- -- AlterTable
11
- ALTER TABLE "routing_logs" ADD COLUMN "flowId" TEXT,
12
- ADD COLUMN "flowNodePath" JSONB;
13
-
14
- -- CreateTable
15
- CREATE TABLE "routing_flows" (
16
- "id" TEXT NOT NULL,
17
- "orgId" TEXT NOT NULL,
18
- "objectType" "SfdcObjectType" NOT NULL,
19
- "name" TEXT NOT NULL DEFAULT 'Untitled Flow',
20
- "status" "FlowStatus" NOT NULL DEFAULT 'DRAFT',
21
- "triggerEvent" "TriggerEvent" NOT NULL DEFAULT 'BOTH',
22
- "isDryRun" BOOLEAN NOT NULL DEFAULT false,
23
- "version" INTEGER NOT NULL DEFAULT 1,
24
- "publishedAt" TIMESTAMP(3),
25
- "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
26
- "updatedAt" TIMESTAMP(3) NOT NULL,
27
-
28
- CONSTRAINT "routing_flows_pkey" PRIMARY KEY ("id")
29
- );
30
-
31
- -- CreateTable
32
- CREATE TABLE "flow_nodes" (
33
- "id" TEXT NOT NULL,
34
- "flowId" TEXT NOT NULL,
35
- "type" "FlowNodeType" NOT NULL,
36
- "label" TEXT,
37
- "positionX" DOUBLE PRECISION NOT NULL DEFAULT 0,
38
- "positionY" DOUBLE PRECISION NOT NULL DEFAULT 0,
39
- "config" JSONB,
40
- "sortOrder" INTEGER NOT NULL DEFAULT 0,
41
- "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
42
- "updatedAt" TIMESTAMP(3) NOT NULL,
43
-
44
- CONSTRAINT "flow_nodes_pkey" PRIMARY KEY ("id")
45
- );
46
-
47
- -- CreateTable
48
- CREATE TABLE "flow_edges" (
49
- "id" TEXT NOT NULL,
50
- "flowId" TEXT NOT NULL,
51
- "fromId" TEXT NOT NULL,
52
- "toId" TEXT NOT NULL,
53
- "label" TEXT,
54
- "sortOrder" INTEGER NOT NULL DEFAULT 0,
55
- "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
56
-
57
- CONSTRAINT "flow_edges_pkey" PRIMARY KEY ("id")
58
- );
59
-
60
- -- CreateIndex
61
- CREATE UNIQUE INDEX "routing_flows_orgId_objectType_key" ON "routing_flows"("orgId", "objectType");
62
-
63
- -- AddForeignKey
64
- ALTER TABLE "routing_flows" ADD CONSTRAINT "routing_flows_orgId_fkey" FOREIGN KEY ("orgId") REFERENCES "organizations"("id") ON DELETE CASCADE ON UPDATE CASCADE;
65
-
66
- -- AddForeignKey
67
- ALTER TABLE "flow_nodes" ADD CONSTRAINT "flow_nodes_flowId_fkey" FOREIGN KEY ("flowId") REFERENCES "routing_flows"("id") ON DELETE CASCADE ON UPDATE CASCADE;
68
-
69
- -- AddForeignKey
70
- ALTER TABLE "flow_edges" ADD CONSTRAINT "flow_edges_flowId_fkey" FOREIGN KEY ("flowId") REFERENCES "routing_flows"("id") ON DELETE CASCADE ON UPDATE CASCADE;
71
-
72
- -- AddForeignKey
73
- ALTER TABLE "flow_edges" ADD CONSTRAINT "flow_edges_fromId_fkey" FOREIGN KEY ("fromId") REFERENCES "flow_nodes"("id") ON DELETE CASCADE ON UPDATE CASCADE;
74
-
75
- -- AddForeignKey
76
- ALTER TABLE "flow_edges" ADD CONSTRAINT "flow_edges_toId_fkey" FOREIGN KEY ("toId") REFERENCES "flow_nodes"("id") ON DELETE CASCADE ON UPDATE CASCADE;
@@ -1,3 +0,0 @@
1
- -- AlterTable
2
- ALTER TABLE "flow_edges" ADD COLUMN "sourceHandle" TEXT;
3
- ALTER TABLE "flow_edges" ADD COLUMN "targetHandle" TEXT;