@voyantjs/crm 0.96.0 → 0.97.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/service/accounts.d.ts +2 -2
- package/dist/service/index.d.ts +2 -2
- package/dist/validation.d.ts +1 -1393
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +1 -536
- package/package.json +8 -7
package/dist/validation.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAA"}
|
package/dist/validation.js
CHANGED
|
@@ -1,536 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
const paginationSchema = z.object({
|
|
4
|
-
limit: z.coerce.number().int().min(1).max(200).default(50),
|
|
5
|
-
offset: z.coerce.number().int().min(0).default(0),
|
|
6
|
-
});
|
|
7
|
-
export const entityTypeSchema = z.enum([
|
|
8
|
-
"organization",
|
|
9
|
-
"person",
|
|
10
|
-
"opportunity",
|
|
11
|
-
"quote",
|
|
12
|
-
"activity",
|
|
13
|
-
]);
|
|
14
|
-
export const recordStatusSchema = z.enum(["active", "inactive", "archived"]);
|
|
15
|
-
export const relationTypeSchema = z.enum(["client", "partner", "supplier", "other"]);
|
|
16
|
-
export const communicationChannelSchema = z.enum([
|
|
17
|
-
"email",
|
|
18
|
-
"phone",
|
|
19
|
-
"whatsapp",
|
|
20
|
-
"sms",
|
|
21
|
-
"meeting",
|
|
22
|
-
"other",
|
|
23
|
-
]);
|
|
24
|
-
export const communicationDirectionSchema = z.enum(["inbound", "outbound"]);
|
|
25
|
-
export const opportunityStatusSchema = z.enum(["open", "won", "lost", "archived"]);
|
|
26
|
-
export const quoteStatusSchema = z.enum([
|
|
27
|
-
"draft",
|
|
28
|
-
"sent",
|
|
29
|
-
"accepted",
|
|
30
|
-
"expired",
|
|
31
|
-
"rejected",
|
|
32
|
-
"archived",
|
|
33
|
-
]);
|
|
34
|
-
export const activityTypeSchema = z.enum(["call", "email", "meeting", "task", "follow_up", "note"]);
|
|
35
|
-
export const activityStatusSchema = z.enum(["planned", "done", "cancelled"]);
|
|
36
|
-
export const participantRoleSchema = z.enum([
|
|
37
|
-
"traveler",
|
|
38
|
-
"booker",
|
|
39
|
-
"decision_maker",
|
|
40
|
-
"finance",
|
|
41
|
-
"other",
|
|
42
|
-
]);
|
|
43
|
-
export const activityLinkRoleSchema = z.enum(["primary", "related"]);
|
|
44
|
-
export const customFieldTypeSchema = z.enum([
|
|
45
|
-
"varchar",
|
|
46
|
-
"text",
|
|
47
|
-
"double",
|
|
48
|
-
"monetary",
|
|
49
|
-
"date",
|
|
50
|
-
"boolean",
|
|
51
|
-
"enum",
|
|
52
|
-
"set",
|
|
53
|
-
"json",
|
|
54
|
-
"address",
|
|
55
|
-
"phone",
|
|
56
|
-
]);
|
|
57
|
-
const nullableTrimmedStringSchema = z
|
|
58
|
-
.string()
|
|
59
|
-
.nullable()
|
|
60
|
-
.optional()
|
|
61
|
-
.transform((value) => (typeof value === "string" ? value.trim() || null : value));
|
|
62
|
-
export const organizationCoreSchema = z.object({
|
|
63
|
-
name: z.string().min(1),
|
|
64
|
-
legalName: z.string().nullable().optional(),
|
|
65
|
-
website: z
|
|
66
|
-
.string()
|
|
67
|
-
.url()
|
|
68
|
-
.nullable()
|
|
69
|
-
.optional()
|
|
70
|
-
.or(z.literal(""))
|
|
71
|
-
.transform((v) => v || null),
|
|
72
|
-
taxId: nullableTrimmedStringSchema,
|
|
73
|
-
industry: z.string().nullable().optional(),
|
|
74
|
-
relation: relationTypeSchema.nullable().optional(),
|
|
75
|
-
ownerId: z.string().nullable().optional(),
|
|
76
|
-
defaultCurrency: z.string().nullable().optional(),
|
|
77
|
-
preferredLanguage: z.string().nullable().optional(),
|
|
78
|
-
paymentTerms: z.number().int().positive().nullable().optional(),
|
|
79
|
-
status: recordStatusSchema.default("active"),
|
|
80
|
-
source: z.string().nullable().optional(),
|
|
81
|
-
sourceRef: z.string().nullable().optional(),
|
|
82
|
-
tags: z.array(z.string()).default([]),
|
|
83
|
-
notes: z.string().nullable().optional(),
|
|
84
|
-
});
|
|
85
|
-
export const insertOrganizationSchema = organizationCoreSchema;
|
|
86
|
-
export const updateOrganizationSchema = organizationCoreSchema.partial();
|
|
87
|
-
export const organizationListSortFieldSchema = z.enum([
|
|
88
|
-
"name",
|
|
89
|
-
"industry",
|
|
90
|
-
"relation",
|
|
91
|
-
"status",
|
|
92
|
-
"createdAt",
|
|
93
|
-
"updatedAt",
|
|
94
|
-
]);
|
|
95
|
-
export const organizationListSortDirSchema = z.enum(["asc", "desc"]);
|
|
96
|
-
export const organizationListQuerySchema = paginationSchema
|
|
97
|
-
.extend({
|
|
98
|
-
ownerId: z.string().optional(),
|
|
99
|
-
relation: relationTypeSchema.optional(),
|
|
100
|
-
status: recordStatusSchema.optional(),
|
|
101
|
-
search: z.string().optional(),
|
|
102
|
-
taxId: z.string().optional(),
|
|
103
|
-
tax_id: z.string().optional(),
|
|
104
|
-
sortBy: organizationListSortFieldSchema.default("updatedAt"),
|
|
105
|
-
sortDir: organizationListSortDirSchema.default("desc"),
|
|
106
|
-
})
|
|
107
|
-
.transform(({ tax_id: taxIdSnake, ...query }) => ({
|
|
108
|
-
...query,
|
|
109
|
-
taxId: query.taxId?.trim() || taxIdSnake?.trim() || undefined,
|
|
110
|
-
}));
|
|
111
|
-
export const personCoreSchema = z.object({
|
|
112
|
-
organizationId: z.string().nullable().optional(),
|
|
113
|
-
firstName: z.string().min(1),
|
|
114
|
-
middleName: z.string().nullable().optional(),
|
|
115
|
-
lastName: z.string().min(1),
|
|
116
|
-
gender: z.enum(["M", "F", "X"]).nullable().optional(),
|
|
117
|
-
jobTitle: z.string().nullable().optional(),
|
|
118
|
-
relation: relationTypeSchema.nullable().optional(),
|
|
119
|
-
preferredLanguage: z.string().nullable().optional(),
|
|
120
|
-
preferredCurrency: z.string().nullable().optional(),
|
|
121
|
-
ownerId: z.string().nullable().optional(),
|
|
122
|
-
status: recordStatusSchema.default("active"),
|
|
123
|
-
source: z.string().nullable().optional(),
|
|
124
|
-
sourceRef: z.string().nullable().optional(),
|
|
125
|
-
tags: z.array(z.string()).default([]),
|
|
126
|
-
dateOfBirth: z.string().date().nullable().optional(),
|
|
127
|
-
notes: z.string().nullable().optional(),
|
|
128
|
-
// Encrypted PII slots (canonical store; documents live in person_documents).
|
|
129
|
-
// `z.lazy(() => …)` defers cross-package schema dereferencing until
|
|
130
|
-
// first parse — see #501 for the bundler chunk-init hazard otherwise.
|
|
131
|
-
accessibilityEncrypted: z.lazy(() => kmsEnvelopeSchema).optional(),
|
|
132
|
-
dietaryEncrypted: z.lazy(() => kmsEnvelopeSchema).optional(),
|
|
133
|
-
loyaltyEncrypted: z.lazy(() => kmsEnvelopeSchema).optional(),
|
|
134
|
-
insuranceEncrypted: z.lazy(() => kmsEnvelopeSchema).optional(),
|
|
135
|
-
// Inline identity fields — synced to identity module on create/update
|
|
136
|
-
email: z.preprocess((value) => (value === "" ? null : value), z.string().email().nullable().optional()),
|
|
137
|
-
phone: z.string().nullable().optional(),
|
|
138
|
-
website: z
|
|
139
|
-
.string()
|
|
140
|
-
.url()
|
|
141
|
-
.nullable()
|
|
142
|
-
.optional()
|
|
143
|
-
.or(z.literal(""))
|
|
144
|
-
.transform((v) => v || null),
|
|
145
|
-
});
|
|
146
|
-
export const insertPersonSchema = personCoreSchema;
|
|
147
|
-
export const updatePersonSchema = personCoreSchema.partial();
|
|
148
|
-
export const personListSortFieldSchema = z.enum([
|
|
149
|
-
"name",
|
|
150
|
-
"relation",
|
|
151
|
-
"status",
|
|
152
|
-
"createdAt",
|
|
153
|
-
"updatedAt",
|
|
154
|
-
]);
|
|
155
|
-
export const personListSortDirSchema = z.enum(["asc", "desc"]);
|
|
156
|
-
export const personListQuerySchema = paginationSchema.extend({
|
|
157
|
-
organizationId: z.string().optional(),
|
|
158
|
-
ownerId: z.string().optional(),
|
|
159
|
-
relation: relationTypeSchema.optional(),
|
|
160
|
-
status: recordStatusSchema.optional(),
|
|
161
|
-
search: z.string().optional(),
|
|
162
|
-
sortBy: personListSortFieldSchema.default("updatedAt"),
|
|
163
|
-
sortDir: personListSortDirSchema.default("desc"),
|
|
164
|
-
});
|
|
165
|
-
export const pipelineCoreSchema = z.object({
|
|
166
|
-
entityType: entityTypeSchema.default("opportunity"),
|
|
167
|
-
name: z.string().min(1),
|
|
168
|
-
isDefault: z.boolean().default(false),
|
|
169
|
-
sortOrder: z.number().int().default(0),
|
|
170
|
-
});
|
|
171
|
-
export const insertPipelineSchema = pipelineCoreSchema;
|
|
172
|
-
export const updatePipelineSchema = pipelineCoreSchema.partial();
|
|
173
|
-
export const pipelineListQuerySchema = paginationSchema.extend({
|
|
174
|
-
entityType: entityTypeSchema.optional(),
|
|
175
|
-
});
|
|
176
|
-
export const stageCoreSchema = z.object({
|
|
177
|
-
pipelineId: z.string(),
|
|
178
|
-
name: z.string().min(1),
|
|
179
|
-
sortOrder: z.number().int().default(0),
|
|
180
|
-
probability: z.number().int().min(0).max(100).nullable().optional(),
|
|
181
|
-
isClosed: z.boolean().default(false),
|
|
182
|
-
isWon: z.boolean().default(false),
|
|
183
|
-
isLost: z.boolean().default(false),
|
|
184
|
-
});
|
|
185
|
-
export const insertStageSchema = stageCoreSchema;
|
|
186
|
-
export const updateStageSchema = stageCoreSchema.partial();
|
|
187
|
-
export const stageListQuerySchema = paginationSchema.extend({
|
|
188
|
-
pipelineId: z.string().optional(),
|
|
189
|
-
});
|
|
190
|
-
export const opportunityCoreSchema = z.object({
|
|
191
|
-
title: z.string().min(1),
|
|
192
|
-
personId: z.string().nullable().optional(),
|
|
193
|
-
organizationId: z.string().nullable().optional(),
|
|
194
|
-
pipelineId: z.string(),
|
|
195
|
-
stageId: z.string(),
|
|
196
|
-
ownerId: z.string().nullable().optional(),
|
|
197
|
-
status: opportunityStatusSchema.default("open"),
|
|
198
|
-
valueAmountCents: z.number().int().nullable().optional(),
|
|
199
|
-
valueCurrency: z.string().nullable().optional(),
|
|
200
|
-
expectedCloseDate: z.string().date().nullable().optional(),
|
|
201
|
-
source: z.string().nullable().optional(),
|
|
202
|
-
sourceRef: z.string().nullable().optional(),
|
|
203
|
-
lostReason: z.string().nullable().optional(),
|
|
204
|
-
tags: z.array(z.string()).default([]),
|
|
205
|
-
});
|
|
206
|
-
export const insertOpportunitySchema = opportunityCoreSchema;
|
|
207
|
-
export const updateOpportunitySchema = opportunityCoreSchema.partial();
|
|
208
|
-
export const opportunityListQuerySchema = paginationSchema.extend({
|
|
209
|
-
personId: z.string().optional(),
|
|
210
|
-
organizationId: z.string().optional(),
|
|
211
|
-
pipelineId: z.string().optional(),
|
|
212
|
-
stageId: z.string().optional(),
|
|
213
|
-
ownerId: z.string().optional(),
|
|
214
|
-
status: opportunityStatusSchema.optional(),
|
|
215
|
-
search: z.string().optional(),
|
|
216
|
-
});
|
|
217
|
-
export const insertOpportunityParticipantSchema = z.object({
|
|
218
|
-
personId: z.string(),
|
|
219
|
-
role: participantRoleSchema.default("other"),
|
|
220
|
-
isPrimary: z.boolean().default(false),
|
|
221
|
-
});
|
|
222
|
-
export const insertOpportunityProductSchema = z.object({
|
|
223
|
-
productId: z.string().nullable().optional(),
|
|
224
|
-
supplierServiceId: z.string().nullable().optional(),
|
|
225
|
-
nameSnapshot: z.string().min(1),
|
|
226
|
-
description: z.string().nullable().optional(),
|
|
227
|
-
quantity: z.number().int().min(1).default(1),
|
|
228
|
-
unitPriceAmountCents: z.number().int().nullable().optional(),
|
|
229
|
-
costAmountCents: z.number().int().nullable().optional(),
|
|
230
|
-
currency: z.string().nullable().optional(),
|
|
231
|
-
discountAmountCents: z.number().int().nullable().optional(),
|
|
232
|
-
});
|
|
233
|
-
export const updateOpportunityProductSchema = insertOpportunityProductSchema.partial();
|
|
234
|
-
export const quoteCoreSchema = z.object({
|
|
235
|
-
opportunityId: z.string(),
|
|
236
|
-
status: quoteStatusSchema.default("draft"),
|
|
237
|
-
validUntil: z.string().date().nullable().optional(),
|
|
238
|
-
currency: z.string().min(1),
|
|
239
|
-
subtotalAmountCents: z.number().int().default(0),
|
|
240
|
-
taxAmountCents: z.number().int().default(0),
|
|
241
|
-
totalAmountCents: z.number().int().default(0),
|
|
242
|
-
notes: z.string().nullable().optional(),
|
|
243
|
-
});
|
|
244
|
-
export const insertQuoteSchema = quoteCoreSchema;
|
|
245
|
-
export const updateQuoteSchema = quoteCoreSchema.partial();
|
|
246
|
-
export const quoteListQuerySchema = paginationSchema.extend({
|
|
247
|
-
opportunityId: z.string().optional(),
|
|
248
|
-
status: quoteStatusSchema.optional(),
|
|
249
|
-
});
|
|
250
|
-
export const quoteLineCoreSchema = z.object({
|
|
251
|
-
productId: z.string().nullable().optional(),
|
|
252
|
-
supplierServiceId: z.string().nullable().optional(),
|
|
253
|
-
description: z.string().min(1),
|
|
254
|
-
quantity: z.number().int().min(1).default(1),
|
|
255
|
-
unitPriceAmountCents: z.number().int().default(0),
|
|
256
|
-
totalAmountCents: z.number().int().default(0),
|
|
257
|
-
currency: z.string().min(1),
|
|
258
|
-
});
|
|
259
|
-
export const insertQuoteLineSchema = quoteLineCoreSchema;
|
|
260
|
-
export const updateQuoteLineSchema = quoteLineCoreSchema.partial();
|
|
261
|
-
export const activityCoreSchema = z.object({
|
|
262
|
-
subject: z.string().min(1),
|
|
263
|
-
type: activityTypeSchema,
|
|
264
|
-
ownerId: z.string().nullable().optional(),
|
|
265
|
-
status: activityStatusSchema.default("planned"),
|
|
266
|
-
dueAt: z.string().datetime().nullable().optional(),
|
|
267
|
-
completedAt: z.string().datetime().nullable().optional(),
|
|
268
|
-
location: z.string().nullable().optional(),
|
|
269
|
-
description: z.string().nullable().optional(),
|
|
270
|
-
});
|
|
271
|
-
export const insertActivitySchema = activityCoreSchema;
|
|
272
|
-
export const updateActivitySchema = activityCoreSchema.partial();
|
|
273
|
-
export const activityListQuerySchema = paginationSchema.extend({
|
|
274
|
-
ownerId: z.string().optional(),
|
|
275
|
-
status: activityStatusSchema.optional(),
|
|
276
|
-
type: activityTypeSchema.optional(),
|
|
277
|
-
entityType: entityTypeSchema.optional(),
|
|
278
|
-
entityId: z.string().optional(),
|
|
279
|
-
search: z.string().optional(),
|
|
280
|
-
});
|
|
281
|
-
export const insertActivityLinkSchema = z.object({
|
|
282
|
-
entityType: entityTypeSchema,
|
|
283
|
-
entityId: z.string(),
|
|
284
|
-
role: activityLinkRoleSchema.default("related"),
|
|
285
|
-
});
|
|
286
|
-
export const insertActivityParticipantSchema = z.object({
|
|
287
|
-
personId: z.string(),
|
|
288
|
-
isPrimary: z.boolean().default(false),
|
|
289
|
-
});
|
|
290
|
-
export const customFieldDefinitionCoreSchema = z.object({
|
|
291
|
-
entityType: entityTypeSchema,
|
|
292
|
-
key: z.string().min(1),
|
|
293
|
-
label: z.string().min(1),
|
|
294
|
-
fieldType: customFieldTypeSchema,
|
|
295
|
-
isRequired: z.boolean().default(false),
|
|
296
|
-
isSearchable: z.boolean().default(false),
|
|
297
|
-
options: z
|
|
298
|
-
.array(z.object({ label: z.string(), value: z.string() }))
|
|
299
|
-
.nullable()
|
|
300
|
-
.optional(),
|
|
301
|
-
});
|
|
302
|
-
export const insertCustomFieldDefinitionSchema = customFieldDefinitionCoreSchema;
|
|
303
|
-
export const updateCustomFieldDefinitionSchema = customFieldDefinitionCoreSchema.partial();
|
|
304
|
-
export const customFieldDefinitionListQuerySchema = paginationSchema.extend({
|
|
305
|
-
entityType: entityTypeSchema.optional(),
|
|
306
|
-
});
|
|
307
|
-
export const upsertCustomFieldValueSchema = z.object({
|
|
308
|
-
entityType: entityTypeSchema,
|
|
309
|
-
entityId: z.string(),
|
|
310
|
-
textValue: z.string().nullable().optional(),
|
|
311
|
-
numberValue: z.number().int().nullable().optional(),
|
|
312
|
-
dateValue: z.string().date().nullable().optional(),
|
|
313
|
-
booleanValue: z.boolean().nullable().optional(),
|
|
314
|
-
monetaryValueCents: z.number().int().nullable().optional(),
|
|
315
|
-
currencyCode: z.string().nullable().optional(),
|
|
316
|
-
jsonValue: z.record(z.string(), z.unknown()).or(z.array(z.string())).nullable().optional(),
|
|
317
|
-
});
|
|
318
|
-
export const customFieldValueListQuerySchema = paginationSchema.extend({
|
|
319
|
-
entityType: entityTypeSchema.optional(),
|
|
320
|
-
entityId: z.string().optional(),
|
|
321
|
-
definitionId: z.string().optional(),
|
|
322
|
-
});
|
|
323
|
-
// ---------- person documents ----------
|
|
324
|
-
export const personDocumentTypeSchema = z.enum([
|
|
325
|
-
"passport",
|
|
326
|
-
"id_card",
|
|
327
|
-
"driver_license",
|
|
328
|
-
"visa",
|
|
329
|
-
"other",
|
|
330
|
-
]);
|
|
331
|
-
export const personDocumentCoreSchema = z.object({
|
|
332
|
-
type: personDocumentTypeSchema,
|
|
333
|
-
// `z.lazy` for cross-package init-cycle protection — see #501.
|
|
334
|
-
numberEncrypted: z.lazy(() => kmsEnvelopeSchema).optional(),
|
|
335
|
-
issuingAuthority: z.string().nullable().optional(),
|
|
336
|
-
issuingCountry: z.string().nullable().optional(),
|
|
337
|
-
issueDate: z.string().date().nullable().optional(),
|
|
338
|
-
expiryDate: z.string().date().nullable().optional(),
|
|
339
|
-
attachmentId: z.string().nullable().optional(),
|
|
340
|
-
isPrimary: z.boolean().default(false),
|
|
341
|
-
notes: z.string().nullable().optional(),
|
|
342
|
-
metadata: z.record(z.string(), z.unknown()).nullable().optional(),
|
|
343
|
-
});
|
|
344
|
-
export const insertPersonDocumentSchema = personDocumentCoreSchema;
|
|
345
|
-
export const updatePersonDocumentSchema = personDocumentCoreSchema.partial();
|
|
346
|
-
export const personDocumentListQuerySchema = paginationSchema.extend({
|
|
347
|
-
type: personDocumentTypeSchema.optional(),
|
|
348
|
-
expiringBefore: z.string().date().optional(),
|
|
349
|
-
});
|
|
350
|
-
/**
|
|
351
|
-
* Plaintext input shape for admin-facing create/update endpoints —
|
|
352
|
-
* the route encrypts `number` server-side using the people KMS key
|
|
353
|
-
* before persisting. Operator UIs prefer this over hand-encrypted
|
|
354
|
-
* envelopes.
|
|
355
|
-
*/
|
|
356
|
-
const personDocumentPlaintextCoreSchema = z.object({
|
|
357
|
-
type: personDocumentTypeSchema,
|
|
358
|
-
number: z.string().max(255).nullable().optional(),
|
|
359
|
-
issuingAuthority: z.string().nullable().optional(),
|
|
360
|
-
issuingCountry: z.string().nullable().optional(),
|
|
361
|
-
issueDate: z.string().date().nullable().optional(),
|
|
362
|
-
expiryDate: z.string().date().nullable().optional(),
|
|
363
|
-
attachmentId: z.string().nullable().optional(),
|
|
364
|
-
isPrimary: z.boolean().default(false),
|
|
365
|
-
notes: z.string().nullable().optional(),
|
|
366
|
-
metadata: z.record(z.string(), z.unknown()).nullable().optional(),
|
|
367
|
-
});
|
|
368
|
-
export const insertPersonDocumentFromPlaintextSchema = personDocumentPlaintextCoreSchema;
|
|
369
|
-
export const updatePersonDocumentFromPlaintextSchema = personDocumentPlaintextCoreSchema.partial();
|
|
370
|
-
/**
|
|
371
|
-
* Plaintext input shape for the four free-text PII slots on
|
|
372
|
-
* `crm.people` (accessibility / dietary / loyalty / insurance). The
|
|
373
|
-
* admin endpoint encrypts each provided value server-side; `null`
|
|
374
|
-
* clears the slot.
|
|
375
|
-
*/
|
|
376
|
-
export const updatePersonProfilePiiSchema = z
|
|
377
|
-
.object({
|
|
378
|
-
accessibility: z.string().max(4000).nullable().optional(),
|
|
379
|
-
dietary: z.string().max(4000).nullable().optional(),
|
|
380
|
-
loyalty: z.string().max(4000).nullable().optional(),
|
|
381
|
-
insurance: z.string().max(4000).nullable().optional(),
|
|
382
|
-
})
|
|
383
|
-
.refine((value) => Object.keys(value).length > 0, {
|
|
384
|
-
message: "At least one field must be provided",
|
|
385
|
-
});
|
|
386
|
-
// ---------- customer signals ----------
|
|
387
|
-
export const customerSignalKindSchema = z.enum([
|
|
388
|
-
"wishlist",
|
|
389
|
-
"notify",
|
|
390
|
-
"inquiry",
|
|
391
|
-
"request_offer",
|
|
392
|
-
"referral",
|
|
393
|
-
]);
|
|
394
|
-
export const customerSignalSourceSchema = z.enum([
|
|
395
|
-
"form",
|
|
396
|
-
"phone",
|
|
397
|
-
"admin",
|
|
398
|
-
"abandoned_cart",
|
|
399
|
-
"website",
|
|
400
|
-
"booking",
|
|
401
|
-
]);
|
|
402
|
-
export const customerSignalStatusSchema = z.enum([
|
|
403
|
-
"new",
|
|
404
|
-
"contacted",
|
|
405
|
-
"qualified",
|
|
406
|
-
"converted",
|
|
407
|
-
"lost",
|
|
408
|
-
"expired",
|
|
409
|
-
]);
|
|
410
|
-
export const customerSignalPrioritySchema = z.enum(["low", "normal", "high", "urgent"]);
|
|
411
|
-
const customerSignalCoreSchema = z.object({
|
|
412
|
-
personId: z.string().min(1),
|
|
413
|
-
productId: z.string().nullable().optional(),
|
|
414
|
-
optionUnitId: z.string().nullable().optional(),
|
|
415
|
-
kind: customerSignalKindSchema,
|
|
416
|
-
source: customerSignalSourceSchema,
|
|
417
|
-
status: customerSignalStatusSchema.default("new"),
|
|
418
|
-
priority: customerSignalPrioritySchema.default("normal"),
|
|
419
|
-
notes: z.string().nullable().optional(),
|
|
420
|
-
tags: z.array(z.string()).default([]),
|
|
421
|
-
assignedToUserId: z.string().nullable().optional(),
|
|
422
|
-
followUpAt: z.string().datetime().nullable().optional(),
|
|
423
|
-
resolvedBookingId: z.string().nullable().optional(),
|
|
424
|
-
sourceSubmissionId: z.string().nullable().optional(),
|
|
425
|
-
metadata: z.record(z.string(), z.unknown()).nullable().optional(),
|
|
426
|
-
});
|
|
427
|
-
export const insertCustomerSignalSchema = customerSignalCoreSchema;
|
|
428
|
-
export const updateCustomerSignalSchema = customerSignalCoreSchema
|
|
429
|
-
.partial()
|
|
430
|
-
.omit({ personId: true });
|
|
431
|
-
export const customerSignalListQuerySchema = paginationSchema.extend({
|
|
432
|
-
personId: z.string().optional(),
|
|
433
|
-
assignedToUserId: z.string().optional(),
|
|
434
|
-
status: customerSignalStatusSchema.optional(),
|
|
435
|
-
kind: customerSignalKindSchema.optional(),
|
|
436
|
-
productId: z.string().optional(),
|
|
437
|
-
search: z.string().optional(),
|
|
438
|
-
});
|
|
439
|
-
export const resolveCustomerSignalSchema = z.object({
|
|
440
|
-
bookingId: z.string().min(1),
|
|
441
|
-
});
|
|
442
|
-
// ---------- person relationships ----------
|
|
443
|
-
export const personRelationshipKindSchema = z.enum([
|
|
444
|
-
"spouse",
|
|
445
|
-
"partner",
|
|
446
|
-
"parent",
|
|
447
|
-
"child",
|
|
448
|
-
"sibling",
|
|
449
|
-
"guardian",
|
|
450
|
-
"ward",
|
|
451
|
-
"emergency_contact",
|
|
452
|
-
"friend",
|
|
453
|
-
"travel_companion",
|
|
454
|
-
"other",
|
|
455
|
-
]);
|
|
456
|
-
const personRelationshipCoreSchema = z.object({
|
|
457
|
-
toPersonId: z.string().min(1),
|
|
458
|
-
kind: personRelationshipKindSchema,
|
|
459
|
-
inverseKind: personRelationshipKindSchema.nullable().optional(),
|
|
460
|
-
startDate: z.string().date().nullable().optional(),
|
|
461
|
-
endDate: z.string().date().nullable().optional(),
|
|
462
|
-
isPrimary: z.boolean().default(false),
|
|
463
|
-
notes: z.string().nullable().optional(),
|
|
464
|
-
metadata: z.record(z.string(), z.unknown()).nullable().optional(),
|
|
465
|
-
/**
|
|
466
|
-
* Set to false to skip writing the symmetric edge when
|
|
467
|
-
* `inverseKind` is provided. Defaults to `true` so operator UIs
|
|
468
|
-
* don't have to maintain both sides.
|
|
469
|
-
*/
|
|
470
|
-
autoInverse: z.boolean().optional(),
|
|
471
|
-
});
|
|
472
|
-
export const insertPersonRelationshipSchema = personRelationshipCoreSchema;
|
|
473
|
-
export const updatePersonRelationshipSchema = personRelationshipCoreSchema
|
|
474
|
-
.partial()
|
|
475
|
-
.omit({ toPersonId: true, autoInverse: true });
|
|
476
|
-
export const personRelationshipListQuerySchema = paginationSchema.extend({
|
|
477
|
-
kind: personRelationshipKindSchema.optional(),
|
|
478
|
-
/**
|
|
479
|
-
* `from` returns only outgoing edges, `to` only incoming, `both`
|
|
480
|
-
* (the default) returns the union — the typical UI shape.
|
|
481
|
-
*/
|
|
482
|
-
direction: z.enum(["from", "to", "both"]).default("both"),
|
|
483
|
-
});
|
|
484
|
-
// ---------- notes ----------
|
|
485
|
-
export const insertPersonNoteSchema = z.object({
|
|
486
|
-
content: z.string().min(1).max(10000),
|
|
487
|
-
});
|
|
488
|
-
export const updatePersonNoteSchema = z.object({
|
|
489
|
-
content: z.string().min(1).max(10000),
|
|
490
|
-
});
|
|
491
|
-
export const insertOrganizationNoteSchema = z.object({
|
|
492
|
-
content: z.string().min(1).max(10000),
|
|
493
|
-
});
|
|
494
|
-
// ---------- payment methods ----------
|
|
495
|
-
export const paymentMethodBrandSchema = z.enum([
|
|
496
|
-
"visa",
|
|
497
|
-
"mastercard",
|
|
498
|
-
"amex",
|
|
499
|
-
"revolut",
|
|
500
|
-
"bank_transfer",
|
|
501
|
-
]);
|
|
502
|
-
const paymentMethodCoreSchema = z.object({
|
|
503
|
-
brand: paymentMethodBrandSchema,
|
|
504
|
-
last4: z.string().min(2).max(8).nullable().optional(),
|
|
505
|
-
holderName: z.string().nullable().optional(),
|
|
506
|
-
expMonth: z.number().int().min(1).max(12).nullable().optional(),
|
|
507
|
-
expYear: z.number().int().min(2000).max(2100).nullable().optional(),
|
|
508
|
-
processorToken: z.string().min(1),
|
|
509
|
-
isDefault: z.boolean().default(false),
|
|
510
|
-
});
|
|
511
|
-
export const insertPersonPaymentMethodSchema = paymentMethodCoreSchema;
|
|
512
|
-
export const updatePersonPaymentMethodSchema = paymentMethodCoreSchema.partial();
|
|
513
|
-
export const updateOrganizationNoteSchema = z.object({
|
|
514
|
-
content: z.string().min(1).max(10000),
|
|
515
|
-
});
|
|
516
|
-
// ---------- communication log ----------
|
|
517
|
-
export const insertCommunicationLogSchema = z.object({
|
|
518
|
-
organizationId: z.string().nullable().optional(),
|
|
519
|
-
channel: communicationChannelSchema,
|
|
520
|
-
direction: communicationDirectionSchema,
|
|
521
|
-
subject: z.string().max(500).nullable().optional(),
|
|
522
|
-
content: z.string().nullable().optional(),
|
|
523
|
-
sentAt: z.string().nullable().optional(),
|
|
524
|
-
});
|
|
525
|
-
export const communicationListQuerySchema = paginationSchema.extend({
|
|
526
|
-
channel: communicationChannelSchema.optional(),
|
|
527
|
-
direction: communicationDirectionSchema.optional(),
|
|
528
|
-
dateFrom: z.string().optional(),
|
|
529
|
-
dateTo: z.string().optional(),
|
|
530
|
-
});
|
|
531
|
-
// ---------- segments ----------
|
|
532
|
-
export const insertSegmentSchema = z.object({
|
|
533
|
-
name: z.string().min(1).max(255),
|
|
534
|
-
description: z.string().nullable().optional(),
|
|
535
|
-
conditions: z.record(z.string(), z.unknown()).nullable().optional(),
|
|
536
|
-
});
|
|
1
|
+
export * from "@voyantjs/crm-contracts";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voyantjs/crm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.97.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -39,12 +39,13 @@
|
|
|
39
39
|
"drizzle-orm": "^0.45.2",
|
|
40
40
|
"hono": "^4.12.10",
|
|
41
41
|
"zod": "^4.3.6",
|
|
42
|
-
"@voyantjs/action-ledger": "0.
|
|
43
|
-
"@voyantjs/core": "0.
|
|
44
|
-
"@voyantjs/
|
|
45
|
-
"@voyantjs/
|
|
46
|
-
"@voyantjs/
|
|
47
|
-
"@voyantjs/
|
|
42
|
+
"@voyantjs/action-ledger": "0.97.0",
|
|
43
|
+
"@voyantjs/core": "0.97.0",
|
|
44
|
+
"@voyantjs/crm-contracts": "0.97.0",
|
|
45
|
+
"@voyantjs/db": "0.97.0",
|
|
46
|
+
"@voyantjs/hono": "0.97.0",
|
|
47
|
+
"@voyantjs/identity": "0.97.0",
|
|
48
|
+
"@voyantjs/utils": "0.97.0"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
50
51
|
"typescript": "^6.0.2",
|