@kohost/api-client 7.12.0 → 7.14.0

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 (57) hide show
  1. package/dist/.tsbuildinfo +1 -0
  2. package/dist/lib/index.d.ts +1 -1
  3. package/dist/lib/index.js +4 -2
  4. package/dist/lib/index.js.map +1 -1
  5. package/dist/lib/money.d.ts +21 -0
  6. package/dist/lib/money.js +29 -1
  7. package/dist/lib/money.js.map +1 -1
  8. package/dist/models/cost.d.ts +17 -0
  9. package/dist/models/cost.js +38 -0
  10. package/dist/models/cost.js.map +1 -0
  11. package/dist/models/emailMessage.js +2 -0
  12. package/dist/models/emailMessage.js.map +1 -1
  13. package/dist/models/index.d.ts +1 -0
  14. package/dist/models/index.js +3 -1
  15. package/dist/models/index.js.map +1 -1
  16. package/dist/schemas/bill.d.ts +14 -6
  17. package/dist/schemas/bill.js +14 -11
  18. package/dist/schemas/bill.js.map +1 -1
  19. package/dist/schemas/cost.d.ts +227 -0
  20. package/dist/schemas/cost.js +45 -0
  21. package/dist/schemas/cost.js.map +1 -0
  22. package/dist/schemas/costEntry.d.ts +222 -0
  23. package/dist/schemas/costEntry.js +162 -0
  24. package/dist/schemas/costEntry.js.map +1 -0
  25. package/dist/schemas/definitions.d.ts +1 -1
  26. package/dist/schemas/definitions.js +1 -0
  27. package/dist/schemas/definitions.js.map +1 -1
  28. package/dist/schemas/emailMessage.d.ts +12 -0
  29. package/dist/schemas/emailMessage.js +8 -0
  30. package/dist/schemas/emailMessage.js.map +1 -1
  31. package/dist/schemas/index.d.ts +7 -6
  32. package/dist/schemas/index.js +2 -1
  33. package/dist/schemas/ticket.d.ts +25 -26
  34. package/dist/schemas/ticket.js +60 -245
  35. package/dist/schemas/ticket.js.map +1 -1
  36. package/dist/useCases/createCost.d.ts +27 -0
  37. package/dist/useCases/createCost.js +47 -0
  38. package/dist/useCases/createCost.js.map +1 -0
  39. package/dist/useCases/editCost.d.ts +36 -0
  40. package/dist/useCases/editCost.js +47 -0
  41. package/dist/useCases/editCost.js.map +1 -0
  42. package/dist/useCases/index.d.ts +5 -0
  43. package/dist/useCases/index.js +11 -1
  44. package/dist/useCases/index.js.map +1 -1
  45. package/dist/useCases/reinstateCost.d.ts +36 -0
  46. package/dist/useCases/reinstateCost.js +47 -0
  47. package/dist/useCases/reinstateCost.js.map +1 -0
  48. package/dist/useCases/setCostInvoice.d.ts +36 -0
  49. package/dist/useCases/setCostInvoice.js +47 -0
  50. package/dist/useCases/setCostInvoice.js.map +1 -0
  51. package/dist/useCases/writeOffCost.d.ts +36 -0
  52. package/dist/useCases/writeOffCost.js +47 -0
  53. package/dist/useCases/writeOffCost.js.map +1 -0
  54. package/dist/validate.d.ts +23 -0
  55. package/dist/validate.js +4 -1
  56. package/dist/validate.js.map +1 -1
  57. package/package.json +1 -1
