@classytic/flow 0.1.4

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 (102) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/LICENSE +21 -0
  3. package/README.md +258 -0
  4. package/dist/allocation-policy-my_HfzdV.d.mts +23 -0
  5. package/dist/base-MWBqRFM2.mjs +16 -0
  6. package/dist/catalog-bridge-K8bdkncJ.d.mts +29 -0
  7. package/dist/cost-layer.port-iH9pvZqB.d.mts +30 -0
  8. package/dist/cost-layer.service-BQ1bs-XN.mjs +86 -0
  9. package/dist/cost-layer.service-DWmo9dQz.d.mts +53 -0
  10. package/dist/count.port-BRqwGbi3.d.mts +57 -0
  11. package/dist/counting/index.d.mts +2 -0
  12. package/dist/counting/index.mjs +2 -0
  13. package/dist/counting.service-BiQXqorv.mjs +232 -0
  14. package/dist/counting.service-CpAxU2G0.d.mts +74 -0
  15. package/dist/domain/contracts/index.d.mts +3 -0
  16. package/dist/domain/contracts/index.mjs +1 -0
  17. package/dist/domain/enums/index.d.mts +2 -0
  18. package/dist/domain/enums/index.mjs +4 -0
  19. package/dist/domain/index.d.mts +24 -0
  20. package/dist/domain/index.mjs +10 -0
  21. package/dist/domain/policies/index.d.mts +4 -0
  22. package/dist/domain/policies/index.mjs +1 -0
  23. package/dist/domain-D5cpMpR0.mjs +96 -0
  24. package/dist/domain-errors-D7S9ydNF.mjs +133 -0
  25. package/dist/enums-C3_z6aHC.mjs +82 -0
  26. package/dist/event-bus-BNmyoJb4.mjs +37 -0
  27. package/dist/event-bus-Um_xrcMY.d.mts +21 -0
  28. package/dist/event-emitter.port-BFh2pasY.d.mts +183 -0
  29. package/dist/event-types-BSqQOvXv.mjs +29 -0
  30. package/dist/events/index.d.mts +3 -0
  31. package/dist/events/index.mjs +3 -0
  32. package/dist/idempotency.port-CTC70JON.d.mts +55 -0
  33. package/dist/index-Bia4m8d2.d.mts +67 -0
  34. package/dist/index-BmNm3oNU2.d.mts +107 -0
  35. package/dist/index-C5PciI9P.d.mts +203 -0
  36. package/dist/index-CMTUKEK_.d.mts +308 -0
  37. package/dist/index-C_aEnozN.d.mts +220 -0
  38. package/dist/index-CulWO137.d.mts +107 -0
  39. package/dist/index-DFF0GJ4J.d.mts +36 -0
  40. package/dist/index-DsE7lZdO.d.mts +11 -0
  41. package/dist/index-DwO9IdNa.d.mts +1 -0
  42. package/dist/index-dtWUZr2a2.d.mts +350 -0
  43. package/dist/index.d.mts +128 -0
  44. package/dist/index.mjs +102 -0
  45. package/dist/insufficient-stock.error-Dyr4BYaV.mjs +15 -0
  46. package/dist/location.port-CValXIpb.d.mts +52 -0
  47. package/dist/lot.port-ChsmvZqs.d.mts +32 -0
  48. package/dist/models/index.d.mts +2 -0
  49. package/dist/models/index.mjs +2 -0
  50. package/dist/models-CHTMbp-G.mjs +1020 -0
  51. package/dist/move-group.port-DHGoQA3d.d.mts +56 -0
  52. package/dist/move-status-DkaFp2GD.mjs +38 -0
  53. package/dist/move.port-Qg1CYp7h.d.mts +89 -0
  54. package/dist/package.service-4tcAwBbr.mjs +95 -0
  55. package/dist/package.service-C605NaBQ.d.mts +42 -0
  56. package/dist/packaging/index.d.mts +2 -0
  57. package/dist/packaging/index.mjs +2 -0
  58. package/dist/procurement/index.d.mts +2 -0
  59. package/dist/procurement/index.mjs +2 -0
  60. package/dist/quant.port-BBa66PBT.d.mts +42 -0
  61. package/dist/removal-policy-BItBB8FD.d.mts +29 -0
  62. package/dist/replenishment-rule.port-DnEYtbyD.d.mts +78 -0
  63. package/dist/replenishment.service-BT9P-HKM.mjs +284 -0
  64. package/dist/replenishment.service-HO0sDhB_.d.mts +89 -0
  65. package/dist/reporting/index.d.mts +2 -0
  66. package/dist/reporting/index.mjs +2 -0
  67. package/dist/reporting-CL5ffrKM.mjs +243 -0
  68. package/dist/repositories/index.d.mts +2 -0
  69. package/dist/repositories/index.mjs +2 -0
  70. package/dist/repositories-nZXJKvLW.mjs +842 -0
  71. package/dist/reservation-status-ZfuTaWG0.mjs +22 -0
  72. package/dist/reservation.port-l9NFQ0si.d.mts +85 -0
  73. package/dist/reservations/index.d.mts +2 -0
  74. package/dist/reservations/index.mjs +2 -0
  75. package/dist/reservations-Cg4wN0QB.mjs +112 -0
  76. package/dist/routing/index.d.mts +362 -0
  77. package/dist/routing/index.mjs +582 -0
  78. package/dist/runtime-config-C0ggPkiK.mjs +40 -0
  79. package/dist/runtime-config-CQLtPPqY.d.mts +38 -0
  80. package/dist/scan-token-CNM9QVLY.d.mts +26 -0
  81. package/dist/scanning/index.d.mts +45 -0
  82. package/dist/scanning/index.mjs +228 -0
  83. package/dist/services/index.d.mts +8 -0
  84. package/dist/services/index.mjs +8 -0
  85. package/dist/services-_lLO4Xbl.mjs +1009 -0
  86. package/dist/stock-move-group-C0DqUfPY.mjs +88 -0
  87. package/dist/stock-package-BIarxbDS.d.mts +19 -0
  88. package/dist/stock-quant-CZhgvTu7.d.mts +41 -0
  89. package/dist/tenant-guard-6Ne-BILP.mjs +12 -0
  90. package/dist/tenant-isolation.error-D3OcKUdx.mjs +11 -0
  91. package/dist/trace.service-B9vAh-l-.d.mts +55 -0
  92. package/dist/trace.service-DE6Eh8_8.mjs +71 -0
  93. package/dist/traceability/index.d.mts +2 -0
  94. package/dist/traceability/index.mjs +2 -0
  95. package/dist/types/index.d.mts +2 -0
  96. package/dist/types/index.mjs +1 -0
  97. package/dist/unit-of-work.port-CWEkrDKu.d.mts +17 -0
  98. package/dist/valuation/index.d.mts +78 -0
  99. package/dist/valuation/index.mjs +103 -0
  100. package/dist/valuation-policy-Dco8c9Vw.d.mts +14 -0
  101. package/dist/virtual-locations-B9zXqPdi.d.mts +38 -0
  102. package/package.json +155 -0
