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