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.
Files changed (78) hide show
  1. package/.turbo/turbo-build.log +5 -0
  2. package/CHANGELOG.md +10 -0
  3. package/README.md +235 -225
  4. package/dist/client.d.ts +25 -0
  5. package/dist/client.d.ts.map +1 -0
  6. package/dist/client.js +103 -0
  7. package/dist/client.js.map +1 -0
  8. package/dist/endpoint.d.ts +102 -0
  9. package/dist/endpoint.d.ts.map +1 -0
  10. package/dist/endpoint.js +96 -0
  11. package/dist/endpoint.js.map +1 -0
  12. package/dist/entities/billing.d.ts +60 -0
  13. package/dist/entities/billing.d.ts.map +1 -0
  14. package/dist/entities/billing.js +954 -0
  15. package/dist/entities/billing.js.map +1 -0
  16. package/dist/entities/customers.d.ts +45 -0
  17. package/dist/entities/customers.d.ts.map +1 -0
  18. package/dist/entities/customers.js +679 -0
  19. package/dist/entities/customers.js.map +1 -0
  20. package/dist/entities/delivery.d.ts +59 -0
  21. package/dist/entities/delivery.d.ts.map +1 -0
  22. package/dist/entities/delivery.js +890 -0
  23. package/dist/entities/delivery.js.map +1 -0
  24. package/dist/entities/index.d.ts +114 -0
  25. package/dist/entities/index.d.ts.map +1 -0
  26. package/dist/entities/index.js +89 -0
  27. package/dist/entities/index.js.map +1 -0
  28. package/dist/entities/operations.d.ts +59 -0
  29. package/dist/entities/operations.d.ts.map +1 -0
  30. package/dist/entities/operations.js +1010 -0
  31. package/dist/entities/operations.js.map +1 -0
  32. package/dist/entities/orchestration.d.ts +52 -0
  33. package/dist/entities/orchestration.d.ts.map +1 -0
  34. package/dist/entities/orchestration.js +883 -0
  35. package/dist/entities/orchestration.js.map +1 -0
  36. package/dist/entities/services.d.ts +50 -0
  37. package/dist/entities/services.d.ts.map +1 -0
  38. package/dist/entities/services.js +805 -0
  39. package/dist/entities/services.js.map +1 -0
  40. package/dist/helpers.d.ts +362 -0
  41. package/dist/helpers.d.ts.map +1 -0
  42. package/dist/helpers.js +400 -0
  43. package/dist/helpers.js.map +1 -0
  44. package/dist/index.d.ts +17 -215
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +18 -172
  47. package/dist/index.js.map +1 -0
  48. package/dist/provider.d.ts +85 -0
  49. package/dist/provider.d.ts.map +1 -0
  50. package/dist/provider.js +158 -0
  51. package/dist/provider.js.map +1 -0
  52. package/dist/service.d.ts +43 -0
  53. package/dist/service.d.ts.map +1 -0
  54. package/dist/service.js +206 -0
  55. package/dist/service.js.map +1 -0
  56. package/dist/types.d.ts +469 -0
  57. package/dist/types.d.ts.map +1 -0
  58. package/dist/types.js +5 -0
  59. package/dist/types.js.map +1 -0
  60. package/examples/client-usage.ts +82 -0
  61. package/examples/translation-service.ts +227 -0
  62. package/package.json +24 -38
  63. package/src/client.ts +132 -0
  64. package/src/endpoint.ts +144 -0
  65. package/src/entities/billing.ts +1037 -0
  66. package/src/entities/customers.ts +740 -0
  67. package/src/entities/delivery.ts +974 -0
  68. package/src/entities/index.ts +157 -0
  69. package/src/entities/operations.ts +1099 -0
  70. package/src/entities/orchestration.ts +956 -0
  71. package/src/entities/services.ts +872 -0
  72. package/src/helpers.ts +474 -0
  73. package/src/index.ts +97 -0
  74. package/src/provider.ts +183 -0
  75. package/src/service.test.ts +195 -0
  76. package/src/service.ts +266 -0
  77. package/src/types.ts +543 -0
  78. package/tsconfig.json +9 -0