@@ -693,7 +693,7 @@ export declare const ticketSchema: {
693
693
  readonly amount: {
694
694
  readonly type: "integer";
695
695
  readonly minimum: 0;
696
- readonly description: "Customer price in integer cents.";
696
+ readonly description: "The amount in integer cents.";
697
697
  };
698
698
  readonly recordedBy: {
699
699
  readonly type: "string";
@@ -709,12 +709,12 @@ export declare const ticketSchema: {
709
709
  readonly type: "object";
710
710
  readonly additionalProperties: false;
711
711
  readonly required: readonly ["amount", "recordedBy", "recordedAt"];
712
- readonly description: "The vendor cost estimate phase of the entry.";
712
+ readonly description: string;
713
713
  readonly properties: {
714
714
  readonly amount: {
715
715
  readonly type: "integer";
716
716
  readonly minimum: 0;
717
- readonly description: "Vendor cost estimate in integer cents.";
717
+ readonly description: "The amount in integer cents.";
718
718
  };
719
719
  readonly recordedBy: {
720
720
  readonly type: "string";
@@ -730,12 +730,12 @@ export declare const ticketSchema: {
730
730
  readonly type: "object";
731
731
  readonly additionalProperties: false;
732
732
  readonly required: readonly ["amount", "recordedBy", "recordedAt"];
733
- readonly description: "The actual vendor cost phase of the entry, recorded after the work.";
733
+ readonly description: string;
734
734
  readonly properties: {
735
735
  readonly amount: {
736
736
  readonly type: "integer";
737
737
  readonly minimum: 0;
738
- readonly description: "Actual vendor cost in integer cents.";
738
+ readonly description: "The amount in integer cents.";
739
739
  };
740
740
  readonly recordedBy: {
741
741
  readonly type: "string";
@@ -754,40 +754,34 @@ export declare const ticketSchema: {
754
754
  readonly properties: {
755
755
  readonly percent: {
756
756
  readonly type: "number";
757
- readonly minimum: 0;
758
757
  readonly description: string;
759
758
  };
760
759
  readonly custom: {
761
760
  readonly type: "boolean";
762
761
  readonly default: false;
763
- readonly description: "Whether the percent was manually overridden rather than keyed from the configured markup tiers. Custom percents are never re-keyed on estimate edits.";
762
+ readonly description: string;
764
763
  };
765
764
  };
766
765
  };
767
- readonly vendorInvoices: {
768
- readonly type: "array";
769
- readonly items: {
770
- readonly $ref: "mediaFile.json";
771
- };
772
- readonly default: readonly [];
773
- readonly description: string;
774
- };
775
- readonly vendorInvoiceNumber: {
766
+ readonly vendorId: {
776
767
  readonly type: readonly ["string", "null"];
777
768
  readonly default: null;
778
769
  readonly description: string;
779
770
  };
780
- readonly vendorId: {
771
+ readonly categoryId: {
781
772
  readonly type: readonly ["string", "null"];
782
773
  readonly default: null;
783
774
  readonly description: string;
784
775
  };
785
- readonly workItemId: {
786
- readonly type: readonly ["string", "null"];
787
- readonly default: null;
776
+ readonly vendorInvoices: {
777
+ readonly type: "array";
778
+ readonly items: {
779
+ readonly $ref: "mediaFile.json";
780
+ };
781
+ readonly default: readonly [];
788
782
  readonly description: string;
789
783
  };
790
- readonly categoryId: {
784
+ readonly vendorInvoiceNumber: {
791
785
  readonly type: readonly ["string", "null"];
792
786
  readonly default: null;
793
787
  readonly description: string;
@@ -802,11 +796,6 @@ export declare const ticketSchema: {
802
796
  readonly default: false;
803
797
  readonly description: string;
804
798
  };
805
- readonly voided: {
806
- readonly type: "boolean";
807
- readonly default: false;
808
- readonly description: string;
809
- };
810
799
  readonly billingReview: {
811
800
  readonly type: "array";
812
801
  readonly default: readonly [];
@@ -851,6 +840,16 @@ export declare const ticketSchema: {
851
840
  };
852
841
  };
853
842
  };
843
+ readonly workItemId: {
844
+ readonly type: readonly ["string", "null"];
845
+ readonly default: null;
846
+ readonly description: string;
847
+ };
848
+ readonly voided: {
849
+ readonly type: "boolean";
850
+ readonly default: false;
851
+ readonly description: string;
852
+ };
854
853
  };
855
854
  }, {
856
855
  readonly type: "object";
@@ -1,3 +1,4 @@
1
+ import { costBillingReview, costEntryProperties, costEntryRequired } from "./costEntry.js";
1
2
  //#region .generated/schemas/ticket.ts
2
3
  const richTextInlineNodes = {
3
4
  type: "array",
@@ -91,6 +92,62 @@ const richTextListItemNode = {
91
92
  content: richTextInlineNodes
92
93
  }
93
94
  };
95
+ const richTextBulletListNode = {
96
+ type: "object",
97
+ additionalProperties: false,
98
+ required: ["type", "content"],
99
+ properties: {
100
+ type: {
101
+ type: "string",
102
+ enum: ["bulletList"]
103
+ },
104
+ content: {
105
+ type: "array",
106
+ minItems: 1,
107
+ items: richTextListItemNode
108
+ }
109
+ }
110
+ };
111
+ const richTextOrderedListNode = {
112
+ type: "object",
113
+ additionalProperties: false,
114
+ required: ["type", "content"],
115
+ properties: {
116
+ type: {
117
+ type: "string",
118
+ enum: ["orderedList"]
119
+ },
120
+ content: {
121
+ type: "array",
122
+ minItems: 1,
123
+ items: richTextListItemNode
124
+ }
125
+ }
126
+ };
127
+ const fullCostEntrySchema = {
128
+ type: "object",
129
+ additionalProperties: false,
130
+ required: costEntryRequired,
131
+ properties: {
132
+ ...costEntryProperties,
133
+ billingReview: costBillingReview([
134
+ "writtenOff",
135
+ "voided",
136
+ "reinstated",
137
+ "divergenceAcknowledged"
138
+ ]),
139
+ workItemId: {
140
+ type: ["string", "null"],
141
+ default: null,
142
+ description: "The Work item on this ticket that produced the cost. Many entries may name one visit, so a single trip's labor and materials can be itemized. Cleared when the Work item is removed — the money record outlives the scheduling record. Internal, redacted org-side."
143
+ },
144
+ voided: {
145
+ type: "boolean",
146
+ default: false,
147
+ description: "Server-maintained denormalization of billingReview (writtenOff pattern): true after a voided entry until a reinstated entry follows. A voided cost is withdrawn: it counts toward neither the approval gate nor financial completion and leaves the uninvoiced pool, but stays on the ticket so every viewer sees it was voided. Never set by clients."
148
+ }
149
+ }
150
+ };
94
151
  const ticketSchema = {
95
152
  $schema: "http://json-schema.org/draft-07/schema",
96
153
  $id: "ticket.json",
@@ -233,38 +290,8 @@ const ticketSchema = {
233
290
  description: "Rich-text block nodes (ADR 0012). Present = rich message: `body` is the server-derived plain-text projection of this tree, and the legacy text/mentions fields are not written.",
234
291
  items: { anyOf: [
235
292
  richTextParagraphNode,
236
- {
237
- type: "object",
238
- additionalProperties: false,
239
- required: ["type", "content"],
240
- properties: {
241
- type: {
242
- type: "string",
243
- enum: ["bulletList"]
244
- },
245
- content: {
246
- type: "array",
247
- minItems: 1,
248
- items: richTextListItemNode
249
- }
250
- }
251
- },
252
- {
253
- type: "object",
254
- additionalProperties: false,
255
- required: ["type", "content"],
256
- properties: {
257
- type: {
258
- type: "string",
259
- enum: ["orderedList"]
260
- },
261
- content: {
262
- type: "array",
263
- minItems: 1,
264
- items: richTextListItemNode
265
- }
266
- }
267
- }
293
+ richTextBulletListNode,
294
+ richTextOrderedListNode
268
295
  ] }
269
296
  },
270
297
  text: {
@@ -635,219 +662,7 @@ const ticketSchema = {
635
662
  type: "array",
636
663
  default: [],
637
664
  description: "Cost line items recorded on the ticket. Each entry stores the customer price and the vendor cost side by side and keeps them independent: the price is seeded from the estimate and markup at recording, and nothing about the vendor side moves it afterwards. Every entry arrives as either the full vendor shape or the redacted price-only shape depending on whether the viewer may see the cost split.",
638
- items: { oneOf: [{
639
- type: "object",
640
- additionalProperties: false,
641
- required: [
642
- "id",
643
- "description",
644
- "currency",
645
- "price",
646
- "estimate",
647
- "markup"
648
- ],
649
- properties: {
650
- id: {
651
- type: "string",
652
- description: "The ID of the cost entry."
653
- },
654
- description: {
655
- type: "string",
656
- description: "What the cost covers."
657
- },
658
- currency: {
659
- type: "string",
660
- default: "USD",
661
- description: "ISO 4217 currency code of the entry's amounts."
662
- },
663
- price: {
664
- type: "object",
665
- additionalProperties: false,
666
- required: [
667
- "amount",
668
- "recordedBy",
669
- "recordedAt"
670
- ],
671
- description: "The authoritative customer price of the entry — what the org is charged, what the approval gate totals, and what a bill line bills. Seeded at recording from the estimate and the markup, and from then on independent of all three: editing `estimate`, `actual`, or `markup` never moves it. Only an explicit price write does.",
672
- properties: {
673
- amount: {
674
- type: "integer",
675
- minimum: 0,
676
- description: "Customer price in integer cents."
677
- },
678
- recordedBy: {
679
- type: "string",
680
- description: "The ID of the user who recorded the amount."
681
- },
682
- recordedAt: {
683
- $ref: "definitions.json#/definitions/date",
684
- description: "When the amount was recorded."
685
- }
686
- }
687
- },
688
- estimate: {
689
- type: "object",
690
- additionalProperties: false,
691
- required: [
692
- "amount",
693
- "recordedBy",
694
- "recordedAt"
695
- ],
696
- description: "The vendor cost estimate phase of the entry.",
697
- properties: {
698
- amount: {
699
- type: "integer",
700
- minimum: 0,
701
- description: "Vendor cost estimate in integer cents."
702
- },
703
- recordedBy: {
704
- type: "string",
705
- description: "The ID of the user who recorded the amount."
706
- },
707
- recordedAt: {
708
- $ref: "definitions.json#/definitions/date",
709
- description: "When the amount was recorded."
710
- }
711
- }
712
- },
713
- actual: {
714
- type: "object",
715
- additionalProperties: false,
716
- required: [
717
- "amount",
718
- "recordedBy",
719
- "recordedAt"
720
- ],
721
- description: "The actual vendor cost phase of the entry, recorded after the work.",
722
- properties: {
723
- amount: {
724
- type: "integer",
725
- minimum: 0,
726
- description: "Actual vendor cost in integer cents."
727
- },
728
- recordedBy: {
729
- type: "string",
730
- description: "The ID of the user who recorded the amount."
731
- },
732
- recordedAt: {
733
- $ref: "definitions.json#/definitions/date",
734
- description: "When the amount was recorded."
735
- }
736
- }
737
- },
738
- markup: {
739
- type: "object",
740
- additionalProperties: false,
741
- required: ["percent"],
742
- properties: {
743
- percent: {
744
- type: "number",
745
- minimum: 0,
746
- description: "Markup percent the initial price was quoted at, uncapped. Context for how that quote was arrived at, not the source of truth for any amount: `price` is stored, so re-keying this percent prices nothing."
747
- },
748
- custom: {
749
- type: "boolean",
750
- default: false,
751
- description: "Whether the percent was manually overridden rather than keyed from the configured markup tiers. Custom percents are never re-keyed on estimate edits."
752
- }
753
- }
754
- },
755
- vendorInvoices: {
756
- type: "array",
757
- items: { $ref: "mediaFile.json" },
758
- default: [],
759
- description: "The vendor's paperwork backing the entry's amounts, attached around recording the actual (or later) — an invoice plus whatever came with it. Internal: the file-store cannot enforce roster-only reads, so the boundary is this field living on the full shape only — the redacted projection never carries it."
760
- },
761
- vendorInvoiceNumber: {
762
- type: ["string", "null"],
763
- default: null,
764
- description: "The vendor's own invoice number. Internal, redacted org-side like the rest of the cost split."
765
- },
766
- vendorId: {
767
- type: ["string", "null"],
768
- default: null,
769
- description: "The Vendor the cost came from. A plain reference — no rollups — recorded alongside the vendor invoice and redacted org-side with the rest of the cost split. Independent of `workItemId`: a vendor cost need not trace to a scheduled visit."
770
- },
771
- workItemId: {
772
- type: ["string", "null"],
773
- default: null,
774
- description: "The Work item on this ticket that produced the cost. Many entries may name one visit, so a single trip's labor and materials can be itemized. Cleared when the Work item is removed — the money record outlives the scheduling record. Internal, redacted org-side."
775
- },
776
- categoryId: {
777
- type: ["string", "null"],
778
- default: null,
779
- description: "The billing category classifying this cost, picked on the reconciliation pool before any bill claims the entry. `AddBillLine` snapshots it onto the claiming line, which owns its own category from then on. Internal, redacted org-side with the rest of the cost split."
780
- },
781
- billId: {
782
- type: ["string", "null"],
783
- default: null,
784
- description: "Backlink to the bill whose draft claimed this cost as a line. Written when a draft bill adds the line, cleared on line removal, draft delete, or bill void; a claimed cost leaves the uninvoiced pool, making double-invoicing structurally impossible. Server-maintained at the repository, never set by clients."
785
- },
786
- writtenOff: {
787
- type: "boolean",
788
- default: false,
789
- description: "Server-maintained denormalization of billingReview (approvalState pattern): true after a writtenOff entry until a reinstated entry follows. A written-off cost leaves the uninvoiced pool. Never set by clients."
790
- },
791
- voided: {
792
- type: "boolean",
793
- default: false,
794
- description: "Server-maintained denormalization of billingReview (writtenOff pattern): true after a voided entry until a reinstated entry follows. A voided cost is withdrawn: it counts toward neither the approval gate nor financial completion and leaves the uninvoiced pool, but stays on the ticket so every viewer sees it was voided. Never set by clients."
795
- },
796
- billingReview: {
797
- type: "array",
798
- default: [],
799
- description: "Append-only billing review history for the entry (approval-history pattern): reversible write-offs and voids, and billed-vs-price divergence acknowledgements. Internal, redacted org-side.",
800
- items: {
801
- type: "object",
802
- additionalProperties: false,
803
- required: [
804
- "id",
805
- "action",
806
- "performedAt"
807
- ],
808
- properties: {
809
- id: {
810
- type: "string",
811
- description: "The ID of the billing review entry."
812
- },
813
- action: {
814
- type: "string",
815
- enum: [
816
- "writtenOff",
817
- "voided",
818
- "reinstated",
819
- "divergenceAcknowledged"
820
- ]
821
- },
822
- performedBy: {
823
- type: ["string", "null"],
824
- default: null,
825
- description: "The ID of the user whose write appended this entry. Null when the write was not user-attributable."
826
- },
827
- performedAt: {
828
- $ref: "definitions.json#/definitions/date",
829
- description: "When the entry was appended."
830
- },
831
- note: {
832
- type: ["string", "null"],
833
- default: null,
834
- description: "Free-text rationale for the action."
835
- },
836
- billedAmount: {
837
- type: "integer",
838
- minimum: 0,
839
- description: "divergenceAcknowledged only: the amount a bill line already charged for this entry, in integer cents, frozen at ack time."
840
- },
841
- priceAmount: {
842
- type: "integer",
843
- minimum: 0,
844
- description: "divergenceAcknowledged only: the entry's stored customer price in integer cents at ack time. A divergence is a billed line that no longer matches the price behind it — a price corrected after the cost was claimed — so the ack silences this one pair and any later price move re-flags it. A vendor actual arriving after billing is not a divergence: it moves margin, not what the customer owes."
845
- }
846
- }
847
- }
848
- }
849
- }
850
- }, {
665
+ items: { oneOf: [fullCostEntrySchema, {
851
666
  type: "object",
852
667
  additionalProperties: false,
853
668
  required: [