@operato/twin-kernel 0.6.1 → 0.6.2

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.
@@ -874,6 +874,22 @@ export interface OrderState {
874
874
  requested?: number;
875
875
  fulfilled?: number;
876
876
  lines?: ObservedOrderLine[];
877
+ /**
878
+ * 이 오더가 **확보해 둔 물품들** — 진행 중인 할당.
879
+ *
880
+ * 이것이 상태에 없으면 **웜스타트가 잃는다.** 잃으면 되살아난 오더는 아무것도 안 잡은 것처럼
881
+ * 보이고, 그 오더에 딸린 진행 중 작업이 완료될 때 계보(`TransformationEvent`)가 **입력 없이**
882
+ * 나간다 — "무엇이 무엇으로 바뀌었나" 의 절반이 사라진다. 실제로 그렇게 되고 있었다.
883
+ *
884
+ * 씨앗이 잃은 것은 예측도 모른다 — 진행 중 자재를 안 잡은 것으로 놓고 미래를 굴리면 답이
885
+ * 낙관 쪽으로 치우친다(`hydrateObserved` 가 상태를 지키는 이유와 같다).
886
+ */
887
+ allocated?: string[];
888
+ /**
889
+ * 이 오더의 거래번호(작업지시·PO·SO) — 계보와 EPCIS 이벤트가 **무슨 거래로** 일어났는지 잇는 축.
890
+ * 이것도 상태에 없어서 되살아난 오더는 빈 문자열을 갖고, 이후 모든 이벤트의 거래번호가 빈다.
891
+ */
892
+ bizTransaction?: string;
877
893
  /** 우선순위 — 표준 `OperationsRequest.Priority`. 작은 값이 급하다. 오더 할당 순서를 정한다. */
878
894
  priority?: number;
879
895
  /** 예정 착수 — 표준 `OperationsRequest.StartTime`. */
@@ -1230,6 +1246,15 @@ export interface OrderStatusDelta {
1230
1246
  priority?: number;
1231
1247
  startTime?: ISOTime;
1232
1248
  endTime?: ISOTime;
1249
+ /**
1250
+ * 이 오더가 **확보해 둔 물품들**과 그 **거래번호** — 진행 중인 할당.
1251
+ *
1252
+ * 델타가 나르지 않으면 웜스타트가 잃는다. 잃으면 되살아난 오더는 아무것도 안 잡은 것처럼
1253
+ * 보이고, 그 오더의 진행 중 작업이 완료될 때 계보(`TransformationEvent`)가 **입력 없이** 나간다 —
1254
+ * "무엇이 무엇으로 바뀌었나" 의 절반이 사라진다. 실제로 그렇게 되고 있었다.
1255
+ */
1256
+ allocated?: string[];
1257
+ bizTransaction?: string;
1233
1258
  }
1234
1259
  export declare const CMD: {
1235
1260
  readonly orderHold: "order.hold";
@@ -520,7 +520,11 @@ export class FlowEngine {
520
520
  없다.** 라이브 트윈이 납기 초과를 한 번도 보고하지 못한 원인 중 하나였다. */
521
521
  ...(o.endTime ? { endTime: o.endTime } : {}),
522
522
  ...(o.startTime ? { startTime: o.startTime } : {}),
523
- ...(o.priority !== undefined ? { priority: o.priority } : {})
523
+ ...(o.priority !== undefined ? { priority: o.priority } : {}),
524
+ /* 확보분과 거래번호도 함께 옮긴다 — 여기서 떨구면 위에서 실어 온 것이 마지막 한 걸음에서
525
+ 사라진다(같은 사실이 델타·스냅샷·이 변환 **세 길**을 지난다). */
526
+ ...(o.allocated?.length ? { allocated: o.allocated } : {}),
527
+ ...(o.bizTransaction ? { bizTransaction: o.bizTransaction } : {})
524
528
  }));
