@operato/ops-contract 0.1.0 → 0.2.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.
@@ -0,0 +1,86 @@
1
+ /** 개체 관측 — 물건 하나가 어디서 무엇이 됐나. */
2
+ export interface CanonicalRecord {
3
+ /**
4
+ * 개체 하나의 식별자. **`quantityList` 를 쓰면 없어도 된다** — 낱개 번호가 없는 자재(밀가루 3.5kg)는
5
+ * 개체가 없다. 둘 다 없으면 무엇을 관측했는지 말하지 않은 것이므로 커널 매핑이 거부한다.
6
+ */
7
+ epc?: string;
8
+ /**
9
+ * 클래스와 수량 — `{ epcClass, quantity, uom? }`. **잔량 절대값을 싣는다**(「얼마 뺐다」가 아니라
10
+ * 「얼마 남았다」). 그래야 사건 하나를 놓쳐도 다음 사건이 정답을 다시 말해 주고 오차가 쌓이지 않는다.
11
+ *
12
+ * 담김(`childQuantityList`)이 하루 먼저 이 자리를 받았다 — 그때와 같은 이유다. 원본이 비직렬 수량을
13
+ * 말할 길이 없어서, 그것이 주된 경로인 시스템(식품 제조 MES)은 라이브를 낼 수 없었다. 커널의
14
+ * 관측 리듀서는 처음부터 이 값을 읽었고 문만 없었다.
15
+ */
16
+ quantityList?: {
17
+ epcClass: string;
18
+ quantity?: number;
19
+ uom?: string;
20
+ }[];
21
+ action: string;
22
+ bizStep: string;
23
+ disposition?: string;
24
+ readPoint?: string;
25
+ bizLocation?: string;
26
+ }
27
+ /**
28
+ * 담김 관측 — **부모와 자식**으로 말한다. 자리 필드는 개체 관측과 같은 이름이다(문자열).
29
+ *
30
+ * 이름은 표준의 것을 그대로 쓴다(`parentID`·`childEPCs`) — 여기서 다시 지으면 매핑이 번역이 되고,
31
+ * 같은 사실에 두 어휘가 생긴다.
32
+ */
33
+ /**
34
+ * 변환 관측 — **무엇으로 무엇이 되었나.** 입력과 출력이 **한 사실에 함께** 있어야 계보가 남는다.
35
+ *
36
+ * 따로 보내면(「이 로트가 없어졌다」와 「이 제품이 생겼다」) 그 둘을 이을 근거가 없다. 그래서 표준이
37
+ * 한 사건에 둘을 담고, 우리 레코드도 같은 모양이다.
38
+ *
39
+ * 이름은 **표준의 것을 그대로** 쓴다(`inputQuantityList` 등). 갈래 판정이 이 이름으로 이루어지므로
40
+ * 커넥터 낱말(`consumed`·`produced`)로 담으면 판정되지 않는다 — 커넥터가 정규 이름으로 담아 보내고
41
+ * 매핑은 그 안에서 값을 고른다.
42
+ *
43
+ * **없는 쪽은 필드를 만들지 않는다.** 빈 배열을 실으면 「없다」고 말하는 것이 된다. 소실(N→0)과
44
+ * 생성(0→N)도 표준이 인정하는 변환이다.
45
+ *
46
+ * `transformationID` 가 한 오더의 여러 단계를 잇는다 — 소비를 먼저 알고 산출을 나중에 알게 되는 원본에서
47
+ * 그 둘을 묶는 유일한 자리다.
48
+ */
49
+ export interface CanonicalTransformationRecord {
50
+ /** 개체로 소비된 것. */
51
+ inputEPCList?: string[];
52
+ /** 클래스와 수량으로 소비된 것 — 로트 단위 소비가 이 자리다. */
53
+ inputQuantityList?: {
54
+ epcClass: string;
55
+ quantity?: number;
56
+ uom?: string;
57
+ }[];
58
+ outputEPCList?: string[];
59
+ outputQuantityList?: {
60
+ epcClass: string;
61
+ quantity?: number;
62
+ uom?: string;
63
+ }[];
64
+ /** 한 오더의 여러 단계를 잇는 식별자. */
65
+ transformationID?: string;
66
+ bizStep: string;
67
+ disposition?: string;
68
+ readPoint?: string;
69
+ bizLocation?: string;
70
+ }
71
+ export interface CanonicalAggregationRecord {
72
+ parentID: string;
73
+ /** 개체로 담긴 자식. 수량으로만 담겼으면 없다(둘 중 하나는 있어야 한다). */
74
+ childEPCs?: string[];
75
+ /** 수량으로 담긴 자식 — `{ epcClass, quantity, uom? }`. 값의 옳고 그름은 커널 검증이 본다. */
76
+ childQuantityList?: {
77
+ epcClass: string;
78
+ quantity?: number;
79
+ uom?: string;
80
+ }[];
81
+ action: string;
82
+ bizStep: string;
83
+ disposition?: string;
84
+ readPoint?: string;
85
+ bizLocation?: string;
86
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -394,7 +394,7 @@ export interface TestResult {
394
394
  * 함께 움직인다. 열린 문자열로 두지 않는 이유는, 처분이 **자원에 효과를 주기** 때문이다 — 커널이 모르는
395
395
  * 결정을 받으면 무엇을 해야 할지 알 수 없고, 그때 조용히 아무것도 하지 않는 것이 가장 나쁘다.
396
396
  */
397
- export declare const DISPOSITION_DECISION: readonly ["rework", "use-as-is", "scrap", "return-to-supplier", "hold"];
397
+ export declare const DISPOSITION_DECISION: readonly ["rework", "repair", "use-as-is", "regrade", "scrap", "return-to-supplier", "hold"];
398
398
  export type DispositionDecision = (typeof DISPOSITION_DECISION)[number];
399
399
  /**
400
400
  * **부적합 처분** — `OP_EVENT.disposition` 의 데이터.
package/dist/contract.js CHANGED
@@ -226,7 +226,32 @@ levelOfType) {
226
226
  * 함께 움직인다. 열린 문자열로 두지 않는 이유는, 처분이 **자원에 효과를 주기** 때문이다 — 커널이 모르는
227
227
  * 결정을 받으면 무엇을 해야 할지 알 수 없고, 그때 조용히 아무것도 하지 않는 것이 가장 나쁘다.
228
228
  */
229
- export const DISPOSITION_DECISION = ['rework', 'use-as-is', 'scrap', 'return-to-supplier', 'hold'];
229
+ export const DISPOSITION_DECISION = [
230
+ /** 원 규격으로 되돌린다 — 공정에 다시 들어가고, 산출물은 원 품목이다. */
231
+ 'rework',
232
+ /**
233
+ * 쓸 수 있게 만들되 **원 규격은 아니다** — 공정에 다시 들어가지만 산출물이 원 품목이 아니다.
234
+ *
235
+ * `rework` 와 나눈 이유는 이름이 아니라 **효과**다. 되돌린 것과 고쳐 쓴 것은 산출물의 정체성이
236
+ * 다르고, 그것을 한 낱말로 묶으면 계보가 「원 품목을 만들었다」고 거짓을 말한다.
237
+ */
238
+ 'repair',
239
+ /** 그대로 쓴다 — 공정도 정체성도 바뀌지 않는다. */
240
+ 'use-as-is',
241
+ /**
242
+ * **등급을 내려 다른 품목으로 판다** — 공정에 다시 들어가지 않고, 그 자리에서 품목 정의가 바뀐다.
243
+ *
244
+ * 다른 넷과 축이 다르다. 폐기도 특채도 아니고 **자재의 품목 자체가 달라진다**(GTIN 이 바뀐다).
245
+ * 식품·철강·섬유에서 일상이다.
246
+ */
247
+ 'regrade',
248
+ /** 재고에서 뺀다. */
249
+ 'scrap',
250
+ /** 공급자에게 돌려보낸다 — 재고에서 빠지되 폐기와 다른 사실이다. */
251
+ 'return-to-supplier',
252
+ /** 아직 정하지 않았다 — 묶어 두고 쓰지 않는다. */
253
+ 'hold'
254
+ ];
230
255
  /**
231
256
  * 이 시험 결과가 **이 시각에 유효한 합격인가.**
232
257
  *
package/dist/index.d.ts CHANGED
@@ -16,3 +16,4 @@ export * from './scenario-validate.ts';
16
16
  export * from './vocabulary.ts';
17
17
  export * from './wms-profile.ts';
18
18
  export * from './yms-profile.ts';
19
+ export * from './canonical-record.ts';
package/dist/index.js CHANGED
@@ -37,3 +37,4 @@ export * from "./scenario-validate.js";
37
37
  export * from "./vocabulary.js";
38
38
  export * from "./wms-profile.js";
39
39
  export * from "./yms-profile.js";
40
+ export * from "./canonical-record.js";
@@ -408,7 +408,32 @@ function hierarchyOf(s, levelOfType) {
408
408
  }
409
409
  };
410
410
  }
411
- var DISPOSITION_DECISION = ["rework", "use-as-is", "scrap", "return-to-supplier", "hold"];
411
+ var DISPOSITION_DECISION = [
412
+ /** 원 규격으로 되돌린다 — 공정에 다시 들어가고, 산출물은 원 품목이다. */
413
+ "rework",
414
+ /**
415
+ * 쓸 수 있게 만들되 **원 규격은 아니다** — 공정에 다시 들어가지만 산출물이 원 품목이 아니다.
416
+ *
417
+ * `rework` 와 나눈 이유는 이름이 아니라 **효과**다. 되돌린 것과 고쳐 쓴 것은 산출물의 정체성이
418
+ * 다르고, 그것을 한 낱말로 묶으면 계보가 「원 품목을 만들었다」고 거짓을 말한다.
419
+ */
420
+ "repair",
421
+ /** 그대로 쓴다 — 공정도 정체성도 바뀌지 않는다. */
422
+ "use-as-is",
423
+ /**
424
+ * **등급을 내려 다른 품목으로 판다** — 공정에 다시 들어가지 않고, 그 자리에서 품목 정의가 바뀐다.
425
+ *
426
+ * 다른 넷과 축이 다르다. 폐기도 특채도 아니고 **자재의 품목 자체가 달라진다**(GTIN 이 바뀐다).
427
+ * 식품·철강·섬유에서 일상이다.
428
+ */
429
+ "regrade",
430
+ /** 재고에서 뺀다. */
431
+ "scrap",
432
+ /** 공급자에게 돌려보낸다 — 재고에서 빠지되 폐기와 다른 사실이다. */
433
+ "return-to-supplier",
434
+ /** 아직 정하지 않았다 — 묶어 두고 쓰지 않는다. */
435
+ "hold"
436
+ ];
412
437
  function testPassedAt(r, at) {
413
438
  if (r.result !== "pass") return false;
414
439
  if (!r.expiresAt || !at) return r.result === "pass";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@operato/ops-contract",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Operations domain contract — the standard vocabulary that producers and readers agree on (EPCIS 2.0/GS1, ISA-95, IEC 61850/ISO 50001). Types, guards, validation. No state, no engine.",
5
5
  "type": "module",
6
6
  "main": "./dist-cjs/index.cjs",