@operato/ops-contract 0.1.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.
Files changed (41) hide show
  1. package/README.md +23 -0
  2. package/dist/capability.d.ts +142 -0
  3. package/dist/capability.js +127 -0
  4. package/dist/capacity.d.ts +99 -0
  5. package/dist/capacity.js +172 -0
  6. package/dist/contract.d.ts +3557 -0
  7. package/dist/contract.js +1248 -0
  8. package/dist/domain-catalog.d.ts +280 -0
  9. package/dist/domain-catalog.js +322 -0
  10. package/dist/domain-definition.d.ts +356 -0
  11. package/dist/domain-definition.js +137 -0
  12. package/dist/ems-profile.d.ts +147 -0
  13. package/dist/ems-profile.js +367 -0
  14. package/dist/energy-ingest.d.ts +214 -0
  15. package/dist/energy-ingest.js +801 -0
  16. package/dist/epcis.d.ts +458 -0
  17. package/dist/epcis.js +640 -0
  18. package/dist/face2-adapter.d.ts +191 -0
  19. package/dist/face2-adapter.js +284 -0
  20. package/dist/index.d.ts +18 -0
  21. package/dist/index.js +39 -0
  22. package/dist/iso-duration.d.ts +5 -0
  23. package/dist/iso-duration.js +43 -0
  24. package/dist/master-data.d.ts +46 -0
  25. package/dist/master-data.js +100 -0
  26. package/dist/mes-profile.d.ts +14 -0
  27. package/dist/mes-profile.js +59 -0
  28. package/dist/operational-ingest.d.ts +44 -0
  29. package/dist/operational-ingest.js +379 -0
  30. package/dist/operations-capability.d.ts +117 -0
  31. package/dist/operations-capability.js +120 -0
  32. package/dist/scenario-validate.d.ts +15 -0
  33. package/dist/scenario-validate.js +72 -0
  34. package/dist/vocabulary.d.ts +28 -0
  35. package/dist/vocabulary.js +81 -0
  36. package/dist/wms-profile.d.ts +20 -0
  37. package/dist/wms-profile.js +58 -0
  38. package/dist/yms-profile.d.ts +15 -0
  39. package/dist/yms-profile.js +39 -0
  40. package/dist-cjs/index.cjs +3767 -0
  41. package/package.json +30 -0
