@updraft-solutions/mcrit-sdk 0.20.5 → 0.21.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.
@@ -162,6 +162,17 @@ export const feeSchema = BaseModel.extend({
162
162
  valid_from: z.string(),
163
163
  });
164
164
 
165
+ export const provisionRuleSchema = z.object({
166
+ type: z.literal("provisionRule"),
167
+ id: z.number(),
168
+ company_id: z.number(),
169
+ crew_role: z.string(),
170
+ fee_id: z.number(),
171
+ fee: feeSchema.optional(),
172
+ created_at: z.string().nullable().optional(),
173
+ updated_at: z.string().nullable().optional(),
174
+ });
175
+
165
176
  export const feeCategoryOptionsSchema = z.object({
166
177
  categories: z.array(z.string()),
167
178
  subcategories: z.record(z.string(), z.array(z.string())),
@@ -964,6 +975,9 @@ export const billingProfileSchema = z.object({
964
975
  updated_at: z.string(),
965
976
  });
966
977
 
978
+ /** Which draft an expense item may join; provision = a company charging its instructors. */
979
+ export const invoiceKindSchema = z.enum(["standard", "provision"]);
980
+
967
981
  export const flightLogSchema = z.object({
968
982
  type: z.literal("flightLog"),
969
983
  id: z.number(),
@@ -1011,6 +1025,9 @@ export const flightLogSchema = z.object({
1011
1025
  to: z.string().nullable().optional(),
1012
1026
  costs: zMoneyObject.nullable().optional(),
1013
1027
  charge: zMoneyObject.nullable().optional(),
1028
+ // Which invoice kinds among this log's items are released (single payload only;
1029
+ // absent on list rows and on rows cached before the field existed).
1030
+ released_invoice_kinds: z.array(invoiceKindSchema).optional(),
1014
1031
  remarks: z.string().nullable().optional(),
1015
1032
  created_at: z.string(),
1016
1033
  updated_at: z.string(),
@@ -1025,6 +1042,8 @@ export const flightLogSchema = z.object({
1025
1042
  export const invoiceSchema = z.object({
1026
1043
  type: z.literal("invoice"),
1027
1044
  id: z.number(),
1045
+ // Optional: rows cached offline before this field existed must still parse.
1046
+ kind: invoiceKindSchema.optional(),
1028
1047
  title: z.string(),
1029
1048
  membership_id: z.number(),
1030
1049
  // List rows (InvoiceListResource) carry the identity-only membership; the
@@ -1571,6 +1590,7 @@ export const expenseItemSchema = z.object({
1571
1590
  model_id: z.number(),
1572
1591
  model_type: z.string(),
1573
1592
  identifier: z.string().nullable(),
1593
+ kind: invoiceKindSchema.optional(),
1574
1594
  // Provenance: the `prices` row this item was generated from. `price_id` is
1575
1595
  // always present (nullable FK); `price` only when the relation is
1576
1596
  // eager-loaded.
@@ -0,0 +1,47 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { expenseItemSchema, flightLogSchema, invoiceSchema, provisionRuleSchema } from "./models";
3
+
4
+ describe("invoice kinds", () => {
5
+ it("accepts the two kinds and tolerates a missing kind on cached rows", () => {
6
+ const base = {
7
+ type: "invoice",
8
+ id: 1,
9
+ title: "INVOICE",
10
+ membership_id: 2,
11
+ billing_profile_id: null,
12
+ created_at: "2026-10-13T10:00:00Z",
13
+ updated_at: "2026-10-13T10:00:00Z",
14
+ };
15
+ expect(invoiceSchema.safeParse({ ...base, kind: "provision" }).success).toBe(true);
16
+ expect(invoiceSchema.safeParse({ ...base }).success).toBe(true);
17
+ expect(invoiceSchema.safeParse({ ...base, kind: "other" }).success).toBe(false);
18
+ });
19
+
20
+ it("parses a provision rule with its embedded fee", () => {
21
+ const parsed = provisionRuleSchema.parse({
22
+ type: "provisionRule",
23
+ id: 1,
24
+ company_id: 3,
25
+ crew_role: "instructor",
26
+ fee_id: 9,
27
+ created_at: "2026-10-13T10:00:00Z",
28
+ updated_at: "2026-10-13T10:00:00Z",
29
+ });
30
+ expect(parsed.crew_role).toBe("instructor");
31
+ });
32
+
33
+ it("carries kind on expense items", () => {
34
+ const item = expenseItemSchema.shape.kind;
35
+ expect(item.safeParse("provision").success).toBe(true);
36
+ expect(item.safeParse(undefined).success).toBe(true);
37
+ });
38
+ });
39
+
40
+ describe("flight log released_invoice_kinds", () => {
41
+ it("accepts kinds and undefined, rejects unknown kinds", () => {
42
+ const f = flightLogSchema.shape.released_invoice_kinds;
43
+ expect(f.safeParse(["provision"]).success).toBe(true);
44
+ expect(f.safeParse(undefined).success).toBe(true);
45
+ expect(f.safeParse(["other"]).success).toBe(false);
46
+ });
47
+ });
@@ -120,6 +120,8 @@ export type ApproachType = z.infer<typeof ModelSchemas.approachTypeSchema>;
120
120
  export type Waypoint = z.infer<typeof ModelSchemas.waypointSchema>;
121
121
 
122
122
  // Financial Types
123
+ export type InvoiceKind = z.infer<typeof ModelSchemas.invoiceKindSchema>;
124
+ export type ProvisionRule = z.infer<typeof ModelSchemas.provisionRuleSchema>;
123
125
  export type Invoice = z.infer<typeof ModelSchemas.invoiceSchema>;
124
126
  export type Expense = z.infer<typeof ModelSchemas.expenseSchema>;
125
127
  export type ExpenseItem = z.infer<typeof ModelSchemas.expenseItemSchema>;