services-as-software 0.1.0 → 2.0.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/.turbo/turbo-build.log +5 -0
- package/CHANGELOG.md +10 -0
- package/README.md +235 -225
- package/dist/client.d.ts +25 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +103 -0
- package/dist/client.js.map +1 -0
- package/dist/endpoint.d.ts +102 -0
- package/dist/endpoint.d.ts.map +1 -0
- package/dist/endpoint.js +96 -0
- package/dist/endpoint.js.map +1 -0
- package/dist/entities/billing.d.ts +60 -0
- package/dist/entities/billing.d.ts.map +1 -0
- package/dist/entities/billing.js +954 -0
- package/dist/entities/billing.js.map +1 -0
- package/dist/entities/customers.d.ts +45 -0
- package/dist/entities/customers.d.ts.map +1 -0
- package/dist/entities/customers.js +679 -0
- package/dist/entities/customers.js.map +1 -0
- package/dist/entities/delivery.d.ts +59 -0
- package/dist/entities/delivery.d.ts.map +1 -0
- package/dist/entities/delivery.js +890 -0
- package/dist/entities/delivery.js.map +1 -0
- package/dist/entities/index.d.ts +114 -0
- package/dist/entities/index.d.ts.map +1 -0
- package/dist/entities/index.js +89 -0
- package/dist/entities/index.js.map +1 -0
- package/dist/entities/operations.d.ts +59 -0
- package/dist/entities/operations.d.ts.map +1 -0
- package/dist/entities/operations.js +1010 -0
- package/dist/entities/operations.js.map +1 -0
- package/dist/entities/orchestration.d.ts +52 -0
- package/dist/entities/orchestration.d.ts.map +1 -0
- package/dist/entities/orchestration.js +883 -0
- package/dist/entities/orchestration.js.map +1 -0
- package/dist/entities/services.d.ts +50 -0
- package/dist/entities/services.d.ts.map +1 -0
- package/dist/entities/services.js +805 -0
- package/dist/entities/services.js.map +1 -0
- package/dist/helpers.d.ts +362 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +400 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.d.ts +17 -215
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -172
- package/dist/index.js.map +1 -0
- package/dist/provider.d.ts +85 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +158 -0
- package/dist/provider.js.map +1 -0
- package/dist/service.d.ts +43 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +206 -0
- package/dist/service.js.map +1 -0
- package/dist/types.d.ts +469 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/examples/client-usage.ts +82 -0
- package/examples/translation-service.ts +227 -0
- package/package.json +24 -38
- package/src/client.ts +132 -0
- package/src/endpoint.ts +144 -0
- package/src/entities/billing.ts +1037 -0
- package/src/entities/customers.ts +740 -0
- package/src/entities/delivery.ts +974 -0
- package/src/entities/index.ts +157 -0
- package/src/entities/operations.ts +1099 -0
- package/src/entities/orchestration.ts +956 -0
- package/src/entities/services.ts +872 -0
- package/src/helpers.ts +474 -0
- package/src/index.ts +97 -0
- package/src/provider.ts +183 -0
- package/src/service.test.ts +195 -0
- package/src/service.ts +266 -0
- package/src/types.ts +543 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,740 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Customer Entity Types (Nouns)
|
|
3
|
+
*
|
|
4
|
+
* Customer entities: ServiceCustomer, ServiceEntitlement, CustomerUsage, CustomerSegment
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { Noun } from 'ai-database'
|
|
10
|
+
|
|
11
|
+
// =============================================================================
|
|
12
|
+
// ServiceCustomer
|
|
13
|
+
// =============================================================================
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* ServiceCustomer entity
|
|
17
|
+
*
|
|
18
|
+
* Customer of a productized service.
|
|
19
|
+
*/
|
|
20
|
+
export const ServiceCustomer: Noun = {
|
|
21
|
+
singular: 'service-customer',
|
|
22
|
+
plural: 'service-customers',
|
|
23
|
+
description: 'A customer of a productized service',
|
|
24
|
+
|
|
25
|
+
properties: {
|
|
26
|
+
// Identity
|
|
27
|
+
id: {
|
|
28
|
+
type: 'string',
|
|
29
|
+
description: 'Customer ID',
|
|
30
|
+
},
|
|
31
|
+
externalId: {
|
|
32
|
+
type: 'string',
|
|
33
|
+
optional: true,
|
|
34
|
+
description: 'External system ID',
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
// Contact
|
|
38
|
+
name: {
|
|
39
|
+
type: 'string',
|
|
40
|
+
description: 'Customer name',
|
|
41
|
+
},
|
|
42
|
+
email: {
|
|
43
|
+
type: 'string',
|
|
44
|
+
optional: true,
|
|
45
|
+
description: 'Email address',
|
|
46
|
+
},
|
|
47
|
+
phone: {
|
|
48
|
+
type: 'string',
|
|
49
|
+
optional: true,
|
|
50
|
+
description: 'Phone number',
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
// Type
|
|
54
|
+
type: {
|
|
55
|
+
type: 'string',
|
|
56
|
+
description: 'Customer type',
|
|
57
|
+
examples: ['individual', 'business', 'enterprise', 'partner'],
|
|
58
|
+
},
|
|
59
|
+
company: {
|
|
60
|
+
type: 'string',
|
|
61
|
+
optional: true,
|
|
62
|
+
description: 'Company name',
|
|
63
|
+
},
|
|
64
|
+
industry: {
|
|
65
|
+
type: 'string',
|
|
66
|
+
optional: true,
|
|
67
|
+
description: 'Industry',
|
|
68
|
+
},
|
|
69
|
+
size: {
|
|
70
|
+
type: 'string',
|
|
71
|
+
optional: true,
|
|
72
|
+
description: 'Company size',
|
|
73
|
+
examples: ['startup', 'smb', 'mid-market', 'enterprise'],
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
// Location
|
|
77
|
+
country: {
|
|
78
|
+
type: 'string',
|
|
79
|
+
optional: true,
|
|
80
|
+
description: 'Country code',
|
|
81
|
+
},
|
|
82
|
+
timezone: {
|
|
83
|
+
type: 'string',
|
|
84
|
+
optional: true,
|
|
85
|
+
description: 'Timezone',
|
|
86
|
+
},
|
|
87
|
+
locale: {
|
|
88
|
+
type: 'string',
|
|
89
|
+
optional: true,
|
|
90
|
+
description: 'Locale',
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
// Billing
|
|
94
|
+
billingEmail: {
|
|
95
|
+
type: 'string',
|
|
96
|
+
optional: true,
|
|
97
|
+
description: 'Billing email',
|
|
98
|
+
},
|
|
99
|
+
billingAddress: {
|
|
100
|
+
type: 'json',
|
|
101
|
+
optional: true,
|
|
102
|
+
description: 'Billing address',
|
|
103
|
+
},
|
|
104
|
+
taxId: {
|
|
105
|
+
type: 'string',
|
|
106
|
+
optional: true,
|
|
107
|
+
description: 'Tax ID',
|
|
108
|
+
},
|
|
109
|
+
defaultCurrency: {
|
|
110
|
+
type: 'string',
|
|
111
|
+
optional: true,
|
|
112
|
+
description: 'Default currency',
|
|
113
|
+
},
|
|
114
|
+
paymentMethod: {
|
|
115
|
+
type: 'string',
|
|
116
|
+
optional: true,
|
|
117
|
+
description: 'Default payment method',
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
// Account Health
|
|
121
|
+
healthScore: {
|
|
122
|
+
type: 'number',
|
|
123
|
+
optional: true,
|
|
124
|
+
description: 'Account health score (0-100)',
|
|
125
|
+
},
|
|
126
|
+
riskLevel: {
|
|
127
|
+
type: 'string',
|
|
128
|
+
optional: true,
|
|
129
|
+
description: 'Churn risk level',
|
|
130
|
+
examples: ['low', 'medium', 'high', 'critical'],
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
// Value
|
|
134
|
+
lifetimeValue: {
|
|
135
|
+
type: 'number',
|
|
136
|
+
optional: true,
|
|
137
|
+
description: 'Lifetime value',
|
|
138
|
+
},
|
|
139
|
+
monthlySpend: {
|
|
140
|
+
type: 'number',
|
|
141
|
+
optional: true,
|
|
142
|
+
description: 'Monthly spend',
|
|
143
|
+
},
|
|
144
|
+
|
|
145
|
+
// Engagement
|
|
146
|
+
lastActivityAt: {
|
|
147
|
+
type: 'date',
|
|
148
|
+
optional: true,
|
|
149
|
+
description: 'Last activity date',
|
|
150
|
+
},
|
|
151
|
+
engagementScore: {
|
|
152
|
+
type: 'number',
|
|
153
|
+
optional: true,
|
|
154
|
+
description: 'Engagement score',
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
// Dates
|
|
158
|
+
createdAt: {
|
|
159
|
+
type: 'date',
|
|
160
|
+
optional: true,
|
|
161
|
+
description: 'Creation date',
|
|
162
|
+
},
|
|
163
|
+
firstPurchaseAt: {
|
|
164
|
+
type: 'date',
|
|
165
|
+
optional: true,
|
|
166
|
+
description: 'First purchase date',
|
|
167
|
+
},
|
|
168
|
+
|
|
169
|
+
// Status
|
|
170
|
+
status: {
|
|
171
|
+
type: 'string',
|
|
172
|
+
description: 'Customer status',
|
|
173
|
+
examples: ['prospect', 'active', 'at-risk', 'churned', 'reactivated'],
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
|
|
177
|
+
relationships: {
|
|
178
|
+
subscriptions: {
|
|
179
|
+
type: 'ServiceSubscription[]',
|
|
180
|
+
description: 'Active subscriptions',
|
|
181
|
+
},
|
|
182
|
+
orders: {
|
|
183
|
+
type: 'ServiceOrder[]',
|
|
184
|
+
description: 'Order history',
|
|
185
|
+
},
|
|
186
|
+
invoices: {
|
|
187
|
+
type: 'Invoice[]',
|
|
188
|
+
description: 'Invoices',
|
|
189
|
+
},
|
|
190
|
+
entitlements: {
|
|
191
|
+
type: 'ServiceEntitlement[]',
|
|
192
|
+
description: 'Current entitlements',
|
|
193
|
+
},
|
|
194
|
+
tickets: {
|
|
195
|
+
type: 'SupportTicket[]',
|
|
196
|
+
description: 'Support tickets',
|
|
197
|
+
},
|
|
198
|
+
segment: {
|
|
199
|
+
type: 'CustomerSegment',
|
|
200
|
+
required: false,
|
|
201
|
+
description: 'Customer segment',
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
|
|
205
|
+
actions: [
|
|
206
|
+
'create',
|
|
207
|
+
'update',
|
|
208
|
+
'activate',
|
|
209
|
+
'suspend',
|
|
210
|
+
'reactivate',
|
|
211
|
+
'churn',
|
|
212
|
+
'merge',
|
|
213
|
+
'delete',
|
|
214
|
+
],
|
|
215
|
+
|
|
216
|
+
events: [
|
|
217
|
+
'created',
|
|
218
|
+
'updated',
|
|
219
|
+
'activated',
|
|
220
|
+
'suspended',
|
|
221
|
+
'reactivated',
|
|
222
|
+
'churned',
|
|
223
|
+
'merged',
|
|
224
|
+
'deleted',
|
|
225
|
+
],
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// =============================================================================
|
|
229
|
+
// ServiceEntitlement
|
|
230
|
+
// =============================================================================
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* ServiceEntitlement entity
|
|
234
|
+
*
|
|
235
|
+
* What a customer is entitled to.
|
|
236
|
+
*/
|
|
237
|
+
export const ServiceEntitlement: Noun = {
|
|
238
|
+
singular: 'service-entitlement',
|
|
239
|
+
plural: 'service-entitlements',
|
|
240
|
+
description: 'What a customer is entitled to use or access',
|
|
241
|
+
|
|
242
|
+
properties: {
|
|
243
|
+
// Identity
|
|
244
|
+
id: {
|
|
245
|
+
type: 'string',
|
|
246
|
+
description: 'Entitlement ID',
|
|
247
|
+
},
|
|
248
|
+
name: {
|
|
249
|
+
type: 'string',
|
|
250
|
+
description: 'Entitlement name',
|
|
251
|
+
},
|
|
252
|
+
description: {
|
|
253
|
+
type: 'string',
|
|
254
|
+
optional: true,
|
|
255
|
+
description: 'Entitlement description',
|
|
256
|
+
},
|
|
257
|
+
|
|
258
|
+
// Type
|
|
259
|
+
type: {
|
|
260
|
+
type: 'string',
|
|
261
|
+
description: 'Entitlement type',
|
|
262
|
+
examples: ['feature', 'quota', 'access', 'capability', 'addon'],
|
|
263
|
+
},
|
|
264
|
+
code: {
|
|
265
|
+
type: 'string',
|
|
266
|
+
optional: true,
|
|
267
|
+
description: 'Entitlement code for checking',
|
|
268
|
+
},
|
|
269
|
+
|
|
270
|
+
// Value
|
|
271
|
+
value: {
|
|
272
|
+
type: 'json',
|
|
273
|
+
optional: true,
|
|
274
|
+
description: 'Entitlement value',
|
|
275
|
+
},
|
|
276
|
+
limit: {
|
|
277
|
+
type: 'number',
|
|
278
|
+
optional: true,
|
|
279
|
+
description: 'Usage limit',
|
|
280
|
+
},
|
|
281
|
+
unlimited: {
|
|
282
|
+
type: 'boolean',
|
|
283
|
+
optional: true,
|
|
284
|
+
description: 'Unlimited access',
|
|
285
|
+
},
|
|
286
|
+
|
|
287
|
+
// Usage
|
|
288
|
+
usedAmount: {
|
|
289
|
+
type: 'number',
|
|
290
|
+
optional: true,
|
|
291
|
+
description: 'Amount used',
|
|
292
|
+
},
|
|
293
|
+
remainingAmount: {
|
|
294
|
+
type: 'number',
|
|
295
|
+
optional: true,
|
|
296
|
+
description: 'Amount remaining',
|
|
297
|
+
},
|
|
298
|
+
usagePercent: {
|
|
299
|
+
type: 'number',
|
|
300
|
+
optional: true,
|
|
301
|
+
description: 'Usage percentage',
|
|
302
|
+
},
|
|
303
|
+
|
|
304
|
+
// Reset
|
|
305
|
+
resetPeriod: {
|
|
306
|
+
type: 'string',
|
|
307
|
+
optional: true,
|
|
308
|
+
description: 'Reset period',
|
|
309
|
+
examples: ['daily', 'weekly', 'monthly', 'yearly', 'never'],
|
|
310
|
+
},
|
|
311
|
+
resetAt: {
|
|
312
|
+
type: 'date',
|
|
313
|
+
optional: true,
|
|
314
|
+
description: 'Next reset date',
|
|
315
|
+
},
|
|
316
|
+
lastResetAt: {
|
|
317
|
+
type: 'date',
|
|
318
|
+
optional: true,
|
|
319
|
+
description: 'Last reset date',
|
|
320
|
+
},
|
|
321
|
+
|
|
322
|
+
// Source
|
|
323
|
+
source: {
|
|
324
|
+
type: 'string',
|
|
325
|
+
optional: true,
|
|
326
|
+
description: 'Entitlement source',
|
|
327
|
+
examples: ['plan', 'addon', 'trial', 'promotion', 'manual'],
|
|
328
|
+
},
|
|
329
|
+
sourceId: {
|
|
330
|
+
type: 'string',
|
|
331
|
+
optional: true,
|
|
332
|
+
description: 'Source ID (plan ID, etc.)',
|
|
333
|
+
},
|
|
334
|
+
|
|
335
|
+
// Validity
|
|
336
|
+
validFrom: {
|
|
337
|
+
type: 'date',
|
|
338
|
+
optional: true,
|
|
339
|
+
description: 'Valid from date',
|
|
340
|
+
},
|
|
341
|
+
validUntil: {
|
|
342
|
+
type: 'date',
|
|
343
|
+
optional: true,
|
|
344
|
+
description: 'Valid until date',
|
|
345
|
+
},
|
|
346
|
+
|
|
347
|
+
// Status
|
|
348
|
+
status: {
|
|
349
|
+
type: 'string',
|
|
350
|
+
description: 'Entitlement status',
|
|
351
|
+
examples: ['active', 'exhausted', 'expired', 'suspended', 'revoked'],
|
|
352
|
+
},
|
|
353
|
+
},
|
|
354
|
+
|
|
355
|
+
relationships: {
|
|
356
|
+
customer: {
|
|
357
|
+
type: 'ServiceCustomer',
|
|
358
|
+
description: 'Customer',
|
|
359
|
+
},
|
|
360
|
+
subscription: {
|
|
361
|
+
type: 'ServiceSubscription',
|
|
362
|
+
required: false,
|
|
363
|
+
description: 'Source subscription',
|
|
364
|
+
},
|
|
365
|
+
plan: {
|
|
366
|
+
type: 'ServicePlan',
|
|
367
|
+
required: false,
|
|
368
|
+
description: 'Source plan',
|
|
369
|
+
},
|
|
370
|
+
},
|
|
371
|
+
|
|
372
|
+
actions: [
|
|
373
|
+
'grant',
|
|
374
|
+
'update',
|
|
375
|
+
'consume',
|
|
376
|
+
'reset',
|
|
377
|
+
'suspend',
|
|
378
|
+
'revoke',
|
|
379
|
+
],
|
|
380
|
+
|
|
381
|
+
events: [
|
|
382
|
+
'granted',
|
|
383
|
+
'updated',
|
|
384
|
+
'consumed',
|
|
385
|
+
'reset',
|
|
386
|
+
'exhausted',
|
|
387
|
+
'suspended',
|
|
388
|
+
'revoked',
|
|
389
|
+
],
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// =============================================================================
|
|
393
|
+
// CustomerUsage
|
|
394
|
+
// =============================================================================
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* CustomerUsage entity
|
|
398
|
+
*
|
|
399
|
+
* Aggregated customer usage data.
|
|
400
|
+
*/
|
|
401
|
+
export const CustomerUsage: Noun = {
|
|
402
|
+
singular: 'customer-usage',
|
|
403
|
+
plural: 'customer-usages',
|
|
404
|
+
description: 'Aggregated usage data for a customer',
|
|
405
|
+
|
|
406
|
+
properties: {
|
|
407
|
+
// Identity
|
|
408
|
+
id: {
|
|
409
|
+
type: 'string',
|
|
410
|
+
description: 'Usage record ID',
|
|
411
|
+
},
|
|
412
|
+
|
|
413
|
+
// Period
|
|
414
|
+
periodType: {
|
|
415
|
+
type: 'string',
|
|
416
|
+
description: 'Period type',
|
|
417
|
+
examples: ['hour', 'day', 'week', 'month', 'quarter', 'year'],
|
|
418
|
+
},
|
|
419
|
+
periodStart: {
|
|
420
|
+
type: 'date',
|
|
421
|
+
description: 'Period start',
|
|
422
|
+
},
|
|
423
|
+
periodEnd: {
|
|
424
|
+
type: 'date',
|
|
425
|
+
description: 'Period end',
|
|
426
|
+
},
|
|
427
|
+
|
|
428
|
+
// Metrics
|
|
429
|
+
totalExecutions: {
|
|
430
|
+
type: 'number',
|
|
431
|
+
optional: true,
|
|
432
|
+
description: 'Total service executions',
|
|
433
|
+
},
|
|
434
|
+
successfulExecutions: {
|
|
435
|
+
type: 'number',
|
|
436
|
+
optional: true,
|
|
437
|
+
description: 'Successful executions',
|
|
438
|
+
},
|
|
439
|
+
failedExecutions: {
|
|
440
|
+
type: 'number',
|
|
441
|
+
optional: true,
|
|
442
|
+
description: 'Failed executions',
|
|
443
|
+
},
|
|
444
|
+
escalatedExecutions: {
|
|
445
|
+
type: 'number',
|
|
446
|
+
optional: true,
|
|
447
|
+
description: 'Escalated executions',
|
|
448
|
+
},
|
|
449
|
+
|
|
450
|
+
// Resource Usage
|
|
451
|
+
tokensUsed: {
|
|
452
|
+
type: 'number',
|
|
453
|
+
optional: true,
|
|
454
|
+
description: 'AI tokens used',
|
|
455
|
+
},
|
|
456
|
+
computeMinutes: {
|
|
457
|
+
type: 'number',
|
|
458
|
+
optional: true,
|
|
459
|
+
description: 'Compute minutes',
|
|
460
|
+
},
|
|
461
|
+
storageGB: {
|
|
462
|
+
type: 'number',
|
|
463
|
+
optional: true,
|
|
464
|
+
description: 'Storage used (GB)',
|
|
465
|
+
},
|
|
466
|
+
bandwidthGB: {
|
|
467
|
+
type: 'number',
|
|
468
|
+
optional: true,
|
|
469
|
+
description: 'Bandwidth used (GB)',
|
|
470
|
+
},
|
|
471
|
+
|
|
472
|
+
// API
|
|
473
|
+
apiCalls: {
|
|
474
|
+
type: 'number',
|
|
475
|
+
optional: true,
|
|
476
|
+
description: 'API calls',
|
|
477
|
+
},
|
|
478
|
+
webhookDeliveries: {
|
|
479
|
+
type: 'number',
|
|
480
|
+
optional: true,
|
|
481
|
+
description: 'Webhook deliveries',
|
|
482
|
+
},
|
|
483
|
+
|
|
484
|
+
// By Resource
|
|
485
|
+
usageByResource: {
|
|
486
|
+
type: 'json',
|
|
487
|
+
optional: true,
|
|
488
|
+
description: 'Usage breakdown by resource',
|
|
489
|
+
},
|
|
490
|
+
|
|
491
|
+
// Limits
|
|
492
|
+
quotaUsed: {
|
|
493
|
+
type: 'json',
|
|
494
|
+
optional: true,
|
|
495
|
+
description: 'Quota used',
|
|
496
|
+
},
|
|
497
|
+
quotaRemaining: {
|
|
498
|
+
type: 'json',
|
|
499
|
+
optional: true,
|
|
500
|
+
description: 'Quota remaining',
|
|
501
|
+
},
|
|
502
|
+
|
|
503
|
+
// Cost
|
|
504
|
+
estimatedCost: {
|
|
505
|
+
type: 'number',
|
|
506
|
+
optional: true,
|
|
507
|
+
description: 'Estimated cost',
|
|
508
|
+
},
|
|
509
|
+
currency: {
|
|
510
|
+
type: 'string',
|
|
511
|
+
optional: true,
|
|
512
|
+
description: 'Currency code',
|
|
513
|
+
},
|
|
514
|
+
|
|
515
|
+
// Comparison
|
|
516
|
+
changeFromPrevious: {
|
|
517
|
+
type: 'number',
|
|
518
|
+
optional: true,
|
|
519
|
+
description: 'Change from previous period (%)',
|
|
520
|
+
},
|
|
521
|
+
|
|
522
|
+
// Status
|
|
523
|
+
status: {
|
|
524
|
+
type: 'string',
|
|
525
|
+
description: 'Record status',
|
|
526
|
+
examples: ['partial', 'complete', 'finalized'],
|
|
527
|
+
},
|
|
528
|
+
},
|
|
529
|
+
|
|
530
|
+
relationships: {
|
|
531
|
+
customer: {
|
|
532
|
+
type: 'ServiceCustomer',
|
|
533
|
+
description: 'Customer',
|
|
534
|
+
},
|
|
535
|
+
subscription: {
|
|
536
|
+
type: 'ServiceSubscription',
|
|
537
|
+
required: false,
|
|
538
|
+
description: 'Related subscription',
|
|
539
|
+
},
|
|
540
|
+
},
|
|
541
|
+
|
|
542
|
+
actions: [
|
|
543
|
+
'record',
|
|
544
|
+
'aggregate',
|
|
545
|
+
'finalize',
|
|
546
|
+
],
|
|
547
|
+
|
|
548
|
+
events: [
|
|
549
|
+
'recorded',
|
|
550
|
+
'aggregated',
|
|
551
|
+
'finalized',
|
|
552
|
+
],
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
// =============================================================================
|
|
556
|
+
// CustomerSegment
|
|
557
|
+
// =============================================================================
|
|
558
|
+
|
|
559
|
+
/**
|
|
560
|
+
* CustomerSegment entity
|
|
561
|
+
*
|
|
562
|
+
* Customer segmentation.
|
|
563
|
+
*/
|
|
564
|
+
export const CustomerSegment: Noun = {
|
|
565
|
+
singular: 'customer-segment',
|
|
566
|
+
plural: 'customer-segments',
|
|
567
|
+
description: 'A segment grouping customers with similar characteristics',
|
|
568
|
+
|
|
569
|
+
properties: {
|
|
570
|
+
// Identity
|
|
571
|
+
name: {
|
|
572
|
+
type: 'string',
|
|
573
|
+
description: 'Segment name',
|
|
574
|
+
},
|
|
575
|
+
slug: {
|
|
576
|
+
type: 'string',
|
|
577
|
+
optional: true,
|
|
578
|
+
description: 'URL-friendly identifier',
|
|
579
|
+
},
|
|
580
|
+
description: {
|
|
581
|
+
type: 'string',
|
|
582
|
+
optional: true,
|
|
583
|
+
description: 'Segment description',
|
|
584
|
+
},
|
|
585
|
+
|
|
586
|
+
// Type
|
|
587
|
+
type: {
|
|
588
|
+
type: 'string',
|
|
589
|
+
description: 'Segment type',
|
|
590
|
+
examples: ['behavioral', 'demographic', 'value', 'engagement', 'lifecycle', 'custom'],
|
|
591
|
+
},
|
|
592
|
+
automated: {
|
|
593
|
+
type: 'boolean',
|
|
594
|
+
optional: true,
|
|
595
|
+
description: 'Automatically maintained',
|
|
596
|
+
},
|
|
597
|
+
|
|
598
|
+
// Criteria
|
|
599
|
+
criteria: {
|
|
600
|
+
type: 'json',
|
|
601
|
+
optional: true,
|
|
602
|
+
description: 'Segment criteria/rules',
|
|
603
|
+
},
|
|
604
|
+
criteriaDescription: {
|
|
605
|
+
type: 'string',
|
|
606
|
+
optional: true,
|
|
607
|
+
description: 'Human-readable criteria',
|
|
608
|
+
},
|
|
609
|
+
|
|
610
|
+
// Size
|
|
611
|
+
customerCount: {
|
|
612
|
+
type: 'number',
|
|
613
|
+
optional: true,
|
|
614
|
+
description: 'Number of customers',
|
|
615
|
+
},
|
|
616
|
+
percentOfTotal: {
|
|
617
|
+
type: 'number',
|
|
618
|
+
optional: true,
|
|
619
|
+
description: 'Percentage of total customers',
|
|
620
|
+
},
|
|
621
|
+
|
|
622
|
+
// Value
|
|
623
|
+
totalRevenue: {
|
|
624
|
+
type: 'number',
|
|
625
|
+
optional: true,
|
|
626
|
+
description: 'Total segment revenue',
|
|
627
|
+
},
|
|
628
|
+
avgRevenue: {
|
|
629
|
+
type: 'number',
|
|
630
|
+
optional: true,
|
|
631
|
+
description: 'Average revenue per customer',
|
|
632
|
+
},
|
|
633
|
+
avgLifetimeValue: {
|
|
634
|
+
type: 'number',
|
|
635
|
+
optional: true,
|
|
636
|
+
description: 'Average LTV',
|
|
637
|
+
},
|
|
638
|
+
|
|
639
|
+
// Behavior
|
|
640
|
+
avgEngagementScore: {
|
|
641
|
+
type: 'number',
|
|
642
|
+
optional: true,
|
|
643
|
+
description: 'Average engagement score',
|
|
644
|
+
},
|
|
645
|
+
avgUsage: {
|
|
646
|
+
type: 'number',
|
|
647
|
+
optional: true,
|
|
648
|
+
description: 'Average usage',
|
|
649
|
+
},
|
|
650
|
+
churnRate: {
|
|
651
|
+
type: 'number',
|
|
652
|
+
optional: true,
|
|
653
|
+
description: 'Segment churn rate',
|
|
654
|
+
},
|
|
655
|
+
|
|
656
|
+
// Targeting
|
|
657
|
+
targetable: {
|
|
658
|
+
type: 'boolean',
|
|
659
|
+
optional: true,
|
|
660
|
+
description: 'Can be targeted for campaigns',
|
|
661
|
+
},
|
|
662
|
+
priority: {
|
|
663
|
+
type: 'number',
|
|
664
|
+
optional: true,
|
|
665
|
+
description: 'Segment priority',
|
|
666
|
+
},
|
|
667
|
+
|
|
668
|
+
// Sync
|
|
669
|
+
lastSyncedAt: {
|
|
670
|
+
type: 'date',
|
|
671
|
+
optional: true,
|
|
672
|
+
description: 'Last membership sync',
|
|
673
|
+
},
|
|
674
|
+
syncFrequency: {
|
|
675
|
+
type: 'string',
|
|
676
|
+
optional: true,
|
|
677
|
+
description: 'Sync frequency',
|
|
678
|
+
examples: ['realtime', 'hourly', 'daily', 'weekly'],
|
|
679
|
+
},
|
|
680
|
+
|
|
681
|
+
// Status
|
|
682
|
+
status: {
|
|
683
|
+
type: 'string',
|
|
684
|
+
description: 'Segment status',
|
|
685
|
+
examples: ['active', 'inactive', 'archived'],
|
|
686
|
+
},
|
|
687
|
+
},
|
|
688
|
+
|
|
689
|
+
relationships: {
|
|
690
|
+
customers: {
|
|
691
|
+
type: 'ServiceCustomer[]',
|
|
692
|
+
description: 'Customers in segment',
|
|
693
|
+
},
|
|
694
|
+
parentSegment: {
|
|
695
|
+
type: 'CustomerSegment',
|
|
696
|
+
required: false,
|
|
697
|
+
description: 'Parent segment',
|
|
698
|
+
},
|
|
699
|
+
childSegments: {
|
|
700
|
+
type: 'CustomerSegment[]',
|
|
701
|
+
description: 'Child segments',
|
|
702
|
+
},
|
|
703
|
+
},
|
|
704
|
+
|
|
705
|
+
actions: [
|
|
706
|
+
'create',
|
|
707
|
+
'update',
|
|
708
|
+
'sync',
|
|
709
|
+
'addCustomer',
|
|
710
|
+
'removeCustomer',
|
|
711
|
+
'archive',
|
|
712
|
+
],
|
|
713
|
+
|
|
714
|
+
events: [
|
|
715
|
+
'created',
|
|
716
|
+
'updated',
|
|
717
|
+
'synced',
|
|
718
|
+
'customerAdded',
|
|
719
|
+
'customerRemoved',
|
|
720
|
+
'archived',
|
|
721
|
+
],
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
// =============================================================================
|
|
725
|
+
// Exports
|
|
726
|
+
// =============================================================================
|
|
727
|
+
|
|
728
|
+
export const CustomerEntities = {
|
|
729
|
+
ServiceCustomer,
|
|
730
|
+
ServiceEntitlement,
|
|
731
|
+
CustomerUsage,
|
|
732
|
+
CustomerSegment,
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
export const CustomerCategories = {
|
|
736
|
+
customers: ['ServiceCustomer'],
|
|
737
|
+
entitlements: ['ServiceEntitlement'],
|
|
738
|
+
usage: ['CustomerUsage'],
|
|
739
|
+
segments: ['CustomerSegment'],
|
|
740
|
+
} as const
|