digital-tools 2.0.2 → 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 +17 -0
- package/package.json +3 -4
- package/src/define.js +267 -0
- package/src/entities/advertising.js +999 -0
- package/src/entities/ai.js +756 -0
- package/src/entities/analytics.js +1588 -0
- package/src/entities/automation.js +601 -0
- package/src/entities/communication.js +1150 -0
- package/src/entities/crm.js +1386 -0
- package/src/entities/design.js +546 -0
- package/src/entities/development.js +2212 -0
- package/src/entities/document.js +874 -0
- package/src/entities/ecommerce.js +1429 -0
- package/src/entities/experiment.js +1039 -0
- package/src/entities/finance.js +3478 -0
- package/src/entities/forms.js +1892 -0
- package/src/entities/hr.js +661 -0
- package/src/entities/identity.js +997 -0
- package/src/entities/index.js +282 -0
- package/src/entities/infrastructure.js +1153 -0
- package/src/entities/knowledge.js +1438 -0
- package/src/entities/marketing.js +1610 -0
- package/src/entities/media.js +1634 -0
- package/src/entities/notification.js +1199 -0
- package/src/entities/presentation.js +1274 -0
- package/src/entities/productivity.js +1317 -0
- package/src/entities/project-management.js +1136 -0
- package/src/entities/recruiting.js +736 -0
- package/src/entities/shipping.js +509 -0
- package/src/entities/signature.js +1102 -0
- package/src/entities/site.js +222 -0
- package/src/entities/spreadsheet.js +1341 -0
- package/src/entities/storage.js +1198 -0
- package/src/entities/support.js +1166 -0
- package/src/entities/video-conferencing.js +1750 -0
- package/src/entities/video.js +950 -0
- package/src/entities.js +1663 -0
- package/src/index.js +74 -0
- package/src/providers/analytics/index.js +17 -0
- package/src/providers/analytics/mixpanel.js +255 -0
- package/src/providers/calendar/cal-com.js +303 -0
- package/src/providers/calendar/google-calendar.js +335 -0
- package/src/providers/calendar/index.js +20 -0
- package/src/providers/crm/hubspot.js +566 -0
- package/src/providers/crm/index.js +17 -0
- package/src/providers/development/github.js +472 -0
- package/src/providers/development/index.js +17 -0
- package/src/providers/ecommerce/index.js +17 -0
- package/src/providers/ecommerce/shopify.js +378 -0
- package/src/providers/email/index.js +20 -0
- package/src/providers/email/resend.js +258 -0
- package/src/providers/email/sendgrid.js +161 -0
- package/src/providers/finance/index.js +17 -0
- package/src/providers/finance/stripe.js +549 -0
- package/src/providers/forms/index.js +17 -0
- package/src/providers/forms/typeform.js +500 -0
- package/src/providers/index.js +123 -0
- package/src/providers/knowledge/index.js +17 -0
- package/src/providers/knowledge/notion.js +389 -0
- package/src/providers/marketing/index.js +17 -0
- package/src/providers/marketing/mailchimp.js +443 -0
- package/src/providers/media/cloudinary.js +318 -0
- package/src/providers/media/index.js +17 -0
- package/src/providers/messaging/index.js +20 -0
- package/src/providers/messaging/slack.js +393 -0
- package/src/providers/messaging/twilio-sms.js +249 -0
- package/src/providers/project-management/index.js +17 -0
- package/src/providers/project-management/linear.js +575 -0
- package/src/providers/registry.js +86 -0
- package/src/providers/spreadsheet/google-sheets.js +375 -0
- package/src/providers/spreadsheet/index.js +20 -0
- package/src/providers/spreadsheet/xlsx.js +423 -0
- package/src/providers/storage/index.js +24 -0
- package/src/providers/storage/s3.js +419 -0
- package/src/providers/support/index.js +17 -0
- package/src/providers/support/zendesk.js +373 -0
- package/src/providers/tasks/index.js +17 -0
- package/src/providers/tasks/todoist.js +286 -0
- package/src/providers/types.js +9 -0
- package/src/providers/video-conferencing/google-meet.js +286 -0
- package/src/providers/video-conferencing/index.js +31 -0
- package/src/providers/video-conferencing/jitsi.js +254 -0
- package/src/providers/video-conferencing/teams.js +270 -0
- package/src/providers/video-conferencing/zoom.js +332 -0
- package/src/registry.js +128 -0
- package/src/tools/communication.js +184 -0
- package/src/tools/data.js +205 -0
- package/src/tools/index.js +11 -0
- package/src/tools/web.js +137 -0
- package/src/types.js +10 -0
- package/test/define.test.js +306 -0
- package/test/registry.test.js +357 -0
- package/test/tools.test.js +363 -0
|
@@ -0,0 +1,1386 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CRM/Sales Entity Types (Nouns)
|
|
3
|
+
*
|
|
4
|
+
* Semantic type definitions for Customer Relationship Management and Sales tools.
|
|
5
|
+
* Each entity defines properties, relationships, actions (Verbs), and events that
|
|
6
|
+
* can be used by both remote human workers AND AI agents.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
// =============================================================================
|
|
11
|
+
// Lead Management
|
|
12
|
+
// =============================================================================
|
|
13
|
+
/**
|
|
14
|
+
* Lead entity
|
|
15
|
+
*
|
|
16
|
+
* Represents a potential customer/sales opportunity that has not yet been qualified
|
|
17
|
+
*/
|
|
18
|
+
export const Lead = {
|
|
19
|
+
singular: 'lead',
|
|
20
|
+
plural: 'leads',
|
|
21
|
+
description: 'A potential customer or sales opportunity',
|
|
22
|
+
properties: {
|
|
23
|
+
// Identity
|
|
24
|
+
firstName: {
|
|
25
|
+
type: 'string',
|
|
26
|
+
description: 'Lead first name',
|
|
27
|
+
},
|
|
28
|
+
lastName: {
|
|
29
|
+
type: 'string',
|
|
30
|
+
description: 'Lead last name',
|
|
31
|
+
},
|
|
32
|
+
fullName: {
|
|
33
|
+
type: 'string',
|
|
34
|
+
optional: true,
|
|
35
|
+
description: 'Full name (computed or provided)',
|
|
36
|
+
},
|
|
37
|
+
title: {
|
|
38
|
+
type: 'string',
|
|
39
|
+
optional: true,
|
|
40
|
+
description: 'Job title',
|
|
41
|
+
},
|
|
42
|
+
// Contact Information
|
|
43
|
+
email: {
|
|
44
|
+
type: 'string',
|
|
45
|
+
optional: true,
|
|
46
|
+
description: 'Primary email address',
|
|
47
|
+
},
|
|
48
|
+
phone: {
|
|
49
|
+
type: 'string',
|
|
50
|
+
optional: true,
|
|
51
|
+
description: 'Primary phone number',
|
|
52
|
+
},
|
|
53
|
+
mobile: {
|
|
54
|
+
type: 'string',
|
|
55
|
+
optional: true,
|
|
56
|
+
description: 'Mobile phone number',
|
|
57
|
+
},
|
|
58
|
+
website: {
|
|
59
|
+
type: 'url',
|
|
60
|
+
optional: true,
|
|
61
|
+
description: 'Personal or company website',
|
|
62
|
+
},
|
|
63
|
+
// Company Information
|
|
64
|
+
company: {
|
|
65
|
+
type: 'string',
|
|
66
|
+
optional: true,
|
|
67
|
+
description: 'Company name',
|
|
68
|
+
},
|
|
69
|
+
industry: {
|
|
70
|
+
type: 'string',
|
|
71
|
+
optional: true,
|
|
72
|
+
description: 'Industry or vertical',
|
|
73
|
+
},
|
|
74
|
+
companySize: {
|
|
75
|
+
type: 'string',
|
|
76
|
+
optional: true,
|
|
77
|
+
description: 'Company size range (e.g., 1-10, 11-50, 51-200)',
|
|
78
|
+
examples: ['1-10', '11-50', '51-200', '201-500', '501-1000', '1000+'],
|
|
79
|
+
},
|
|
80
|
+
revenue: {
|
|
81
|
+
type: 'number',
|
|
82
|
+
optional: true,
|
|
83
|
+
description: 'Annual revenue in USD',
|
|
84
|
+
},
|
|
85
|
+
// Address
|
|
86
|
+
street: {
|
|
87
|
+
type: 'string',
|
|
88
|
+
optional: true,
|
|
89
|
+
description: 'Street address',
|
|
90
|
+
},
|
|
91
|
+
city: {
|
|
92
|
+
type: 'string',
|
|
93
|
+
optional: true,
|
|
94
|
+
description: 'City',
|
|
95
|
+
},
|
|
96
|
+
state: {
|
|
97
|
+
type: 'string',
|
|
98
|
+
optional: true,
|
|
99
|
+
description: 'State or province',
|
|
100
|
+
},
|
|
101
|
+
postalCode: {
|
|
102
|
+
type: 'string',
|
|
103
|
+
optional: true,
|
|
104
|
+
description: 'ZIP or postal code',
|
|
105
|
+
},
|
|
106
|
+
country: {
|
|
107
|
+
type: 'string',
|
|
108
|
+
optional: true,
|
|
109
|
+
description: 'Country',
|
|
110
|
+
},
|
|
111
|
+
// Lead Qualification
|
|
112
|
+
status: {
|
|
113
|
+
type: 'string',
|
|
114
|
+
description: 'Lead status: new, contacted, qualified, unqualified, converted, lost',
|
|
115
|
+
examples: ['new', 'contacted', 'qualified', 'unqualified', 'converted', 'lost'],
|
|
116
|
+
},
|
|
117
|
+
source: {
|
|
118
|
+
type: 'string',
|
|
119
|
+
optional: true,
|
|
120
|
+
description: 'Lead source: website, referral, advertisement, event, social, cold-call, partner',
|
|
121
|
+
examples: ['website', 'referral', 'advertisement', 'event', 'social', 'cold-call', 'partner', 'imported'],
|
|
122
|
+
},
|
|
123
|
+
score: {
|
|
124
|
+
type: 'number',
|
|
125
|
+
optional: true,
|
|
126
|
+
description: 'Lead score (0-100) indicating likelihood to convert',
|
|
127
|
+
},
|
|
128
|
+
rating: {
|
|
129
|
+
type: 'string',
|
|
130
|
+
optional: true,
|
|
131
|
+
description: 'Lead quality rating: hot, warm, cold',
|
|
132
|
+
examples: ['hot', 'warm', 'cold'],
|
|
133
|
+
},
|
|
134
|
+
// Context
|
|
135
|
+
description: {
|
|
136
|
+
type: 'string',
|
|
137
|
+
optional: true,
|
|
138
|
+
description: 'Notes or description about the lead',
|
|
139
|
+
},
|
|
140
|
+
notes: {
|
|
141
|
+
type: 'string',
|
|
142
|
+
optional: true,
|
|
143
|
+
description: 'Additional notes',
|
|
144
|
+
},
|
|
145
|
+
tags: {
|
|
146
|
+
type: 'string',
|
|
147
|
+
array: true,
|
|
148
|
+
optional: true,
|
|
149
|
+
description: 'Tags for categorization',
|
|
150
|
+
},
|
|
151
|
+
// Campaign
|
|
152
|
+
campaign: {
|
|
153
|
+
type: 'string',
|
|
154
|
+
optional: true,
|
|
155
|
+
description: 'Marketing campaign that generated this lead',
|
|
156
|
+
},
|
|
157
|
+
referredBy: {
|
|
158
|
+
type: 'string',
|
|
159
|
+
optional: true,
|
|
160
|
+
description: 'Who referred this lead',
|
|
161
|
+
},
|
|
162
|
+
// Tracking
|
|
163
|
+
lastContactedAt: {
|
|
164
|
+
type: 'datetime',
|
|
165
|
+
optional: true,
|
|
166
|
+
description: 'When the lead was last contacted',
|
|
167
|
+
},
|
|
168
|
+
convertedAt: {
|
|
169
|
+
type: 'datetime',
|
|
170
|
+
optional: true,
|
|
171
|
+
description: 'When the lead was converted to an account/opportunity',
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
relationships: {
|
|
175
|
+
owner: {
|
|
176
|
+
type: 'Contact',
|
|
177
|
+
description: 'Sales rep or user who owns this lead',
|
|
178
|
+
},
|
|
179
|
+
activities: {
|
|
180
|
+
type: 'Activity[]',
|
|
181
|
+
backref: 'lead',
|
|
182
|
+
description: 'Activities associated with this lead',
|
|
183
|
+
},
|
|
184
|
+
convertedAccount: {
|
|
185
|
+
type: 'Account',
|
|
186
|
+
required: false,
|
|
187
|
+
description: 'Account created when lead was converted',
|
|
188
|
+
},
|
|
189
|
+
convertedDeal: {
|
|
190
|
+
type: 'Deal',
|
|
191
|
+
required: false,
|
|
192
|
+
description: 'Deal/opportunity created when lead was converted',
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
actions: [
|
|
196
|
+
'create',
|
|
197
|
+
'update',
|
|
198
|
+
'delete',
|
|
199
|
+
'qualify',
|
|
200
|
+
'disqualify',
|
|
201
|
+
'convert',
|
|
202
|
+
'assign',
|
|
203
|
+
'contact',
|
|
204
|
+
'score',
|
|
205
|
+
'merge',
|
|
206
|
+
'import',
|
|
207
|
+
'export',
|
|
208
|
+
'tag',
|
|
209
|
+
'untag',
|
|
210
|
+
],
|
|
211
|
+
events: [
|
|
212
|
+
'created',
|
|
213
|
+
'updated',
|
|
214
|
+
'deleted',
|
|
215
|
+
'qualified',
|
|
216
|
+
'disqualified',
|
|
217
|
+
'converted',
|
|
218
|
+
'assigned',
|
|
219
|
+
'contacted',
|
|
220
|
+
'scored',
|
|
221
|
+
'merged',
|
|
222
|
+
'imported',
|
|
223
|
+
'exported',
|
|
224
|
+
'tagged',
|
|
225
|
+
],
|
|
226
|
+
};
|
|
227
|
+
// =============================================================================
|
|
228
|
+
// Deal/Opportunity Management
|
|
229
|
+
// =============================================================================
|
|
230
|
+
/**
|
|
231
|
+
* Deal entity (also known as Opportunity in some CRMs)
|
|
232
|
+
*
|
|
233
|
+
* Represents a qualified sales opportunity with revenue potential
|
|
234
|
+
*/
|
|
235
|
+
export const Deal = {
|
|
236
|
+
singular: 'deal',
|
|
237
|
+
plural: 'deals',
|
|
238
|
+
description: 'A sales opportunity or deal in progress',
|
|
239
|
+
properties: {
|
|
240
|
+
// Identity
|
|
241
|
+
name: {
|
|
242
|
+
type: 'string',
|
|
243
|
+
description: 'Deal name or title',
|
|
244
|
+
},
|
|
245
|
+
description: {
|
|
246
|
+
type: 'string',
|
|
247
|
+
optional: true,
|
|
248
|
+
description: 'Description of the opportunity',
|
|
249
|
+
},
|
|
250
|
+
// Financial
|
|
251
|
+
value: {
|
|
252
|
+
type: 'number',
|
|
253
|
+
description: 'Deal value or amount in USD',
|
|
254
|
+
},
|
|
255
|
+
currency: {
|
|
256
|
+
type: 'string',
|
|
257
|
+
optional: true,
|
|
258
|
+
description: 'Currency code (ISO 4217)',
|
|
259
|
+
examples: ['USD', 'EUR', 'GBP', 'CAD', 'AUD'],
|
|
260
|
+
},
|
|
261
|
+
expectedRevenue: {
|
|
262
|
+
type: 'number',
|
|
263
|
+
optional: true,
|
|
264
|
+
description: 'Expected revenue (value * probability)',
|
|
265
|
+
},
|
|
266
|
+
// Deal Stage & Status
|
|
267
|
+
stage: {
|
|
268
|
+
type: 'string',
|
|
269
|
+
description: 'Current pipeline stage',
|
|
270
|
+
examples: ['prospecting', 'qualification', 'proposal', 'negotiation', 'closed-won', 'closed-lost'],
|
|
271
|
+
},
|
|
272
|
+
probability: {
|
|
273
|
+
type: 'number',
|
|
274
|
+
optional: true,
|
|
275
|
+
description: 'Win probability percentage (0-100)',
|
|
276
|
+
},
|
|
277
|
+
status: {
|
|
278
|
+
type: 'string',
|
|
279
|
+
description: 'Deal status: open, won, lost, abandoned',
|
|
280
|
+
examples: ['open', 'won', 'lost', 'abandoned'],
|
|
281
|
+
},
|
|
282
|
+
// Dates
|
|
283
|
+
closeDate: {
|
|
284
|
+
type: 'date',
|
|
285
|
+
optional: true,
|
|
286
|
+
description: 'Expected or actual close date',
|
|
287
|
+
},
|
|
288
|
+
closedAt: {
|
|
289
|
+
type: 'datetime',
|
|
290
|
+
optional: true,
|
|
291
|
+
description: 'When the deal was closed',
|
|
292
|
+
},
|
|
293
|
+
lastActivityAt: {
|
|
294
|
+
type: 'datetime',
|
|
295
|
+
optional: true,
|
|
296
|
+
description: 'Last activity timestamp',
|
|
297
|
+
},
|
|
298
|
+
// Context
|
|
299
|
+
source: {
|
|
300
|
+
type: 'string',
|
|
301
|
+
optional: true,
|
|
302
|
+
description: 'How the opportunity was sourced',
|
|
303
|
+
examples: ['inbound', 'outbound', 'referral', 'partner', 'marketing'],
|
|
304
|
+
},
|
|
305
|
+
type: {
|
|
306
|
+
type: 'string',
|
|
307
|
+
optional: true,
|
|
308
|
+
description: 'Deal type: new-business, upsell, renewal, cross-sell',
|
|
309
|
+
examples: ['new-business', 'upsell', 'renewal', 'cross-sell'],
|
|
310
|
+
},
|
|
311
|
+
priority: {
|
|
312
|
+
type: 'string',
|
|
313
|
+
optional: true,
|
|
314
|
+
description: 'Deal priority: low, medium, high, critical',
|
|
315
|
+
examples: ['low', 'medium', 'high', 'critical'],
|
|
316
|
+
},
|
|
317
|
+
// Loss/Win Analysis
|
|
318
|
+
lostReason: {
|
|
319
|
+
type: 'string',
|
|
320
|
+
optional: true,
|
|
321
|
+
description: 'Reason why deal was lost',
|
|
322
|
+
examples: ['price', 'competition', 'timing', 'no-decision', 'product-fit'],
|
|
323
|
+
},
|
|
324
|
+
competitorName: {
|
|
325
|
+
type: 'string',
|
|
326
|
+
optional: true,
|
|
327
|
+
description: 'Competitor involved in the deal',
|
|
328
|
+
},
|
|
329
|
+
// Notes
|
|
330
|
+
notes: {
|
|
331
|
+
type: 'string',
|
|
332
|
+
optional: true,
|
|
333
|
+
description: 'Notes about the deal',
|
|
334
|
+
},
|
|
335
|
+
tags: {
|
|
336
|
+
type: 'string',
|
|
337
|
+
array: true,
|
|
338
|
+
optional: true,
|
|
339
|
+
description: 'Tags for categorization',
|
|
340
|
+
},
|
|
341
|
+
},
|
|
342
|
+
relationships: {
|
|
343
|
+
account: {
|
|
344
|
+
type: 'Account',
|
|
345
|
+
backref: 'deals',
|
|
346
|
+
description: 'The account/company this deal is with',
|
|
347
|
+
},
|
|
348
|
+
owner: {
|
|
349
|
+
type: 'Contact',
|
|
350
|
+
description: 'Sales rep who owns this deal',
|
|
351
|
+
},
|
|
352
|
+
pipeline: {
|
|
353
|
+
type: 'Pipeline',
|
|
354
|
+
backref: 'deals',
|
|
355
|
+
description: 'Sales pipeline this deal belongs to',
|
|
356
|
+
},
|
|
357
|
+
currentStage: {
|
|
358
|
+
type: 'Stage',
|
|
359
|
+
description: 'Current pipeline stage',
|
|
360
|
+
},
|
|
361
|
+
contacts: {
|
|
362
|
+
type: 'Contact[]',
|
|
363
|
+
description: 'Contacts involved in this deal',
|
|
364
|
+
},
|
|
365
|
+
activities: {
|
|
366
|
+
type: 'Activity[]',
|
|
367
|
+
backref: 'deal',
|
|
368
|
+
description: 'Activities related to this deal',
|
|
369
|
+
},
|
|
370
|
+
quotes: {
|
|
371
|
+
type: 'Quote[]',
|
|
372
|
+
backref: 'deal',
|
|
373
|
+
description: 'Quotes/proposals sent for this deal',
|
|
374
|
+
},
|
|
375
|
+
products: {
|
|
376
|
+
type: 'Product[]',
|
|
377
|
+
description: 'Products included in this deal',
|
|
378
|
+
},
|
|
379
|
+
},
|
|
380
|
+
actions: [
|
|
381
|
+
'create',
|
|
382
|
+
'update',
|
|
383
|
+
'delete',
|
|
384
|
+
'advance',
|
|
385
|
+
'moveToStage',
|
|
386
|
+
'win',
|
|
387
|
+
'lose',
|
|
388
|
+
'abandon',
|
|
389
|
+
'reopen',
|
|
390
|
+
'clone',
|
|
391
|
+
'assign',
|
|
392
|
+
'addContact',
|
|
393
|
+
'removeContact',
|
|
394
|
+
'addProduct',
|
|
395
|
+
'removeProduct',
|
|
396
|
+
'createQuote',
|
|
397
|
+
'logActivity',
|
|
398
|
+
],
|
|
399
|
+
events: [
|
|
400
|
+
'created',
|
|
401
|
+
'updated',
|
|
402
|
+
'deleted',
|
|
403
|
+
'advanced',
|
|
404
|
+
'stageChanged',
|
|
405
|
+
'won',
|
|
406
|
+
'lost',
|
|
407
|
+
'abandoned',
|
|
408
|
+
'reopened',
|
|
409
|
+
'cloned',
|
|
410
|
+
'assigned',
|
|
411
|
+
'contactAdded',
|
|
412
|
+
'contactRemoved',
|
|
413
|
+
'productAdded',
|
|
414
|
+
'productRemoved',
|
|
415
|
+
'quoteCreated',
|
|
416
|
+
'activityLogged',
|
|
417
|
+
],
|
|
418
|
+
};
|
|
419
|
+
// =============================================================================
|
|
420
|
+
// Account Management
|
|
421
|
+
// =============================================================================
|
|
422
|
+
/**
|
|
423
|
+
* Account entity
|
|
424
|
+
*
|
|
425
|
+
* Represents a company or organization (customer or prospect)
|
|
426
|
+
*/
|
|
427
|
+
export const Account = {
|
|
428
|
+
singular: 'account',
|
|
429
|
+
plural: 'accounts',
|
|
430
|
+
description: 'A company or organization account',
|
|
431
|
+
properties: {
|
|
432
|
+
// Identity
|
|
433
|
+
name: {
|
|
434
|
+
type: 'string',
|
|
435
|
+
description: 'Account/company name',
|
|
436
|
+
},
|
|
437
|
+
legalName: {
|
|
438
|
+
type: 'string',
|
|
439
|
+
optional: true,
|
|
440
|
+
description: 'Legal business name',
|
|
441
|
+
},
|
|
442
|
+
description: {
|
|
443
|
+
type: 'string',
|
|
444
|
+
optional: true,
|
|
445
|
+
description: 'Description of the account',
|
|
446
|
+
},
|
|
447
|
+
// Company Information
|
|
448
|
+
industry: {
|
|
449
|
+
type: 'string',
|
|
450
|
+
optional: true,
|
|
451
|
+
description: 'Industry or vertical',
|
|
452
|
+
},
|
|
453
|
+
website: {
|
|
454
|
+
type: 'url',
|
|
455
|
+
optional: true,
|
|
456
|
+
description: 'Company website',
|
|
457
|
+
},
|
|
458
|
+
employeeCount: {
|
|
459
|
+
type: 'number',
|
|
460
|
+
optional: true,
|
|
461
|
+
description: 'Number of employees',
|
|
462
|
+
},
|
|
463
|
+
revenue: {
|
|
464
|
+
type: 'number',
|
|
465
|
+
optional: true,
|
|
466
|
+
description: 'Annual revenue in USD',
|
|
467
|
+
},
|
|
468
|
+
// Contact Information
|
|
469
|
+
phone: {
|
|
470
|
+
type: 'string',
|
|
471
|
+
optional: true,
|
|
472
|
+
description: 'Main phone number',
|
|
473
|
+
},
|
|
474
|
+
email: {
|
|
475
|
+
type: 'string',
|
|
476
|
+
optional: true,
|
|
477
|
+
description: 'General contact email',
|
|
478
|
+
},
|
|
479
|
+
// Address
|
|
480
|
+
billingStreet: {
|
|
481
|
+
type: 'string',
|
|
482
|
+
optional: true,
|
|
483
|
+
description: 'Billing street address',
|
|
484
|
+
},
|
|
485
|
+
billingCity: {
|
|
486
|
+
type: 'string',
|
|
487
|
+
optional: true,
|
|
488
|
+
description: 'Billing city',
|
|
489
|
+
},
|
|
490
|
+
billingState: {
|
|
491
|
+
type: 'string',
|
|
492
|
+
optional: true,
|
|
493
|
+
description: 'Billing state/province',
|
|
494
|
+
},
|
|
495
|
+
billingPostalCode: {
|
|
496
|
+
type: 'string',
|
|
497
|
+
optional: true,
|
|
498
|
+
description: 'Billing ZIP/postal code',
|
|
499
|
+
},
|
|
500
|
+
billingCountry: {
|
|
501
|
+
type: 'string',
|
|
502
|
+
optional: true,
|
|
503
|
+
description: 'Billing country',
|
|
504
|
+
},
|
|
505
|
+
shippingStreet: {
|
|
506
|
+
type: 'string',
|
|
507
|
+
optional: true,
|
|
508
|
+
description: 'Shipping street address',
|
|
509
|
+
},
|
|
510
|
+
shippingCity: {
|
|
511
|
+
type: 'string',
|
|
512
|
+
optional: true,
|
|
513
|
+
description: 'Shipping city',
|
|
514
|
+
},
|
|
515
|
+
shippingState: {
|
|
516
|
+
type: 'string',
|
|
517
|
+
optional: true,
|
|
518
|
+
description: 'Shipping state/province',
|
|
519
|
+
},
|
|
520
|
+
shippingPostalCode: {
|
|
521
|
+
type: 'string',
|
|
522
|
+
optional: true,
|
|
523
|
+
description: 'Shipping ZIP/postal code',
|
|
524
|
+
},
|
|
525
|
+
shippingCountry: {
|
|
526
|
+
type: 'string',
|
|
527
|
+
optional: true,
|
|
528
|
+
description: 'Shipping country',
|
|
529
|
+
},
|
|
530
|
+
// Account Status
|
|
531
|
+
type: {
|
|
532
|
+
type: 'string',
|
|
533
|
+
optional: true,
|
|
534
|
+
description: 'Account type: prospect, customer, partner, competitor, other',
|
|
535
|
+
examples: ['prospect', 'customer', 'partner', 'competitor', 'other'],
|
|
536
|
+
},
|
|
537
|
+
status: {
|
|
538
|
+
type: 'string',
|
|
539
|
+
optional: true,
|
|
540
|
+
description: 'Account status: active, inactive, suspended, churned',
|
|
541
|
+
examples: ['active', 'inactive', 'suspended', 'churned'],
|
|
542
|
+
},
|
|
543
|
+
priority: {
|
|
544
|
+
type: 'string',
|
|
545
|
+
optional: true,
|
|
546
|
+
description: 'Account priority: low, medium, high, strategic',
|
|
547
|
+
examples: ['low', 'medium', 'high', 'strategic'],
|
|
548
|
+
},
|
|
549
|
+
tier: {
|
|
550
|
+
type: 'string',
|
|
551
|
+
optional: true,
|
|
552
|
+
description: 'Customer tier: bronze, silver, gold, platinum',
|
|
553
|
+
examples: ['bronze', 'silver', 'gold', 'platinum'],
|
|
554
|
+
},
|
|
555
|
+
// Financials
|
|
556
|
+
lifetime_value: {
|
|
557
|
+
type: 'number',
|
|
558
|
+
optional: true,
|
|
559
|
+
description: 'Total lifetime value of the account',
|
|
560
|
+
},
|
|
561
|
+
totalRevenue: {
|
|
562
|
+
type: 'number',
|
|
563
|
+
optional: true,
|
|
564
|
+
description: 'Total revenue from this account',
|
|
565
|
+
},
|
|
566
|
+
// Metadata
|
|
567
|
+
notes: {
|
|
568
|
+
type: 'string',
|
|
569
|
+
optional: true,
|
|
570
|
+
description: 'Notes about the account',
|
|
571
|
+
},
|
|
572
|
+
tags: {
|
|
573
|
+
type: 'string',
|
|
574
|
+
array: true,
|
|
575
|
+
optional: true,
|
|
576
|
+
description: 'Tags for categorization',
|
|
577
|
+
},
|
|
578
|
+
// Tracking
|
|
579
|
+
lastContactedAt: {
|
|
580
|
+
type: 'datetime',
|
|
581
|
+
optional: true,
|
|
582
|
+
description: 'Last contact timestamp',
|
|
583
|
+
},
|
|
584
|
+
customerSince: {
|
|
585
|
+
type: 'date',
|
|
586
|
+
optional: true,
|
|
587
|
+
description: 'Date became a customer',
|
|
588
|
+
},
|
|
589
|
+
},
|
|
590
|
+
relationships: {
|
|
591
|
+
owner: {
|
|
592
|
+
type: 'Contact',
|
|
593
|
+
description: 'Account owner (sales rep or CSM)',
|
|
594
|
+
},
|
|
595
|
+
parentAccount: {
|
|
596
|
+
type: 'Account',
|
|
597
|
+
required: false,
|
|
598
|
+
description: 'Parent account if this is a subsidiary',
|
|
599
|
+
},
|
|
600
|
+
childAccounts: {
|
|
601
|
+
type: 'Account[]',
|
|
602
|
+
description: 'Subsidiary accounts',
|
|
603
|
+
},
|
|
604
|
+
contacts: {
|
|
605
|
+
type: 'Contact[]',
|
|
606
|
+
backref: 'account',
|
|
607
|
+
description: 'Contacts at this account',
|
|
608
|
+
},
|
|
609
|
+
deals: {
|
|
610
|
+
type: 'Deal[]',
|
|
611
|
+
backref: 'account',
|
|
612
|
+
description: 'Deals/opportunities with this account',
|
|
613
|
+
},
|
|
614
|
+
activities: {
|
|
615
|
+
type: 'Activity[]',
|
|
616
|
+
backref: 'account',
|
|
617
|
+
description: 'Activities related to this account',
|
|
618
|
+
},
|
|
619
|
+
quotes: {
|
|
620
|
+
type: 'Quote[]',
|
|
621
|
+
backref: 'account',
|
|
622
|
+
description: 'Quotes sent to this account',
|
|
623
|
+
},
|
|
624
|
+
},
|
|
625
|
+
actions: [
|
|
626
|
+
'create',
|
|
627
|
+
'update',
|
|
628
|
+
'delete',
|
|
629
|
+
'merge',
|
|
630
|
+
'activate',
|
|
631
|
+
'deactivate',
|
|
632
|
+
'suspend',
|
|
633
|
+
'assign',
|
|
634
|
+
'addContact',
|
|
635
|
+
'removeContact',
|
|
636
|
+
'createDeal',
|
|
637
|
+
'createQuote',
|
|
638
|
+
'logActivity',
|
|
639
|
+
'upgrade',
|
|
640
|
+
'downgrade',
|
|
641
|
+
],
|
|
642
|
+
events: [
|
|
643
|
+
'created',
|
|
644
|
+
'updated',
|
|
645
|
+
'deleted',
|
|
646
|
+
'merged',
|
|
647
|
+
'activated',
|
|
648
|
+
'deactivated',
|
|
649
|
+
'suspended',
|
|
650
|
+
'assigned',
|
|
651
|
+
'contactAdded',
|
|
652
|
+
'contactRemoved',
|
|
653
|
+
'dealCreated',
|
|
654
|
+
'quoteCreated',
|
|
655
|
+
'activityLogged',
|
|
656
|
+
'upgraded',
|
|
657
|
+
'downgraded',
|
|
658
|
+
],
|
|
659
|
+
};
|
|
660
|
+
// =============================================================================
|
|
661
|
+
// Pipeline & Stage Management
|
|
662
|
+
// =============================================================================
|
|
663
|
+
/**
|
|
664
|
+
* Pipeline entity
|
|
665
|
+
*
|
|
666
|
+
* Represents a sales pipeline with defined stages
|
|
667
|
+
*/
|
|
668
|
+
export const Pipeline = {
|
|
669
|
+
singular: 'pipeline',
|
|
670
|
+
plural: 'pipelines',
|
|
671
|
+
description: 'A sales pipeline with defined stages',
|
|
672
|
+
properties: {
|
|
673
|
+
name: {
|
|
674
|
+
type: 'string',
|
|
675
|
+
description: 'Pipeline name',
|
|
676
|
+
},
|
|
677
|
+
description: {
|
|
678
|
+
type: 'string',
|
|
679
|
+
optional: true,
|
|
680
|
+
description: 'Description of the pipeline',
|
|
681
|
+
},
|
|
682
|
+
type: {
|
|
683
|
+
type: 'string',
|
|
684
|
+
optional: true,
|
|
685
|
+
description: 'Pipeline type: sales, partnership, renewal',
|
|
686
|
+
examples: ['sales', 'partnership', 'renewal'],
|
|
687
|
+
},
|
|
688
|
+
isDefault: {
|
|
689
|
+
type: 'boolean',
|
|
690
|
+
optional: true,
|
|
691
|
+
description: 'Whether this is the default pipeline',
|
|
692
|
+
},
|
|
693
|
+
isActive: {
|
|
694
|
+
type: 'boolean',
|
|
695
|
+
optional: true,
|
|
696
|
+
description: 'Whether this pipeline is active',
|
|
697
|
+
},
|
|
698
|
+
stageCount: {
|
|
699
|
+
type: 'number',
|
|
700
|
+
optional: true,
|
|
701
|
+
description: 'Number of stages in the pipeline',
|
|
702
|
+
},
|
|
703
|
+
totalValue: {
|
|
704
|
+
type: 'number',
|
|
705
|
+
optional: true,
|
|
706
|
+
description: 'Total value of all deals in this pipeline',
|
|
707
|
+
},
|
|
708
|
+
dealCount: {
|
|
709
|
+
type: 'number',
|
|
710
|
+
optional: true,
|
|
711
|
+
description: 'Number of deals in this pipeline',
|
|
712
|
+
},
|
|
713
|
+
},
|
|
714
|
+
relationships: {
|
|
715
|
+
stages: {
|
|
716
|
+
type: 'Stage[]',
|
|
717
|
+
backref: 'pipeline',
|
|
718
|
+
description: 'Stages in this pipeline',
|
|
719
|
+
},
|
|
720
|
+
deals: {
|
|
721
|
+
type: 'Deal[]',
|
|
722
|
+
backref: 'pipeline',
|
|
723
|
+
description: 'Deals in this pipeline',
|
|
724
|
+
},
|
|
725
|
+
},
|
|
726
|
+
actions: [
|
|
727
|
+
'create',
|
|
728
|
+
'update',
|
|
729
|
+
'delete',
|
|
730
|
+
'activate',
|
|
731
|
+
'deactivate',
|
|
732
|
+
'setDefault',
|
|
733
|
+
'addStage',
|
|
734
|
+
'removeStage',
|
|
735
|
+
'reorderStages',
|
|
736
|
+
'clone',
|
|
737
|
+
],
|
|
738
|
+
events: [
|
|
739
|
+
'created',
|
|
740
|
+
'updated',
|
|
741
|
+
'deleted',
|
|
742
|
+
'activated',
|
|
743
|
+
'deactivated',
|
|
744
|
+
'setAsDefault',
|
|
745
|
+
'stageAdded',
|
|
746
|
+
'stageRemoved',
|
|
747
|
+
'stagesReordered',
|
|
748
|
+
'cloned',
|
|
749
|
+
],
|
|
750
|
+
};
|
|
751
|
+
/**
|
|
752
|
+
* Stage entity
|
|
753
|
+
*
|
|
754
|
+
* Represents a stage within a sales pipeline
|
|
755
|
+
*/
|
|
756
|
+
export const Stage = {
|
|
757
|
+
singular: 'stage',
|
|
758
|
+
plural: 'stages',
|
|
759
|
+
description: 'A stage in a sales pipeline',
|
|
760
|
+
properties: {
|
|
761
|
+
name: {
|
|
762
|
+
type: 'string',
|
|
763
|
+
description: 'Stage name',
|
|
764
|
+
examples: ['Prospecting', 'Qualification', 'Proposal', 'Negotiation', 'Closed Won', 'Closed Lost'],
|
|
765
|
+
},
|
|
766
|
+
description: {
|
|
767
|
+
type: 'string',
|
|
768
|
+
optional: true,
|
|
769
|
+
description: 'Description of what this stage represents',
|
|
770
|
+
},
|
|
771
|
+
order: {
|
|
772
|
+
type: 'number',
|
|
773
|
+
description: 'Display order in the pipeline (0-indexed)',
|
|
774
|
+
},
|
|
775
|
+
probability: {
|
|
776
|
+
type: 'number',
|
|
777
|
+
optional: true,
|
|
778
|
+
description: 'Default win probability for deals in this stage (0-100)',
|
|
779
|
+
},
|
|
780
|
+
type: {
|
|
781
|
+
type: 'string',
|
|
782
|
+
description: 'Stage type: open, won, lost',
|
|
783
|
+
examples: ['open', 'won', 'lost'],
|
|
784
|
+
},
|
|
785
|
+
rottenDays: {
|
|
786
|
+
type: 'number',
|
|
787
|
+
optional: true,
|
|
788
|
+
description: 'Number of days before deals in this stage are considered stale',
|
|
789
|
+
},
|
|
790
|
+
color: {
|
|
791
|
+
type: 'string',
|
|
792
|
+
optional: true,
|
|
793
|
+
description: 'Display color for the stage (hex code)',
|
|
794
|
+
},
|
|
795
|
+
dealCount: {
|
|
796
|
+
type: 'number',
|
|
797
|
+
optional: true,
|
|
798
|
+
description: 'Number of deals currently in this stage',
|
|
799
|
+
},
|
|
800
|
+
totalValue: {
|
|
801
|
+
type: 'number',
|
|
802
|
+
optional: true,
|
|
803
|
+
description: 'Total value of deals in this stage',
|
|
804
|
+
},
|
|
805
|
+
},
|
|
806
|
+
relationships: {
|
|
807
|
+
pipeline: {
|
|
808
|
+
type: 'Pipeline',
|
|
809
|
+
backref: 'stages',
|
|
810
|
+
description: 'Pipeline this stage belongs to',
|
|
811
|
+
},
|
|
812
|
+
deals: {
|
|
813
|
+
type: 'Deal[]',
|
|
814
|
+
description: 'Deals currently in this stage',
|
|
815
|
+
},
|
|
816
|
+
},
|
|
817
|
+
actions: [
|
|
818
|
+
'create',
|
|
819
|
+
'update',
|
|
820
|
+
'delete',
|
|
821
|
+
'reorder',
|
|
822
|
+
'moveDeals',
|
|
823
|
+
],
|
|
824
|
+
events: [
|
|
825
|
+
'created',
|
|
826
|
+
'updated',
|
|
827
|
+
'deleted',
|
|
828
|
+
'reordered',
|
|
829
|
+
'dealsMoved',
|
|
830
|
+
],
|
|
831
|
+
};
|
|
832
|
+
// =============================================================================
|
|
833
|
+
// Activity Management
|
|
834
|
+
// =============================================================================
|
|
835
|
+
/**
|
|
836
|
+
* Activity entity
|
|
837
|
+
*
|
|
838
|
+
* Represents a CRM activity (call, email, meeting, note, task)
|
|
839
|
+
*/
|
|
840
|
+
export const Activity = {
|
|
841
|
+
singular: 'activity',
|
|
842
|
+
plural: 'activities',
|
|
843
|
+
description: 'A CRM activity such as a call, email, meeting, or note',
|
|
844
|
+
properties: {
|
|
845
|
+
// Activity Details
|
|
846
|
+
type: {
|
|
847
|
+
type: 'string',
|
|
848
|
+
description: 'Activity type: call, email, meeting, task, note, demo, lunch, other',
|
|
849
|
+
examples: ['call', 'email', 'meeting', 'task', 'note', 'demo', 'lunch', 'other'],
|
|
850
|
+
},
|
|
851
|
+
subject: {
|
|
852
|
+
type: 'string',
|
|
853
|
+
description: 'Activity subject or title',
|
|
854
|
+
},
|
|
855
|
+
description: {
|
|
856
|
+
type: 'string',
|
|
857
|
+
optional: true,
|
|
858
|
+
description: 'Detailed description or notes',
|
|
859
|
+
},
|
|
860
|
+
// Status
|
|
861
|
+
status: {
|
|
862
|
+
type: 'string',
|
|
863
|
+
optional: true,
|
|
864
|
+
description: 'Activity status: scheduled, completed, canceled, no-show',
|
|
865
|
+
examples: ['scheduled', 'completed', 'canceled', 'no-show'],
|
|
866
|
+
},
|
|
867
|
+
outcome: {
|
|
868
|
+
type: 'string',
|
|
869
|
+
optional: true,
|
|
870
|
+
description: 'Activity outcome: successful, unsuccessful, left-voicemail, no-answer',
|
|
871
|
+
examples: ['successful', 'unsuccessful', 'left-voicemail', 'no-answer', 'busy'],
|
|
872
|
+
},
|
|
873
|
+
// Timing
|
|
874
|
+
scheduledAt: {
|
|
875
|
+
type: 'datetime',
|
|
876
|
+
optional: true,
|
|
877
|
+
description: 'When the activity is scheduled',
|
|
878
|
+
},
|
|
879
|
+
completedAt: {
|
|
880
|
+
type: 'datetime',
|
|
881
|
+
optional: true,
|
|
882
|
+
description: 'When the activity was completed',
|
|
883
|
+
},
|
|
884
|
+
dueAt: {
|
|
885
|
+
type: 'datetime',
|
|
886
|
+
optional: true,
|
|
887
|
+
description: 'When the activity is due (for tasks)',
|
|
888
|
+
},
|
|
889
|
+
duration: {
|
|
890
|
+
type: 'number',
|
|
891
|
+
optional: true,
|
|
892
|
+
description: 'Duration in minutes',
|
|
893
|
+
},
|
|
894
|
+
// Priority
|
|
895
|
+
priority: {
|
|
896
|
+
type: 'string',
|
|
897
|
+
optional: true,
|
|
898
|
+
description: 'Priority: low, medium, high',
|
|
899
|
+
examples: ['low', 'medium', 'high'],
|
|
900
|
+
},
|
|
901
|
+
// Context
|
|
902
|
+
direction: {
|
|
903
|
+
type: 'string',
|
|
904
|
+
optional: true,
|
|
905
|
+
description: 'For calls/emails: inbound, outbound',
|
|
906
|
+
examples: ['inbound', 'outbound'],
|
|
907
|
+
},
|
|
908
|
+
location: {
|
|
909
|
+
type: 'string',
|
|
910
|
+
optional: true,
|
|
911
|
+
description: 'Meeting location or phone number',
|
|
912
|
+
},
|
|
913
|
+
// Flags
|
|
914
|
+
isPrivate: {
|
|
915
|
+
type: 'boolean',
|
|
916
|
+
optional: true,
|
|
917
|
+
description: 'Whether the activity is private',
|
|
918
|
+
},
|
|
919
|
+
isArchived: {
|
|
920
|
+
type: 'boolean',
|
|
921
|
+
optional: true,
|
|
922
|
+
description: 'Whether the activity is archived',
|
|
923
|
+
},
|
|
924
|
+
},
|
|
925
|
+
relationships: {
|
|
926
|
+
owner: {
|
|
927
|
+
type: 'Contact',
|
|
928
|
+
description: 'Person who owns/created this activity',
|
|
929
|
+
},
|
|
930
|
+
lead: {
|
|
931
|
+
type: 'Lead',
|
|
932
|
+
required: false,
|
|
933
|
+
backref: 'activities',
|
|
934
|
+
description: 'Lead associated with this activity',
|
|
935
|
+
},
|
|
936
|
+
deal: {
|
|
937
|
+
type: 'Deal',
|
|
938
|
+
required: false,
|
|
939
|
+
backref: 'activities',
|
|
940
|
+
description: 'Deal associated with this activity',
|
|
941
|
+
},
|
|
942
|
+
account: {
|
|
943
|
+
type: 'Account',
|
|
944
|
+
required: false,
|
|
945
|
+
backref: 'activities',
|
|
946
|
+
description: 'Account associated with this activity',
|
|
947
|
+
},
|
|
948
|
+
contacts: {
|
|
949
|
+
type: 'Contact[]',
|
|
950
|
+
description: 'Contacts involved in this activity',
|
|
951
|
+
},
|
|
952
|
+
attendees: {
|
|
953
|
+
type: 'Contact[]',
|
|
954
|
+
description: 'Meeting attendees',
|
|
955
|
+
},
|
|
956
|
+
},
|
|
957
|
+
actions: [
|
|
958
|
+
'create',
|
|
959
|
+
'update',
|
|
960
|
+
'delete',
|
|
961
|
+
'complete',
|
|
962
|
+
'schedule',
|
|
963
|
+
'reschedule',
|
|
964
|
+
'cancel',
|
|
965
|
+
'archive',
|
|
966
|
+
'unarchive',
|
|
967
|
+
'addAttendee',
|
|
968
|
+
'removeAttendee',
|
|
969
|
+
'log',
|
|
970
|
+
],
|
|
971
|
+
events: [
|
|
972
|
+
'created',
|
|
973
|
+
'updated',
|
|
974
|
+
'deleted',
|
|
975
|
+
'completed',
|
|
976
|
+
'scheduled',
|
|
977
|
+
'rescheduled',
|
|
978
|
+
'canceled',
|
|
979
|
+
'archived',
|
|
980
|
+
'unarchived',
|
|
981
|
+
'attendeeAdded',
|
|
982
|
+
'attendeeRemoved',
|
|
983
|
+
'logged',
|
|
984
|
+
],
|
|
985
|
+
};
|
|
986
|
+
// =============================================================================
|
|
987
|
+
// Quote & Product Management
|
|
988
|
+
// =============================================================================
|
|
989
|
+
/**
|
|
990
|
+
* Quote entity
|
|
991
|
+
*
|
|
992
|
+
* Represents a sales quote or proposal with line items
|
|
993
|
+
*/
|
|
994
|
+
export const Quote = {
|
|
995
|
+
singular: 'quote',
|
|
996
|
+
plural: 'quotes',
|
|
997
|
+
description: 'A sales quote or proposal',
|
|
998
|
+
properties: {
|
|
999
|
+
// Identity
|
|
1000
|
+
name: {
|
|
1001
|
+
type: 'string',
|
|
1002
|
+
description: 'Quote name or title',
|
|
1003
|
+
},
|
|
1004
|
+
quoteNumber: {
|
|
1005
|
+
type: 'string',
|
|
1006
|
+
optional: true,
|
|
1007
|
+
description: 'Unique quote number',
|
|
1008
|
+
},
|
|
1009
|
+
description: {
|
|
1010
|
+
type: 'string',
|
|
1011
|
+
optional: true,
|
|
1012
|
+
description: 'Quote description',
|
|
1013
|
+
},
|
|
1014
|
+
// Status
|
|
1015
|
+
status: {
|
|
1016
|
+
type: 'string',
|
|
1017
|
+
description: 'Quote status: draft, sent, viewed, accepted, rejected, expired',
|
|
1018
|
+
examples: ['draft', 'sent', 'viewed', 'accepted', 'rejected', 'expired'],
|
|
1019
|
+
},
|
|
1020
|
+
// Financials
|
|
1021
|
+
subtotal: {
|
|
1022
|
+
type: 'number',
|
|
1023
|
+
description: 'Subtotal before tax and discount',
|
|
1024
|
+
},
|
|
1025
|
+
discount: {
|
|
1026
|
+
type: 'number',
|
|
1027
|
+
optional: true,
|
|
1028
|
+
description: 'Discount amount',
|
|
1029
|
+
},
|
|
1030
|
+
discountPercent: {
|
|
1031
|
+
type: 'number',
|
|
1032
|
+
optional: true,
|
|
1033
|
+
description: 'Discount percentage',
|
|
1034
|
+
},
|
|
1035
|
+
tax: {
|
|
1036
|
+
type: 'number',
|
|
1037
|
+
optional: true,
|
|
1038
|
+
description: 'Tax amount',
|
|
1039
|
+
},
|
|
1040
|
+
taxPercent: {
|
|
1041
|
+
type: 'number',
|
|
1042
|
+
optional: true,
|
|
1043
|
+
description: 'Tax percentage',
|
|
1044
|
+
},
|
|
1045
|
+
total: {
|
|
1046
|
+
type: 'number',
|
|
1047
|
+
description: 'Total amount',
|
|
1048
|
+
},
|
|
1049
|
+
currency: {
|
|
1050
|
+
type: 'string',
|
|
1051
|
+
optional: true,
|
|
1052
|
+
description: 'Currency code (ISO 4217)',
|
|
1053
|
+
examples: ['USD', 'EUR', 'GBP', 'CAD', 'AUD'],
|
|
1054
|
+
},
|
|
1055
|
+
// Terms
|
|
1056
|
+
validUntil: {
|
|
1057
|
+
type: 'date',
|
|
1058
|
+
optional: true,
|
|
1059
|
+
description: 'Quote expiration date',
|
|
1060
|
+
},
|
|
1061
|
+
terms: {
|
|
1062
|
+
type: 'string',
|
|
1063
|
+
optional: true,
|
|
1064
|
+
description: 'Terms and conditions',
|
|
1065
|
+
},
|
|
1066
|
+
paymentTerms: {
|
|
1067
|
+
type: 'string',
|
|
1068
|
+
optional: true,
|
|
1069
|
+
description: 'Payment terms: net-30, net-60, due-on-receipt',
|
|
1070
|
+
examples: ['net-30', 'net-60', 'net-90', 'due-on-receipt'],
|
|
1071
|
+
},
|
|
1072
|
+
// Tracking
|
|
1073
|
+
sentAt: {
|
|
1074
|
+
type: 'datetime',
|
|
1075
|
+
optional: true,
|
|
1076
|
+
description: 'When the quote was sent',
|
|
1077
|
+
},
|
|
1078
|
+
viewedAt: {
|
|
1079
|
+
type: 'datetime',
|
|
1080
|
+
optional: true,
|
|
1081
|
+
description: 'When the quote was first viewed',
|
|
1082
|
+
},
|
|
1083
|
+
acceptedAt: {
|
|
1084
|
+
type: 'datetime',
|
|
1085
|
+
optional: true,
|
|
1086
|
+
description: 'When the quote was accepted',
|
|
1087
|
+
},
|
|
1088
|
+
// Document
|
|
1089
|
+
documentUrl: {
|
|
1090
|
+
type: 'url',
|
|
1091
|
+
optional: true,
|
|
1092
|
+
description: 'URL to the quote document (PDF)',
|
|
1093
|
+
},
|
|
1094
|
+
publicUrl: {
|
|
1095
|
+
type: 'url',
|
|
1096
|
+
optional: true,
|
|
1097
|
+
description: 'Public URL for customer to view quote',
|
|
1098
|
+
},
|
|
1099
|
+
// Notes
|
|
1100
|
+
notes: {
|
|
1101
|
+
type: 'string',
|
|
1102
|
+
optional: true,
|
|
1103
|
+
description: 'Internal notes about the quote',
|
|
1104
|
+
},
|
|
1105
|
+
},
|
|
1106
|
+
relationships: {
|
|
1107
|
+
deal: {
|
|
1108
|
+
type: 'Deal',
|
|
1109
|
+
required: false,
|
|
1110
|
+
backref: 'quotes',
|
|
1111
|
+
description: 'Deal this quote is for',
|
|
1112
|
+
},
|
|
1113
|
+
account: {
|
|
1114
|
+
type: 'Account',
|
|
1115
|
+
required: false,
|
|
1116
|
+
backref: 'quotes',
|
|
1117
|
+
description: 'Account receiving this quote',
|
|
1118
|
+
},
|
|
1119
|
+
owner: {
|
|
1120
|
+
type: 'Contact',
|
|
1121
|
+
description: 'Sales rep who created the quote',
|
|
1122
|
+
},
|
|
1123
|
+
lineItems: {
|
|
1124
|
+
type: 'QuoteLineItem[]',
|
|
1125
|
+
backref: 'quote',
|
|
1126
|
+
description: 'Line items in this quote',
|
|
1127
|
+
},
|
|
1128
|
+
contact: {
|
|
1129
|
+
type: 'Contact',
|
|
1130
|
+
required: false,
|
|
1131
|
+
description: 'Primary contact for this quote',
|
|
1132
|
+
},
|
|
1133
|
+
},
|
|
1134
|
+
actions: [
|
|
1135
|
+
'create',
|
|
1136
|
+
'update',
|
|
1137
|
+
'delete',
|
|
1138
|
+
'send',
|
|
1139
|
+
'resend',
|
|
1140
|
+
'accept',
|
|
1141
|
+
'reject',
|
|
1142
|
+
'expire',
|
|
1143
|
+
'clone',
|
|
1144
|
+
'generatePdf',
|
|
1145
|
+
'addLineItem',
|
|
1146
|
+
'removeLineItem',
|
|
1147
|
+
'applyDiscount',
|
|
1148
|
+
],
|
|
1149
|
+
events: [
|
|
1150
|
+
'created',
|
|
1151
|
+
'updated',
|
|
1152
|
+
'deleted',
|
|
1153
|
+
'sent',
|
|
1154
|
+
'resent',
|
|
1155
|
+
'viewed',
|
|
1156
|
+
'accepted',
|
|
1157
|
+
'rejected',
|
|
1158
|
+
'expired',
|
|
1159
|
+
'cloned',
|
|
1160
|
+
'pdfGenerated',
|
|
1161
|
+
'lineItemAdded',
|
|
1162
|
+
'lineItemRemoved',
|
|
1163
|
+
'discountApplied',
|
|
1164
|
+
],
|
|
1165
|
+
};
|
|
1166
|
+
/**
|
|
1167
|
+
* QuoteLineItem entity
|
|
1168
|
+
*
|
|
1169
|
+
* Represents a single line item on a quote
|
|
1170
|
+
*/
|
|
1171
|
+
export const QuoteLineItem = {
|
|
1172
|
+
singular: 'quote line item',
|
|
1173
|
+
plural: 'quote line items',
|
|
1174
|
+
description: 'A line item on a sales quote',
|
|
1175
|
+
properties: {
|
|
1176
|
+
description: {
|
|
1177
|
+
type: 'string',
|
|
1178
|
+
description: 'Item description',
|
|
1179
|
+
},
|
|
1180
|
+
quantity: {
|
|
1181
|
+
type: 'number',
|
|
1182
|
+
description: 'Quantity',
|
|
1183
|
+
},
|
|
1184
|
+
unitPrice: {
|
|
1185
|
+
type: 'number',
|
|
1186
|
+
description: 'Price per unit',
|
|
1187
|
+
},
|
|
1188
|
+
discount: {
|
|
1189
|
+
type: 'number',
|
|
1190
|
+
optional: true,
|
|
1191
|
+
description: 'Discount amount per unit',
|
|
1192
|
+
},
|
|
1193
|
+
discountPercent: {
|
|
1194
|
+
type: 'number',
|
|
1195
|
+
optional: true,
|
|
1196
|
+
description: 'Discount percentage',
|
|
1197
|
+
},
|
|
1198
|
+
total: {
|
|
1199
|
+
type: 'number',
|
|
1200
|
+
description: 'Total line item amount (quantity * unitPrice - discount)',
|
|
1201
|
+
},
|
|
1202
|
+
order: {
|
|
1203
|
+
type: 'number',
|
|
1204
|
+
optional: true,
|
|
1205
|
+
description: 'Display order',
|
|
1206
|
+
},
|
|
1207
|
+
},
|
|
1208
|
+
relationships: {
|
|
1209
|
+
quote: {
|
|
1210
|
+
type: 'Quote',
|
|
1211
|
+
backref: 'lineItems',
|
|
1212
|
+
description: 'Quote this line item belongs to',
|
|
1213
|
+
},
|
|
1214
|
+
product: {
|
|
1215
|
+
type: 'Product',
|
|
1216
|
+
required: false,
|
|
1217
|
+
description: 'Product being sold (if applicable)',
|
|
1218
|
+
},
|
|
1219
|
+
},
|
|
1220
|
+
actions: ['create', 'update', 'delete', 'reorder'],
|
|
1221
|
+
events: ['created', 'updated', 'deleted', 'reordered'],
|
|
1222
|
+
};
|
|
1223
|
+
/**
|
|
1224
|
+
* Product entity
|
|
1225
|
+
*
|
|
1226
|
+
* Represents a product or service that can be sold
|
|
1227
|
+
*/
|
|
1228
|
+
export const Product = {
|
|
1229
|
+
singular: 'product',
|
|
1230
|
+
plural: 'products',
|
|
1231
|
+
description: 'A product or service that can be sold',
|
|
1232
|
+
properties: {
|
|
1233
|
+
// Identity
|
|
1234
|
+
name: {
|
|
1235
|
+
type: 'string',
|
|
1236
|
+
description: 'Product name',
|
|
1237
|
+
},
|
|
1238
|
+
sku: {
|
|
1239
|
+
type: 'string',
|
|
1240
|
+
optional: true,
|
|
1241
|
+
description: 'Stock keeping unit (SKU)',
|
|
1242
|
+
},
|
|
1243
|
+
code: {
|
|
1244
|
+
type: 'string',
|
|
1245
|
+
optional: true,
|
|
1246
|
+
description: 'Product code',
|
|
1247
|
+
},
|
|
1248
|
+
description: {
|
|
1249
|
+
type: 'string',
|
|
1250
|
+
optional: true,
|
|
1251
|
+
description: 'Product description',
|
|
1252
|
+
},
|
|
1253
|
+
// Categorization
|
|
1254
|
+
category: {
|
|
1255
|
+
type: 'string',
|
|
1256
|
+
optional: true,
|
|
1257
|
+
description: 'Product category',
|
|
1258
|
+
},
|
|
1259
|
+
type: {
|
|
1260
|
+
type: 'string',
|
|
1261
|
+
optional: true,
|
|
1262
|
+
description: 'Product type: physical, service, subscription, digital',
|
|
1263
|
+
examples: ['physical', 'service', 'subscription', 'digital'],
|
|
1264
|
+
},
|
|
1265
|
+
// Pricing
|
|
1266
|
+
price: {
|
|
1267
|
+
type: 'number',
|
|
1268
|
+
description: 'Base price',
|
|
1269
|
+
},
|
|
1270
|
+
cost: {
|
|
1271
|
+
type: 'number',
|
|
1272
|
+
optional: true,
|
|
1273
|
+
description: 'Cost of goods sold',
|
|
1274
|
+
},
|
|
1275
|
+
currency: {
|
|
1276
|
+
type: 'string',
|
|
1277
|
+
optional: true,
|
|
1278
|
+
description: 'Currency code (ISO 4217)',
|
|
1279
|
+
examples: ['USD', 'EUR', 'GBP', 'CAD', 'AUD'],
|
|
1280
|
+
},
|
|
1281
|
+
priceUnit: {
|
|
1282
|
+
type: 'string',
|
|
1283
|
+
optional: true,
|
|
1284
|
+
description: 'Pricing unit: unit, hour, day, month, year',
|
|
1285
|
+
examples: ['unit', 'hour', 'day', 'month', 'year'],
|
|
1286
|
+
},
|
|
1287
|
+
// Status
|
|
1288
|
+
isActive: {
|
|
1289
|
+
type: 'boolean',
|
|
1290
|
+
optional: true,
|
|
1291
|
+
description: 'Whether the product is active/available',
|
|
1292
|
+
},
|
|
1293
|
+
isRecurring: {
|
|
1294
|
+
type: 'boolean',
|
|
1295
|
+
optional: true,
|
|
1296
|
+
description: 'Whether this is a recurring/subscription product',
|
|
1297
|
+
},
|
|
1298
|
+
isTaxable: {
|
|
1299
|
+
type: 'boolean',
|
|
1300
|
+
optional: true,
|
|
1301
|
+
description: 'Whether the product is taxable',
|
|
1302
|
+
},
|
|
1303
|
+
// Inventory (if applicable)
|
|
1304
|
+
stock: {
|
|
1305
|
+
type: 'number',
|
|
1306
|
+
optional: true,
|
|
1307
|
+
description: 'Current stock quantity',
|
|
1308
|
+
},
|
|
1309
|
+
reorderPoint: {
|
|
1310
|
+
type: 'number',
|
|
1311
|
+
optional: true,
|
|
1312
|
+
description: 'Inventory level triggering reorder',
|
|
1313
|
+
},
|
|
1314
|
+
// Metadata
|
|
1315
|
+
tags: {
|
|
1316
|
+
type: 'string',
|
|
1317
|
+
array: true,
|
|
1318
|
+
optional: true,
|
|
1319
|
+
description: 'Product tags',
|
|
1320
|
+
},
|
|
1321
|
+
imageUrl: {
|
|
1322
|
+
type: 'url',
|
|
1323
|
+
optional: true,
|
|
1324
|
+
description: 'Product image URL',
|
|
1325
|
+
},
|
|
1326
|
+
},
|
|
1327
|
+
relationships: {
|
|
1328
|
+
deals: {
|
|
1329
|
+
type: 'Deal[]',
|
|
1330
|
+
description: 'Deals including this product',
|
|
1331
|
+
},
|
|
1332
|
+
},
|
|
1333
|
+
actions: [
|
|
1334
|
+
'create',
|
|
1335
|
+
'update',
|
|
1336
|
+
'delete',
|
|
1337
|
+
'activate',
|
|
1338
|
+
'deactivate',
|
|
1339
|
+
'adjustPrice',
|
|
1340
|
+
'updateStock',
|
|
1341
|
+
'reorder',
|
|
1342
|
+
],
|
|
1343
|
+
events: [
|
|
1344
|
+
'created',
|
|
1345
|
+
'updated',
|
|
1346
|
+
'deleted',
|
|
1347
|
+
'activated',
|
|
1348
|
+
'deactivated',
|
|
1349
|
+
'priceAdjusted',
|
|
1350
|
+
'stockUpdated',
|
|
1351
|
+
'reordered',
|
|
1352
|
+
],
|
|
1353
|
+
};
|
|
1354
|
+
// =============================================================================
|
|
1355
|
+
// Export all CRM entities
|
|
1356
|
+
// =============================================================================
|
|
1357
|
+
/**
|
|
1358
|
+
* All CRM/Sales entity types
|
|
1359
|
+
*/
|
|
1360
|
+
export const CRMEntities = {
|
|
1361
|
+
// Core Entities
|
|
1362
|
+
Lead,
|
|
1363
|
+
Deal,
|
|
1364
|
+
Account,
|
|
1365
|
+
// Pipeline
|
|
1366
|
+
Pipeline,
|
|
1367
|
+
Stage,
|
|
1368
|
+
// Activities
|
|
1369
|
+
Activity,
|
|
1370
|
+
// Quotes & Products
|
|
1371
|
+
Quote,
|
|
1372
|
+
QuoteLineItem,
|
|
1373
|
+
Product,
|
|
1374
|
+
};
|
|
1375
|
+
/**
|
|
1376
|
+
* CRM Entity categories for organization
|
|
1377
|
+
*/
|
|
1378
|
+
export const CRMCategories = {
|
|
1379
|
+
leads: ['Lead'],
|
|
1380
|
+
opportunities: ['Deal'],
|
|
1381
|
+
accounts: ['Account'],
|
|
1382
|
+
pipeline: ['Pipeline', 'Stage'],
|
|
1383
|
+
activities: ['Activity'],
|
|
1384
|
+
quotes: ['Quote', 'QuoteLineItem'],
|
|
1385
|
+
products: ['Product'],
|
|
1386
|
+
};
|