@@ -0,0 +1,1037 @@
1
+ /**
2
+ * Billing Entity Types (Nouns)
3
+ *
4
+ * Billing & commerce: ServiceQuote, ServiceOrder, ServiceSubscription, Usage, Invoice, Payment
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+
9
+ import type { Noun } from 'ai-database'
10
+
11
+ // =============================================================================
12
+ // ServiceQuote
13
+ // =============================================================================
14
+
15
+ /**
16
+ * ServiceQuote entity
17
+ *
18
+ * Price quote for a service.
19
+ */
20
+ export const ServiceQuote: Noun = {
21
+ singular: 'service-quote',
22
+ plural: 'service-quotes',
23
+ description: 'A price quote for a service',
24
+
25
+ properties: {
26
+ // Identity
27
+ id: {
28
+ type: 'string',
29
+ description: 'Quote ID',
30
+ },
31
+ number: {
32
+ type: 'string',
33
+ optional: true,
34
+ description: 'Quote number',
35
+ },
36
+
37
+ // Details
38
+ title: {
39
+ type: 'string',
40
+ optional: true,
41
+ description: 'Quote title',
42
+ },
43
+ description: {
44
+ type: 'string',
45
+ optional: true,
46
+ description: 'Quote description',
47
+ },
48
+ scope: {
49
+ type: 'string',
50
+ optional: true,
51
+ description: 'Scope of work',
52
+ },
53
+
54
+ // Line Items
55
+ lineItems: {
56
+ type: 'json',
57
+ optional: true,
58
+ description: 'Quote line items',
59
+ },
60
+
61
+ // Pricing
62
+ subtotal: {
63
+ type: 'number',
64
+ optional: true,
65
+ description: 'Subtotal before tax/discount',
66
+ },
67
+ discount: {
68
+ type: 'number',
69
+ optional: true,
70
+ description: 'Discount amount',
71
+ },
72
+ discountPercent: {
73
+ type: 'number',
74
+ optional: true,
75
+ description: 'Discount percentage',
76
+ },
77
+ tax: {
78
+ type: 'number',
79
+ optional: true,
80
+ description: 'Tax amount',
81
+ },
82
+ total: {
83
+ type: 'number',
84
+ description: 'Total quoted amount',
85
+ },
86
+ currency: {
87
+ type: 'string',
88
+ optional: true,
89
+ description: 'Currency code',
90
+ },
91
+
92
+ // Terms
93
+ paymentTerms: {
94
+ type: 'string',
95
+ optional: true,
96
+ description: 'Payment terms',
97
+ examples: ['net-30', 'net-60', 'due-on-receipt', 'milestone', 'upfront'],
98
+ },
99
+ deliveryTerms: {
100
+ type: 'string',
101
+ optional: true,
102
+ description: 'Delivery terms',
103
+ },
104
+
105
+ // Validity
106
+ validFrom: {
107
+ type: 'date',
108
+ optional: true,
109
+ description: 'Valid from date',
110
+ },
111
+ validUntil: {
112
+ type: 'date',
113
+ optional: true,
114
+ description: 'Valid until date',
115
+ },
116
+
117
+ // Acceptance
118
+ acceptedAt: {
119
+ type: 'date',
120
+ optional: true,
121
+ description: 'Acceptance date',
122
+ },
123
+ acceptedBy: {
124
+ type: 'string',
125
+ optional: true,
126
+ description: 'Accepted by',
127
+ },
128
+
129
+ // Status
130
+ status: {
131
+ type: 'string',
132
+ description: 'Quote status',
133
+ examples: ['draft', 'sent', 'viewed', 'accepted', 'rejected', 'expired', 'superseded'],
134
+ },
135
+ },
136
+
137
+ relationships: {
138
+ service: {
139
+ type: 'ProductizedService',
140
+ description: 'Quoted service',
141
+ },
142
+ offering: {
143
+ type: 'ServiceOffering',
144
+ required: false,
145
+ description: 'Service offering',
146
+ },
147
+ customer: {
148
+ type: 'ServiceCustomer',
149
+ description: 'Customer',
150
+ },
151
+ order: {
152
+ type: 'ServiceOrder',
153
+ required: false,
154
+ description: 'Resulting order',
155
+ },
156
+ },
157
+
158
+ actions: [
159
+ 'create',
160
+ 'update',
161
+ 'send',
162
+ 'resend',
163
+ 'accept',
164
+ 'reject',
165
+ 'expire',
166
+ 'supersede',
167
+ ],
168
+
169
+ events: [
170
+ 'created',
171
+ 'updated',
172
+ 'sent',
173
+ 'viewed',
174
+ 'accepted',
175
+ 'rejected',
176
+ 'expired',
177
+ 'superseded',
178
+ ],
179
+ }
180
+
181
+ // =============================================================================
182
+ // ServiceOrder
183
+ // =============================================================================
184
+
185
+ /**
186
+ * ServiceOrder entity
187
+ *
188
+ * Customer order for a service.
189
+ */
190
+ export const ServiceOrder: Noun = {
191
+ singular: 'service-order',
192
+ plural: 'service-orders',
193
+ description: 'A customer order for a service',
194
+
195
+ properties: {
196
+ // Identity
197
+ id: {
198
+ type: 'string',
199
+ description: 'Order ID',
200
+ },
201
+ orderNumber: {
202
+ type: 'string',
203
+ optional: true,
204
+ description: 'Order number',
205
+ },
206
+
207
+ // Details
208
+ description: {
209
+ type: 'string',
210
+ optional: true,
211
+ description: 'Order description',
212
+ },
213
+ requirements: {
214
+ type: 'json',
215
+ optional: true,
216
+ description: 'Customer requirements',
217
+ },
218
+ notes: {
219
+ type: 'string',
220
+ optional: true,
221
+ description: 'Order notes',
222
+ },
223
+
224
+ // Line Items
225
+ lineItems: {
226
+ type: 'json',
227
+ optional: true,
228
+ description: 'Order line items',
229
+ },
230
+ quantity: {
231
+ type: 'number',
232
+ optional: true,
233
+ description: 'Quantity ordered',
234
+ },
235
+
236
+ // Pricing
237
+ subtotal: {
238
+ type: 'number',
239
+ optional: true,
240
+ description: 'Subtotal',
241
+ },
242
+ discount: {
243
+ type: 'number',
244
+ optional: true,
245
+ description: 'Discount amount',
246
+ },
247
+ tax: {
248
+ type: 'number',
249
+ optional: true,
250
+ description: 'Tax amount',
251
+ },
252
+ total: {
253
+ type: 'number',
254
+ description: 'Total amount',
255
+ },
256
+ currency: {
257
+ type: 'string',
258
+ optional: true,
259
+ description: 'Currency code',
260
+ },
261
+
262
+ // Delivery
263
+ deliveryMethod: {
264
+ type: 'string',
265
+ optional: true,
266
+ description: 'Delivery method',
267
+ },
268
+ expectedDelivery: {
269
+ type: 'date',
270
+ optional: true,
271
+ description: 'Expected delivery date',
272
+ },
273
+ actualDelivery: {
274
+ type: 'date',
275
+ optional: true,
276
+ description: 'Actual delivery date',
277
+ },
278
+
279
+ // Priority
280
+ priority: {
281
+ type: 'string',
282
+ optional: true,
283
+ description: 'Order priority',
284
+ examples: ['standard', 'rush', 'express', 'critical'],
285
+ },
286
+
287
+ // Dates
288
+ orderedAt: {
289
+ type: 'date',
290
+ optional: true,
291
+ description: 'Order date',
292
+ },
293
+ completedAt: {
294
+ type: 'date',
295
+ optional: true,
296
+ description: 'Completion date',
297
+ },
298
+
299
+ // Status
300
+ status: {
301
+ type: 'string',
302
+ description: 'Order status',
303
+ examples: ['pending', 'confirmed', 'processing', 'in-progress', 'review', 'completed', 'delivered', 'cancelled', 'refunded'],
304
+ },
305
+ fulfillmentStatus: {
306
+ type: 'string',
307
+ optional: true,
308
+ description: 'Fulfillment status',
309
+ examples: ['unfulfilled', 'partial', 'fulfilled'],
310
+ },
311
+ paymentStatus: {
312
+ type: 'string',
313
+ optional: true,
314
+ description: 'Payment status',
315
+ examples: ['unpaid', 'partial', 'paid', 'refunded'],
316
+ },
317
+ },
318
+
319
+ relationships: {
320
+ service: {
321
+ type: 'ProductizedService',
322
+ description: 'Service ordered',
323
+ },
324
+ offering: {
325
+ type: 'ServiceOffering',
326
+ required: false,
327
+ description: 'Service offering',
328
+ },
329
+ customer: {
330
+ type: 'ServiceCustomer',
331
+ description: 'Customer',
332
+ },
333
+ quote: {
334
+ type: 'ServiceQuote',
335
+ required: false,
336
+ description: 'Source quote',
337
+ },
338
+ executions: {
339
+ type: 'ServiceExecution[]',
340
+ description: 'Service executions',
341
+ },
342
+ invoices: {
343
+ type: 'Invoice[]',
344
+ description: 'Related invoices',
345
+ },
346
+ },
347
+
348
+ actions: [
349
+ 'create',
350
+ 'confirm',
351
+ 'process',
352
+ 'start',
353
+ 'complete',
354
+ 'deliver',
355
+ 'cancel',
356
+ 'refund',
357
+ ],
358
+
359
+ events: [
360
+ 'created',
361
+ 'confirmed',
362
+ 'processing',
363
+ 'started',
364
+ 'completed',
365
+ 'delivered',
366
+ 'cancelled',
367
+ 'refunded',
368
+ ],
369
+ }
370
+
371
+ // =============================================================================
372
+ // ServiceSubscription
373
+ // =============================================================================
374
+
375
+ /**
376
+ * ServiceSubscription entity
377
+ *
378
+ * Recurring service subscription.
379
+ */
380
+ export const ServiceSubscription: Noun = {
381
+ singular: 'service-subscription',
382
+ plural: 'service-subscriptions',
383
+ description: 'A recurring subscription to a service',
384
+
385
+ properties: {
386
+ // Identity
387
+ id: {
388
+ type: 'string',
389
+ description: 'Subscription ID',
390
+ },
391
+
392
+ // Billing
393
+ billingCycle: {
394
+ type: 'string',
395
+ description: 'Billing cycle',
396
+ examples: ['monthly', 'quarterly', 'yearly'],
397
+ },
398
+ price: {
399
+ type: 'number',
400
+ description: 'Subscription price',
401
+ },
402
+ currency: {
403
+ type: 'string',
404
+ optional: true,
405
+ description: 'Currency code',
406
+ },
407
+
408
+ // Period
409
+ currentPeriodStart: {
410
+ type: 'date',
411
+ optional: true,
412
+ description: 'Current period start',
413
+ },
414
+ currentPeriodEnd: {
415
+ type: 'date',
416
+ optional: true,
417
+ description: 'Current period end',
418
+ },
419
+ nextBillingDate: {
420
+ type: 'date',
421
+ optional: true,
422
+ description: 'Next billing date',
423
+ },
424
+
425
+ // Trial
426
+ trialStart: {
427
+ type: 'date',
428
+ optional: true,
429
+ description: 'Trial start date',
430
+ },
431
+ trialEnd: {
432
+ type: 'date',
433
+ optional: true,
434
+ description: 'Trial end date',
435
+ },
436
+ onTrial: {
437
+ type: 'boolean',
438
+ optional: true,
439
+ description: 'Currently on trial',
440
+ },
441
+
442
+ // Usage
443
+ usageThisPeriod: {
444
+ type: 'json',
445
+ optional: true,
446
+ description: 'Usage in current period',
447
+ },
448
+ usageLimits: {
449
+ type: 'json',
450
+ optional: true,
451
+ description: 'Usage limits',
452
+ },
453
+
454
+ // Entitlements
455
+ entitlements: {
456
+ type: 'string',
457
+ array: true,
458
+ optional: true,
459
+ description: 'Active entitlements',
460
+ },
461
+
462
+ // Cancellation
463
+ cancelAtPeriodEnd: {
464
+ type: 'boolean',
465
+ optional: true,
466
+ description: 'Cancel at period end',
467
+ },
468
+ cancelledAt: {
469
+ type: 'date',
470
+ optional: true,
471
+ description: 'Cancellation date',
472
+ },
473
+ cancellationReason: {
474
+ type: 'string',
475
+ optional: true,
476
+ description: 'Cancellation reason',
477
+ },
478
+
479
+ // Dates
480
+ startedAt: {
481
+ type: 'date',
482
+ optional: true,
483
+ description: 'Subscription start',
484
+ },
485
+ endedAt: {
486
+ type: 'date',
487
+ optional: true,
488
+ description: 'Subscription end',
489
+ },
490
+
491
+ // Status
492
+ status: {
493
+ type: 'string',
494
+ description: 'Subscription status',
495
+ examples: ['trialing', 'active', 'past_due', 'paused', 'cancelled', 'expired'],
496
+ },
497
+ },
498
+
499
+ relationships: {
500
+ service: {
501
+ type: 'ProductizedService',
502
+ description: 'Service subscribed to',
503
+ },
504
+ plan: {
505
+ type: 'ServicePlan',
506
+ description: 'Subscription plan',
507
+ },
508
+ customer: {
509
+ type: 'ServiceCustomer',
510
+ description: 'Customer',
511
+ },
512
+ invoices: {
513
+ type: 'Invoice[]',
514
+ description: 'Subscription invoices',
515
+ },
516
+ payments: {
517
+ type: 'Payment[]',
518
+ description: 'Subscription payments',
519
+ },
520
+ },
521
+
522
+ actions: [
523
+ 'create',
524
+ 'activate',
525
+ 'pause',
526
+ 'resume',
527
+ 'upgrade',
528
+ 'downgrade',
529
+ 'cancel',
530
+ 'renew',
531
+ ],
532
+
533
+ events: [
534
+ 'created',
535
+ 'activated',
536
+ 'paused',
537
+ 'resumed',
538
+ 'upgraded',
539
+ 'downgraded',
540
+ 'cancelled',
541
+ 'renewed',
542
+ 'trialEnded',
543
+ ],
544
+ }
545
+
546
+ // =============================================================================
547
+ // Usage
548
+ // =============================================================================
549
+
550
+ /**
551
+ * Usage entity
552
+ *
553
+ * Service usage tracking record.
554
+ */
555
+ export const Usage: Noun = {
556
+ singular: 'usage',
557
+ plural: 'usages',
558
+ description: 'A service usage tracking record',
559
+
560
+ properties: {
561
+ // Identity
562
+ id: {
563
+ type: 'string',
564
+ description: 'Usage record ID',
565
+ },
566
+
567
+ // Resource
568
+ resource: {
569
+ type: 'string',
570
+ description: 'Resource used',
571
+ },
572
+ resourceType: {
573
+ type: 'string',
574
+ optional: true,
575
+ description: 'Resource type',
576
+ examples: ['api-call', 'execution', 'storage', 'compute', 'tokens', 'bandwidth'],
577
+ },
578
+
579
+ // Quantity
580
+ quantity: {
581
+ type: 'number',
582
+ description: 'Usage quantity',
583
+ },
584
+ unit: {
585
+ type: 'string',
586
+ optional: true,
587
+ description: 'Unit of measure',
588
+ examples: ['requests', 'minutes', 'gb', 'tokens', 'executions'],
589
+ },
590
+
591
+ // Time
592
+ timestamp: {
593
+ type: 'date',
594
+ description: 'Usage timestamp',
595
+ },
596
+ periodStart: {
597
+ type: 'date',
598
+ optional: true,
599
+ description: 'Period start',
600
+ },
601
+ periodEnd: {
602
+ type: 'date',
603
+ optional: true,
604
+ description: 'Period end',
605
+ },
606
+
607
+ // Cost
608
+ unitCost: {
609
+ type: 'number',
610
+ optional: true,
611
+ description: 'Cost per unit',
612
+ },
613
+ totalCost: {
614
+ type: 'number',
615
+ optional: true,
616
+ description: 'Total cost',
617
+ },
618
+ currency: {
619
+ type: 'string',
620
+ optional: true,
621
+ description: 'Currency code',
622
+ },
623
+
624
+ // Context
625
+ metadata: {
626
+ type: 'json',
627
+ optional: true,
628
+ description: 'Usage metadata',
629
+ },
630
+ requestId: {
631
+ type: 'string',
632
+ optional: true,
633
+ description: 'Related request ID',
634
+ },
635
+
636
+ // Billing
637
+ billed: {
638
+ type: 'boolean',
639
+ optional: true,
640
+ description: 'Has been billed',
641
+ },
642
+ invoiceId: {
643
+ type: 'string',
644
+ optional: true,
645
+ description: 'Related invoice ID',
646
+ },
647
+
648
+ // Status
649
+ status: {
650
+ type: 'string',
651
+ description: 'Usage status',
652
+ examples: ['recorded', 'aggregated', 'billed', 'disputed'],
653
+ },
654
+ },
655
+
656
+ relationships: {
657
+ customer: {
658
+ type: 'ServiceCustomer',
659
+ description: 'Customer',
660
+ },
661
+ subscription: {
662
+ type: 'ServiceSubscription',
663
+ required: false,
664
+ description: 'Related subscription',
665
+ },
666
+ execution: {
667
+ type: 'ServiceExecution',
668
+ required: false,
669
+ description: 'Related execution',
670
+ },
671
+ },
672
+
673
+ actions: [
674
+ 'record',
675
+ 'aggregate',
676
+ 'bill',
677
+ 'dispute',
678
+ 'adjust',
679
+ ],
680
+
681
+ events: [
682
+ 'recorded',
683
+ 'aggregated',
684
+ 'billed',
685
+ 'disputed',
686
+ 'adjusted',
687
+ ],
688
+ }
689
+
690
+ // =============================================================================
691
+ // Invoice
692
+ // =============================================================================
693
+
694
+ /**
695
+ * Invoice entity
696
+ *
697
+ * Billing invoice.
698
+ */
699
+ export const Invoice: Noun = {
700
+ singular: 'invoice',
701
+ plural: 'invoices',
702
+ description: 'A billing invoice',
703
+
704
+ properties: {
705
+ // Identity
706
+ id: {
707
+ type: 'string',
708
+ description: 'Invoice ID',
709
+ },
710
+ number: {
711
+ type: 'string',
712
+ optional: true,
713
+ description: 'Invoice number',
714
+ },
715
+
716
+ // Details
717
+ description: {
718
+ type: 'string',
719
+ optional: true,
720
+ description: 'Invoice description',
721
+ },
722
+ lineItems: {
723
+ type: 'json',
724
+ optional: true,
725
+ description: 'Invoice line items',
726
+ },
727
+
728
+ // Amounts
729
+ subtotal: {
730
+ type: 'number',
731
+ optional: true,
732
+ description: 'Subtotal',
733
+ },
734
+ discount: {
735
+ type: 'number',
736
+ optional: true,
737
+ description: 'Discount amount',
738
+ },
739
+ tax: {
740
+ type: 'number',
741
+ optional: true,
742
+ description: 'Tax amount',
743
+ },
744
+ total: {
745
+ type: 'number',
746
+ description: 'Total amount',
747
+ },
748
+ amountDue: {
749
+ type: 'number',
750
+ optional: true,
751
+ description: 'Amount due',
752
+ },
753
+ amountPaid: {
754
+ type: 'number',
755
+ optional: true,
756
+ description: 'Amount paid',
757
+ },
758
+ currency: {
759
+ type: 'string',
760
+ optional: true,
761
+ description: 'Currency code',
762
+ },
763
+
764
+ // Period
765
+ periodStart: {
766
+ type: 'date',
767
+ optional: true,
768
+ description: 'Billing period start',
769
+ },
770
+ periodEnd: {
771
+ type: 'date',
772
+ optional: true,
773
+ description: 'Billing period end',
774
+ },
775
+
776
+ // Dates
777
+ issuedAt: {
778
+ type: 'date',
779
+ optional: true,
780
+ description: 'Issue date',
781
+ },
782
+ dueDate: {
783
+ type: 'date',
784
+ optional: true,
785
+ description: 'Due date',
786
+ },
787
+ paidAt: {
788
+ type: 'date',
789
+ optional: true,
790
+ description: 'Payment date',
791
+ },
792
+
793
+ // Delivery
794
+ sentAt: {
795
+ type: 'date',
796
+ optional: true,
797
+ description: 'Sent date',
798
+ },
799
+ sentTo: {
800
+ type: 'string',
801
+ optional: true,
802
+ description: 'Sent to email',
803
+ },
804
+
805
+ // PDF
806
+ pdfUrl: {
807
+ type: 'string',
808
+ optional: true,
809
+ description: 'PDF download URL',
810
+ },
811
+
812
+ // Status
813
+ status: {
814
+ type: 'string',
815
+ description: 'Invoice status',
816
+ examples: ['draft', 'open', 'sent', 'paid', 'partial', 'overdue', 'void', 'uncollectible'],
817
+ },
818
+ },
819
+
820
+ relationships: {
821
+ customer: {
822
+ type: 'ServiceCustomer',
823
+ description: 'Customer',
824
+ },
825
+ subscription: {
826
+ type: 'ServiceSubscription',
827
+ required: false,
828
+ description: 'Related subscription',
829
+ },
830
+ order: {
831
+ type: 'ServiceOrder',
832
+ required: false,
833
+ description: 'Related order',
834
+ },
835
+ payments: {
836
+ type: 'Payment[]',
837
+ description: 'Invoice payments',
838
+ },
839
+ },
840
+
841
+ actions: [
842
+ 'create',
843
+ 'finalize',
844
+ 'send',
845
+ 'pay',
846
+ 'void',
847
+ 'markUncollectible',
848
+ 'refund',
849
+ ],
850
+
851
+ events: [
852
+ 'created',
853
+ 'finalized',
854
+ 'sent',
855
+ 'paid',
856
+ 'voided',
857
+ 'markedUncollectible',
858
+ 'refunded',
859
+ ],
860
+ }
861
+
862
+ // =============================================================================
863
+ // Payment
864
+ // =============================================================================
865
+
866
+ /**
867
+ * Payment entity
868
+ *
869
+ * Payment record.
870
+ */
871
+ export const Payment: Noun = {
872
+ singular: 'payment',
873
+ plural: 'payments',
874
+ description: 'A payment record',
875
+
876
+ properties: {
877
+ // Identity
878
+ id: {
879
+ type: 'string',
880
+ description: 'Payment ID',
881
+ },
882
+ externalId: {
883
+ type: 'string',
884
+ optional: true,
885
+ description: 'External payment ID (Stripe, etc.)',
886
+ },
887
+
888
+ // Amount
889
+ amount: {
890
+ type: 'number',
891
+ description: 'Payment amount',
892
+ },
893
+ currency: {
894
+ type: 'string',
895
+ optional: true,
896
+ description: 'Currency code',
897
+ },
898
+ fee: {
899
+ type: 'number',
900
+ optional: true,
901
+ description: 'Processing fee',
902
+ },
903
+ netAmount: {
904
+ type: 'number',
905
+ optional: true,
906
+ description: 'Net amount after fees',
907
+ },
908
+
909
+ // Method
910
+ method: {
911
+ type: 'string',
912
+ description: 'Payment method',
913
+ examples: ['card', 'bank_transfer', 'paypal', 'crypto', 'invoice', 'check'],
914
+ },
915
+ methodDetails: {
916
+ type: 'json',
917
+ optional: true,
918
+ description: 'Method details (card last 4, etc.)',
919
+ },
920
+
921
+ // Provider
922
+ provider: {
923
+ type: 'string',
924
+ optional: true,
925
+ description: 'Payment provider',
926
+ examples: ['stripe', 'paypal', 'square', 'manual'],
927
+ },
928
+
929
+ // Timing
930
+ createdAt: {
931
+ type: 'date',
932
+ optional: true,
933
+ description: 'Creation date',
934
+ },
935
+ processedAt: {
936
+ type: 'date',
937
+ optional: true,
938
+ description: 'Processing date',
939
+ },
940
+ settledAt: {
941
+ type: 'date',
942
+ optional: true,
943
+ description: 'Settlement date',
944
+ },
945
+
946
+ // Refund
947
+ refundedAmount: {
948
+ type: 'number',
949
+ optional: true,
950
+ description: 'Amount refunded',
951
+ },
952
+ refundedAt: {
953
+ type: 'date',
954
+ optional: true,
955
+ description: 'Refund date',
956
+ },
957
+ refundReason: {
958
+ type: 'string',
959
+ optional: true,
960
+ description: 'Refund reason',
961
+ },
962
+
963
+ // Failure
964
+ failureCode: {
965
+ type: 'string',
966
+ optional: true,
967
+ description: 'Failure code',
968
+ },
969
+ failureMessage: {
970
+ type: 'string',
971
+ optional: true,
972
+ description: 'Failure message',
973
+ },
974
+
975
+ // Status
976
+ status: {
977
+ type: 'string',
978
+ description: 'Payment status',
979
+ examples: ['pending', 'processing', 'succeeded', 'failed', 'refunded', 'disputed'],
980
+ },
981
+ },
982
+
983
+ relationships: {
984
+ customer: {
985
+ type: 'ServiceCustomer',
986
+ description: 'Customer',
987
+ },
988
+ invoice: {
989
+ type: 'Invoice',
990
+ required: false,
991
+ description: 'Related invoice',
992
+ },
993
+ subscription: {
994
+ type: 'ServiceSubscription',
995
+ required: false,
996
+ description: 'Related subscription',
997
+ },
998
+ },
999
+
1000
+ actions: [
1001
+ 'create',
1002
+ 'process',
1003
+ 'capture',
1004
+ 'refund',
1005
+ 'dispute',
1006
+ ],
1007
+
1008
+ events: [
1009
+ 'created',
1010
+ 'processing',
1011
+ 'succeeded',
1012
+ 'failed',
1013
+ 'refunded',
1014
+ 'disputed',
1015
+ ],
1016
+ }
1017
+
1018
+ // =============================================================================
1019
+ // Exports
1020
+ // =============================================================================
1021
+
1022
+ export const BillingEntities = {
1023
+ ServiceQuote,
1024
+ ServiceOrder,
1025
+ ServiceSubscription,
1026
+ Usage,
1027
+ Invoice,
1028
+ Payment,
1029
+ }
1030
+
1031
+ export const BillingCategories = {
1032
+ quotes: ['ServiceQuote'],
1033
+ orders: ['ServiceOrder'],
1034
+ subscriptions: ['ServiceSubscription'],
1035
+ usage: ['Usage'],
1036
+ invoicing: ['Invoice', 'Payment'],
1037
+ } as const