@voyantjs/crm 0.106.1 → 0.107.1
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/README.md +3 -3
- package/dist/booking-extension.d.ts +7 -7
- package/dist/booking-extension.d.ts.map +1 -1
- package/dist/booking-extension.js +8 -5
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/routes/activities.d.ts +2 -2
- package/dist/routes/custom-fields.d.ts +6 -6
- package/dist/routes/index.d.ts +518 -51
- package/dist/routes/index.d.ts.map +1 -1
- package/dist/routes/index.js +2 -2
- package/dist/routes/pipelines.d.ts +4 -4
- package/dist/routes/quote-versions.d.ts +746 -0
- package/dist/routes/quote-versions.d.ts.map +1 -0
- package/dist/routes/quote-versions.js +175 -0
- package/dist/routes/quotes.d.ts +161 -53
- package/dist/routes/quotes.d.ts.map +1 -1
- package/dist/routes/quotes.js +29 -11
- package/dist/schema-activities.d.ts +6 -6
- package/dist/schema-relations.d.ts +19 -18
- package/dist/schema-relations.d.ts.map +1 -1
- package/dist/schema-relations.js +38 -31
- package/dist/schema-sales.d.ts +206 -87
- package/dist/schema-sales.d.ts.map +1 -1
- package/dist/schema-sales.js +62 -50
- package/dist/schema-shared.d.ts +3 -3
- package/dist/schema-shared.d.ts.map +1 -1
- package/dist/schema-shared.js +5 -16
- package/dist/schema-signals.d.ts +1 -1
- package/dist/schema-signals.js +1 -1
- package/dist/service/accounts-merge.js +10 -10
- package/dist/service/activities.d.ts +6 -6
- package/dist/service/custom-fields.d.ts +6 -6
- package/dist/service/index.d.ts +338 -139
- package/dist/service/index.d.ts.map +1 -1
- package/dist/service/index.js +2 -2
- package/dist/service/pipelines.d.ts +4 -4
- package/dist/service/quote-versions.d.ts +674 -0
- package/dist/service/quote-versions.d.ts.map +1 -0
- package/dist/service/quote-versions.js +399 -0
- package/dist/service/quotes.d.ts +426 -94
- package/dist/service/quotes.d.ts.map +1 -1
- package/dist/service/quotes.js +63 -22
- package/package.json +7 -7
- package/dist/routes/opportunities.d.ts +0 -387
- package/dist/routes/opportunities.d.ts.map +0 -1
- package/dist/routes/opportunities.js +0 -70
- package/dist/service/opportunities.d.ts +0 -822
- package/dist/service/opportunities.d.ts.map +0 -1
- package/dist/service/opportunities.js +0 -117
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-sales.d.ts","sourceRoot":"","sources":["../src/schema-sales.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"schema-sales.d.ts","sourceRoot":"","sources":["../src/schema-sales.ts"],"names":[],"mappings":"AAsBA,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiBrB,CAAA;AAED,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsBlB,CAAA;AAED,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6ClB,CAAA;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwB7B,CAAA;AAED,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyBzB,CAAA;AAED,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkCzB,CAAA;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuB7B,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG,OAAO,SAAS,CAAC,YAAY,CAAA;AACpD,MAAM,MAAM,WAAW,GAAG,OAAO,SAAS,CAAC,YAAY,CAAA;AACvD,MAAM,MAAM,KAAK,GAAG,OAAO,MAAM,CAAC,YAAY,CAAA;AAC9C,MAAM,MAAM,QAAQ,GAAG,OAAO,MAAM,CAAC,YAAY,CAAA;AACjD,MAAM,MAAM,KAAK,GAAG,OAAO,MAAM,CAAC,YAAY,CAAA;AAC9C,MAAM,MAAM,QAAQ,GAAG,OAAO,MAAM,CAAC,YAAY,CAAA;AACjD,MAAM,MAAM,gBAAgB,GAAG,OAAO,iBAAiB,CAAC,YAAY,CAAA;AACpE,MAAM,MAAM,mBAAmB,GAAG,OAAO,iBAAiB,CAAC,YAAY,CAAA;AACvE,MAAM,MAAM,YAAY,GAAG,OAAO,aAAa,CAAC,YAAY,CAAA;AAC5D,MAAM,MAAM,eAAe,GAAG,OAAO,aAAa,CAAC,YAAY,CAAA;AAC/D,MAAM,MAAM,YAAY,GAAG,OAAO,aAAa,CAAC,YAAY,CAAA;AAC5D,MAAM,MAAM,eAAe,GAAG,OAAO,aAAa,CAAC,YAAY,CAAA;AAC/D,MAAM,MAAM,gBAAgB,GAAG,OAAO,iBAAiB,CAAC,YAAY,CAAA;AACpE,MAAM,MAAM,mBAAmB,GAAG,OAAO,iBAAiB,CAAC,YAAY,CAAA"}
|
package/dist/schema-sales.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { typeId, typeIdRef } from "@voyantjs/db/lib/typeid-column";
|
|
2
2
|
import { boolean, date, index, integer, jsonb, pgTable, text, timestamp, uniqueIndex, } from "drizzle-orm/pg-core";
|
|
3
3
|
import { organizations, people } from "./schema-accounts.js";
|
|
4
|
-
import { entityTypeEnum,
|
|
4
|
+
import { entityTypeEnum, participantRoleEnum, quoteStatusEnum, quoteVersionStatusEnum, } from "./schema-shared.js";
|
|
5
5
|
export const pipelines = pgTable("pipelines", {
|
|
6
6
|
id: typeId("pipelines"),
|
|
7
|
-
entityType: entityTypeEnum("entity_type").notNull().default("
|
|
7
|
+
entityType: entityTypeEnum("entity_type").notNull().default("quote"),
|
|
8
8
|
name: text("name").notNull(),
|
|
9
9
|
isDefault: boolean("is_default").notNull().default(false),
|
|
10
10
|
sortOrder: integer("sort_order").notNull().default(0),
|
|
@@ -35,8 +35,8 @@ export const stages = pgTable("stages", {
|
|
|
35
35
|
index("idx_stages_pipeline_sort").on(table.pipelineId, table.sortOrder, table.createdAt),
|
|
36
36
|
uniqueIndex("uidx_stages_pipeline_name").on(table.pipelineId, table.name),
|
|
37
37
|
]);
|
|
38
|
-
export const
|
|
39
|
-
id: typeId("
|
|
38
|
+
export const quotes = pgTable("quotes", {
|
|
39
|
+
id: typeId("quotes"),
|
|
40
40
|
title: text("title").notNull(),
|
|
41
41
|
personId: typeIdRef("person_id").references(() => people.id, { onDelete: "set null" }),
|
|
42
42
|
organizationId: typeIdRef("organization_id").references(() => organizations.id, {
|
|
@@ -49,7 +49,8 @@ export const opportunities = pgTable("opportunities", {
|
|
|
49
49
|
.notNull()
|
|
50
50
|
.references(() => stages.id, { onDelete: "restrict" }),
|
|
51
51
|
ownerId: text("owner_id"),
|
|
52
|
-
status:
|
|
52
|
+
status: quoteStatusEnum("status").notNull().default("open"),
|
|
53
|
+
acceptedVersionId: typeIdRef("accepted_version_id"),
|
|
53
54
|
valueAmountCents: integer("value_amount_cents"),
|
|
54
55
|
valueCurrency: text("value_currency"),
|
|
55
56
|
expectedCloseDate: date("expected_close_date"),
|
|
@@ -62,24 +63,25 @@ export const opportunities = pgTable("opportunities", {
|
|
|
62
63
|
stageChangedAt: timestamp("stage_changed_at", { withTimezone: true }).notNull().defaultNow(),
|
|
63
64
|
closedAt: timestamp("closed_at", { withTimezone: true }),
|
|
64
65
|
}, (table) => [
|
|
65
|
-
index("
|
|
66
|
-
index("
|
|
67
|
-
index("
|
|
68
|
-
index("
|
|
69
|
-
index("
|
|
70
|
-
index("
|
|
71
|
-
index("
|
|
72
|
-
index("
|
|
73
|
-
index("
|
|
74
|
-
index("
|
|
75
|
-
index("
|
|
76
|
-
index("
|
|
66
|
+
index("idx_quotes_person").on(table.personId),
|
|
67
|
+
index("idx_quotes_org").on(table.organizationId),
|
|
68
|
+
index("idx_quotes_pipeline").on(table.pipelineId),
|
|
69
|
+
index("idx_quotes_stage").on(table.stageId),
|
|
70
|
+
index("idx_quotes_owner").on(table.ownerId),
|
|
71
|
+
index("idx_quotes_status").on(table.status),
|
|
72
|
+
index("idx_quotes_accepted_version").on(table.acceptedVersionId),
|
|
73
|
+
index("idx_quotes_person_updated").on(table.personId, table.updatedAt),
|
|
74
|
+
index("idx_quotes_org_updated").on(table.organizationId, table.updatedAt),
|
|
75
|
+
index("idx_quotes_pipeline_updated").on(table.pipelineId, table.updatedAt),
|
|
76
|
+
index("idx_quotes_stage_updated").on(table.stageId, table.updatedAt),
|
|
77
|
+
index("idx_quotes_owner_updated").on(table.ownerId, table.updatedAt),
|
|
78
|
+
index("idx_quotes_status_updated").on(table.status, table.updatedAt),
|
|
77
79
|
]);
|
|
78
|
-
export const
|
|
79
|
-
id: typeId("
|
|
80
|
-
|
|
80
|
+
export const quoteParticipants = pgTable("quote_participants", {
|
|
81
|
+
id: typeId("quote_participants"),
|
|
82
|
+
quoteId: typeIdRef("quote_id")
|
|
81
83
|
.notNull()
|
|
82
|
-
.references(() =>
|
|
84
|
+
.references(() => quotes.id, { onDelete: "cascade" }),
|
|
83
85
|
personId: typeIdRef("person_id")
|
|
84
86
|
.notNull()
|
|
85
87
|
.references(() => people.id, { onDelete: "cascade" }),
|
|
@@ -87,16 +89,16 @@ export const opportunityParticipants = pgTable("opportunity_participants", {
|
|
|
87
89
|
isPrimary: boolean("is_primary").notNull().default(false),
|
|
88
90
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
89
91
|
}, (table) => [
|
|
90
|
-
index("
|
|
91
|
-
index("
|
|
92
|
-
index("
|
|
93
|
-
uniqueIndex("
|
|
92
|
+
index("idx_quote_participants_quote").on(table.quoteId),
|
|
93
|
+
index("idx_quote_participants_quote_primary").on(table.quoteId, table.isPrimary, table.createdAt),
|
|
94
|
+
index("idx_quote_participants_person").on(table.personId),
|
|
95
|
+
uniqueIndex("uidx_quote_participants_unique").on(table.quoteId, table.personId),
|
|
94
96
|
]);
|
|
95
|
-
export const
|
|
96
|
-
id: typeId("
|
|
97
|
-
|
|
97
|
+
export const quoteProducts = pgTable("quote_products", {
|
|
98
|
+
id: typeId("quote_products"),
|
|
99
|
+
quoteId: typeIdRef("quote_id")
|
|
98
100
|
.notNull()
|
|
99
|
-
.references(() =>
|
|
101
|
+
.references(() => quotes.id, { onDelete: "cascade" }),
|
|
100
102
|
productId: text("product_id"),
|
|
101
103
|
supplierServiceId: text("supplier_service_id"),
|
|
102
104
|
nameSnapshot: text("name_snapshot").notNull(),
|
|
@@ -109,37 +111,47 @@ export const opportunityProducts = pgTable("opportunity_products", {
|
|
|
109
111
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
110
112
|
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
|
|
111
113
|
}, (table) => [
|
|
112
|
-
index("
|
|
113
|
-
index("
|
|
114
|
-
index("
|
|
115
|
-
index("
|
|
114
|
+
index("idx_quote_products_quote").on(table.quoteId),
|
|
115
|
+
index("idx_quote_products_quote_created").on(table.quoteId, table.createdAt),
|
|
116
|
+
index("idx_quote_products_product").on(table.productId),
|
|
117
|
+
index("idx_quote_products_supplier_service").on(table.supplierServiceId),
|
|
116
118
|
]);
|
|
117
|
-
export const
|
|
118
|
-
id: typeId("
|
|
119
|
-
|
|
119
|
+
export const quoteVersions = pgTable("quote_versions", {
|
|
120
|
+
id: typeId("quote_versions"),
|
|
121
|
+
quoteId: typeIdRef("quote_id")
|
|
120
122
|
.notNull()
|
|
121
|
-
.references(() =>
|
|
122
|
-
|
|
123
|
+
.references(() => quotes.id, { onDelete: "cascade" }),
|
|
124
|
+
label: text("label"),
|
|
125
|
+
status: quoteVersionStatusEnum("status").notNull().default("draft"),
|
|
126
|
+
supersedesId: typeIdRef("supersedes_id").references(() => quoteVersions.id, {
|
|
127
|
+
onDelete: "set null",
|
|
128
|
+
}),
|
|
129
|
+
tripSnapshotId: text("trip_snapshot_id"),
|
|
123
130
|
validUntil: date("valid_until"),
|
|
124
131
|
currency: text("currency").notNull(),
|
|
125
132
|
subtotalAmountCents: integer("subtotal_amount_cents").notNull().default(0),
|
|
126
133
|
taxAmountCents: integer("tax_amount_cents").notNull().default(0),
|
|
127
134
|
totalAmountCents: integer("total_amount_cents").notNull().default(0),
|
|
128
135
|
notes: text("notes"),
|
|
136
|
+
sentAt: timestamp("sent_at", { withTimezone: true }),
|
|
137
|
+
viewedAt: timestamp("viewed_at", { withTimezone: true }),
|
|
138
|
+
decidedAt: timestamp("decided_at", { withTimezone: true }),
|
|
129
139
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
130
140
|
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
|
|
131
141
|
archivedAt: timestamp("archived_at", { withTimezone: true }),
|
|
132
142
|
}, (table) => [
|
|
133
|
-
index("
|
|
134
|
-
index("
|
|
135
|
-
index("
|
|
136
|
-
index("
|
|
143
|
+
index("idx_quote_versions_quote").on(table.quoteId),
|
|
144
|
+
index("idx_quote_versions_status").on(table.status),
|
|
145
|
+
index("idx_quote_versions_supersedes").on(table.supersedesId),
|
|
146
|
+
index("idx_quote_versions_trip_snapshot").on(table.tripSnapshotId),
|
|
147
|
+
index("idx_quote_versions_quote_updated").on(table.quoteId, table.updatedAt),
|
|
148
|
+
index("idx_quote_versions_status_updated").on(table.status, table.updatedAt),
|
|
137
149
|
]);
|
|
138
|
-
export const
|
|
139
|
-
id: typeId("
|
|
140
|
-
|
|
150
|
+
export const quoteVersionLines = pgTable("quote_version_lines", {
|
|
151
|
+
id: typeId("quote_version_lines"),
|
|
152
|
+
quoteVersionId: typeIdRef("quote_version_id")
|
|
141
153
|
.notNull()
|
|
142
|
-
.references(() =>
|
|
154
|
+
.references(() => quoteVersions.id, { onDelete: "cascade" }),
|
|
143
155
|
productId: text("product_id"),
|
|
144
156
|
supplierServiceId: text("supplier_service_id"),
|
|
145
157
|
description: text("description").notNull(),
|
|
@@ -150,8 +162,8 @@ export const quoteLines = pgTable("quote_lines", {
|
|
|
150
162
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
151
163
|
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
|
|
152
164
|
}, (table) => [
|
|
153
|
-
index("
|
|
154
|
-
index("
|
|
155
|
-
index("
|
|
156
|
-
index("
|
|
165
|
+
index("idx_quote_version_lines_version").on(table.quoteVersionId),
|
|
166
|
+
index("idx_quote_version_lines_version_created").on(table.quoteVersionId, table.createdAt),
|
|
167
|
+
index("idx_quote_version_lines_product").on(table.productId),
|
|
168
|
+
index("idx_quote_version_lines_supplier_service").on(table.supplierServiceId),
|
|
157
169
|
]);
|
package/dist/schema-shared.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export declare const entityTypeEnum: import("drizzle-orm/pg-core").PgEnum<["organization", "person", "
|
|
1
|
+
export declare const entityTypeEnum: import("drizzle-orm/pg-core").PgEnum<["organization", "person", "quote", "activity"]>;
|
|
2
2
|
export declare const relationTypeEnum: import("drizzle-orm/pg-core").PgEnum<["client", "partner", "supplier", "other"]>;
|
|
3
3
|
export declare const communicationChannelEnum: import("drizzle-orm/pg-core").PgEnum<["email", "phone", "whatsapp", "sms", "meeting", "other"]>;
|
|
4
4
|
export declare const communicationDirectionEnum: import("drizzle-orm/pg-core").PgEnum<["inbound", "outbound"]>;
|
|
5
5
|
export declare const recordStatusEnum: import("drizzle-orm/pg-core").PgEnum<["active", "inactive", "archived"]>;
|
|
6
|
-
export declare const
|
|
7
|
-
export declare const
|
|
6
|
+
export declare const quoteStatusEnum: import("drizzle-orm/pg-core").PgEnum<["open", "won", "lost", "archived"]>;
|
|
7
|
+
export declare const quoteVersionStatusEnum: import("drizzle-orm/pg-core").PgEnum<["draft", "sent", "accepted", "declined", "superseded", "expired"]>;
|
|
8
8
|
export declare const activityTypeEnum: import("drizzle-orm/pg-core").PgEnum<["call", "email", "meeting", "task", "follow_up", "note"]>;
|
|
9
9
|
export declare const activityStatusEnum: import("drizzle-orm/pg-core").PgEnum<["planned", "done", "cancelled"]>;
|
|
10
10
|
export declare const activityLinkRoleEnum: import("drizzle-orm/pg-core").PgEnum<["primary", "related"]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-shared.d.ts","sourceRoot":"","sources":["../src/schema-shared.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"schema-shared.d.ts","sourceRoot":"","sources":["../src/schema-shared.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc,uFAAyE,CAAA;AAEpG,eAAO,MAAM,gBAAgB,kFAAsE,CAAA;AAEnG,eAAO,MAAM,wBAAwB,iGAOnC,CAAA;AAEF,eAAO,MAAM,0BAA0B,+DAA6D,CAAA;AAEpG,eAAO,MAAM,gBAAgB,0EAA8D,CAAA;AAE3F,eAAO,MAAM,eAAe,2EAA8D,CAAA;AAE1F,eAAO,MAAM,sBAAsB,0GAOjC,CAAA;AAEF,eAAO,MAAM,gBAAgB,iGAO3B,CAAA;AAEF,eAAO,MAAM,kBAAkB,wEAA8D,CAAA;AAE7F,eAAO,MAAM,oBAAoB,8DAAuD,CAAA;AAExF,eAAO,MAAM,mBAAmB,oGAM9B,CAAA;AAEF,eAAO,MAAM,mBAAmB,+IAY9B,CAAA"}
|
package/dist/schema-shared.js
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import { pgEnum } from "drizzle-orm/pg-core";
|
|
2
|
-
export const entityTypeEnum = pgEnum("entity_type", [
|
|
3
|
-
"organization",
|
|
4
|
-
"person",
|
|
5
|
-
"opportunity",
|
|
6
|
-
"quote",
|
|
7
|
-
"activity",
|
|
8
|
-
]);
|
|
2
|
+
export const entityTypeEnum = pgEnum("entity_type", ["organization", "person", "quote", "activity"]);
|
|
9
3
|
export const relationTypeEnum = pgEnum("relation_type", ["client", "partner", "supplier", "other"]);
|
|
10
4
|
export const communicationChannelEnum = pgEnum("communication_channel", [
|
|
11
5
|
"email",
|
|
@@ -17,19 +11,14 @@ export const communicationChannelEnum = pgEnum("communication_channel", [
|
|
|
17
11
|
]);
|
|
18
12
|
export const communicationDirectionEnum = pgEnum("communication_direction", ["inbound", "outbound"]);
|
|
19
13
|
export const recordStatusEnum = pgEnum("record_status", ["active", "inactive", "archived"]);
|
|
20
|
-
export const
|
|
21
|
-
|
|
22
|
-
"won",
|
|
23
|
-
"lost",
|
|
24
|
-
"archived",
|
|
25
|
-
]);
|
|
26
|
-
export const quoteStatusEnum = pgEnum("quote_status", [
|
|
14
|
+
export const quoteStatusEnum = pgEnum("quote_status", ["open", "won", "lost", "archived"]);
|
|
15
|
+
export const quoteVersionStatusEnum = pgEnum("quote_version_status", [
|
|
27
16
|
"draft",
|
|
28
17
|
"sent",
|
|
29
18
|
"accepted",
|
|
19
|
+
"declined",
|
|
20
|
+
"superseded",
|
|
30
21
|
"expired",
|
|
31
|
-
"rejected",
|
|
32
|
-
"archived",
|
|
33
22
|
]);
|
|
34
23
|
export const activityTypeEnum = pgEnum("activity_type", [
|
|
35
24
|
"call",
|
package/dist/schema-signals.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Customer signals — lighter than `
|
|
2
|
+
* Customer signals — lighter than `quotes` (no deal value or
|
|
3
3
|
* stages), heavier than `segments` (lifecycle + assignment). Records
|
|
4
4
|
* "person X expressed interest in product/departure Y from source Z,
|
|
5
5
|
* status pending". The most common use cases:
|
package/dist/schema-signals.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Customer signals — lighter than `
|
|
2
|
+
* Customer signals — lighter than `quotes` (no deal value or
|
|
3
3
|
* stages), heavier than `segments` (lifecycle + assignment). Records
|
|
4
4
|
* "person X expressed interest in product/departure Y from source Z,
|
|
5
5
|
* status pending". The most common use cases:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { identityAddresses, identityContactPoints, identityNamedContacts, } from "@voyantjs/identity/schema";
|
|
2
2
|
import { and, eq, inArray, ne, or, sql } from "drizzle-orm";
|
|
3
|
-
import { activityLinks, activityParticipants, communicationLog, customerSignals, customFieldValues,
|
|
3
|
+
import { activityLinks, activityParticipants, communicationLog, customerSignals, customFieldValues, organizationNotes, organizations, people, personDocuments, personNotes, personPaymentMethods, personRelationships, quoteParticipants, quotes, segmentMembers, } from "../schema.js";
|
|
4
4
|
import { hydratePeople, organizationEntityType, personEntityType } from "./accounts-shared.js";
|
|
5
5
|
export class CrmMergeError extends Error {
|
|
6
6
|
status;
|
|
@@ -156,10 +156,10 @@ async function mergeEntityLinks(db, entityType, keepId, mergeId) {
|
|
|
156
156
|
.where(and(eq(customFieldValues.entityType, entityType), eq(customFieldValues.entityId, mergeId)));
|
|
157
157
|
}
|
|
158
158
|
async function dedupePersonJoinTables(db, keepId, mergeId) {
|
|
159
|
-
await db.delete(
|
|
159
|
+
await db.delete(quoteParticipants).where(and(eq(quoteParticipants.personId, mergeId), sql `EXISTS (
|
|
160
160
|
SELECT 1
|
|
161
|
-
FROM
|
|
162
|
-
WHERE keep_participant.
|
|
161
|
+
FROM quote_participants keep_participant
|
|
162
|
+
WHERE keep_participant.quote_id = ${quoteParticipants.quoteId}
|
|
163
163
|
AND keep_participant.person_id = ${keepId}
|
|
164
164
|
)`));
|
|
165
165
|
await db.delete(activityParticipants).where(and(eq(activityParticipants.personId, mergeId), sql `EXISTS (
|
|
@@ -258,13 +258,13 @@ export const accountMergeService = {
|
|
|
258
258
|
.set({ personId: keepId })
|
|
259
259
|
.where(eq(communicationLog.personId, mergeId));
|
|
260
260
|
await tx
|
|
261
|
-
.update(
|
|
261
|
+
.update(quotes)
|
|
262
262
|
.set({ personId: keepId, updatedAt: new Date() })
|
|
263
|
-
.where(eq(
|
|
263
|
+
.where(eq(quotes.personId, mergeId));
|
|
264
264
|
await tx
|
|
265
|
-
.update(
|
|
265
|
+
.update(quoteParticipants)
|
|
266
266
|
.set({ personId: keepId })
|
|
267
|
-
.where(eq(
|
|
267
|
+
.where(eq(quoteParticipants.personId, mergeId));
|
|
268
268
|
await tx
|
|
269
269
|
.update(activityParticipants)
|
|
270
270
|
.set({ personId: keepId })
|
|
@@ -347,9 +347,9 @@ export const accountMergeService = {
|
|
|
347
347
|
.set({ organizationId: keepId })
|
|
348
348
|
.where(eq(communicationLog.organizationId, mergeId));
|
|
349
349
|
await tx
|
|
350
|
-
.update(
|
|
350
|
+
.update(quotes)
|
|
351
351
|
.set({ organizationId: keepId, updatedAt: new Date() })
|
|
352
|
-
.where(eq(
|
|
352
|
+
.where(eq(quotes.organizationId, mergeId));
|
|
353
353
|
await updateOptionalReferences(tx, OPTIONAL_ORGANIZATION_REFERENCES, keepId, mergeId);
|
|
354
354
|
await updateOptionalEntityTargetReferences(tx, OPTIONAL_ORGANIZATION_ENTITY_TARGET_REFERENCES, keepId, mergeId);
|
|
355
355
|
await tx.delete(organizations).where(eq(organizations.id, mergeId));
|
|
@@ -107,14 +107,14 @@ export declare const activitiesService: {
|
|
|
107
107
|
tableName: "activity_links";
|
|
108
108
|
dataType: "string";
|
|
109
109
|
columnType: "PgEnumColumn";
|
|
110
|
-
data: "organization" | "person" | "
|
|
110
|
+
data: "organization" | "person" | "quote" | "activity";
|
|
111
111
|
driverParam: string;
|
|
112
112
|
notNull: true;
|
|
113
113
|
hasDefault: false;
|
|
114
114
|
isPrimaryKey: false;
|
|
115
115
|
isAutoincrement: false;
|
|
116
116
|
hasRuntimeDefault: false;
|
|
117
|
-
enumValues: ["organization", "person", "
|
|
117
|
+
enumValues: ["organization", "person", "quote", "activity"];
|
|
118
118
|
baseColumn: never;
|
|
119
119
|
identity: undefined;
|
|
120
120
|
generated: undefined;
|
|
@@ -173,7 +173,7 @@ export declare const activitiesService: {
|
|
|
173
173
|
}, "single", Record<"activity_links", "not-null">, false, "where" | "orderBy", {
|
|
174
174
|
id: string;
|
|
175
175
|
activityId: string;
|
|
176
|
-
entityType: "organization" | "person" | "
|
|
176
|
+
entityType: "organization" | "person" | "quote" | "activity";
|
|
177
177
|
entityId: string;
|
|
178
178
|
role: "primary" | "related";
|
|
179
179
|
createdAt: Date;
|
|
@@ -217,14 +217,14 @@ export declare const activitiesService: {
|
|
|
217
217
|
tableName: "activity_links";
|
|
218
218
|
dataType: "string";
|
|
219
219
|
columnType: "PgEnumColumn";
|
|
220
|
-
data: "organization" | "person" | "
|
|
220
|
+
data: "organization" | "person" | "quote" | "activity";
|
|
221
221
|
driverParam: string;
|
|
222
222
|
notNull: true;
|
|
223
223
|
hasDefault: false;
|
|
224
224
|
isPrimaryKey: false;
|
|
225
225
|
isAutoincrement: false;
|
|
226
226
|
hasRuntimeDefault: false;
|
|
227
|
-
enumValues: ["organization", "person", "
|
|
227
|
+
enumValues: ["organization", "person", "quote", "activity"];
|
|
228
228
|
baseColumn: never;
|
|
229
229
|
identity: undefined;
|
|
230
230
|
generated: undefined;
|
|
@@ -285,7 +285,7 @@ export declare const activitiesService: {
|
|
|
285
285
|
id: string;
|
|
286
286
|
createdAt: Date;
|
|
287
287
|
role: "primary" | "related";
|
|
288
|
-
entityType: "organization" | "person" | "
|
|
288
|
+
entityType: "organization" | "person" | "quote" | "activity";
|
|
289
289
|
entityId: string;
|
|
290
290
|
activityId: string;
|
|
291
291
|
} | undefined>;
|
|
@@ -10,7 +10,7 @@ export declare const customFieldsService: {
|
|
|
10
10
|
listCustomFieldDefinitions(db: PostgresJsDatabase, query: CustomFieldDefinitionListQuery): Promise<{
|
|
11
11
|
data: {
|
|
12
12
|
id: string;
|
|
13
|
-
entityType: "organization" | "person" | "
|
|
13
|
+
entityType: "organization" | "person" | "quote" | "activity";
|
|
14
14
|
key: string;
|
|
15
15
|
label: string;
|
|
16
16
|
fieldType: "boolean" | "json" | "date" | "text" | "set" | "enum" | "phone" | "varchar" | "double" | "monetary" | "address";
|
|
@@ -29,7 +29,7 @@ export declare const customFieldsService: {
|
|
|
29
29
|
}>;
|
|
30
30
|
getCustomFieldDefinitionById(db: PostgresJsDatabase, id: string): Promise<{
|
|
31
31
|
id: string;
|
|
32
|
-
entityType: "organization" | "person" | "
|
|
32
|
+
entityType: "organization" | "person" | "quote" | "activity";
|
|
33
33
|
key: string;
|
|
34
34
|
label: string;
|
|
35
35
|
fieldType: "boolean" | "json" | "date" | "text" | "set" | "enum" | "phone" | "varchar" | "double" | "monetary" | "address";
|
|
@@ -51,7 +51,7 @@ export declare const customFieldsService: {
|
|
|
51
51
|
createdAt: Date;
|
|
52
52
|
key: string;
|
|
53
53
|
updatedAt: Date;
|
|
54
|
-
entityType: "organization" | "person" | "
|
|
54
|
+
entityType: "organization" | "person" | "quote" | "activity";
|
|
55
55
|
label: string;
|
|
56
56
|
fieldType: "boolean" | "json" | "date" | "text" | "set" | "enum" | "phone" | "varchar" | "double" | "monetary" | "address";
|
|
57
57
|
isRequired: boolean;
|
|
@@ -59,7 +59,7 @@ export declare const customFieldsService: {
|
|
|
59
59
|
} | undefined>;
|
|
60
60
|
updateCustomFieldDefinition(db: PostgresJsDatabase, id: string, data: UpdateCustomFieldDefinitionInput): Promise<{
|
|
61
61
|
id: string;
|
|
62
|
-
entityType: "organization" | "person" | "
|
|
62
|
+
entityType: "organization" | "person" | "quote" | "activity";
|
|
63
63
|
key: string;
|
|
64
64
|
label: string;
|
|
65
65
|
fieldType: "boolean" | "json" | "date" | "text" | "set" | "enum" | "phone" | "varchar" | "double" | "monetary" | "address";
|
|
@@ -79,7 +79,7 @@ export declare const customFieldsService: {
|
|
|
79
79
|
data: {
|
|
80
80
|
id: string;
|
|
81
81
|
definitionId: string;
|
|
82
|
-
entityType: "organization" | "person" | "
|
|
82
|
+
entityType: "organization" | "person" | "quote" | "activity";
|
|
83
83
|
entityId: string;
|
|
84
84
|
textValue: string | null;
|
|
85
85
|
numberValue: number | null;
|
|
@@ -99,7 +99,7 @@ export declare const customFieldsService: {
|
|
|
99
99
|
id: string;
|
|
100
100
|
createdAt: Date;
|
|
101
101
|
updatedAt: Date;
|
|
102
|
-
entityType: "organization" | "person" | "
|
|
102
|
+
entityType: "organization" | "person" | "quote" | "activity";
|
|
103
103
|
entityId: string;
|
|
104
104
|
definitionId: string;
|
|
105
105
|
textValue: string | null;
|