@@ -0,0 +1,458 @@
1
+ /** EPCIS 2.0 JSON-LD 컨텍스트 — 이벤트를 자기기술적 EPCIS 오브젝트로 만든다. */
2
+ export declare const EPCIS_CONTEXT = "https://ref.gs1.org/standards/epcis/2.0.0/epcis-context.jsonld";
3
+ /** 커널 시계는 UTC(BASE_EPOCH) 기준 → 고정 오프셋. */
4
+ export declare const UTC_OFFSET = "+00:00";
5
+ export declare const DISP: {
6
+ readonly in_progress: "urn:epcglobal:cbv:disp:in_progress";
7
+ readonly sellable: "urn:epcglobal:cbv:disp:sellable_accessible";
8
+ readonly reserved: "urn:epcglobal:cbv:disp:reserved";
9
+ readonly in_transit: "urn:epcglobal:cbv:disp:in_transit";
10
+ readonly non_sellable: "urn:epcglobal:cbv:disp:non_sellable_other";
11
+ /**
12
+ * **기한이 지났다** — CBV `expired`.
13
+ *
14
+ * ── 왜 `non_sellable` 로 계산하지 않나 (2026-08-24) ─────────────────────────────
15
+ * 커널의 `non_sellable` 은 CBV 의 `non_sellable_other`, 즉 **「그 밖의 이유」**다. 기한 지남을 거기
16
+ * 넣으면 「기한이 지나 못 판다」와 「깨져서 못 판다」가 같은 값이 되고, 화면은 회수·폐기의 사유를
17
+ * 구별할 수 없다. 식품에서 그 둘은 다른 조치다.
18
+ *
19
+ * 그리고 표준에 **정확한 낱말이 있다** — 합치는 것은 있는 낱말을 버리는 것이다.
20
+ *
21
+ * ── 기한 날짜와 다른 축이다 ────────────────────────────────────────────────
22
+ * `ItemState.expiry` 는 **날짜**이고 이것은 **상태**다. 날짜가 있으면 「지났나」는 파생이지만, 원본이
23
+ * 「기한 지남」을 상태로 선언하는 시스템이 있다 — 그때 이 값은 관측이다.
24
+ *
25
+ * 둘이 어긋나면(날짜는 남았는데 상태가 지남, 또는 그 반대) **어느 쪽이 맞다고 정하지 않는다** —
26
+ * 아직 그 판정을 세울 근거가 없다. 어긋남의 구분을 없애지 않는 것이 지금의 규율이다.
27
+ *
28
+ * ── 원문으로 확인했다 (2026-08-24) ────────────────────────────────────────
29
+ * 1차 출처: **CBV Standard Release 2.0, Ratified Jun 2022** §7.2.3 처분 값 표(38개). 이 객체의
30
+ * 다른 값들(`in_progress`·`sellable_accessible`·`reserved`·`in_transit`·`non_sellable_other`)도
31
+ * 그 표에 있다.
32
+ *
33
+ * **`non_sellable_expired` 를 쓰지 않는 이유**: 그 값은 CBV 1.0 의 것이고 표준이 **폐기**했다 —
34
+ * 「deprecated in favour of new disposition values expired, damaged, disposed, … introduced in
35
+ * CBV 1.1」. 폐기된 값을 쓰면 새 소비처가 읽지 못한다.
36
+ *
37
+ * 참고: GS1 어휘 등록처(`ref.gs1.org/cbv/…`)로는 확인할 수 없었다 — **없는 값에도 같은 응답**을
38
+ * 준다(지어낸 값의 JSON-LD 가 실재 값과 바이트까지 같았다). 그 경로를 근거로 삼지 말 것.
39
+ */
40
+ readonly expired: "urn:epcglobal:cbv:disp:expired";
41
+ /**
42
+ * **검사에 합격했다 / 불합격했다** — CBV `conformant` / `non_conformant`.
43
+ *
44
+ * 1차 출처(CBV 2.0 §7.2.3) 정의 그대로다.
45
+ *
46
+ * conformant Outcome of a successful/passed inspection in an inspecting or repairing step
47
+ * non_conformant Outcome of an unsuccessful/failed inspection in an inspecting or repairing step
48
+ *
49
+ * ── 왜 시험 결과 축을 자원에 더하지 않고 이것을 쓰나 (2026-08-24) ────────────
50
+ * 로트의 검사 판정을 담을 자리를 찾다가 `ItemState.testResults` 를 더하려 했다. 그런데 표준은 그
51
+ * 사실을 **이미 처분으로 말한다**: `bizStep: inspecting` 사건에 이 처분이 붙는다.
52
+ *
53
+ * 처분을 쓰면 두 가지가 공짜로 성립한다.
54
+ * ① **상태 ⊆ 이벤트** — 처분은 이미 사건에서 온다. 상태에만 있는 축을 만들지 않는다
55
+ * ② **운영에 곧 닿는다** — 「이 자재를 쓸 수 있나」가 처분으로 답해진다(판정을 따로 읽지 않는다)
56
+ *
57
+ * 시험의 **자세한 내용**(어느 명세로, 무엇을 재어)은 다른 물음이고, 표준은 그것을 `TestResult` 로
58
+ * 두며 결과가 대상을 가리킨다(`TestableObjectID`) — 대상이 결과를 들지 않는다. 그 축이 필요해지면
59
+ * 그때 열되, **판정 자체는 여기서 끝난다.**
60
+ */
61
+ readonly conformant: "urn:epcglobal:cbv:disp:conformant";
62
+ readonly non_conformant: "urn:epcglobal:cbv:disp:non_conformant";
63
+ };
64
+ /**
65
+ * **자재 소비·산출의 CBV 단계** — 도메인 무관하게 코어가 쓴다.
66
+ *
67
+ * 업종별 단계(입고·피킹·출하…)는 각 프로파일이 갖지만, "자재가 들어갔다/나왔다" 는 셋 다 하는 일이라
68
+ * 코어에 있어야 한다. 프로파일 하나에 두면 다른 업종이 그것을 가져다 쓰면서 방언이 생긴다.
69
+ */
70
+ export declare const CBV_BIZSTEP: {
71
+ /** 공정에 자재가 들어갔다 — ISA-95 `MaterialUse: Consumed`. */
72
+ readonly consuming: "urn:epcglobal:cbv:bizstep:consuming";
73
+ /** 새 물품이 생겨 계보가 시작된다 — ISA-95 `MaterialUse: Produced`. */
74
+ readonly commissioning: "urn:epcglobal:cbv:bizstep:commissioning";
75
+ /**
76
+ * **검사** — CBV `inspecting`. 1차 출처(CBV 2.0) 정의: 「Process of reviewing objects to address
77
+ * potential physical or documentation defects」이고, 「표본과 달리 검사된 대상은 그대로 남는다」고
78
+ * 이어진다(즉 검사는 물건을 소비하지 않는다).
79
+ *
80
+ * 이 단계에 `DISP.conformant`/`DISP.non_conformant` 가 붙어 판정이 처분으로 남는다 — 입고검수·
81
+ * 공정 중 검사가 그 모양이다.
82
+ */
83
+ readonly inspecting: "urn:epcglobal:cbv:bizstep:inspecting";
84
+ /**
85
+ * **어느 단계로도 이름 붙지 않는 활동** — 원문: 「A business step not identified by any other」.
86
+ *
87
+ * 이것은 근사가 아니라 **표준이 준 낱말**이다. 그 구별이 중요하다: 재고 조정처럼 한 낱말이 두 일을
88
+ * 하는 원천(세어 보고 맞춘 것 · 사람이 정정한 것)을 `cycle_counting` 으로 옮기면 **일어나지 않은
89
+ * 계수를 기록**하게 된다. 그때 쓰는 것이 이 값이고, 무슨 일이었는지는 값으로 함께 나른다.
90
+ *
91
+ * 원문 확인: CBV Standard Release 2.0(Ratified Jun 2022) §7.1.
92
+ */
93
+ readonly other: "urn:epcglobal:cbv:bizstep:other";
94
+ };
95
+ export type EpcisEventType = 'ObjectEvent' | 'AggregationEvent' | 'TransactionEvent' | 'TransformationEvent';
96
+ export type EpcisAction = 'ADD' | 'OBSERVE' | 'DELETE';
97
+ /**
98
+ * **봉투에 실리는 EPCIS 사건 종류의 이름** — 소비처가 손으로 적지 않게 (2026-08-28).
99
+ *
100
+ * 봉투의 `eventType` 은 `epcis.<클래스>` 다(§`face2-adapter`·§`flow-engine` 이 그 접두사를 붙인다).
101
+ * 그 문자열을 화면·조회가 손으로 적으면 곧 방언이 되고, 클래스가 늘 때 한쪽만 고쳐진다.
102
+ *
103
+ * ── 왜 필요한가 ─────────────────────────────────────────────────────────────
104
+ * 「물건이 움직인 사건만 보는 목록」이 지금 **제외 목록**으로 만들어져 있다 — 운영·에너지 종류 열아홉
105
+ * 개를 적어 빼는 방식이다. 그 방식은 두 가지로 약하다.
106
+ *
107
+ * ① **닫히지 않는다.** 커널이 세 번째 계열을 만들면 그 계열 전부가 오류 없이 「움직임」으로 들어온다.
108
+ * 실제로 그 일이 세 번 있었다(사람 상태·자산 상태·에너지).
109
+ * ② **색인을 못 쓴다.** 제외 + 시각순은 색인이 듣지 않아, 그 트윈의 종류 분포가 비용을 정한다
110
+ * (실측: 에너지가 0.008%인 트윈에서 같은 모양이 37초였다).
111
+ *
112
+ * 담을 것을 말하면 정의가 닫힌다 — **물건이 움직인 사건 = EPCIS 사건**이고 그 클래스는 표준이 정한다.
113
+ * 커널이 채널을 늘려도 이 집합은 늘지 않는다.
114
+ *
115
+ * 우리 커널이 다루는 클래스는 넷이다. 표준의 `AssociationEvent` 는 아직 만들지 않았고, 만들면 이 상수에
116
+ * 더한다 — 그 한 곳만 고치면 소비처가 함께 따라온다.
117
+ */
118
+ export declare const EPCIS_EVENT: {
119
+ readonly object: "epcis.ObjectEvent";
120
+ readonly aggregation: "epcis.AggregationEvent";
121
+ readonly transaction: "epcis.TransactionEvent";
122
+ readonly transformation: "epcis.TransformationEvent";
123
+ };
124
+ /** 봉투의 `eventType` 이 EPCIS 사건인가 — 접두사 하나로 판정한다(클래스가 늘어도 그대로 산다). */
125
+ export declare function isEpcisEventType(eventType: unknown): boolean;
126
+ /**
127
+ * 수량 요소 — **클래스 식별자 + 얼마나**. 표준이 세 경우를 규정한다(EPCIS 2.0 §7.3.3.1).
128
+ *
129
+ * | 품목 성격 | quantity | uom | 뜻 |
130
+ * |---|---|---|---|
131
+ * | 고정 계량 | 양의 **정수** | 없음 | 그 클래스의 **개수** |
132
+ * | 가변 계량 | 양수(정수 아니어도) | 있음 | quantity=크기, uom=물리 단위 |
133
+ * | 아무 것 | **없음** | 없음 | 수량을 **모른다**(미지정) |
134
+ *
135
+ * 즉 **`uom` 이 없으면 개수, 있으면 물리량**이다. 개수 단위(each 등)를 `uom` 에 넣는 것은 표준이
136
+ * 의도한 방식이 아니다 — 개수는 uom 없이 정수로 쓴다.
137
+ *
138
+ * 수량을 모를 때 0 으로 꾸미지 않도록 표준이 **"둘 다 생략"** 자리를 따로 두었다.
139
+ */
140
+ export interface QuantityElement {
141
+ /** 클래스 식별자 — `urn:epc:idpat:…`(조건) 또는 `urn:epc:class:lgtin:…`(로트 클래스). */
142
+ epcClass: string;
143
+ /**
144
+ * 얼마나. **모르면 생략한다**(0 이 아니다).
145
+ * uom 없으면 양의 정수(개수), uom 있으면 양수(물리량, 소수 허용).
146
+ */
147
+ quantity?: number;
148
+ /**
149
+ * 측정 단위 — UN/CEFACT 권고 20 "Common Code" 의 2~3자 코드.
150
+ * 표준은 그중 **길이·면적·부피·질량**만 허용하고 폐기(X)·비권장(D) 코드를 제외한다.
151
+ * 예: MTR(미터) 허용 / F17(피트당 파운드힘) 불허. `quantity` 가 없으면 이 값도 없어야 한다.
152
+ */
153
+ uom?: string;
154
+ }
155
+ export interface BizTransactionElement {
156
+ type: string;
157
+ bizTransaction: string;
158
+ }
159
+ export interface LocationRef {
160
+ id: string;
161
+ }
162
+ /**
163
+ * 정정 선언 — 이미 캡처된 이벤트를 취소·수정한다(EPCIS 2.0 `errorDeclaration`).
164
+ *
165
+ * 실 시스템은 잘못 보낸 이벤트를 정정한다. 받을 자리가 없으면 정정이 **또 하나의 사실**로 쌓여
166
+ * 재고·이력이 조용히 틀어진다(목 연동에서는 드러나지 않고 실 시스템에서 바로 터진다).
167
+ */
168
+ export interface ErrorDeclaration {
169
+ /** 정정을 선언한 시각(ISO). 표준 필수. */
170
+ declarationTime: string;
171
+ /** 정정 이유 — CBV 어휘 URN(did_not_occur / incorrect_data). 도메인이 넓게 쓸 수 있어 열린 문자열. */
172
+ reason?: string;
173
+ /** 이 정정이 가리키는 원본 이벤트들의 `eventID`. */
174
+ correctiveEventIDs?: string[];
175
+ }
176
+ /**
177
+ * 이전 당사자 — 소유·보관이 누구에게서 누구로 옮겨지는가(EPCIS 2.0 §7.3.5).
178
+ * `type` 은 이전의 종류를 가리키는 표준 어휘(예: "owning party"), `source`/`destination` 은 그 당사자다.
179
+ * 3PL·위탁재고·수탁처럼 **물건은 그대로인데 권리가 옮겨지는** 일을 이것으로 표현한다.
180
+ */
181
+ export interface SourceElement {
182
+ type: string;
183
+ source: string;
184
+ }
185
+ export interface DestinationElement {
186
+ type: string;
187
+ destination: string;
188
+ }
189
+ /**
190
+ * 지속 상태 — 이벤트 **이후에도 유효한** 업무 조건(EPCIS 2.0 §7.3.4).
191
+ *
192
+ * `disposition` 은 그 순간의 상태이고, 이쪽은 **명시적으로 해제될 때까지 유지**된다. 그래서 회수 대상처럼
193
+ * 매 이벤트에 다시 말하지 않아도 되는 성질을 담는다. set 과 unset 은 서로 독립이다.
194
+ */
195
+ export interface PersistentDisposition {
196
+ /** 이 이벤트 이후 **설정**되는 조건 URI 들(해제될 때까지 유지). */
197
+ set?: string[];
198
+ /** 이 이벤트 이후 **해제**되는 조건 URI 들. */
199
+ unset?: string[];
200
+ }
201
+ /**
202
+ * 센서 관측 묶음 — 콜드체인·충격·습도 같은 물리 측정(EPCIS 2.0 §7.4).
203
+ *
204
+ * 하나의 `sensorMetadata`(모든 보고에 공통으로 적용되는 메타)와 **하나 이상의** `sensorReport`
205
+ * (개별 관측)로 이루어진다. 안의 속성은 인라인이고 어휘가 넓어, 커널은 **구조만 통과**시키고
206
+ * 값의 해석은 도메인에 맡긴다(없는 어휘를 발명하지 않는다).
207
+ */
208
+ export interface SensorElement {
209
+ sensorMetadata?: Record<string, unknown>;
210
+ sensorReport: Record<string, unknown>[];
211
+ }
212
+ /** EPCIS 2.0 공통 헤더(모든 이벤트). action 은 여기 없음 — TransformationEvent 는 action 이 없다. */
213
+ interface EpcisHeader {
214
+ '@context': string;
215
+ type: EpcisEventType;
216
+ /**
217
+ * 이벤트 자신의 정체성(EPCIS 2.0 `eventID`, 대문자 D).
218
+ *
219
+ * **봉투(`CanonicalEnvelope.eventId`)와 다른 것이다** — 봉투 id 는 우리 전송 단위의 id 이고, 이쪽은
220
+ * EPCIS 이벤트 자체의 id 다. 정정 이벤트가 원본을 `correctiveEventIDs` 로 가리켜야 하므로 이벤트
221
+ * 자신의 id 가 필요하다. 이름이 비슷해 혼동하기 쉬우니 봉투 id 를 그대로 재사용하지 말 것.
222
+ */
223
+ eventID?: string;
224
+ /** 발생 시각(ISO). */
225
+ eventTime: string;
226
+ eventTimeZoneOffset: string;
227
+ /**
228
+ * **기록** 시각(ISO) — 발생 시각과 별개다.
229
+ *
230
+ * 이 둘이 어긋나는 것이 실 연동의 정상이다(현장에서 일어난 뒤 늦게 도착). 소비처가 순서를 판정할 때
231
+ * `eventTime` 만 보면 늦게 도착한 옛 이벤트가 최신 상태를 덮는다 — 그 판정의 재료가 이 값이다.
232
+ */
233
+ recordTime?: string;
234
+ bizStep: string;
235
+ disposition?: string;
236
+ readPoint?: LocationRef;
237
+ bizLocation?: LocationRef;
238
+ bizTransactionList?: BizTransactionElement[];
239
+ /** 정정 선언(있으면 이 이벤트는 앞선 이벤트를 정정하는 것이다). */
240
+ errorDeclaration?: ErrorDeclaration;
241
+ /**
242
+ * 개체·로트 마스터데이터 — **값이 같은 범위가 작은** 서술 속성(EPCIS 2.0 §7.3.8).
243
+ *
244
+ * 품목 마스터데이터(무게·치수)는 같은 GTIN 전부에 같은 값이지만, 이쪽은 **한 로트** 또는
245
+ * **한 개체**마다 다를 수 있다(대표 예: 유통기한). 그래서 물건이 처음 생겨나는 이벤트에 한 번 붙인다.
246
+ *
247
+ * 안에 들어가는 속성 이름은 **표준이 정의하지 않는다** — "이름 붙은 속성들의 집합(값은 임의 타입)"
248
+ * 이고 구체적 요소는 EPCIS 위에 얹히는 상위 문서가 정한다(§7.3.8). 그래서 커널은 자리만 열고 어휘를
249
+ * 발명하지 않으며, 받은 것을 **잃지 않고 통과**시킨다.
250
+ *
251
+ * **배치 규칙(§7.3.8)**: 개체가 존재하기 시작할 때 정의되므로 `ObjectEvent`(action=ADD)와
252
+ * `TransformationEvent` 에만 실을 수 있다. 변환에서는 **출력**에 적용된다(입력 아님).
253
+ * 그리고 객체의 생애 동안 **정적**인 것만 담는다 — 변하는 것은 이벤트의 몫이다.
254
+ */
255
+ ilmd?: Record<string, unknown>;
256
+ /** 이전 출발 당사자들(소유·보관 이전). */
257
+ sourceList?: SourceElement[];
258
+ /** 이전 도착 당사자들. */
259
+ destinationList?: DestinationElement[];
260
+ /** 이벤트 이후에도 유지되는 업무 조건(해제될 때까지). */
261
+ persistentDisposition?: PersistentDisposition;
262
+ /** 센서 관측 묶음(콜드체인 등). */
263
+ sensorElementList?: SensorElement[];
264
+ /** 인증 상세를 가리키는 URL(규제 산업). */
265
+ certificationInfo?: string;
266
+ }
267
+ /** action 을 갖는 이벤트(Object/Aggregation/Transaction). */
268
+ interface EpcisActionEvent extends EpcisHeader {
269
+ action: EpcisAction;
270
+ }
271
+ export interface EpcisObjectEvent extends EpcisActionEvent {
272
+ type: 'ObjectEvent';
273
+ epcList: string[];
274
+ quantityList?: QuantityElement[];
275
+ }
276
+ export interface EpcisAggregationEvent extends EpcisActionEvent {
277
+ type: 'AggregationEvent';
278
+ parentID: string;
279
+ childEPCs?: string[];
280
+ childQuantityList?: QuantityElement[];
281
+ }
282
+ export interface EpcisTransactionEvent extends EpcisActionEvent {
283
+ type: 'TransactionEvent';
284
+ bizTransactionList: BizTransactionElement[];
285
+ parentID?: string;
286
+ epcList?: string[];
287
+ quantityList?: QuantityElement[];
288
+ }
289
+ /** 변환(제조): 입력 소비 → 출력 생산. action 없음(EPCIS 2.0). */
290
+ export interface EpcisTransformationEvent extends EpcisHeader {
291
+ type: 'TransformationEvent';
292
+ inputEPCList?: string[];
293
+ inputQuantityList?: QuantityElement[];
294
+ outputEPCList?: string[];
295
+ outputQuantityList?: QuantityElement[];
296
+ transformationID?: string;
297
+ }
298
+ export type EpcisEvent = EpcisObjectEvent | EpcisAggregationEvent | EpcisTransactionEvent | EpcisTransformationEvent;
299
+ /** SSCC (물류단위: 팔레트/화물/트레일러) — 결정적 카운터 기반. */
300
+ export declare function ssccUri(companyPrefix: string, serial: number): string;
301
+ /** 비직렬 수량용 SGTIN 패턴(epcClass) — 로트를 따지지 않는 품목 클래스. quantityList 에 사용. */
302
+ export declare function sgtinClass(companyPrefix: string, itemRef: string): string;
303
+ /**
304
+ * 우리가 방출하는 개체·로트 마스터데이터의 속성 이름 — **한 곳에 모은다.**
305
+ *
306
+ * 표준은 이 이름들을 정의하지 않는다(§7.3.8: 상위 문서 소관). 그래서 값을 실으려면 이름을 정해야 하는데,
307
+ * 흩뿌리면 곧 방언이 된다. GS1 CBV 마스터데이터 이름공간(`urn:epcglobal:cbv:mda:`)의 정식 명칭을
308
+ * 확인하면 **이 상수만 바꾸면 되도록** 여기 모아 둔다.
309
+ *
310
+ * ⚠ 아래 이름은 **아직 정본 확인 전**이다(CBV 마스터데이터 문서 필요). 받는 경로는 이름과 무관하게
311
+ * 동작하므로(받은 것을 잃지 않고 통과) 이 상수는 우리가 **생산할 때**만 쓰인다.
312
+ */
313
+ export declare const ILMD_ATTR: {
314
+ /** 유통기한·만료(로트 단위). */
315
+ readonly expiry: "cbvmda:itemExpirationDate";
316
+ /** 로트·배치 번호(직렬 개체에 로트를 붙일 때). */
317
+ readonly lot: "cbvmda:lotNumber";
318
+ };
319
+ /**
320
+ * 품번 + 로트 클래스(LGTIN) — 낱개 일련번호가 없고 **로트로 관리**하는 자재의 표준 식별자.
321
+ *
322
+ * 원자재·화학·식품이 이 경우다. 로트가 식별자의 한 마디로 들어가므로 "로트별 재고" 가 별도 필드 없이
323
+ * epcClass 별 집계가 된다. 개체가 아니라 클래스이므로 `epcList` 가 아니라 `quantityList` 에 쓴다.
324
+ *
325
+ * 문법(EPC Tag Data Standard 2.1.0 §6.4.1):
326
+ * urn:epc:class:lgtin:CompanyPrefix.ItemRefAndIndicator.Lot
327
+ * 예) urn:epc:class:lgtin:4012345.012345.998877
328
+ * 두 숫자 마디의 자릿수 합은 13(점 제외), Lot 은 GS3A3Component(URI 이스케이프 허용).
329
+ */
330
+ export declare function lgtinClass(companyPrefix: string, itemRefAndIndicator: string, lot: string): string;
331
+ /** 식별자를 뜯어 본 결과 — 소비처가 문자열을 자르지 않게 한다(자르면 규칙이 어긋난다). */
332
+ export interface ParsedEpc {
333
+ /** 표준 스킴. 모르면 'unknown'(원문을 그대로 남긴다 — 추측하지 않는다). */
334
+ scheme: 'sgtin' | 'lgtin' | 'idpat' | 'sscc' | 'gdti' | 'grai' | 'giai' | 'sgln' | 'unknown';
335
+ /** 개체 단위인가(epcList 에 들어갈 것인가). 클래스 식별자는 false. */
336
+ instance: boolean;
337
+ /** 품목 클래스 키 — `CompanyPrefix.ItemRef`(sgtin/lgtin/idpat 에서). */
338
+ gtinKey?: string;
339
+ /** 로트 번호(LGTIN 에만 있다). */
340
+ lot?: string;
341
+ /** 일련번호(SGTIN·SSCC 등 개체 식별자에만). */
342
+ serial?: string;
343
+ /** 원문 — 해석에 실패해도 잃지 않는다. */
344
+ uri: string;
345
+ }
346
+ /**
347
+ * EPC/클래스 식별자 파서 — **표준 지식이라 커널이 소유한다.**
348
+ *
349
+ * 소비처가 `uri.split(':').pop()` 으로 자르면 규칙이 어긋난다(실제로 화면이 LGTIN 의 마지막 마디인
350
+ * 로트를 SKU 이름으로 표시할 위험이 있었다). 뜯는 일은 여기 한 곳에서 한다.
351
+ */
352
+ export declare function parseEpc(uri: string): ParsedEpc;
353
+ /** 거래문서 식별자 = GDTI (PO/SO/WO/어포인트먼트 등). */
354
+ export declare function gdtiUri(companyPrefix: string, docType: string, serial: number): string;
355
+ /**
356
+ * **선언된 이름공간 아래의 거래 문서 식별자** — GDTI 를 쓰지 않는 길.
357
+ *
358
+ * ── 왜 이 길이 필요한가 (2026-08-21) ───────────────────────────────────────
359
+ * GDTI 는 `회사 프리픽스 + 문서 타입 + 일련번호`이고 **문서 타입은 회사가 배정한다**(GS1 이 공표하는
360
+ * 목록이 아니다). 그런데 커널이 `'403'`(작업지시)·`'401'`·`'402'`·`'404'` 를 스스로 정하고 있었다.
361
+ *
362
+ * 표준은 거래 문서 식별자에 GDTI 만 요구하지 않는다. CBV 2.0 이 세 형태를 더 정한다:
363
+ * · §8.5.5 `http(s)://[Subdomain.]Domain/⁎⁎/bt/transID` — 그 도메인 소유자가 배정
364
+ * · §8.5.4 `urn:URNNamespace:⁎⁎:bt:transID` — URN 이름공간 소유자가 배정
365
+ * · §8.5.3 `urn:epcglobal:cbv:bt:gln:transID` — GLN 소유자가 배정
366
+ *
367
+ * `bt` 표지가 **필수**이고, `transID` 는 경로 성분 **하나**다(「only one URI path component SHALL
368
+ * follow the /bt/」). 그래서 회사가 **도메인만 있으면** 문서 타입을 정할 일이 없다 — 이것이 GDTI 보다
369
+ * 진입장벽이 낮은 길이다.
370
+ *
371
+ * 이름공간의 모양으로 URL 형태와 URN 형태를 가른다. 판정할 수 없는 모양이면 **답하지 않는다**(지어내지
372
+ * 않는다) — 호출부가 다른 길을 고르게 한다.
373
+ */
374
+ /**
375
+ * **선언된 이름공간 아래의 개체 식별자** — SSCC·GRAI 를 쓰지 않는 길.
376
+ *
377
+ * 팔레트(SSCC)·트레일러(GRAI)는 개체 식별자이고, 그 조립에는 GS1 회사 프리픽스가 필요하다. 프리픽스가
378
+ * 없는 현장은 그 길로 갈 수 없다 — 그런데 커널이 프리픽스를 지어내면 저널에 남의 번호가 영구히 남는다.
379
+ *
380
+ * 표준이 다른 길을 정해 두었다.
381
+ * · CBV 2.0 §8.2.4 `http(s)://[Subdomain.]Domain/⁎⁎/obj/Objid` — 그 도메인 소유자가 배정
382
+ * · CBV 2.0 §8.2.3 `urn:URNNamespace:⁎⁎:obj:Objid` — URN 이름공간 소유자가 배정
383
+ *
384
+ * `obj` 표지가 필수다(클래스의 `class`·거래문서의 `bt` 와 같은 구조다). 다만 표준은 EPC URI 나 Digital
385
+ * Link 를 **권한다**(SHOULD) — 이 길은 프리픽스가 없을 때의 정합 경로다.
386
+ */
387
+ export declare function objectUri(namespace: string, objId: string | number): string | undefined;
388
+ export declare function bizTransactionUri(namespace: string, transId: string | number): string | undefined;
389
+ /** 모든 빌더가 공통으로 받는 표준 헤더 옵션(선택) — 방출부가 필요할 때 채운다. */
390
+ export interface EpcisHeaderOptions {
391
+ eventID?: string;
392
+ recordTime?: string;
393
+ errorDeclaration?: ErrorDeclaration;
394
+ ilmd?: Record<string, unknown>;
395
+ sourceList?: SourceElement[];
396
+ destinationList?: DestinationElement[];
397
+ persistentDisposition?: PersistentDisposition;
398
+ sensorElementList?: SensorElement[];
399
+ certificationInfo?: string;
400
+ }
401
+ export declare function objectEvent(p: {
402
+ eventTime: string;
403
+ action: EpcisAction;
404
+ bizStep: string;
405
+ disposition?: string;
406
+ epcList: string[];
407
+ quantityList?: QuantityElement[];
408
+ readPoint?: string;
409
+ bizLocation?: string;
410
+ bizTransactionList?: BizTransactionElement[];
411
+ } & EpcisHeaderOptions): EpcisObjectEvent;
412
+ export declare function aggregationEvent(p: {
413
+ eventTime: string;
414
+ action: EpcisAction;
415
+ bizStep: string;
416
+ disposition?: string;
417
+ parentID: string;
418
+ childEPCs?: string[];
419
+ childQuantityList?: QuantityElement[];
420
+ readPoint?: string;
421
+ bizLocation?: string;
422
+ } & EpcisHeaderOptions): EpcisAggregationEvent;
423
+ export declare function transactionEvent(p: {
424
+ eventTime: string;
425
+ action: EpcisAction;
426
+ bizStep: string;
427
+ disposition?: string;
428
+ bizTransactionList: BizTransactionElement[];
429
+ parentID?: string;
430
+ epcList?: string[];
431
+ quantityList?: QuantityElement[];
432
+ readPoint?: string;
433
+ bizLocation?: string;
434
+ } & EpcisHeaderOptions): EpcisTransactionEvent;
435
+ /** 변환(제조) — 입력 EPC/수량 소비 → 출력 EPC/수량 생산. action 없음. */
436
+ export declare function transformationEvent(p: {
437
+ eventTime: string;
438
+ bizStep: string;
439
+ disposition?: string;
440
+ inputEPCList?: string[];
441
+ inputQuantityList?: QuantityElement[];
442
+ outputEPCList?: string[];
443
+ outputQuantityList?: QuantityElement[];
444
+ transformationID?: string;
445
+ readPoint?: string;
446
+ bizLocation?: string;
447
+ bizTransactionList?: BizTransactionElement[];
448
+ } & EpcisHeaderOptions): EpcisTransformationEvent;
449
+ /**
450
+ * 그 GS1 키의 자리 수가 맞나 — 어긋나면 왜인지 말한다.
451
+ *
452
+ * `urn:epc:{id,idpat,class}:<키>:<프리픽스>.<참조>[.<직렬>]` 모양만 본다. 그 밖의 형식(도메인 기반
453
+ * 식별자 등)은 이 규약의 대상이 아니므로 아무 말도 하지 않는다.
454
+ */
455
+ export declare function gs1KeyDigitViolation(uri: string | undefined): string | undefined;
456
+ export declare function classIdentifierViolation(epcClass: string | undefined): string | undefined;
457
+ export declare function validateEpcisEvent(e: EpcisEvent): string[];
458
+ export {};