@burdenoff/microfe-movethewheels 2026.1016.2 → 2026.1016.3

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 (31) hide show
  1. package/dist/components/freight-cost/FreightCommercialEditor.js +217 -0
  2. package/dist/components/freight-cost/FreightCommercialFactEditor.js +217 -0
  3. package/dist/components/freight-cost/FreightCommercialHistory.js +115 -0
  4. package/dist/components/freight-cost/FreightDraftForm.js +106 -91
  5. package/dist/components/freight-cost/FreightHistory.js +42 -40
  6. package/dist/generated/freight-cost-operations.d.ts +959 -0
  7. package/dist/hooks/useFreightRecoveryAction.js +20 -20
  8. package/dist/movethewheels/components/freight-cost/FreightCommercialEditor.d.ts +8 -0
  9. package/dist/movethewheels/components/freight-cost/FreightCommercialFactEditor.d.ts +8 -0
  10. package/dist/movethewheels/components/freight-cost/FreightCommercialHistory.d.ts +4 -0
  11. package/dist/movethewheels/components/freight-cost/FreightDraftForm.d.ts +4 -2
  12. package/dist/movethewheels/components/freight-cost/FreightHistory.d.ts +2 -2
  13. package/dist/movethewheels/utils/freightCommercial.d.ts +44 -0
  14. package/dist/pages/FreightEstimatePage.js +96 -92
  15. package/dist/src/generated/freight-cost-operations.js +495 -6
  16. package/dist/utils/freightAcknowledgement.js +6 -5
  17. package/dist/utils/freightCommercial.js +194 -0
  18. package/dist/utils/freightRecovery.js +22 -22
  19. package/package.json +4 -3
  20. package/src/generated/freight-cost-operations.ts +831 -1
  21. package/src/movethewheels/components/freight-cost/FreightCommercialEditor.tsx +236 -0
  22. package/src/movethewheels/components/freight-cost/FreightCommercialFactEditor.tsx +258 -0
  23. package/src/movethewheels/components/freight-cost/FreightCommercialHistory.tsx +90 -0
  24. package/src/movethewheels/components/freight-cost/FreightDraftForm.tsx +33 -4
  25. package/src/movethewheels/components/freight-cost/FreightHistory.tsx +4 -2
  26. package/src/movethewheels/hooks/useFreightRecoveryAction.ts +2 -1
  27. package/src/movethewheels/pages/FreightEstimatePage.tsx +14 -7
  28. package/src/movethewheels/utils/freightAcknowledgement.ts +3 -1
  29. package/src/movethewheels/utils/freightCommercial.ts +388 -0
  30. package/src/movethewheels/utils/freightRecovery.ts +6 -2
  31. package/src/operations/freight-cost/commercial.graphql +483 -0