@@ -0,0 +1,232 @@
1
+ import { t as assertTenantContext } from "./tenant-guard-6Ne-BILP.mjs";
2
+ import { t as FlowEvents } from "./event-types-BSqQOvXv.mjs";
3
+ import { a as formatDocumentNumber, i as requireStandardMode } from "./runtime-config-C0ggPkiK.mjs";
4
+ //#region src/services/counting.service.ts
5
+ var CountingService = class {
6
+ constructor(countPort, quantPort, movePort, moveGroupPort, unitOfWork, eventEmitter, getNextSequence, runtimeConfig, virtualLocations) {
7
+ this.countPort = countPort;
8
+ this.quantPort = quantPort;
9
+ this.movePort = movePort;
10
+ this.moveGroupPort = moveGroupPort;
11
+ this.unitOfWork = unitOfWork;
12
+ this.eventEmitter = eventEmitter;
13
+ this.getNextSequence = getNextSequence;
14
+ this.runtimeConfig = runtimeConfig;
15
+ this.virtualLocations = virtualLocations;
16
+ }
17
+ async createSession(input, ctx) {
18
+ requireStandardMode(this.runtimeConfig, "Cycle counting");
19
+ assertTenantContext(ctx);
20
+ return this.unitOfWork.withTransaction(async (session) => {
21
+ const countNumber = formatDocumentNumber("CNT", await this.getNextSequence("CNT", ctx.organizationId));
22
+ const count = await this.countPort.create({
23
+ organizationId: ctx.organizationId,
24
+ countNumber,
25
+ countType: input.countType,
26
+ scope: input.scope,
27
+ status: "draft",
28
+ freezePolicy: input.freezePolicy ?? "none",
29
+ createdBy: ctx.actorId
30
+ }, session);
31
+ if (input.scope.locationId || input.scope.skuRefs && input.scope.skuRefs.length > 0) {
32
+ const filter = { organizationId: ctx.organizationId };
33
+ if (input.scope.locationId) filter.locationId = input.scope.locationId;
34
+ if (input.scope.skuRefs && input.scope.skuRefs.length > 0) filter.skuRef = { $in: input.scope.skuRefs };
35
+ const quants = await this.quantPort.findMany(filter, ctx, session);
36
+ if (quants.length > 0) {
37
+ const lines = quants.map((q) => ({
38
+ organizationId: ctx.organizationId,
39
+ countId: count._id,
40
+ skuRef: q.skuRef,
41
+ locationId: q.locationId,
42
+ lotId: q.lotId,
43
+ expectedQuantity: q.quantityOnHand,
44
+ countedQuantity: 0,
45
+ variance: -q.quantityOnHand
46
+ }));
47
+ await this.countPort.submitLines(count._id, lines, session);
48
+ }
49
+ }
50
+ return count;
51
+ });
52
+ }
53
+ async getById(countId, ctx) {
54
+ assertTenantContext(ctx);
55
+ return this.countPort.findById(countId, ctx);
56
+ }
57
+ async submitLines(countId, lines, ctx) {
58
+ assertTenantContext(ctx);
59
+ const count = await this.requireCount(countId, ctx);
60
+ const countLines = [];
61
+ for (const line of lines) {
62
+ const expectedQuantity = (await this.quantPort.getAvailability({
63
+ skuRef: line.skuRef,
64
+ locationId: line.locationId
65
+ }, ctx)).quantityOnHand;
66
+ const variance = line.countedQuantity - expectedQuantity;
67
+ countLines.push({
68
+ organizationId: ctx.organizationId,
69
+ countId,
70
+ skuRef: line.skuRef,
71
+ locationId: line.locationId,
72
+ lotId: line.lotId,
73
+ serialCode: line.serialCode,
74
+ expectedQuantity,
75
+ countedQuantity: line.countedQuantity,
76
+ variance,
77
+ varianceReason: line.varianceReason
78
+ });
79
+ }
80
+ const createdLines = await this.countPort.submitLines(countId, countLines);
81
+ await this.countPort.updateStatus(countId, "submitted", { submittedAt: /* @__PURE__ */ new Date() });
82
+ await this.eventEmitter.emit(FlowEvents.COUNT_STARTED, {
83
+ organizationId: ctx.organizationId,
84
+ countId,
85
+ countNumber: count.countNumber,
86
+ countType: count.countType,
87
+ lineCount: createdLines.length
88
+ });
89
+ return createdLines;
90
+ }
91
+ async calculateVariance(countId, ctx) {
92
+ assertTenantContext(ctx);
93
+ await this.requireCount(countId, ctx);
94
+ const lines = await this.countPort.getLines(countId, ctx);
95
+ const varianceLines = lines.filter((l) => l.variance !== 0);
96
+ return {
97
+ countId,
98
+ totalLines: lines.length,
99
+ matchedLines: lines.length - varianceLines.length,
100
+ varianceLines: varianceLines.length,
101
+ lines: lines.map((l) => ({
102
+ skuRef: l.skuRef,
103
+ locationId: l.locationId,
104
+ expected: l.expectedQuantity,
105
+ counted: l.countedQuantity,
106
+ variance: l.variance,
107
+ variancePercent: l.expectedQuantity !== 0 ? l.variance / l.expectedQuantity * 100 : l.countedQuantity !== 0 ? 100 : 0
108
+ }))
109
+ };
110
+ }
111
+ async reconcile(countId, options, ctx) {
112
+ assertTenantContext(ctx);
113
+ await this.requireCount(countId, ctx);
114
+ return this.unitOfWork.withTransaction(async (session) => {
115
+ const lines = await this.countPort.getLines(countId, ctx, session);
116
+ const varianceLines = lines.filter((l) => l.variance !== 0);
117
+ const docNumber = formatDocumentNumber("CNT", await this.getNextSequence("CNT", ctx.organizationId));
118
+ const moveGroup = await this.moveGroupPort.create({
119
+ organizationId: ctx.organizationId,
120
+ groupType: "count_reconciliation",
121
+ documentNumber: docNumber,
122
+ createdBy: ctx.actorId,
123
+ metadata: { countId }
124
+ }, session);
125
+ const adjustmentMoves = [];
126
+ let autoApproved = 0;
127
+ let needsManualReview = 0;
128
+ for (const line of varianceLines) {
129
+ let sourceLocationId;
130
+ let destinationLocationId;
131
+ if (line.variance > 0) {
132
+ sourceLocationId = this.virtualLocations.adjustment;
133
+ destinationLocationId = line.locationId;
134
+ } else {
135
+ sourceLocationId = line.locationId;
136
+ destinationLocationId = this.virtualLocations.adjustment;
137
+ }
138
+ const absVariance = Math.abs(line.variance);
139
+ const isAutoApproved = options.autoApproveThreshold !== void 0 && absVariance <= options.autoApproveThreshold;
140
+ if (isAutoApproved) autoApproved++;
141
+ else needsManualReview++;
142
+ const move = await this.movePort.create({
143
+ moveGroupId: moveGroup._id,
144
+ operationType: "count",
145
+ skuRef: line.skuRef,
146
+ sourceLocationId,
147
+ destinationLocationId,
148
+ quantityPlanned: absVariance,
149
+ organizationId: ctx.organizationId,
150
+ createdBy: ctx.actorId,
151
+ referenceType: "count",
152
+ referenceId: countId,
153
+ metadata: {
154
+ countLineId: line._id,
155
+ variance: line.variance,
156
+ expectedQuantity: line.expectedQuantity,
157
+ countedQuantity: line.countedQuantity,
158
+ varianceReason: line.varianceReason,
159
+ autoApproved: isAutoApproved
160
+ }
161
+ }, session);
162
+ adjustmentMoves.push(move);
163
+ }
164
+ await this.countPort.updateStatus(countId, "reconciled", { reconciledAt: /* @__PURE__ */ new Date() }, session);
165
+ await this.eventEmitter.emit(FlowEvents.COUNT_RECONCILED, {
166
+ organizationId: ctx.organizationId,
167
+ countId,
168
+ totalLines: lines.length,
169
+ varianceLines: varianceLines.length,
170
+ autoApproved,
171
+ needsManualReview,
172
+ moveGroupId: moveGroup._id,
173
+ documentNumber: moveGroup.documentNumber
174
+ }, session);
175
+ return {
176
+ countId,
177
+ totalLines: lines.length,
178
+ varianceLines: varianceLines.length,
179
+ autoApproved,
180
+ needsManualReview,
181
+ adjustmentMoves
182
+ };
183
+ });
184
+ }
185
+ async postReconciliationMoves(countId, ctx) {
186
+ assertTenantContext(ctx);
187
+ const count = await this.requireCount(countId, ctx);
188
+ const moves = await this.movePort.findMany({
189
+ referenceType: "count",
190
+ referenceId: countId,
191
+ organizationId: ctx.organizationId
192
+ }, ctx);
193
+ await this.unitOfWork.withTransaction(async (session) => {
194
+ for (const move of moves) {
195
+ if (move.status === "done" || move.status === "cancelled") continue;
196
+ const executedAt = /* @__PURE__ */ new Date();
197
+ await this.movePort.updateStatus(move._id, "done", {
198
+ quantityDone: move.quantityPlanned,
199
+ executedAt
200
+ }, session);
201
+ await this.quantPort.upsert({
202
+ organizationId: ctx.organizationId,
203
+ skuRef: move.skuRef,
204
+ locationId: move.sourceLocationId,
205
+ quantityDelta: -move.quantityPlanned,
206
+ inDate: executedAt
207
+ }, session);
208
+ await this.quantPort.upsert({
209
+ organizationId: ctx.organizationId,
210
+ skuRef: move.skuRef,
211
+ locationId: move.destinationLocationId,
212
+ quantityDelta: move.quantityPlanned,
213
+ inDate: executedAt
214
+ }, session);
215
+ }
216
+ await this.countPort.updateStatus(countId, "approved", { approvedBy: ctx.actorId }, session);
217
+ await this.eventEmitter.emit(FlowEvents.ADJUSTMENT_POSTED, {
218
+ organizationId: ctx.organizationId,
219
+ countId,
220
+ countNumber: count.countNumber,
221
+ movesPosted: moves.filter((m) => m.status !== "done" && m.status !== "cancelled").length
222
+ }, session);
223
+ });
224
+ }
225
+ async requireCount(countId, ctx) {
226
+ const count = await this.countPort.findById(countId, ctx);
227
+ if (!count) throw new Error(`Inventory count ${countId} not found`);
228
+ return count;
229
+ }
230
+ };
231
+ //#endregion
232
+ export { CountingService as t };
@@ -0,0 +1,74 @@
1
+ import { n as VirtualLocationMap } from "./virtual-locations-B9zXqPdi.mjs";
2
+ import { a as CountLine, i as InventoryCount, t as CountPort } from "./count.port-BRqwGbi3.mjs";
3
+ import { n as MovePort, r as StockMove } from "./move.port-Qg1CYp7h.mjs";
4
+ import { t as FlowContext } from "./index-DFF0GJ4J.mjs";
5
+ import { n as MoveGroupPort } from "./move-group.port-DHGoQA3d.mjs";
6
+ import { n as UnitOfWork } from "./unit-of-work.port-CWEkrDKu.mjs";
7
+ import { t as EventEmitterPort } from "./event-emitter.port-BFh2pasY.mjs";
8
+ import { r as QuantPort } from "./quant.port-BBa66PBT.mjs";
9
+ import { t as RuntimeConfig } from "./runtime-config-CQLtPPqY.mjs";
10
+
11
+ //#region src/services/counting.service.d.ts
12
+ interface CreateCountInput {
13
+ countType: 'full' | 'cycle' | 'spot';
14
+ scope: {
15
+ nodeId?: string;
16
+ locationId?: string;
17
+ skuRefs?: string[];
18
+ };
19
+ freezePolicy?: 'hard_freeze' | 'soft_freeze' | 'none';
20
+ }
21
+ interface CountLineInput {
22
+ skuRef: string;
23
+ locationId: string;
24
+ lotId?: string;
25
+ serialCode?: string;
26
+ countedQuantity: number;
27
+ varianceReason?: string;
28
+ }
29
+ interface VarianceReport {
30
+ countId: string;
31
+ totalLines: number;
32
+ matchedLines: number;
33
+ varianceLines: number;
34
+ lines: Array<{
35
+ skuRef: string;
36
+ locationId: string;
37
+ expected: number;
38
+ counted: number;
39
+ variance: number;
40
+ variancePercent: number;
41
+ }>;
42
+ }
43
+ interface ReconcileOptions {
44
+ autoApproveThreshold?: number;
45
+ }
46
+ interface ReconcileResult {
47
+ countId: string;
48
+ totalLines: number;
49
+ varianceLines: number;
50
+ autoApproved: number;
51
+ needsManualReview: number;
52
+ adjustmentMoves: StockMove[];
53
+ }
54
+ declare class CountingService {
55
+ private countPort;
56
+ private quantPort;
57
+ private movePort;
58
+ private moveGroupPort;
59
+ private unitOfWork;
60
+ private eventEmitter;
61
+ private getNextSequence;
62
+ private runtimeConfig;
63
+ private virtualLocations;
64
+ constructor(countPort: CountPort, quantPort: QuantPort, movePort: MovePort, moveGroupPort: MoveGroupPort, unitOfWork: UnitOfWork, eventEmitter: EventEmitterPort, getNextSequence: (prefix: string, organizationId: string) => Promise<number>, runtimeConfig: RuntimeConfig, virtualLocations: VirtualLocationMap);
65
+ createSession(input: CreateCountInput, ctx: FlowContext): Promise<InventoryCount>;
66
+ getById(countId: string, ctx: FlowContext): Promise<InventoryCount | null>;
67
+ submitLines(countId: string, lines: CountLineInput[], ctx: FlowContext): Promise<CountLine[]>;
68
+ calculateVariance(countId: string, ctx: FlowContext): Promise<VarianceReport>;
69
+ reconcile(countId: string, options: ReconcileOptions, ctx: FlowContext): Promise<ReconcileResult>;
70
+ postReconciliationMoves(countId: string, ctx: FlowContext): Promise<void>;
71
+ private requireCount;
72
+ }
73
+ //#endregion
74
+ export { ReconcileResult as a, ReconcileOptions as i, CountingService as n, VarianceReport as o, CreateCountInput as r, CountLineInput as t };
@@ -0,0 +1,3 @@
1
+ import { t as AuthContext } from "../../index-DsE7lZdO.mjs";
2
+ import { n as CatalogBridge, r as SkuDetails, t as AvailabilityUpdate } from "../../catalog-bridge-K8bdkncJ.mjs";
3
+ export { AuthContext, AvailabilityUpdate, CatalogBridge, SkuDetails };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ import { a as ReservationStatus, c as VIRTUAL_LOCATION_TYPES, d as MOVE_STATUS_TRANSITIONS, f as MoveStatus, i as StockStatus, l as GroupType, n as TrackingMode, o as LocationType, p as isValidMoveTransition, r as SELLABLE_STATUSES, s as STOCKABLE_LOCATION_TYPES, t as ValuationMethod, u as OperationType } from "../../index-CulWO137.mjs";
2
+ export { GroupType, LocationType, MOVE_STATUS_TRANSITIONS, MoveStatus, OperationType, ReservationStatus, SELLABLE_STATUSES, STOCKABLE_LOCATION_TYPES, StockStatus, TrackingMode, VIRTUAL_LOCATION_TYPES, ValuationMethod, isValidMoveTransition };
@@ -0,0 +1,4 @@
1
+ import { n as MoveStatus, r as isValidMoveTransition, t as MOVE_STATUS_TRANSITIONS } from "../../move-status-DkaFp2GD.mjs";
2
+ import { n as GroupType, t as ReservationStatus } from "../../reservation-status-ZfuTaWG0.mjs";
3
+ import { a as OperationType, c as VIRTUAL_LOCATION_TYPES, i as StockStatus, n as TrackingMode, o as LocationType, r as SELLABLE_STATUSES, s as STOCKABLE_LOCATION_TYPES, t as ValuationMethod } from "../../enums-C3_z6aHC.mjs";
4
+ export { GroupType, LocationType, MOVE_STATUS_TRANSITIONS, MoveStatus, OperationType, ReservationStatus, SELLABLE_STATUSES, STOCKABLE_LOCATION_TYPES, StockStatus, TrackingMode, VIRTUAL_LOCATION_TYPES, ValuationMethod, isValidMoveTransition };
@@ -0,0 +1,24 @@
1
+ import { i as resolveVirtualLocations, n as VirtualLocationMap, r as buildVirtualSourceTypes, t as DEFAULT_VIRTUAL_LOCATIONS } from "../virtual-locations-B9zXqPdi.mjs";
2
+ import { a as CountLine, i as InventoryCount, n as CountScope, r as CountStatus, t as CountPort } from "../count.port-BRqwGbi3.mjs";
3
+ import { a as ReservationStatus, c as VIRTUAL_LOCATION_TYPES, d as MOVE_STATUS_TRANSITIONS, f as MoveStatus, i as StockStatus, l as GroupType, n as TrackingMode, o as LocationType, p as isValidMoveTransition, r as SELLABLE_STATUSES, s as STOCKABLE_LOCATION_TYPES, t as ValuationMethod, u as OperationType } from "../index-CulWO137.mjs";
4
+ import { a as TrackingAssignment, i as assertMoveTransition, n as MovePort, r as StockMove, t as CreateMoveInput } from "../move.port-Qg1CYp7h.mjs";
5
+ import { n as CostLayer, t as CostLayerPort } from "../cost-layer.port-iH9pvZqB.mjs";
6
+ import { a as Address, i as Reservation, n as ReservationPort, o as InventoryNode, r as NodePort, t as CreateReservationInput } from "../reservation.port-l9NFQ0si.mjs";
7
+ import { n as Location, t as LocationPort } from "../location.port-CValXIpb.mjs";
8
+ import { a as ProcurementOrder, i as ProcurementItem, n as ProcurementPort, o as ProcurementStatus, r as ReplenishmentRule, t as ReplenishmentRulePort } from "../replenishment-rule.port-DnEYtbyD.mjs";
9
+ import { n as StockLot, t as LotPort } from "../lot.port-ChsmvZqs.mjs";
10
+ import { a as StockMoveGroup, i as MoveGroupStatus, n as MoveGroupPort, r as MOVE_GROUP_STATUS_TRANSITIONS, t as CreateMoveGroupInput } from "../move-group.port-DHGoQA3d.mjs";
11
+ import { t as StockPackage } from "../stock-package-BIarxbDS.mjs";
12
+ import { n as StockQuant, t as QuantIdentity } from "../stock-quant-CZhgvTu7.mjs";
13
+ import { n as UnitOfWork, t as TransactionSession } from "../unit-of-work.port-CWEkrDKu.mjs";
14
+ import { t as EventEmitterPort } from "../event-emitter.port-BFh2pasY.mjs";
15
+ import { i as QuantUpdate, n as AvailabilityQuery, r as QuantPort, t as Availability } from "../quant.port-BBa66PBT.mjs";
16
+ import { t as AuthContext } from "../index-DsE7lZdO.mjs";
17
+ import { n as CatalogBridge, r as SkuDetails, t as AvailabilityUpdate } from "../catalog-bridge-K8bdkncJ.mjs";
18
+ import { C as ReservationNotFoundError, D as FlowError, E as ValidationError, S as QuantMismatchError, T as StockFrozenError, _ as MoveAlreadyPostedError, a as SkuRef, b as NodeNotFoundError, c as ReservationExpiredError, d as InsufficientStockError, f as ConcurrencyConflictError, g as LotRequiredError, h as LocationNotStockableError, i as convertToBase, l as LocationCapacityExceededError, m as LocationNotFoundError, n as UoMQuantity, o as Quantity, p as DuplicateReservationError, r as convertFromBase, s as TenantIsolationError, t as UoMConversion, u as InvalidTransitionError, v as MoveGroupNotFoundError, w as SerialQuantityError, x as ProcurementNotApprovedError, y as NegativeStockError } from "../index-C_aEnozN.mjs";
19
+ import { n as AllocationResult, t as AllocationPolicy } from "../allocation-policy-my_HfzdV.mjs";
20
+ import { n as PutawayPolicy, t as RemovalPolicy } from "../removal-policy-BItBB8FD.mjs";
21
+ import { t as ValuationPolicy } from "../valuation-policy-Dco8c9Vw.mjs";
22
+ import { t as IdempotencyPort } from "../idempotency.port-CTC70JON.mjs";
23
+ import { n as ScanResolution, t as GS1Resolution } from "../scan-token-CNM9QVLY.mjs";
24
+ export { Address, AllocationPolicy, AllocationResult, AuthContext, Availability, AvailabilityQuery, AvailabilityUpdate, CatalogBridge, ConcurrencyConflictError, CostLayer, CostLayerPort, CountLine, CountPort, CountScope, CountStatus, CreateMoveGroupInput, CreateMoveInput, CreateReservationInput, DEFAULT_VIRTUAL_LOCATIONS, DuplicateReservationError, EventEmitterPort, FlowError, GS1Resolution, GroupType, IdempotencyPort, InsufficientStockError, InvalidTransitionError, InventoryCount, InventoryNode, Location, LocationCapacityExceededError, LocationNotFoundError, LocationNotStockableError, LocationPort, LocationType, LotPort, LotRequiredError, MOVE_GROUP_STATUS_TRANSITIONS, MOVE_STATUS_TRANSITIONS, MoveAlreadyPostedError, MoveGroupNotFoundError, MoveGroupPort, MoveGroupStatus, MovePort, MoveStatus, NegativeStockError, NodeNotFoundError, NodePort, OperationType, ProcurementItem, ProcurementNotApprovedError, ProcurementOrder, ProcurementPort, ProcurementStatus, PutawayPolicy, QuantIdentity, QuantMismatchError, QuantPort, QuantUpdate, Quantity, RemovalPolicy, ReplenishmentRule, ReplenishmentRulePort, Reservation, ReservationExpiredError, ReservationNotFoundError, ReservationPort, ReservationStatus, SELLABLE_STATUSES, STOCKABLE_LOCATION_TYPES, ScanResolution, SerialQuantityError, SkuDetails, SkuRef, StockFrozenError, StockLot, StockMove, StockMoveGroup, StockPackage, StockQuant, StockStatus, TenantIsolationError, TrackingAssignment, TrackingMode, TransactionSession, UnitOfWork, UoMConversion, UoMQuantity, VIRTUAL_LOCATION_TYPES, ValidationError, ValuationMethod, ValuationPolicy, VirtualLocationMap, assertMoveTransition, buildVirtualSourceTypes, convertFromBase, convertToBase, isValidMoveTransition, resolveVirtualLocations };
@@ -0,0 +1,10 @@
1
+ import { a as DEFAULT_VIRTUAL_LOCATIONS, i as InvalidTransitionError, n as assertMoveTransition, o as buildVirtualSourceTypes, r as ReservationExpiredError, s as resolveVirtualLocations, t as MOVE_GROUP_STATUS_TRANSITIONS } from "../stock-move-group-C0DqUfPY.mjs";
2
+ import { t as FlowError } from "../base-MWBqRFM2.mjs";
3
+ import { a as LotRequiredError, c as NegativeStockError, d as QuantMismatchError, f as ReservationNotFoundError, h as ValidationError, i as LocationNotStockableError, l as NodeNotFoundError, m as StockFrozenError, n as DuplicateReservationError, o as MoveAlreadyPostedError, p as SerialQuantityError, r as LocationNotFoundError, s as MoveGroupNotFoundError, t as ConcurrencyConflictError, u as ProcurementNotApprovedError } from "../domain-errors-D7S9ydNF.mjs";
4
+ import { t as InsufficientStockError } from "../insufficient-stock.error-Dyr4BYaV.mjs";
5
+ import { a as LocationCapacityExceededError, i as Quantity, n as convertToBase, r as SkuRef, t as convertFromBase } from "../domain-D5cpMpR0.mjs";
6
+ import { t as TenantIsolationError } from "../tenant-isolation.error-D3OcKUdx.mjs";
7
+ import { n as MoveStatus, r as isValidMoveTransition, t as MOVE_STATUS_TRANSITIONS } from "../move-status-DkaFp2GD.mjs";
8
+ import { n as GroupType, t as ReservationStatus } from "../reservation-status-ZfuTaWG0.mjs";
9
+ import { a as OperationType, c as VIRTUAL_LOCATION_TYPES, i as StockStatus, n as TrackingMode, o as LocationType, r as SELLABLE_STATUSES, s as STOCKABLE_LOCATION_TYPES, t as ValuationMethod } from "../enums-C3_z6aHC.mjs";
10
+ export { ConcurrencyConflictError, DEFAULT_VIRTUAL_LOCATIONS, DuplicateReservationError, FlowError, GroupType, InsufficientStockError, InvalidTransitionError, LocationCapacityExceededError, LocationNotFoundError, LocationNotStockableError, LocationType, LotRequiredError, MOVE_GROUP_STATUS_TRANSITIONS, MOVE_STATUS_TRANSITIONS, MoveAlreadyPostedError, MoveGroupNotFoundError, MoveStatus, NegativeStockError, NodeNotFoundError, OperationType, ProcurementNotApprovedError, QuantMismatchError, Quantity, ReservationExpiredError, ReservationNotFoundError, ReservationStatus, SELLABLE_STATUSES, STOCKABLE_LOCATION_TYPES, SerialQuantityError, SkuRef, StockFrozenError, StockStatus, TenantIsolationError, TrackingMode, VIRTUAL_LOCATION_TYPES, ValidationError, ValuationMethod, assertMoveTransition, buildVirtualSourceTypes, convertFromBase, convertToBase, isValidMoveTransition, resolveVirtualLocations };
@@ -0,0 +1,4 @@
1
+ import { n as AllocationResult, t as AllocationPolicy } from "../../allocation-policy-my_HfzdV.mjs";
2
+ import { n as PutawayPolicy, t as RemovalPolicy } from "../../removal-policy-BItBB8FD.mjs";
3
+ import { t as ValuationPolicy } from "../../valuation-policy-Dco8c9Vw.mjs";
4
+ export { AllocationPolicy, AllocationResult, PutawayPolicy, RemovalPolicy, ValuationPolicy };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,96 @@
1
+ import { t as FlowError } from "./base-MWBqRFM2.mjs";
2
+ import { h as ValidationError } from "./domain-errors-D7S9ydNF.mjs";
3
+ //#region src/domain/errors/location-capacity-exceeded.error.ts
4
+ var LocationCapacityExceededError = class extends FlowError {
5
+ code = "LOCATION_CAPACITY_EXCEEDED";
6
+ httpStatus = 422;
7
+ constructor(locationId, capacity, requested) {
8
+ super(`Location ${locationId} capacity exceeded: capacity ${capacity}, requested ${requested}`);
9
+ this.locationId = locationId;
10
+ this.capacity = capacity;
11
+ this.requested = requested;
12
+ }
13
+ };
14
+ //#endregion
15
+ //#region src/domain/value-objects/quantity.ts
16
+ /**
17
+ * Non-negative quantity value object.
18
+ * Used for planned/done quantities on moves and availability.
19
+ */
20
+ var Quantity = class Quantity {
21
+ constructor(value) {
22
+ this.value = value;
23
+ }
24
+ static create(value) {
25
+ if (!Number.isFinite(value)) throw new ValidationError("Quantity must be a finite number");
26
+ if (value < 0) throw new ValidationError(`Quantity must be non-negative, got ${value}`);
27
+ return new Quantity(value);
28
+ }
29
+ static zero() {
30
+ return new Quantity(0);
31
+ }
32
+ add(other) {
33
+ return new Quantity(this.value + other.value);
34
+ }
35
+ subtract(other) {
36
+ const result = this.value - other.value;
37
+ if (result < 0) throw new ValidationError(`Quantity subtraction would result in negative: ${this.value} - ${other.value}`);
38
+ return new Quantity(result);
39
+ }
40
+ isZero() {
41
+ return this.value === 0;
42
+ }
43
+ isGreaterThan(other) {
44
+ return this.value > other.value;
45
+ }
46
+ isGreaterThanOrEqual(other) {
47
+ return this.value >= other.value;
48
+ }
49
+ equals(other) {
50
+ return this.value === other.value;
51
+ }
52
+ toString() {
53
+ return String(this.value);
54
+ }
55
+ };
56
+ //#endregion
57
+ //#region src/domain/value-objects/sku-ref.ts
58
+ /**
59
+ * Product/variant reference — opaque string identifier linking to the external catalog.
60
+ * Flow never owns the product definition; it references via skuRef.
61
+ */
62
+ var SkuRef = class SkuRef {
63
+ constructor(value) {
64
+ this.value = value;
65
+ }
66
+ static create(value) {
67
+ if (!value || value.trim().length === 0) throw new ValidationError("skuRef must be a non-empty string");
68
+ return new SkuRef(value.trim());
69
+ }
70
+ equals(other) {
71
+ return this.value === other.value;
72
+ }
73
+ toString() {
74
+ return this.value;
75
+ }
76
+ };
77
+ //#endregion
78
+ //#region src/domain/value-objects/uom-quantity.ts
79
+ /**
80
+ * Convert quantity from one UoM to base UoM.
81
+ */
82
+ function convertToBase(quantity, conversion) {
83
+ if (quantity < 0) throw new ValidationError("Quantity must be non-negative");
84
+ if (conversion.factor <= 0) throw new ValidationError("UoM conversion factor must be positive");
85
+ return quantity * conversion.factor;
86
+ }
87
+ /**
88
+ * Convert quantity from base UoM to target UoM.
89
+ */
90
+ function convertFromBase(quantity, conversion) {
91
+ if (quantity < 0) throw new ValidationError("Quantity must be non-negative");
92
+ if (conversion.factor === 0) throw new ValidationError("UoM conversion factor cannot be zero");
93
+ return quantity / conversion.factor;
94
+ }
95
+ //#endregion
96
+ export { LocationCapacityExceededError as a, Quantity as i, convertToBase as n, SkuRef as r, convertFromBase as t };
@@ -0,0 +1,133 @@
1
+ import { t as FlowError } from "./base-MWBqRFM2.mjs";
2
+ //#region src/domain/errors/domain-errors.ts
3
+ var DuplicateReservationError = class extends FlowError {
4
+ code = "DUPLICATE_RESERVATION";
5
+ httpStatus = 409;
6
+ constructor(ownerType, ownerId, skuRef) {
7
+ super(`Duplicate reservation for ${ownerType}/${ownerId} on ${skuRef}`);
8
+ this.ownerType = ownerType;
9
+ this.ownerId = ownerId;
10
+ this.skuRef = skuRef;
11
+ }
12
+ };
13
+ var LocationNotStockableError = class extends FlowError {
14
+ code = "LOCATION_NOT_STOCKABLE";
15
+ httpStatus = 422;
16
+ constructor(locationId, locationType) {
17
+ super(`Location ${locationId} (type: ${locationType}) does not hold physical stock`);
18
+ this.locationId = locationId;
19
+ this.locationType = locationType;
20
+ }
21
+ };
22
+ var NegativeStockError = class extends FlowError {
23
+ code = "NEGATIVE_STOCK";
24
+ httpStatus = 422;
25
+ constructor(skuRef, locationId, currentQty, requestedQty) {
26
+ super(`Operation would result in negative stock for ${skuRef} at ${locationId}: current ${currentQty}, requested ${requestedQty}`);
27
+ this.skuRef = skuRef;
28
+ this.locationId = locationId;
29
+ this.currentQty = currentQty;
30
+ this.requestedQty = requestedQty;
31
+ }
32
+ };
33
+ var MoveAlreadyPostedError = class extends FlowError {
34
+ code = "MOVE_ALREADY_POSTED";
35
+ httpStatus = 409;
36
+ constructor(moveId) {
37
+ super(`Move ${moveId} is already posted (done); mutations are not allowed`);
38
+ this.moveId = moveId;
39
+ }
40
+ };
41
+ var ConcurrencyConflictError = class extends FlowError {
42
+ code = "CONCURRENCY_CONFLICT";
43
+ httpStatus = 409;
44
+ constructor(message = "Optimistic concurrency check failed; retry the operation") {
45
+ super(message);
46
+ }
47
+ };
48
+ var QuantMismatchError = class extends FlowError {
49
+ code = "QUANT_MISMATCH";
50
+ httpStatus = 500;
51
+ constructor(skuRef, locationId, expected, actual) {
52
+ super(`Quant balance mismatch for ${skuRef} at ${locationId}: expected ${expected}, actual ${actual}`);
53
+ this.skuRef = skuRef;
54
+ this.locationId = locationId;
55
+ this.expected = expected;
56
+ this.actual = actual;
57
+ }
58
+ };
59
+ var LotRequiredError = class extends FlowError {
60
+ code = "LOT_REQUIRED";
61
+ httpStatus = 422;
62
+ constructor(skuRef) {
63
+ super(`SKU ${skuRef} requires lot/serial assignment but none was provided`);
64
+ this.skuRef = skuRef;
65
+ }
66
+ };
67
+ var SerialQuantityError = class extends FlowError {
68
+ code = "SERIAL_QUANTITY";
69
+ httpStatus = 422;
70
+ constructor(serialCode) {
71
+ super(`Serial-tracked item ${serialCode} must have quantity exactly 1`);
72
+ this.serialCode = serialCode;
73
+ }
74
+ };
75
+ var StockFrozenError = class extends FlowError {
76
+ code = "STOCK_FROZEN";
77
+ httpStatus = 423;
78
+ constructor(locationId, reason) {
79
+ super(`Stock at ${locationId} is frozen: ${reason}`);
80
+ this.locationId = locationId;
81
+ this.reason = reason;
82
+ }
83
+ };
84
+ var ProcurementNotApprovedError = class extends FlowError {
85
+ code = "PROCUREMENT_NOT_APPROVED";
86
+ httpStatus = 422;
87
+ constructor(orderId) {
88
+ super(`Cannot receive against procurement order ${orderId}: not approved/ordered`);
89
+ this.orderId = orderId;
90
+ }
91
+ };
92
+ var NodeNotFoundError = class extends FlowError {
93
+ code = "NODE_NOT_FOUND";
94
+ httpStatus = 404;
95
+ constructor(nodeId) {
96
+ super(`Inventory node ${nodeId} not found`);
97
+ this.nodeId = nodeId;
98
+ }
99
+ };
100
+ var LocationNotFoundError = class extends FlowError {
101
+ code = "LOCATION_NOT_FOUND";
102
+ httpStatus = 404;
103
+ constructor(locationId) {
104
+ super(`Location ${locationId} not found`);
105
+ this.locationId = locationId;
106
+ }
107
+ };
108
+ var MoveGroupNotFoundError = class extends FlowError {
109
+ code = "MOVE_GROUP_NOT_FOUND";
110
+ httpStatus = 404;
111
+ constructor(groupId) {
112
+ super(`Move group ${groupId} not found`);
113
+ this.groupId = groupId;
114
+ }
115
+ };
116
+ var ReservationNotFoundError = class extends FlowError {
117
+ code = "RESERVATION_NOT_FOUND";
118
+ httpStatus = 404;
119
+ constructor(reservationId) {
120
+ super(`Reservation ${reservationId} not found`);
121
+ this.reservationId = reservationId;
122
+ }
123
+ };
124
+ var ValidationError = class extends FlowError {
125
+ code = "VALIDATION_ERROR";
126
+ httpStatus = 400;
127
+ constructor(message, fields) {
128
+ super(message);
129
+ this.fields = fields;
130
+ }
131
+ };
132
+ //#endregion
133
+ export { LotRequiredError as a, NegativeStockError as c, QuantMismatchError as d, ReservationNotFoundError as f, ValidationError as h, LocationNotStockableError as i, NodeNotFoundError as l, StockFrozenError as m, DuplicateReservationError as n, MoveAlreadyPostedError as o, SerialQuantityError as p, LocationNotFoundError as r, MoveGroupNotFoundError as s, ConcurrencyConflictError as t, ProcurementNotApprovedError as u };