525
529
  for (const o of observedOrders) {
526
530
  const lines = (o.lines ?? []).map(l => ({ gtin: l.gtin, requested: l.requested - (l.fulfilled ?? 0) })).filter(l => l.requested > 0);
@@ -534,7 +538,10 @@ export class FlowEngine {
534
538
  continue; // 이미 이행 완료 → 예측 대상 아님
535
539
  this.orders.set(o.orderId, {
536
540
  id: o.orderId, kind: o.kind, status: 'created', requested: remaining, fulfilled: 0,
537
- bizTransaction: '', allocated: [], picked: [], shipmentEpc: null, lines,
541
+ /* **확보해 것과 거래번호를 이어받는다.** 비우면 되살아난 오더가 아무것도 안 잡은 것처럼
542
+ 보이고, 그 오더의 진행 중 작업이 완료될 때 계보가 입력 없이 나간다. 상태가 말해 주지
543
+ 않으면(옛 저널) 그때는 비는 것이 사실이다 — 없는 것을 지어내지 않는다. */
544
+ bizTransaction: o.bizTransaction ?? '', allocated: (o.allocated ?? []).slice(), picked: [], shipmentEpc: null, lines,
538
545
  /* **보류를 이어받는다** — 잃으면 씨앗이 사람이 일부러 멈춘 오더를 다시 계획해 내보낸다.
539
546
  씨앗 왕복 대조가 이것을 잡았다(그 전에는 사람이 코드를 읽어야만 알 수 있었다). */
540
547
  ...(o.held ? { held: true } : {}),
@@ -860,6 +867,10 @@ export class FlowEngine {
860
867
  ...(o.priority !== undefined ? { priority: o.priority } : {}),
861
868
  ...(o.startTime ? { startTime: o.startTime } : {}),
862
869
  ...(o.endTime ? { endTime: o.endTime } : {}),
870
+ /* 진행 중 확보분과 거래번호 — **스냅샷에도** 실어야 한다. 델타에만 실으면 스냅샷으로
871
+ 재기동하는 경로(체크포인트)에서 그대로 잃는다(같은 사실을 두 길로 나르는 값이다). */
872
+ ...(o.allocated?.length ? { allocated: o.allocated.slice() } : {}),
873
+ ...(o.bizTransaction ? { bizTransaction: o.bizTransaction } : {}),
863
874
  held: o.held
864
875
  })),
865
876
  attentions: this.computeAttentions(),
@@ -1460,7 +1471,11 @@ export class FlowEngine {
1460
1471
  ...(o.priority !== undefined ? { priority: o.priority } : {}),
1461
1472
  ...(o.startTime ? { startTime: o.startTime } : {}),
1462
1473
  ...(o.endTime ? { endTime: o.endTime } : {}),
1463
- ...(o.lines?.length ? { lines: o.lines.map(l => ({ gtin: l.gtin, requested: l.requested })) } : {})
1474
+ ...(o.lines?.length ? { lines: o.lines.map(l => ({ gtin: l.gtin, requested: l.requested })) } : {}),
1475
+ /* 진행 중 할당과 거래번호를 함께 싣는다 — 이것이 없으면 웜스타트가 잃고, 되살아난 오더의
1476
+ 계보가 입력 없이 나간다(무엇이 무엇으로 바뀌었나의 절반이 사라진다). */
1477
+ ...(o.allocated?.length ? { allocated: o.allocated.slice() } : {}),
1478
+ ...(o.bizTransaction ? { bizTransaction: o.bizTransaction } : {})
1464
1479
  });
1465
1480
  }
1466
1481
  // ── 내부 mechanics ─────────────────────────────────────────────────────────
@@ -342,6 +342,10 @@ export class ObservedReducer {
342
342
  ...(d.priority !== undefined ? { priority: d.priority } : {}),
343
343
  ...(d.startTime ? { startTime: d.startTime } : {}),
344
344
  ...(d.endTime ? { endTime: d.endTime } : {}),
345
+ /* 진행 중 확보분과 거래번호 — **미러도 같은 필드를 채운다.** 시뮬만 아는 사실을 두면
346
+ 그 위에서 세운 예측이 두 구동에서 달라진다(패리티 검사가 지키는 것이 이것이다). */
347
+ ...(d.allocated?.length ? { allocated: d.allocated.slice() } : {}),
348
+ ...(d.bizTransaction ? { bizTransaction: d.bizTransaction } : {}),
345
349
  held: d.held
346
350
  });
347
351
  break;
@@ -1181,6 +1181,10 @@ var ObservedReducer = class {
1181
1181
  ...d.priority !== void 0 ? { priority: d.priority } : {},
1182
1182
  ...d.startTime ? { startTime: d.startTime } : {},
1183
1183
  ...d.endTime ? { endTime: d.endTime } : {},
1184
+ /* 진행 중 확보분과 거래번호 — **미러도 같은 필드를 채운다.** 시뮬만 아는 사실을 두면
1185
+ 그 위에서 세운 예측이 두 구동에서 달라진다(패리티 검사가 지키는 것이 이것이다). */
1186
+ ...d.allocated?.length ? { allocated: d.allocated.slice() } : {},
1187
+ ...d.bizTransaction ? { bizTransaction: d.bizTransaction } : {},
1184
1188
  held: d.held
1185
1189
  });
