business-as-code 2.0.1 → 2.1.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/CHANGELOG.md +25 -0
- package/examples/basic-usage.js +282 -0
- package/package.json +3 -4
- package/src/business.js +108 -0
- package/src/dollar.js +106 -0
- package/src/entities/assets.js +322 -0
- package/src/entities/business.js +369 -0
- package/src/entities/communication.js +254 -0
- package/src/entities/customers.js +988 -0
- package/src/entities/financials.js +931 -0
- package/src/entities/goals.js +799 -0
- package/src/entities/index.js +197 -0
- package/src/entities/legal.js +300 -0
- package/src/entities/market.js +300 -0
- package/src/entities/marketing.js +1156 -0
- package/src/entities/offerings.js +726 -0
- package/src/entities/operations.js +786 -0
- package/src/entities/organization.js +806 -0
- package/src/entities/partnerships.js +299 -0
- package/src/entities/planning.js +270 -0
- package/src/entities/projects.js +348 -0
- package/src/entities/risk.js +292 -0
- package/src/entities/sales.js +1247 -0
- package/src/financials.js +296 -0
- package/src/goals.js +214 -0
- package/src/index.js +131 -0
- package/src/index.test.js +274 -0
- package/src/kpis.js +231 -0
- package/src/metrics.js +324 -0
- package/src/okrs.js +268 -0
- package/src/organization.js +172 -0
- package/src/process.js +240 -0
- package/src/product.js +144 -0
- package/src/queries.js +414 -0
- package/src/roles.js +254 -0
- package/src/service.js +139 -0
- package/src/types.js +4 -0
- package/src/vision.js +67 -0
- package/src/workflow.js +246 -0
|
@@ -0,0 +1,988 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Customer Entity Types (Nouns)
|
|
3
|
+
*
|
|
4
|
+
* Customer and relationship management: Customer, Account, Contact, Segment, Persona.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
// =============================================================================
|
|
9
|
+
// Customer
|
|
10
|
+
// =============================================================================
|
|
11
|
+
/**
|
|
12
|
+
* Customer entity
|
|
13
|
+
*
|
|
14
|
+
* Represents a customer (individual or company).
|
|
15
|
+
*/
|
|
16
|
+
export const Customer = {
|
|
17
|
+
singular: 'customer',
|
|
18
|
+
plural: 'customers',
|
|
19
|
+
description: 'A customer (individual or company)',
|
|
20
|
+
properties: {
|
|
21
|
+
// Identity
|
|
22
|
+
name: {
|
|
23
|
+
type: 'string',
|
|
24
|
+
description: 'Customer name',
|
|
25
|
+
},
|
|
26
|
+
email: {
|
|
27
|
+
type: 'string',
|
|
28
|
+
optional: true,
|
|
29
|
+
description: 'Primary email',
|
|
30
|
+
},
|
|
31
|
+
phone: {
|
|
32
|
+
type: 'string',
|
|
33
|
+
optional: true,
|
|
34
|
+
description: 'Primary phone',
|
|
35
|
+
},
|
|
36
|
+
// Type
|
|
37
|
+
type: {
|
|
38
|
+
type: 'string',
|
|
39
|
+
description: 'Customer type',
|
|
40
|
+
examples: ['individual', 'company', 'nonprofit', 'government'],
|
|
41
|
+
},
|
|
42
|
+
// Classification
|
|
43
|
+
tier: {
|
|
44
|
+
type: 'string',
|
|
45
|
+
optional: true,
|
|
46
|
+
description: 'Customer tier',
|
|
47
|
+
examples: ['free', 'starter', 'pro', 'business', 'enterprise', 'strategic'],
|
|
48
|
+
},
|
|
49
|
+
segment: {
|
|
50
|
+
type: 'string',
|
|
51
|
+
optional: true,
|
|
52
|
+
description: 'Customer segment',
|
|
53
|
+
},
|
|
54
|
+
industry: {
|
|
55
|
+
type: 'string',
|
|
56
|
+
optional: true,
|
|
57
|
+
description: 'Industry',
|
|
58
|
+
},
|
|
59
|
+
// Lifecycle
|
|
60
|
+
stage: {
|
|
61
|
+
type: 'string',
|
|
62
|
+
description: 'Customer lifecycle stage',
|
|
63
|
+
examples: ['prospect', 'trial', 'onboarding', 'active', 'at-risk', 'churned', 'won-back'],
|
|
64
|
+
},
|
|
65
|
+
source: {
|
|
66
|
+
type: 'string',
|
|
67
|
+
optional: true,
|
|
68
|
+
description: 'Acquisition source',
|
|
69
|
+
examples: ['organic', 'paid', 'referral', 'partner', 'outbound', 'event'],
|
|
70
|
+
},
|
|
71
|
+
referredBy: {
|
|
72
|
+
type: 'string',
|
|
73
|
+
optional: true,
|
|
74
|
+
description: 'Referrer ID or name',
|
|
75
|
+
},
|
|
76
|
+
// Dates
|
|
77
|
+
firstContactAt: {
|
|
78
|
+
type: 'datetime',
|
|
79
|
+
optional: true,
|
|
80
|
+
description: 'First contact date',
|
|
81
|
+
},
|
|
82
|
+
convertedAt: {
|
|
83
|
+
type: 'datetime',
|
|
84
|
+
optional: true,
|
|
85
|
+
description: 'Conversion date',
|
|
86
|
+
},
|
|
87
|
+
churnedAt: {
|
|
88
|
+
type: 'datetime',
|
|
89
|
+
optional: true,
|
|
90
|
+
description: 'Churn date',
|
|
91
|
+
},
|
|
92
|
+
// Value
|
|
93
|
+
lifetimeValue: {
|
|
94
|
+
type: 'number',
|
|
95
|
+
optional: true,
|
|
96
|
+
description: 'Customer lifetime value',
|
|
97
|
+
},
|
|
98
|
+
mrr: {
|
|
99
|
+
type: 'number',
|
|
100
|
+
optional: true,
|
|
101
|
+
description: 'Monthly recurring revenue',
|
|
102
|
+
},
|
|
103
|
+
arr: {
|
|
104
|
+
type: 'number',
|
|
105
|
+
optional: true,
|
|
106
|
+
description: 'Annual recurring revenue',
|
|
107
|
+
},
|
|
108
|
+
currency: {
|
|
109
|
+
type: 'string',
|
|
110
|
+
optional: true,
|
|
111
|
+
description: 'Currency code',
|
|
112
|
+
},
|
|
113
|
+
// Health
|
|
114
|
+
healthScore: {
|
|
115
|
+
type: 'number',
|
|
116
|
+
optional: true,
|
|
117
|
+
description: 'Customer health score (0-100)',
|
|
118
|
+
},
|
|
119
|
+
nps: {
|
|
120
|
+
type: 'number',
|
|
121
|
+
optional: true,
|
|
122
|
+
description: 'Net Promoter Score (-100 to 100)',
|
|
123
|
+
},
|
|
124
|
+
lastActivityAt: {
|
|
125
|
+
type: 'datetime',
|
|
126
|
+
optional: true,
|
|
127
|
+
description: 'Last activity date',
|
|
128
|
+
},
|
|
129
|
+
// Location
|
|
130
|
+
country: {
|
|
131
|
+
type: 'string',
|
|
132
|
+
optional: true,
|
|
133
|
+
description: 'Country',
|
|
134
|
+
},
|
|
135
|
+
region: {
|
|
136
|
+
type: 'string',
|
|
137
|
+
optional: true,
|
|
138
|
+
description: 'Region',
|
|
139
|
+
},
|
|
140
|
+
timezone: {
|
|
141
|
+
type: 'string',
|
|
142
|
+
optional: true,
|
|
143
|
+
description: 'Timezone',
|
|
144
|
+
},
|
|
145
|
+
// Company info (for B2B)
|
|
146
|
+
companySize: {
|
|
147
|
+
type: 'string',
|
|
148
|
+
optional: true,
|
|
149
|
+
description: 'Company size',
|
|
150
|
+
examples: ['1-10', '11-50', '51-200', '201-500', '501-1000', '1000+'],
|
|
151
|
+
},
|
|
152
|
+
annualRevenue: {
|
|
153
|
+
type: 'number',
|
|
154
|
+
optional: true,
|
|
155
|
+
description: 'Annual revenue',
|
|
156
|
+
},
|
|
157
|
+
website: {
|
|
158
|
+
type: 'url',
|
|
159
|
+
optional: true,
|
|
160
|
+
description: 'Website URL',
|
|
161
|
+
},
|
|
162
|
+
// Tags
|
|
163
|
+
tags: {
|
|
164
|
+
type: 'string',
|
|
165
|
+
array: true,
|
|
166
|
+
optional: true,
|
|
167
|
+
description: 'Tags',
|
|
168
|
+
},
|
|
169
|
+
// Status
|
|
170
|
+
status: {
|
|
171
|
+
type: 'string',
|
|
172
|
+
description: 'Customer status',
|
|
173
|
+
examples: ['active', 'inactive', 'suspended', 'deleted'],
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
relationships: {
|
|
177
|
+
account: {
|
|
178
|
+
type: 'Account',
|
|
179
|
+
required: false,
|
|
180
|
+
description: 'Parent account (for B2B)',
|
|
181
|
+
},
|
|
182
|
+
contacts: {
|
|
183
|
+
type: 'Contact[]',
|
|
184
|
+
description: 'Associated contacts',
|
|
185
|
+
},
|
|
186
|
+
owner: {
|
|
187
|
+
type: 'Worker',
|
|
188
|
+
required: false,
|
|
189
|
+
description: 'Account owner/CSM',
|
|
190
|
+
},
|
|
191
|
+
segment: {
|
|
192
|
+
type: 'Segment',
|
|
193
|
+
required: false,
|
|
194
|
+
description: 'Customer segment',
|
|
195
|
+
},
|
|
196
|
+
subscriptions: {
|
|
197
|
+
type: 'Subscription[]',
|
|
198
|
+
description: 'Active subscriptions',
|
|
199
|
+
},
|
|
200
|
+
contracts: {
|
|
201
|
+
type: 'Contract[]',
|
|
202
|
+
description: 'Contracts',
|
|
203
|
+
},
|
|
204
|
+
deals: {
|
|
205
|
+
type: 'Deal[]',
|
|
206
|
+
description: 'Sales deals',
|
|
207
|
+
},
|
|
208
|
+
interactions: {
|
|
209
|
+
type: 'Interaction[]',
|
|
210
|
+
description: 'Interaction history',
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
actions: [
|
|
214
|
+
'create',
|
|
215
|
+
'update',
|
|
216
|
+
'qualify',
|
|
217
|
+
'convert',
|
|
218
|
+
'onboard',
|
|
219
|
+
'upgrade',
|
|
220
|
+
'downgrade',
|
|
221
|
+
'renew',
|
|
222
|
+
'markAtRisk',
|
|
223
|
+
'churn',
|
|
224
|
+
'winBack',
|
|
225
|
+
'merge',
|
|
226
|
+
'archive',
|
|
227
|
+
],
|
|
228
|
+
events: [
|
|
229
|
+
'created',
|
|
230
|
+
'updated',
|
|
231
|
+
'qualified',
|
|
232
|
+
'converted',
|
|
233
|
+
'onboarded',
|
|
234
|
+
'upgraded',
|
|
235
|
+
'downgraded',
|
|
236
|
+
'renewed',
|
|
237
|
+
'markedAtRisk',
|
|
238
|
+
'churned',
|
|
239
|
+
'wonBack',
|
|
240
|
+
'merged',
|
|
241
|
+
'archived',
|
|
242
|
+
],
|
|
243
|
+
};
|
|
244
|
+
// =============================================================================
|
|
245
|
+
// Account
|
|
246
|
+
// =============================================================================
|
|
247
|
+
/**
|
|
248
|
+
* Account entity
|
|
249
|
+
*
|
|
250
|
+
* Represents a company account (B2B).
|
|
251
|
+
*/
|
|
252
|
+
export const Account = {
|
|
253
|
+
singular: 'account',
|
|
254
|
+
plural: 'accounts',
|
|
255
|
+
description: 'A company account (B2B)',
|
|
256
|
+
properties: {
|
|
257
|
+
// Identity
|
|
258
|
+
name: {
|
|
259
|
+
type: 'string',
|
|
260
|
+
description: 'Account/company name',
|
|
261
|
+
},
|
|
262
|
+
legalName: {
|
|
263
|
+
type: 'string',
|
|
264
|
+
optional: true,
|
|
265
|
+
description: 'Legal entity name',
|
|
266
|
+
},
|
|
267
|
+
domain: {
|
|
268
|
+
type: 'string',
|
|
269
|
+
optional: true,
|
|
270
|
+
description: 'Primary domain',
|
|
271
|
+
},
|
|
272
|
+
website: {
|
|
273
|
+
type: 'url',
|
|
274
|
+
optional: true,
|
|
275
|
+
description: 'Website URL',
|
|
276
|
+
},
|
|
277
|
+
// Classification
|
|
278
|
+
type: {
|
|
279
|
+
type: 'string',
|
|
280
|
+
optional: true,
|
|
281
|
+
description: 'Account type',
|
|
282
|
+
examples: ['prospect', 'customer', 'partner', 'competitor'],
|
|
283
|
+
},
|
|
284
|
+
tier: {
|
|
285
|
+
type: 'string',
|
|
286
|
+
optional: true,
|
|
287
|
+
description: 'Account tier',
|
|
288
|
+
examples: ['smb', 'mid-market', 'enterprise', 'strategic'],
|
|
289
|
+
},
|
|
290
|
+
industry: {
|
|
291
|
+
type: 'string',
|
|
292
|
+
optional: true,
|
|
293
|
+
description: 'Industry',
|
|
294
|
+
},
|
|
295
|
+
// Size
|
|
296
|
+
employees: {
|
|
297
|
+
type: 'number',
|
|
298
|
+
optional: true,
|
|
299
|
+
description: 'Employee count',
|
|
300
|
+
},
|
|
301
|
+
annualRevenue: {
|
|
302
|
+
type: 'number',
|
|
303
|
+
optional: true,
|
|
304
|
+
description: 'Annual revenue',
|
|
305
|
+
},
|
|
306
|
+
// Location
|
|
307
|
+
headquarters: {
|
|
308
|
+
type: 'string',
|
|
309
|
+
optional: true,
|
|
310
|
+
description: 'Headquarters location',
|
|
311
|
+
},
|
|
312
|
+
country: {
|
|
313
|
+
type: 'string',
|
|
314
|
+
optional: true,
|
|
315
|
+
description: 'Country',
|
|
316
|
+
},
|
|
317
|
+
region: {
|
|
318
|
+
type: 'string',
|
|
319
|
+
optional: true,
|
|
320
|
+
description: 'Region',
|
|
321
|
+
},
|
|
322
|
+
// Relationship
|
|
323
|
+
parentAccountId: {
|
|
324
|
+
type: 'string',
|
|
325
|
+
optional: true,
|
|
326
|
+
description: 'Parent account (for subsidiaries)',
|
|
327
|
+
},
|
|
328
|
+
// Value
|
|
329
|
+
totalContractValue: {
|
|
330
|
+
type: 'number',
|
|
331
|
+
optional: true,
|
|
332
|
+
description: 'Total contract value',
|
|
333
|
+
},
|
|
334
|
+
arr: {
|
|
335
|
+
type: 'number',
|
|
336
|
+
optional: true,
|
|
337
|
+
description: 'Annual recurring revenue',
|
|
338
|
+
},
|
|
339
|
+
currency: {
|
|
340
|
+
type: 'string',
|
|
341
|
+
optional: true,
|
|
342
|
+
description: 'Currency code',
|
|
343
|
+
},
|
|
344
|
+
// Health
|
|
345
|
+
healthScore: {
|
|
346
|
+
type: 'number',
|
|
347
|
+
optional: true,
|
|
348
|
+
description: 'Account health score',
|
|
349
|
+
},
|
|
350
|
+
// IDs
|
|
351
|
+
crmId: {
|
|
352
|
+
type: 'string',
|
|
353
|
+
optional: true,
|
|
354
|
+
description: 'External CRM ID',
|
|
355
|
+
},
|
|
356
|
+
// Status
|
|
357
|
+
status: {
|
|
358
|
+
type: 'string',
|
|
359
|
+
description: 'Account status',
|
|
360
|
+
examples: ['active', 'inactive', 'churned', 'archived'],
|
|
361
|
+
},
|
|
362
|
+
},
|
|
363
|
+
relationships: {
|
|
364
|
+
owner: {
|
|
365
|
+
type: 'Worker',
|
|
366
|
+
required: false,
|
|
367
|
+
description: 'Account owner',
|
|
368
|
+
},
|
|
369
|
+
contacts: {
|
|
370
|
+
type: 'Contact[]',
|
|
371
|
+
description: 'Account contacts',
|
|
372
|
+
},
|
|
373
|
+
customers: {
|
|
374
|
+
type: 'Customer[]',
|
|
375
|
+
description: 'Associated customers',
|
|
376
|
+
},
|
|
377
|
+
deals: {
|
|
378
|
+
type: 'Deal[]',
|
|
379
|
+
description: 'Sales deals',
|
|
380
|
+
},
|
|
381
|
+
contracts: {
|
|
382
|
+
type: 'Contract[]',
|
|
383
|
+
description: 'Contracts',
|
|
384
|
+
},
|
|
385
|
+
parent: {
|
|
386
|
+
type: 'Account',
|
|
387
|
+
required: false,
|
|
388
|
+
description: 'Parent account',
|
|
389
|
+
},
|
|
390
|
+
subsidiaries: {
|
|
391
|
+
type: 'Account[]',
|
|
392
|
+
description: 'Subsidiary accounts',
|
|
393
|
+
},
|
|
394
|
+
},
|
|
395
|
+
actions: [
|
|
396
|
+
'create',
|
|
397
|
+
'update',
|
|
398
|
+
'merge',
|
|
399
|
+
'assignOwner',
|
|
400
|
+
'updateTier',
|
|
401
|
+
'addContact',
|
|
402
|
+
'removeContact',
|
|
403
|
+
'archive',
|
|
404
|
+
],
|
|
405
|
+
events: [
|
|
406
|
+
'created',
|
|
407
|
+
'updated',
|
|
408
|
+
'merged',
|
|
409
|
+
'ownerAssigned',
|
|
410
|
+
'tierUpdated',
|
|
411
|
+
'contactAdded',
|
|
412
|
+
'contactRemoved',
|
|
413
|
+
'archived',
|
|
414
|
+
],
|
|
415
|
+
};
|
|
416
|
+
// =============================================================================
|
|
417
|
+
// Contact
|
|
418
|
+
// =============================================================================
|
|
419
|
+
/**
|
|
420
|
+
* Contact entity
|
|
421
|
+
*
|
|
422
|
+
* Represents a person/contact at a customer or account.
|
|
423
|
+
*/
|
|
424
|
+
export const Contact = {
|
|
425
|
+
singular: 'contact',
|
|
426
|
+
plural: 'contacts',
|
|
427
|
+
description: 'A person/contact at a customer or account',
|
|
428
|
+
properties: {
|
|
429
|
+
// Identity
|
|
430
|
+
firstName: {
|
|
431
|
+
type: 'string',
|
|
432
|
+
description: 'First name',
|
|
433
|
+
},
|
|
434
|
+
lastName: {
|
|
435
|
+
type: 'string',
|
|
436
|
+
description: 'Last name',
|
|
437
|
+
},
|
|
438
|
+
email: {
|
|
439
|
+
type: 'string',
|
|
440
|
+
description: 'Email address',
|
|
441
|
+
},
|
|
442
|
+
phone: {
|
|
443
|
+
type: 'string',
|
|
444
|
+
optional: true,
|
|
445
|
+
description: 'Phone number',
|
|
446
|
+
},
|
|
447
|
+
// Role
|
|
448
|
+
title: {
|
|
449
|
+
type: 'string',
|
|
450
|
+
optional: true,
|
|
451
|
+
description: 'Job title',
|
|
452
|
+
},
|
|
453
|
+
department: {
|
|
454
|
+
type: 'string',
|
|
455
|
+
optional: true,
|
|
456
|
+
description: 'Department',
|
|
457
|
+
},
|
|
458
|
+
role: {
|
|
459
|
+
type: 'string',
|
|
460
|
+
optional: true,
|
|
461
|
+
description: 'Role in buying process',
|
|
462
|
+
examples: ['decision-maker', 'influencer', 'champion', 'blocker', 'end-user', 'economic-buyer', 'technical-buyer'],
|
|
463
|
+
},
|
|
464
|
+
seniority: {
|
|
465
|
+
type: 'string',
|
|
466
|
+
optional: true,
|
|
467
|
+
description: 'Seniority level',
|
|
468
|
+
examples: ['c-level', 'vp', 'director', 'manager', 'individual-contributor'],
|
|
469
|
+
},
|
|
470
|
+
// Contact preferences
|
|
471
|
+
preferredChannel: {
|
|
472
|
+
type: 'string',
|
|
473
|
+
optional: true,
|
|
474
|
+
description: 'Preferred contact channel',
|
|
475
|
+
examples: ['email', 'phone', 'linkedin', 'slack'],
|
|
476
|
+
},
|
|
477
|
+
timezone: {
|
|
478
|
+
type: 'string',
|
|
479
|
+
optional: true,
|
|
480
|
+
description: 'Timezone',
|
|
481
|
+
},
|
|
482
|
+
// Social
|
|
483
|
+
linkedinUrl: {
|
|
484
|
+
type: 'url',
|
|
485
|
+
optional: true,
|
|
486
|
+
description: 'LinkedIn URL',
|
|
487
|
+
},
|
|
488
|
+
twitterHandle: {
|
|
489
|
+
type: 'string',
|
|
490
|
+
optional: true,
|
|
491
|
+
description: 'Twitter handle',
|
|
492
|
+
},
|
|
493
|
+
// Engagement
|
|
494
|
+
lastContactedAt: {
|
|
495
|
+
type: 'datetime',
|
|
496
|
+
optional: true,
|
|
497
|
+
description: 'Last contacted date',
|
|
498
|
+
},
|
|
499
|
+
lastRespondedAt: {
|
|
500
|
+
type: 'datetime',
|
|
501
|
+
optional: true,
|
|
502
|
+
description: 'Last response date',
|
|
503
|
+
},
|
|
504
|
+
// Opt-in
|
|
505
|
+
marketingOptIn: {
|
|
506
|
+
type: 'boolean',
|
|
507
|
+
optional: true,
|
|
508
|
+
description: 'Marketing opt-in',
|
|
509
|
+
},
|
|
510
|
+
salesOptIn: {
|
|
511
|
+
type: 'boolean',
|
|
512
|
+
optional: true,
|
|
513
|
+
description: 'Sales opt-in',
|
|
514
|
+
},
|
|
515
|
+
// Tags
|
|
516
|
+
tags: {
|
|
517
|
+
type: 'string',
|
|
518
|
+
array: true,
|
|
519
|
+
optional: true,
|
|
520
|
+
description: 'Tags',
|
|
521
|
+
},
|
|
522
|
+
// Status
|
|
523
|
+
status: {
|
|
524
|
+
type: 'string',
|
|
525
|
+
description: 'Contact status',
|
|
526
|
+
examples: ['active', 'inactive', 'bounced', 'unsubscribed', 'archived'],
|
|
527
|
+
},
|
|
528
|
+
},
|
|
529
|
+
relationships: {
|
|
530
|
+
account: {
|
|
531
|
+
type: 'Account',
|
|
532
|
+
required: false,
|
|
533
|
+
description: 'Parent account',
|
|
534
|
+
},
|
|
535
|
+
customer: {
|
|
536
|
+
type: 'Customer',
|
|
537
|
+
required: false,
|
|
538
|
+
description: 'Associated customer',
|
|
539
|
+
},
|
|
540
|
+
owner: {
|
|
541
|
+
type: 'Worker',
|
|
542
|
+
required: false,
|
|
543
|
+
description: 'Contact owner',
|
|
544
|
+
},
|
|
545
|
+
deals: {
|
|
546
|
+
type: 'Deal[]',
|
|
547
|
+
description: 'Associated deals',
|
|
548
|
+
},
|
|
549
|
+
interactions: {
|
|
550
|
+
type: 'Interaction[]',
|
|
551
|
+
description: 'Interaction history',
|
|
552
|
+
},
|
|
553
|
+
},
|
|
554
|
+
actions: [
|
|
555
|
+
'create',
|
|
556
|
+
'update',
|
|
557
|
+
'merge',
|
|
558
|
+
'assignOwner',
|
|
559
|
+
'optIn',
|
|
560
|
+
'optOut',
|
|
561
|
+
'markBounced',
|
|
562
|
+
'archive',
|
|
563
|
+
],
|
|
564
|
+
events: [
|
|
565
|
+
'created',
|
|
566
|
+
'updated',
|
|
567
|
+
'merged',
|
|
568
|
+
'ownerAssigned',
|
|
569
|
+
'optedIn',
|
|
570
|
+
'optedOut',
|
|
571
|
+
'bounced',
|
|
572
|
+
'archived',
|
|
573
|
+
],
|
|
574
|
+
};
|
|
575
|
+
// =============================================================================
|
|
576
|
+
// Segment
|
|
577
|
+
// =============================================================================
|
|
578
|
+
/**
|
|
579
|
+
* Segment entity
|
|
580
|
+
*
|
|
581
|
+
* Represents a customer segment.
|
|
582
|
+
*/
|
|
583
|
+
export const Segment = {
|
|
584
|
+
singular: 'segment',
|
|
585
|
+
plural: 'segments',
|
|
586
|
+
description: 'A customer segment',
|
|
587
|
+
properties: {
|
|
588
|
+
// Identity
|
|
589
|
+
name: {
|
|
590
|
+
type: 'string',
|
|
591
|
+
description: 'Segment name',
|
|
592
|
+
},
|
|
593
|
+
description: {
|
|
594
|
+
type: 'string',
|
|
595
|
+
optional: true,
|
|
596
|
+
description: 'Segment description',
|
|
597
|
+
},
|
|
598
|
+
// Type
|
|
599
|
+
type: {
|
|
600
|
+
type: 'string',
|
|
601
|
+
optional: true,
|
|
602
|
+
description: 'Segment type',
|
|
603
|
+
examples: ['demographic', 'behavioral', 'firmographic', 'technographic', 'psychographic'],
|
|
604
|
+
},
|
|
605
|
+
// Criteria
|
|
606
|
+
criteria: {
|
|
607
|
+
type: 'json',
|
|
608
|
+
optional: true,
|
|
609
|
+
description: 'Segment criteria/filters',
|
|
610
|
+
},
|
|
611
|
+
criteriaDescription: {
|
|
612
|
+
type: 'string',
|
|
613
|
+
optional: true,
|
|
614
|
+
description: 'Human-readable criteria',
|
|
615
|
+
},
|
|
616
|
+
// Size
|
|
617
|
+
size: {
|
|
618
|
+
type: 'number',
|
|
619
|
+
optional: true,
|
|
620
|
+
description: 'Number of customers in segment',
|
|
621
|
+
},
|
|
622
|
+
// Value
|
|
623
|
+
totalRevenue: {
|
|
624
|
+
type: 'number',
|
|
625
|
+
optional: true,
|
|
626
|
+
description: 'Total revenue from segment',
|
|
627
|
+
},
|
|
628
|
+
avgRevenue: {
|
|
629
|
+
type: 'number',
|
|
630
|
+
optional: true,
|
|
631
|
+
description: 'Average revenue per customer',
|
|
632
|
+
},
|
|
633
|
+
avgLTV: {
|
|
634
|
+
type: 'number',
|
|
635
|
+
optional: true,
|
|
636
|
+
description: 'Average lifetime value',
|
|
637
|
+
},
|
|
638
|
+
// Behavior
|
|
639
|
+
avgChurnRate: {
|
|
640
|
+
type: 'number',
|
|
641
|
+
optional: true,
|
|
642
|
+
description: 'Average churn rate',
|
|
643
|
+
},
|
|
644
|
+
avgNPS: {
|
|
645
|
+
type: 'number',
|
|
646
|
+
optional: true,
|
|
647
|
+
description: 'Average NPS',
|
|
648
|
+
},
|
|
649
|
+
// Dynamic
|
|
650
|
+
isDynamic: {
|
|
651
|
+
type: 'boolean',
|
|
652
|
+
optional: true,
|
|
653
|
+
description: 'Auto-updates based on criteria',
|
|
654
|
+
},
|
|
655
|
+
lastCalculatedAt: {
|
|
656
|
+
type: 'datetime',
|
|
657
|
+
optional: true,
|
|
658
|
+
description: 'Last calculation time',
|
|
659
|
+
},
|
|
660
|
+
// Status
|
|
661
|
+
status: {
|
|
662
|
+
type: 'string',
|
|
663
|
+
description: 'Segment status',
|
|
664
|
+
examples: ['active', 'inactive', 'archived'],
|
|
665
|
+
},
|
|
666
|
+
},
|
|
667
|
+
relationships: {
|
|
668
|
+
customers: {
|
|
669
|
+
type: 'Customer[]',
|
|
670
|
+
description: 'Customers in segment',
|
|
671
|
+
},
|
|
672
|
+
campaigns: {
|
|
673
|
+
type: 'Campaign[]',
|
|
674
|
+
description: 'Targeted campaigns',
|
|
675
|
+
},
|
|
676
|
+
persona: {
|
|
677
|
+
type: 'Persona',
|
|
678
|
+
required: false,
|
|
679
|
+
description: 'Associated persona',
|
|
680
|
+
},
|
|
681
|
+
},
|
|
682
|
+
actions: [
|
|
683
|
+
'create',
|
|
684
|
+
'update',
|
|
685
|
+
'refresh',
|
|
686
|
+
'addCustomer',
|
|
687
|
+
'removeCustomer',
|
|
688
|
+
'archive',
|
|
689
|
+
],
|
|
690
|
+
events: [
|
|
691
|
+
'created',
|
|
692
|
+
'updated',
|
|
693
|
+
'refreshed',
|
|
694
|
+
'customerAdded',
|
|
695
|
+
'customerRemoved',
|
|
696
|
+
'archived',
|
|
697
|
+
],
|
|
698
|
+
};
|
|
699
|
+
// =============================================================================
|
|
700
|
+
// Persona
|
|
701
|
+
// =============================================================================
|
|
702
|
+
/**
|
|
703
|
+
* Persona entity
|
|
704
|
+
*
|
|
705
|
+
* Represents a buyer or user persona.
|
|
706
|
+
*/
|
|
707
|
+
export const Persona = {
|
|
708
|
+
singular: 'persona',
|
|
709
|
+
plural: 'personas',
|
|
710
|
+
description: 'A buyer or user persona',
|
|
711
|
+
properties: {
|
|
712
|
+
// Identity
|
|
713
|
+
name: {
|
|
714
|
+
type: 'string',
|
|
715
|
+
description: 'Persona name',
|
|
716
|
+
},
|
|
717
|
+
description: {
|
|
718
|
+
type: 'string',
|
|
719
|
+
optional: true,
|
|
720
|
+
description: 'Persona description',
|
|
721
|
+
},
|
|
722
|
+
avatarUrl: {
|
|
723
|
+
type: 'url',
|
|
724
|
+
optional: true,
|
|
725
|
+
description: 'Avatar image URL',
|
|
726
|
+
},
|
|
727
|
+
// Type
|
|
728
|
+
type: {
|
|
729
|
+
type: 'string',
|
|
730
|
+
optional: true,
|
|
731
|
+
description: 'Persona type',
|
|
732
|
+
examples: ['buyer', 'user', 'influencer', 'decision-maker'],
|
|
733
|
+
},
|
|
734
|
+
// Demographics
|
|
735
|
+
jobTitle: {
|
|
736
|
+
type: 'string',
|
|
737
|
+
optional: true,
|
|
738
|
+
description: 'Typical job title',
|
|
739
|
+
},
|
|
740
|
+
department: {
|
|
741
|
+
type: 'string',
|
|
742
|
+
optional: true,
|
|
743
|
+
description: 'Typical department',
|
|
744
|
+
},
|
|
745
|
+
seniority: {
|
|
746
|
+
type: 'string',
|
|
747
|
+
optional: true,
|
|
748
|
+
description: 'Seniority level',
|
|
749
|
+
},
|
|
750
|
+
companySize: {
|
|
751
|
+
type: 'string',
|
|
752
|
+
optional: true,
|
|
753
|
+
description: 'Typical company size',
|
|
754
|
+
},
|
|
755
|
+
industry: {
|
|
756
|
+
type: 'string',
|
|
757
|
+
optional: true,
|
|
758
|
+
description: 'Typical industry',
|
|
759
|
+
},
|
|
760
|
+
// Psychographics
|
|
761
|
+
goals: {
|
|
762
|
+
type: 'string',
|
|
763
|
+
array: true,
|
|
764
|
+
optional: true,
|
|
765
|
+
description: 'Goals and objectives',
|
|
766
|
+
},
|
|
767
|
+
challenges: {
|
|
768
|
+
type: 'string',
|
|
769
|
+
array: true,
|
|
770
|
+
optional: true,
|
|
771
|
+
description: 'Pain points and challenges',
|
|
772
|
+
},
|
|
773
|
+
motivations: {
|
|
774
|
+
type: 'string',
|
|
775
|
+
array: true,
|
|
776
|
+
optional: true,
|
|
777
|
+
description: 'Motivations',
|
|
778
|
+
},
|
|
779
|
+
objections: {
|
|
780
|
+
type: 'string',
|
|
781
|
+
array: true,
|
|
782
|
+
optional: true,
|
|
783
|
+
description: 'Common objections',
|
|
784
|
+
},
|
|
785
|
+
// Behavior
|
|
786
|
+
preferredChannels: {
|
|
787
|
+
type: 'string',
|
|
788
|
+
array: true,
|
|
789
|
+
optional: true,
|
|
790
|
+
description: 'Preferred communication channels',
|
|
791
|
+
},
|
|
792
|
+
contentPreferences: {
|
|
793
|
+
type: 'string',
|
|
794
|
+
array: true,
|
|
795
|
+
optional: true,
|
|
796
|
+
description: 'Content format preferences',
|
|
797
|
+
},
|
|
798
|
+
buyingProcess: {
|
|
799
|
+
type: 'string',
|
|
800
|
+
optional: true,
|
|
801
|
+
description: 'Typical buying process',
|
|
802
|
+
},
|
|
803
|
+
// Messaging
|
|
804
|
+
valueProposition: {
|
|
805
|
+
type: 'string',
|
|
806
|
+
optional: true,
|
|
807
|
+
description: 'Value proposition for this persona',
|
|
808
|
+
},
|
|
809
|
+
messagingGuidelines: {
|
|
810
|
+
type: 'string',
|
|
811
|
+
optional: true,
|
|
812
|
+
description: 'Messaging guidelines',
|
|
813
|
+
},
|
|
814
|
+
keywords: {
|
|
815
|
+
type: 'string',
|
|
816
|
+
array: true,
|
|
817
|
+
optional: true,
|
|
818
|
+
description: 'Keywords/phrases that resonate',
|
|
819
|
+
},
|
|
820
|
+
// Status
|
|
821
|
+
status: {
|
|
822
|
+
type: 'string',
|
|
823
|
+
description: 'Persona status',
|
|
824
|
+
examples: ['active', 'draft', 'archived'],
|
|
825
|
+
},
|
|
826
|
+
},
|
|
827
|
+
relationships: {
|
|
828
|
+
segments: {
|
|
829
|
+
type: 'Segment[]',
|
|
830
|
+
description: 'Associated segments',
|
|
831
|
+
},
|
|
832
|
+
products: {
|
|
833
|
+
type: 'Product[]',
|
|
834
|
+
description: 'Relevant products',
|
|
835
|
+
},
|
|
836
|
+
content: {
|
|
837
|
+
type: 'Content[]',
|
|
838
|
+
description: 'Content for this persona',
|
|
839
|
+
},
|
|
840
|
+
campaigns: {
|
|
841
|
+
type: 'Campaign[]',
|
|
842
|
+
description: 'Targeted campaigns',
|
|
843
|
+
},
|
|
844
|
+
},
|
|
845
|
+
actions: [
|
|
846
|
+
'create',
|
|
847
|
+
'update',
|
|
848
|
+
'validate',
|
|
849
|
+
'archive',
|
|
850
|
+
],
|
|
851
|
+
events: [
|
|
852
|
+
'created',
|
|
853
|
+
'updated',
|
|
854
|
+
'validated',
|
|
855
|
+
'archived',
|
|
856
|
+
],
|
|
857
|
+
};
|
|
858
|
+
// =============================================================================
|
|
859
|
+
// Interaction
|
|
860
|
+
// =============================================================================
|
|
861
|
+
/**
|
|
862
|
+
* Interaction entity
|
|
863
|
+
*
|
|
864
|
+
* Represents a customer interaction/touchpoint.
|
|
865
|
+
*/
|
|
866
|
+
export const Interaction = {
|
|
867
|
+
singular: 'interaction',
|
|
868
|
+
plural: 'interactions',
|
|
869
|
+
description: 'A customer interaction or touchpoint',
|
|
870
|
+
properties: {
|
|
871
|
+
// Type
|
|
872
|
+
type: {
|
|
873
|
+
type: 'string',
|
|
874
|
+
description: 'Interaction type',
|
|
875
|
+
examples: ['email', 'call', 'meeting', 'chat', 'support-ticket', 'demo', 'webinar', 'event', 'social'],
|
|
876
|
+
},
|
|
877
|
+
direction: {
|
|
878
|
+
type: 'string',
|
|
879
|
+
optional: true,
|
|
880
|
+
description: 'Interaction direction',
|
|
881
|
+
examples: ['inbound', 'outbound'],
|
|
882
|
+
},
|
|
883
|
+
// Content
|
|
884
|
+
subject: {
|
|
885
|
+
type: 'string',
|
|
886
|
+
optional: true,
|
|
887
|
+
description: 'Subject/title',
|
|
888
|
+
},
|
|
889
|
+
description: {
|
|
890
|
+
type: 'string',
|
|
891
|
+
optional: true,
|
|
892
|
+
description: 'Description/notes',
|
|
893
|
+
},
|
|
894
|
+
// Timing
|
|
895
|
+
occurredAt: {
|
|
896
|
+
type: 'datetime',
|
|
897
|
+
description: 'When it occurred',
|
|
898
|
+
},
|
|
899
|
+
duration: {
|
|
900
|
+
type: 'number',
|
|
901
|
+
optional: true,
|
|
902
|
+
description: 'Duration in minutes',
|
|
903
|
+
},
|
|
904
|
+
// Outcome
|
|
905
|
+
outcome: {
|
|
906
|
+
type: 'string',
|
|
907
|
+
optional: true,
|
|
908
|
+
description: 'Interaction outcome',
|
|
909
|
+
examples: ['positive', 'neutral', 'negative', 'no-response'],
|
|
910
|
+
},
|
|
911
|
+
sentiment: {
|
|
912
|
+
type: 'string',
|
|
913
|
+
optional: true,
|
|
914
|
+
description: 'Customer sentiment',
|
|
915
|
+
examples: ['very-positive', 'positive', 'neutral', 'negative', 'very-negative'],
|
|
916
|
+
},
|
|
917
|
+
nextSteps: {
|
|
918
|
+
type: 'string',
|
|
919
|
+
optional: true,
|
|
920
|
+
description: 'Next steps',
|
|
921
|
+
},
|
|
922
|
+
// Channel
|
|
923
|
+
channel: {
|
|
924
|
+
type: 'string',
|
|
925
|
+
optional: true,
|
|
926
|
+
description: 'Channel used',
|
|
927
|
+
},
|
|
928
|
+
// Attribution
|
|
929
|
+
campaignId: {
|
|
930
|
+
type: 'string',
|
|
931
|
+
optional: true,
|
|
932
|
+
description: 'Associated campaign',
|
|
933
|
+
},
|
|
934
|
+
},
|
|
935
|
+
relationships: {
|
|
936
|
+
customer: {
|
|
937
|
+
type: 'Customer',
|
|
938
|
+
required: false,
|
|
939
|
+
description: 'Customer',
|
|
940
|
+
},
|
|
941
|
+
contact: {
|
|
942
|
+
type: 'Contact',
|
|
943
|
+
required: false,
|
|
944
|
+
description: 'Contact',
|
|
945
|
+
},
|
|
946
|
+
account: {
|
|
947
|
+
type: 'Account',
|
|
948
|
+
required: false,
|
|
949
|
+
description: 'Account',
|
|
950
|
+
},
|
|
951
|
+
createdBy: {
|
|
952
|
+
type: 'Worker',
|
|
953
|
+
required: false,
|
|
954
|
+
description: 'Who logged it',
|
|
955
|
+
},
|
|
956
|
+
deal: {
|
|
957
|
+
type: 'Deal',
|
|
958
|
+
required: false,
|
|
959
|
+
description: 'Associated deal',
|
|
960
|
+
},
|
|
961
|
+
},
|
|
962
|
+
actions: [
|
|
963
|
+
'log',
|
|
964
|
+
'update',
|
|
965
|
+
'delete',
|
|
966
|
+
],
|
|
967
|
+
events: [
|
|
968
|
+
'logged',
|
|
969
|
+
'updated',
|
|
970
|
+
'deleted',
|
|
971
|
+
],
|
|
972
|
+
};
|
|
973
|
+
// =============================================================================
|
|
974
|
+
// Exports
|
|
975
|
+
// =============================================================================
|
|
976
|
+
export const CustomerEntities = {
|
|
977
|
+
Customer,
|
|
978
|
+
Account,
|
|
979
|
+
Contact,
|
|
980
|
+
Segment,
|
|
981
|
+
Persona,
|
|
982
|
+
Interaction,
|
|
983
|
+
};
|
|
984
|
+
export const CustomerCategories = {
|
|
985
|
+
customers: ['Customer', 'Account', 'Contact'],
|
|
986
|
+
segmentation: ['Segment', 'Persona'],
|
|
987
|
+
engagement: ['Interaction'],
|
|
988
|
+
};
|