@@ -0,0 +1,194 @@
1
+ //#region src/movethewheels/utils/freightCommercial.ts
2
+ var e = [
3
+ "origin",
4
+ "destination",
5
+ "carrier",
6
+ "service",
7
+ "cargo",
8
+ "weight",
9
+ "volume",
10
+ "equipment"
11
+ ], t = "Not recorded for this cost version";
12
+ function n() {
13
+ return {
14
+ facts: i(),
15
+ selectedLegs: [],
16
+ reviewed: null
17
+ };
18
+ }
19
+ function r(e = "UNKNOWN") {
20
+ return {
21
+ status: e,
22
+ reason: e === "UNKNOWN" ? t : "",
23
+ label: "",
24
+ reference: "",
25
+ description: "",
26
+ kind: "",
27
+ jurisdiction: "",
28
+ amount: "",
29
+ unit: "",
30
+ zeroReason: "",
31
+ count: "",
32
+ sourceReference: "",
33
+ sourceRevision: "",
34
+ observedAt: "",
35
+ evidenceLinks: []
36
+ };
37
+ }
38
+ function i() {
39
+ return {
40
+ origin: r(),
41
+ destination: r(),
42
+ carrier: r(),
43
+ service: r(),
44
+ cargo: r(),
45
+ weight: r(),
46
+ volume: r(),
47
+ equipment: r()
48
+ };
49
+ }
50
+ function a(e, t, n) {
51
+ let r = e.trim();
52
+ if (!r || r.length > t) throw Error(`${n}: enter 1–${t} characters.`);
53
+ return r;
54
+ }
55
+ function o(e) {
56
+ if (!/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d{3}Z$/.test(e) || new Date(e).toISOString() !== e || Date.parse(e) > Date.now()) throw Error("Use a valid observed time no later than now.");
57
+ return e;
58
+ }
59
+ function s(e, t) {
60
+ if (!/^(0|[1-9][0-9]{0,17})(\.[0-9]{0,5}[1-9])?$/.test(e)) throw Error("Use a canonical nonnegative decimal: up to 18 integer and 6 fractional digits, no exponent or trailing fractional zero.");
61
+ if (e === "0") return a(t, 255, "Recorded zero reason");
62
+ if (t.trim()) throw Error("A zero reason belongs only to an amount of zero.");
63
+ return null;
64
+ }
65
+ function c(e, t) {
66
+ let n = e.evidenceLinks;
67
+ if (n.length < 1 || n.length > 2 || new Set(n.map((e) => JSON.stringify([e.fileId, e.versionId]))).size !== n.length || n.some((e) => !t.some((t) => t.fileId === e.fileId && t.versionId === e.versionId))) throw Error("Choose 1–2 distinct exact evidence versions already selected for this cost record.");
68
+ return {
69
+ sourceReference: a(e.sourceReference, 255, "Fact source"),
70
+ sourceRevision: a(e.sourceRevision, 255, "Fact source revision"),
71
+ observedAt: e.observedAt ? o(e.observedAt) : null,
72
+ evidenceLinks: [...n].sort((e, t) => JSON.stringify([e.fileId, e.versionId]) < JSON.stringify([t.fileId, t.versionId]) ? -1 : +(JSON.stringify([e.fileId, e.versionId]) > JSON.stringify([t.fileId, t.versionId]))).map((e) => ({ ...e }))
73
+ };
74
+ }
75
+ function l(e, t, n) {
76
+ let r = (t) => {
77
+ let r = e[t];
78
+ if (r.status === "UNKNOWN") return {
79
+ status: r.status,
80
+ value: null,
81
+ reason: a(r.reason, 255, t),
82
+ provenance: null
83
+ };
84
+ if (r.status !== "SOURCED" && r.status !== "NOT_APPLICABLE") throw Error("Choose a supported commercial fact status.");
85
+ return {
86
+ status: r.status,
87
+ value: null,
88
+ reason: r.status === "NOT_APPLICABLE" ? a(r.reason, 255, t) : null,
89
+ provenance: c(r, n)
90
+ };
91
+ }, i = (t) => {
92
+ let n = r(t), i = e[t];
93
+ if (n.status !== "SOURCED") return n;
94
+ if (i.kind !== "ADDRESS_LABEL" && i.kind !== "PORT_LABEL" && i.kind !== "TERMINAL_LABEL" && i.kind !== "POSTCODE_LABEL" && i.kind !== "CUSTOM_LABEL") throw Error("Choose a location label kind.");
95
+ return {
96
+ ...n,
97
+ value: {
98
+ kind: i.kind,
99
+ label: a(i.label, 255, t),
100
+ jurisdictionLabel: i.jurisdiction.trim() ? a(i.jurisdiction, 120, "Jurisdiction label") : null
101
+ }
102
+ };
103
+ }, o = r("weight"), l = r("volume"), u = r("carrier"), d = r("service"), f = r("cargo"), p = r("equipment"), m = e.weight, h = e.volume;
104
+ if (m.status === "SOURCED" && m.unit !== "KG" && m.unit !== "TONNE" && m.unit !== "LB") throw Error("Choose a recorded weight unit.");
105
+ if (h.status === "SOURCED" && h.unit !== "M3" && h.unit !== "FT3") throw Error("Choose a recorded volume unit.");
106
+ if (e.equipment.status === "SOURCED" && (!/^[1-9][0-9]{0,5}$/.test(e.equipment.count) || Number(e.equipment.count) > 1e5)) throw Error("Equipment count must be an integer from 1 to 100000.");
107
+ if (t.length > 16 || new Set(t.map((e) => e.id)).size !== t.length) throw Error("Select at most 16 distinct reviewed legs.");
108
+ let g = {
109
+ schemaVersion: 1,
110
+ selectedLegs: t.map((e) => ({
111
+ id: a(e.id, 200, "Leg ID"),
112
+ expectedUpdatedAt: e.expectedUpdatedAt
113
+ })).sort((e, t) => e.id < t.id ? -1 : +(e.id > t.id)),
114
+ origin: i("origin"),
115
+ destination: i("destination"),
116
+ carrier: u.status === "SOURCED" ? {
117
+ ...u,
118
+ value: {
119
+ reference: a(e.carrier.reference, 120, "Carrier reference"),
120
+ label: a(e.carrier.label, 255, "Carrier label")
121
+ }
122
+ } : u,
123
+ service: d.status === "SOURCED" ? {
124
+ ...d,
125
+ value: a(e.service.label, 120, "Service")
126
+ } : d,
127
+ cargo: f.status === "SOURCED" ? {
128
+ ...f,
129
+ value: {
130
+ classificationLabel: a(e.cargo.label, 120, "Cargo classification"),
131
+ description: a(e.cargo.description, 500, "Cargo description")
132
+ }
133
+ } : f,
134
+ weight: o.status === "SOURCED" ? {
135
+ ...o,
136
+ value: {
137
+ amount: m.amount,
138
+ unit: m.unit === "KG" ? "KG" : m.unit === "TONNE" ? "TONNE" : "LB",
139
+ zeroReason: s(m.amount, m.zeroReason)
140
+ }
141
+ } : o,
142
+ volume: l.status === "SOURCED" ? {
143
+ ...l,
144
+ value: {
145
+ amount: h.amount,
146
+ unit: h.unit === "M3" ? "M3" : "FT3",
147
+ zeroReason: s(h.amount, h.zeroReason)
148
+ }
149
+ } : l,
150
+ equipment: p.status === "SOURCED" ? {
151
+ ...p,
152
+ value: {
153
+ typeLabel: a(e.equipment.label, 120, "Equipment type"),
154
+ count: Number(e.equipment.count)
155
+ }
156
+ } : p
157
+ };
158
+ if (new TextEncoder().encode(JSON.stringify(g)).byteLength > 32768) throw Error("Commercial capture exceeds 32768 bytes. Shorten facts before saving.");
159
+ return g;
160
+ }
161
+ function u(e) {
162
+ function t(e) {
163
+ return Array.isArray(e) ? e.map(t) : e && typeof e == "object" ? Object.fromEntries(Object.entries(e).filter(([e]) => e !== "__typename").sort(([e], [t]) => e.localeCompare(t)).map(([e, n]) => [e, t(n)])) : e;
164
+ }
165
+ return JSON.stringify(t(e));
166
+ }
167
+ function d(e, t) {
168
+ if (!e || typeof e != "object" || !("commercialCapture" in e) || !e.commercialCapture || typeof e.commercialCapture != "object") return !1;
169
+ let n = e.commercialCapture;
170
+ if (!t.commercialCapture || typeof t.commercialCapture != "object" || !("selectedLegs" in t.commercialCapture) || !Array.isArray(t.commercialCapture.selectedLegs) || !("ownerShipment" in n) || !n.ownerShipment || typeof n.ownerShipment != "object" || !("shipmentId" in n.ownerShipment) || n.ownerShipment.shipmentId !== t.shipmentId || !("updatedAt" in n.ownerShipment) || n.ownerShipment.updatedAt !== t.expectedShipmentUpdatedAt || !("primaryMode" in n.ownerShipment) || typeof n.ownerShipment.primaryMode != "string" || ![
171
+ "AIR",
172
+ "OCEAN",
173
+ "RAIL",
174
+ "ROAD"
175
+ ].includes(n.ownerShipment.primaryMode) || !("ownerLegs" in n) || !Array.isArray(n.ownerLegs) || u(Object.fromEntries(Object.entries(n).filter(([e]) => e !== "ownerShipment" && e !== "ownerLegs"))) !== u(t.commercialCapture)) return !1;
176
+ let r = t.commercialCapture.selectedLegs, i = n.ownerLegs;
177
+ return i.length === r.length && r.every((e) => e && typeof e == "object" && "id" in e && "expectedUpdatedAt" in e && i.some((t) => t && typeof t == "object" && "id" in t && t.id === e.id && "updatedAt" in t && t.updatedAt === e.expectedUpdatedAt && "legNumber" in t && typeof t.legNumber == "number" && Number.isInteger(t.legNumber) && t.legNumber > 0 && "mode" in t && typeof t.mode == "string" && [
178
+ "AIR",
179
+ "OCEAN",
180
+ "RAIL",
181
+ "ROAD"
182
+ ].includes(t.mode) && ["carrierId", "carrierName"].every((e) => e in t && (Reflect.get(t, e) === null || typeof Reflect.get(t, e) == "string")) && [
183
+ "weightKg",
184
+ "volumeCbm",
185
+ "containerCount"
186
+ ].every((e) => e in t && (Reflect.get(t, e) === null || typeof Reflect.get(t, e) == "number" && Number.isFinite(Reflect.get(t, e)))) && "containerType" in t && (t.containerType === null || typeof t.containerType == "string" && [
187
+ "FCL_20FT",
188
+ "FCL_40FT",
189
+ "FCL_40FT_HC",
190
+ "LCL"
191
+ ].includes(t.containerType))));
192
+ }
193
+ //#endregion
194
+ export { u as commercialCanonical, l as commercialCaptureInput, e as commercialSlots, d as matchesCommercialCapture, n as newCommercialEditor, r as newCommercialFact };
@@ -1,36 +1,36 @@
1
- import { SaveFreightCostsDocument as e } from "../src/generated/freight-cost-operations.js";
2
- import { print as t } from "graphql";
1
+ import { SaveFreightCommercialCostsDocument as e, SaveFreightCostsDocument as t } from "../src/generated/freight-cost-operations.js";
2
+ import { print as n } from "graphql";
3
3
  //#region src/movethewheels/utils/freightRecovery.ts