1186
1190
  break;
@@ -2502,7 +2506,11 @@ var FlowEngine = class {
2502
2506
  없다.** 라이브 트윈이 납기 초과를 한 번도 보고하지 못한 원인 중 하나였다. */
2503
2507
  ...o.endTime ? { endTime: o.endTime } : {},
2504
2508
  ...o.startTime ? { startTime: o.startTime } : {},
2505
- ...o.priority !== void 0 ? { priority: o.priority } : {}
2509
+ ...o.priority !== void 0 ? { priority: o.priority } : {},
2510
+ /* 확보분과 거래번호도 함께 옮긴다 — 여기서 떨구면 위에서 실어 온 것이 마지막 한 걸음에서
2511
+ 사라진다(같은 사실이 델타·스냅샷·이 변환 **세 길**을 지난다). */
2512
+ ...o.allocated?.length ? { allocated: o.allocated } : {},
2513
+ ...o.bizTransaction ? { bizTransaction: o.bizTransaction } : {}
2506
2514
  }));
2507
2515
  for (const o of observedOrders) {
2508
2516
  const lines = (o.lines ?? []).map((l) => ({ gtin: l.gtin, requested: l.requested - (l.fulfilled ?? 0) })).filter((l) => l.requested > 0);
@@ -2514,8 +2522,11 @@ var FlowEngine = class {
2514
2522
  status: "created",
2515
2523
  requested: remaining,
2516
2524
  fulfilled: 0,
2517
- bizTransaction: "",
2518
- allocated: [],
2525
+ /* **확보해 둔 것과 거래번호를 이어받는다.** 비우면 되살아난 오더가 아무것도 안 잡은 것처럼
2526
+ 보이고, 그 오더의 진행 중 작업이 완료될 때 계보가 입력 없이 나간다. 상태가 말해 주지
2527
+ 않으면(옛 저널) 그때는 비는 것이 사실이다 — 없는 것을 지어내지 않는다. */
2528
+ bizTransaction: o.bizTransaction ?? "",
2529
+ allocated: (o.allocated ?? []).slice(),
2519
2530
  picked: [],
2520
2531
  shipmentEpc: null,
2521
2532
  lines,
@@ -2823,6 +2834,10 @@ var FlowEngine = class {
2823
2834
  ...o.priority !== void 0 ? { priority: o.priority } : {},
2824
2835
  ...o.startTime ? { startTime: o.startTime } : {},
2825
2836
  ...o.endTime ? { endTime: o.endTime } : {},
2837
+ /* 진행 중 확보분과 거래번호 — **스냅샷에도** 실어야 한다. 델타에만 실으면 스냅샷으로
2838
+ 재기동하는 경로(체크포인트)에서 그대로 잃는다(같은 사실을 두 길로 나르는 값이다). */
2839
+ ...o.allocated?.length ? { allocated: o.allocated.slice() } : {},
2840
+ ...o.bizTransaction ? { bizTransaction: o.bizTransaction } : {},
2826
2841
  held: o.held
2827
2842
  })),
2828
2843
  attentions: this.computeAttentions(),
@@ -3367,7 +3382,11 @@ var FlowEngine = class {
3367
3382
  ...o.priority !== void 0 ? { priority: o.priority } : {},
3368
3383
  ...o.startTime ? { startTime: o.startTime } : {},
3369
3384
  ...o.endTime ? { endTime: o.endTime } : {},
3370
- ...o.lines?.length ? { lines: o.lines.map((l) => ({ gtin: l.gtin, requested: l.requested })) } : {}
3385
+ ...o.lines?.length ? { lines: o.lines.map((l) => ({ gtin: l.gtin, requested: l.requested })) } : {},
3386
+ /* 진행 중 할당과 거래번호를 함께 싣는다 — 이것이 없으면 웜스타트가 잃고, 되살아난 오더의
3387
+ 계보가 입력 없이 나간다(무엇이 무엇으로 바뀌었나의 절반이 사라진다). */
3388
+ ...o.allocated?.length ? { allocated: o.allocated.slice() } : {},
3389
+ ...o.bizTransaction ? { bizTransaction: o.bizTransaction } : {}
3371
3390
  });
3372
3391
  }
3373
3392
  // ── 내부 mechanics ─────────────────────────────────────────────────────────
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@operato/twin-kernel",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "type": "module",
5
5
  "description": "Twin Domain Kernel — framework-agnostic, zero-dep (domain + sim + 3-channel contract). WMS/YMS/MES, EPCIS 2.0 · ISA-95.",
6
6
  "publishConfig": {