4
- var n = "movethewheels.freight.unresolved.v1";
5
- function r(n) {
6
- if (!n || new TextEncoder().encode(n).byteLength > 2e5) return null;
4
+ var r = "movethewheels.freight.unresolved.v1";
5
+ function i(r) {
6
+ if (!r || new TextEncoder().encode(r).byteLength > 2e5) return null;
7
7
  try {
8
- let r = JSON.parse(n);
9
- if (typeof r != "object" || !r || !("version" in r) || r.version !== 1 || !("scope" in r) || !("input" in r) || !("operation" in r) || r.operation !== t(e) || !("key" in r) || typeof r.key != "string" || !r.key || r.key.length > 200 || !("success" in r) || typeof r.success != "string" || r.success.length > 500 || typeof r.input != "object" || r.input === null || Array.isArray(r.input) || typeof r.scope != "object" || r.scope === null) return null;
10
- let i = r.scope;
11
- return !("actorId" in i) || typeof i.actorId != "string" || !i.actorId || !("workspaceId" in i) || typeof i.workspaceId != "string" || !i.workspaceId || !("tenantId" in i) || typeof i.tenantId != "string" || !("organizationId" in i) || typeof i.organizationId != "string" || !i.organizationId || !("gateway" in i) || typeof i.gateway != "string" || !("projectId" in i) || i.projectId !== null && typeof i.projectId != "string" ? null : {
8
+ let i = JSON.parse(r);
9
+ if (typeof i != "object" || !i || !("version" in i) || i.version !== 1 || !("scope" in i) || !("input" in i) || !("operation" in i) || i.operation !== n(t) && i.operation !== n(e) || !("key" in i) || typeof i.key != "string" || !i.key || i.key.length > 200 || !("success" in i) || typeof i.success != "string" || i.success.length > 500 || typeof i.input != "object" || i.input === null || Array.isArray(i.input) || typeof i.scope != "object" || i.scope === null) return null;
10
+ let a = i.scope;
11
+ return !("actorId" in a) || typeof a.actorId != "string" || !a.actorId || !("workspaceId" in a) || typeof a.workspaceId != "string" || !a.workspaceId || !("tenantId" in a) || typeof a.tenantId != "string" || !("organizationId" in a) || typeof a.organizationId != "string" || !a.organizationId || !("gateway" in a) || typeof a.gateway != "string" || !("projectId" in a) || a.projectId !== null && typeof a.projectId != "string" ? null : {
12
12
  version: 1,
13
13
  scope: {
14
- actorId: i.actorId,
15
- workspaceId: i.workspaceId,
16
- tenantId: i.tenantId,
17
- organizationId: i.organizationId,
18
- gateway: i.gateway,
19
- projectId: i.projectId
14
+ actorId: a.actorId,
15
+ workspaceId: a.workspaceId,
16
+ tenantId: a.tenantId,
17
+ organizationId: a.organizationId,
18
+ gateway: a.gateway,
19
+ projectId: a.projectId
20
20
  },
21
- operation: r.operation,
22
- input: structuredClone(r.input),
23
- key: r.key,
24
- success: r.success
21
+ operation: i.operation,
22
+ input: structuredClone(i.input),
23
+ key: i.key,
24
+ success: i.success
25
25
  };
26
26
  } catch {
27
27
  return null;
28
28
  }
29
29
  }
30
- function i(e) {
30
+ function a(e) {
31
31
  let t = JSON.stringify(e);
32
- if (!r(t)) throw Error("Cannot safely retain this freight request. Nothing was sent.");
32
+ if (!i(t)) throw Error("Cannot safely retain this freight request. Nothing was sent.");
33
33
  return t;
34
34
  }
35
35
  //#endregion
36
- export { n as FREIGHT_RECOVERY_STORAGE, r as decodeFreightRecovery, i as encodeFreightRecovery };
36
+ export { r as FREIGHT_RECOVERY_STORAGE, i as decodeFreightRecovery, a as encodeFreightRecovery };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-movethewheels",
3
- "version": "2026.1016.2",
3
+ "version": "2026.1016.3",
4
4
  "description": "Burdenoff MoveTheWheels Microfrontend - Logistics & Supply Chain Management Platform",
5
5
  "type": "module",
6
6
  "files": [
@@ -36,7 +36,7 @@
36
36
  "format": "prettier --write \"src/**/*.{ts,tsx}\"",
37
37
  "type:check": "bash scripts/build-limits.sh tsc --noEmit",
38
38
  "validate:schema-drift": "graphql-schema-drift",
39
- "sanity": "bash scripts/build-limits.sh --gate bash -c 'bun run codegen && bun run validate:schema-drift && bun run lint:sanity && bun run format && bun run type:check && bun run verify:live-logistics-contract && bun run verify:empty-reuse-retry && bun run verify:empty-reuse-recovery && bun run verify:trip-utilization-input && bun run verify:trip-draft-context && bun run verify:stock-binding-input && bun run verify:stock-observation-input && bun run verify:pending-pick-input && bun run verify:pick-review-ack && bun run verify:freight-input && bun run verify:freight-recovery && bun run verify:procedure-input && bun run verify:consolidation && bun run verify:multimodal-single-attempt && bun run verify:workspace-predispatch && bun run verify:tracking-quality-outcomes && bun run verify:shipment-status-authority && bun run verify:free-time-permissions && bun run verify:braces-depth && bun run build && bun run build-storybook'",
39
+ "sanity": "bash scripts/build-limits.sh --gate bash -c 'bun run codegen && bun run validate:schema-drift && bun run lint:sanity && bun run format && bun run type:check && bun run verify:live-logistics-contract && bun run verify:empty-reuse-retry && bun run verify:empty-reuse-recovery && bun run verify:trip-utilization-input && bun run verify:trip-draft-context && bun run verify:stock-binding-input && bun run verify:stock-observation-input && bun run verify:pending-pick-input && bun run verify:pick-review-ack && bun run verify:freight-input && bun run verify:freight-recovery && bun run verify:freight-commercial && bun run verify:procedure-input && bun run verify:consolidation && bun run verify:multimodal-single-attempt && bun run verify:workspace-predispatch && bun run verify:tracking-quality-outcomes && bun run verify:shipment-status-authority && bun run verify:free-time-permissions && bun run verify:braces-depth && bun run build && bun run build-storybook'",
40
40
  "storybook": "storybook dev -p 6006",
41
41
  "build-storybook": "storybook build",
42
42
  "test:storybook": "test-storybook",
@@ -66,7 +66,8 @@
66
66
  "verify:tracking-quality-outcomes": "bun test scripts/verify-tracking-quality-outcomes.test.ts",
67
67
  "verify:braces-depth": "bun test scripts/braces-depth-patch.test.ts",
68
68
  "verify:shipment-status-authority": "bun scripts/verify-shipment-status-command.mjs",
69
- "verify:free-time-permissions": "bun scripts/verify-free-time-permission-gates.mjs"
69
+ "verify:free-time-permissions": "bun scripts/verify-free-time-permission-gates.mjs",
70
+ "verify:freight-commercial": "bun scripts/verify-freight-commercial.mjs && bun scripts/verify-freight-commercial-recovery.mjs && bun scripts/verify-freight-commercial-mounted.mjs"
70
71
  },
71
72
  "dependencies": {
72
73
  "@apollo/client": "^4.0.11",