@things-factory/ops-master 10.0.18

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 (181) hide show
  1. package/.dockerignore +31 -0
  2. package/dist-client/index.d.ts +1 -0
  3. package/dist-client/index.js +2 -0
  4. package/dist-client/index.js.map +1 -0
  5. package/dist-client/pages/master-axes.d.ts +33 -0
  6. package/dist-client/pages/master-axes.js +176 -0
  7. package/dist-client/pages/master-axes.js.map +1 -0
  8. package/dist-client/pages/master-list.d.ts +68 -0
  9. package/dist-client/pages/master-list.js +267 -0
  10. package/dist-client/pages/master-list.js.map +1 -0
  11. package/dist-client/route.d.ts +1 -0
  12. package/dist-client/route.js +8 -0
  13. package/dist-client/route.js.map +1 -0
  14. package/dist-client/tsconfig.tsbuildinfo +1 -0
  15. package/dist-server/index.d.ts +1 -0
  16. package/dist-server/index.js +5 -0
  17. package/dist-server/index.js.map +1 -0
  18. package/dist-server/service/asset/asset-lifecycle.d.ts +83 -0
  19. package/dist-server/service/asset/asset-lifecycle.js +99 -0
  20. package/dist-server/service/asset/asset-lifecycle.js.map +1 -0
  21. package/dist-server/service/asset/asset-master-resolver.d.ts +44 -0
  22. package/dist-server/service/asset/asset-master-resolver.js +140 -0
  23. package/dist-server/service/asset/asset-master-resolver.js.map +1 -0
  24. package/dist-server/service/asset/asset-master.d.ts +21 -0
  25. package/dist-server/service/asset/asset-master.js +25 -0
  26. package/dist-server/service/asset/asset-master.js.map +1 -0
  27. package/dist-server/service/asset/asset-query.d.ts +8 -0
  28. package/dist-server/service/asset/asset-query.js +50 -0
  29. package/dist-server/service/asset/asset-query.js.map +1 -0
  30. package/dist-server/service/asset/index.d.ts +6 -0
  31. package/dist-server/service/asset/index.js +10 -0
  32. package/dist-server/service/asset/index.js.map +1 -0
  33. package/dist-server/service/asset/physical-asset-class.d.ts +34 -0
  34. package/dist-server/service/asset/physical-asset-class.js +104 -0
  35. package/dist-server/service/asset/physical-asset-class.js.map +1 -0
  36. package/dist-server/service/asset/physical-asset.d.ts +53 -0
  37. package/dist-server/service/asset/physical-asset.js +123 -0
  38. package/dist-server/service/asset/physical-asset.js.map +1 -0
  39. package/dist-server/service/equipment/equipment-class.d.ts +34 -0
  40. package/dist-server/service/equipment/equipment-class.js +104 -0
  41. package/dist-server/service/equipment/equipment-class.js.map +1 -0
  42. package/dist-server/service/equipment/equipment-master-resolver.d.ts +60 -0
  43. package/dist-server/service/equipment/equipment-master-resolver.js +200 -0
  44. package/dist-server/service/equipment/equipment-master-resolver.js.map +1 -0
  45. package/dist-server/service/equipment/equipment-master.d.ts +29 -0
  46. package/dist-server/service/equipment/equipment-master.js +36 -0
  47. package/dist-server/service/equipment/equipment-master.js.map +1 -0
  48. package/dist-server/service/equipment/equipment-query.d.ts +8 -0
  49. package/dist-server/service/equipment/equipment-query.js +50 -0
  50. package/dist-server/service/equipment/equipment-query.js.map +1 -0
  51. package/dist-server/service/equipment/equipment.d.ts +45 -0
  52. package/dist-server/service/equipment/equipment.js +133 -0
  53. package/dist-server/service/equipment/equipment.js.map +1 -0
  54. package/dist-server/service/equipment/index.d.ts +8 -0
  55. package/dist-server/service/equipment/index.js +12 -0
  56. package/dist-server/service/equipment/index.js.map +1 -0
  57. package/dist-server/service/equipment/state-period-rules.d.ts +76 -0
  58. package/dist-server/service/equipment/state-period-rules.js +88 -0
  59. package/dist-server/service/equipment/state-period-rules.js.map +1 -0
  60. package/dist-server/service/equipment/stop-reason-query.d.ts +11 -0
  61. package/dist-server/service/equipment/stop-reason-query.js +39 -0
  62. package/dist-server/service/equipment/stop-reason-query.js.map +1 -0
  63. package/dist-server/service/equipment/stop-reason.d.ts +58 -0
  64. package/dist-server/service/equipment/stop-reason.js +114 -0
  65. package/dist-server/service/equipment/stop-reason.js.map +1 -0
  66. package/dist-server/service/index.d.ts +46 -0
  67. package/dist-server/service/index.js +80 -0
  68. package/dist-server/service/index.js.map +1 -0
  69. package/dist-server/service/location/index.d.ts +5 -0
  70. package/dist-server/service/location/index.js +9 -0
  71. package/dist-server/service/location/index.js.map +1 -0
  72. package/dist-server/service/location/location-master-resolver.d.ts +28 -0
  73. package/dist-server/service/location/location-master-resolver.js +80 -0
  74. package/dist-server/service/location/location-master-resolver.js.map +1 -0
  75. package/dist-server/service/location/location-master.d.ts +24 -0
  76. package/dist-server/service/location/location-master.js +27 -0
  77. package/dist-server/service/location/location-master.js.map +1 -0
  78. package/dist-server/service/location/location-query.d.ts +7 -0
  79. package/dist-server/service/location/location-query.js +41 -0
  80. package/dist-server/service/location/location-query.js.map +1 -0
  81. package/dist-server/service/location/operational-location.d.ts +52 -0
  82. package/dist-server/service/location/operational-location.js +132 -0
  83. package/dist-server/service/location/operational-location.js.map +1 -0
  84. package/dist-server/service/master-axis.d.ts +29 -0
  85. package/dist-server/service/master-axis.js +39 -0
  86. package/dist-server/service/master-axis.js.map +1 -0
  87. package/dist-server/service/master-crud.d.ts +44 -0
  88. package/dist-server/service/master-crud.js +73 -0
  89. package/dist-server/service/master-crud.js.map +1 -0
  90. package/dist-server/service/master-list.d.ts +12 -0
  91. package/dist-server/service/master-list.js +24 -0
  92. package/dist-server/service/master-list.js.map +1 -0
  93. package/dist-server/service/material/index.d.ts +6 -0
  94. package/dist-server/service/material/index.js +10 -0
  95. package/dist-server/service/material/index.js.map +1 -0
  96. package/dist-server/service/material/material-class.d.ts +34 -0
  97. package/dist-server/service/material/material-class.js +104 -0
  98. package/dist-server/service/material/material-class.js.map +1 -0
  99. package/dist-server/service/material/material-definition.d.ts +42 -0
  100. package/dist-server/service/material/material-definition.js +112 -0
  101. package/dist-server/service/material/material-definition.js.map +1 -0
  102. package/dist-server/service/material/material-master-resolver.d.ts +44 -0
  103. package/dist-server/service/material/material-master-resolver.js +140 -0
  104. package/dist-server/service/material/material-master-resolver.js.map +1 -0
  105. package/dist-server/service/material/material-master.d.ts +9 -0
  106. package/dist-server/service/material/material-master.js +24 -0
  107. package/dist-server/service/material/material-master.js.map +1 -0
  108. package/dist-server/service/material/material-query.d.ts +8 -0
  109. package/dist-server/service/material/material-query.js +50 -0
  110. package/dist-server/service/material/material-query.js.map +1 -0
  111. package/dist-server/service/operation/index.d.ts +5 -0
  112. package/dist-server/service/operation/index.js +9 -0
  113. package/dist-server/service/operation/index.js.map +1 -0
  114. package/dist-server/service/operation/operation-definition.d.ts +52 -0
  115. package/dist-server/service/operation/operation-definition.js +142 -0
  116. package/dist-server/service/operation/operation-definition.js.map +1 -0
  117. package/dist-server/service/operation/operation-master-resolver.d.ts +28 -0
  118. package/dist-server/service/operation/operation-master-resolver.js +80 -0
  119. package/dist-server/service/operation/operation-master-resolver.js.map +1 -0
  120. package/dist-server/service/operation/operation-master.d.ts +21 -0
  121. package/dist-server/service/operation/operation-master.js +28 -0
  122. package/dist-server/service/operation/operation-master.js.map +1 -0
  123. package/dist-server/service/operation/operation-query.d.ts +7 -0
  124. package/dist-server/service/operation/operation-query.js +41 -0
  125. package/dist-server/service/operation/operation-query.js.map +1 -0
  126. package/dist-server/service/personnel/index.d.ts +6 -0
  127. package/dist-server/service/personnel/index.js +10 -0
  128. package/dist-server/service/personnel/index.js.map +1 -0
  129. package/dist-server/service/personnel/person.d.ts +51 -0
  130. package/dist-server/service/personnel/person.js +119 -0
  131. package/dist-server/service/personnel/person.js.map +1 -0
  132. package/dist-server/service/personnel/personnel-class.d.ts +54 -0
  133. package/dist-server/service/personnel/personnel-class.js +114 -0
  134. package/dist-server/service/personnel/personnel-class.js.map +1 -0
  135. package/dist-server/service/personnel/personnel-master-resolver.d.ts +44 -0
  136. package/dist-server/service/personnel/personnel-master-resolver.js +140 -0
  137. package/dist-server/service/personnel/personnel-master-resolver.js.map +1 -0
  138. package/dist-server/service/personnel/personnel-master.d.ts +39 -0
  139. package/dist-server/service/personnel/personnel-master.js +34 -0
  140. package/dist-server/service/personnel/personnel-master.js.map +1 -0
  141. package/dist-server/service/personnel/personnel-query.d.ts +21 -0
  142. package/dist-server/service/personnel/personnel-query.js +57 -0
  143. package/dist-server/service/personnel/personnel-query.js.map +1 -0
  144. package/dist-server/service/personnel/qualification.d.ts +97 -0
  145. package/dist-server/service/personnel/qualification.js +122 -0
  146. package/dist-server/service/personnel/qualification.js.map +1 -0
  147. package/dist-server/service/resource/resource-class.d.ts +25 -0
  148. package/dist-server/service/resource/resource-class.js +29 -0
  149. package/dist-server/service/resource/resource-class.js.map +1 -0
  150. package/dist-server/service/status/axis-stamp.d.ts +16 -0
  151. package/dist-server/service/status/axis-stamp.js +22 -0
  152. package/dist-server/service/status/axis-stamp.js.map +1 -0
  153. package/dist-server/service/status/index.d.ts +3 -0
  154. package/dist-server/service/status/index.js +7 -0
  155. package/dist-server/service/status/index.js.map +1 -0
  156. package/dist-server/service/status/master-status.d.ts +45 -0
  157. package/dist-server/service/status/master-status.js +129 -0
  158. package/dist-server/service/status/master-status.js.map +1 -0
  159. package/dist-server/service/test-spec/index.d.ts +5 -0
  160. package/dist-server/service/test-spec/index.js +9 -0
  161. package/dist-server/service/test-spec/index.js.map +1 -0
  162. package/dist-server/service/test-spec/test-spec-master-resolver.d.ts +28 -0
  163. package/dist-server/service/test-spec/test-spec-master-resolver.js +80 -0
  164. package/dist-server/service/test-spec/test-spec-master-resolver.js.map +1 -0
  165. package/dist-server/service/test-spec/test-spec-master.d.ts +6 -0
  166. package/dist-server/service/test-spec/test-spec-master.js +18 -0
  167. package/dist-server/service/test-spec/test-spec-master.js.map +1 -0
  168. package/dist-server/service/test-spec/test-spec-query.d.ts +7 -0
  169. package/dist-server/service/test-spec/test-spec-query.js +41 -0
  170. package/dist-server/service/test-spec/test-spec-query.js.map +1 -0
  171. package/dist-server/service/test-spec/test-specification.d.ts +41 -0
  172. package/dist-server/service/test-spec/test-specification.js +106 -0
  173. package/dist-server/service/test-spec/test-specification.js.map +1 -0
  174. package/dist-server/tsconfig.tsbuildinfo +1 -0
  175. package/package.json +50 -0
  176. package/things-factory.config.js +12 -0
  177. package/translations/en.json +53 -0
  178. package/translations/ja.json +1 -0
  179. package/translations/ko.json +53 -0
  180. package/translations/ms.json +1 -0
  181. package/translations/zh.json +1 -0
@@ -0,0 +1,52 @@
1
+ import { Domain } from '@things-factory/shell';
2
+ import { User } from '@things-factory/auth-base';
3
+ /**
4
+ * 자리 — **ISA-95 `OperationalLocation`**.
5
+ *
6
+ * 표준 원문은 「자원이 놓이거나 놓일 것으로 예상되는 논리적·물리적 장소」다. 자기 계층을 재귀로 갖고,
7
+ * 설비는 자기 자리를 이것으로 가리킨다. 자리와 설비를 나눠 두는 것은 표준의 구조다.
8
+ *
9
+ * ── 용량을 지어내지 않는다 ──────────────────────────────────────────────────
10
+ * `capacity` 는 그 자리에 몇이 들어가는가다. 모르면 비워 둔다. 실측에서 임의로 1 을 넣었더니 물품
11
+ * 하나에 포화 경고가 났다 — 없는 것보다 나쁜 수다.
12
+ */
13
+ export declare class OperationalLocation {
14
+ readonly id: string;
15
+ domain?: Domain;
16
+ domainId?: string;
17
+ /** 표준 `ID` — 트윈으로 나갈 때 `locations[].id` 가 된다. */
18
+ name: string;
19
+ description?: string;
20
+ /** 자리 타입 — 도메인 카탈로그가 정한 키(`raw-store` · `weld-station` 같은 것). */
21
+ type: string;
22
+ /**
23
+ * ISA-95 설비 계층 단 — `ProductionLine` · `WorkCell` · `StorageZone` · `ProcessCell` · `Unit` 등.
24
+ *
25
+ * 적지 않으면 타입으로 알아낸다. 적으면 그것이 기준이다 — 현장이 자기 계층을 더 잘 안다.
26
+ */
27
+ level?: string;
28
+ /** 이 자리에 몇이 들어가나. **모르면 비운다.** */
29
+ capacity?: number;
30
+ /** 동시에 몇을 처리하나(대기 이론의 서버 수). 표준에 없는 우리 축이다. */
31
+ parallelism?: number;
32
+ /** 상위 자리 — 표준 `OperationalLocationChild`(재귀)의 반대 방향. */
33
+ parentId?: string;
34
+ /** 자리 속성 — 표준 `OperationalLocationProperty`. */
35
+ properties?: Record<string, unknown>[];
36
+ /** 이 자리에 걸리는 `TestSpecification` 참조들 — 구역 온도 기준 같은 것이 여기 붙는다. */
37
+ testSpecificationIds?: string[];
38
+ /** 언제부터 유효한가 — 표준 `EffectiveStartDate`. */
39
+ effectiveStart?: Date;
40
+ /**
41
+ * 언제까지 유효한가 — 표준 `EffectiveEndDate`.
42
+ *
43
+ * **없앨 때 행을 지우지 않고 이 칸을 채운다.** 지우면 그것을 가리키는 지난 기록이 가리킬 것을 잃는다.
44
+ */
45
+ effectiveEnd?: Date;
46
+ createdAt?: Date;
47
+ updatedAt?: Date;
48
+ creator?: User;
49
+ creatorId?: string;
50
+ updater?: User;
51
+ updaterId?: string;
52
+ }
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OperationalLocation = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const typeorm_1 = require("typeorm");
6
+ const type_graphql_1 = require("type-graphql");
7
+ const shell_1 = require("@things-factory/shell");
8
+ const auth_base_1 = require("@things-factory/auth-base");
9
+ /**
10
+ * 자리 — **ISA-95 `OperationalLocation`**.
11
+ *
12
+ * 표준 원문은 「자원이 놓이거나 놓일 것으로 예상되는 논리적·물리적 장소」다. 자기 계층을 재귀로 갖고,
13
+ * 설비는 자기 자리를 이것으로 가리킨다. 자리와 설비를 나눠 두는 것은 표준의 구조다.
14
+ *
15
+ * ── 용량을 지어내지 않는다 ──────────────────────────────────────────────────
16
+ * `capacity` 는 그 자리에 몇이 들어가는가다. 모르면 비워 둔다. 실측에서 임의로 1 을 넣었더니 물품
17
+ * 하나에 포화 경고가 났다 — 없는 것보다 나쁜 수다.
18
+ */
19
+ let OperationalLocation = class OperationalLocation {
20
+ };
21
+ exports.OperationalLocation = OperationalLocation;
22
+ tslib_1.__decorate([
23
+ (0, typeorm_1.PrimaryGeneratedColumn)('uuid'),
24
+ (0, type_graphql_1.Field)(type => type_graphql_1.ID),
25
+ tslib_1.__metadata("design:type", String)
26
+ ], OperationalLocation.prototype, "id", void 0);
27
+ tslib_1.__decorate([
28
+ (0, typeorm_1.ManyToOne)(type => shell_1.Domain),
29
+ (0, type_graphql_1.Field)(type => shell_1.Domain),
30
+ tslib_1.__metadata("design:type", shell_1.Domain)
31
+ ], OperationalLocation.prototype, "domain", void 0);
32
+ tslib_1.__decorate([
33
+ (0, typeorm_1.RelationId)((location) => location.domain),
34
+ tslib_1.__metadata("design:type", String)
35
+ ], OperationalLocation.prototype, "domainId", void 0);
36
+ tslib_1.__decorate([
37
+ (0, typeorm_1.Column)(),
38
+ (0, type_graphql_1.Field)(),
39
+ tslib_1.__metadata("design:type", String)
40
+ ], OperationalLocation.prototype, "name", void 0);
41
+ tslib_1.__decorate([
42
+ (0, typeorm_1.Column)({ nullable: true }),
43
+ (0, type_graphql_1.Field)({ nullable: true }),
44
+ tslib_1.__metadata("design:type", String)
45
+ ], OperationalLocation.prototype, "description", void 0);
46
+ tslib_1.__decorate([
47
+ (0, typeorm_1.Column)(),
48
+ (0, type_graphql_1.Field)(),
49
+ tslib_1.__metadata("design:type", String)
50
+ ], OperationalLocation.prototype, "type", void 0);
51
+ tslib_1.__decorate([
52
+ (0, typeorm_1.Column)({ nullable: true }),
53
+ (0, type_graphql_1.Field)({ nullable: true }),
54
+ tslib_1.__metadata("design:type", String)
55
+ ], OperationalLocation.prototype, "level", void 0);
56
+ tslib_1.__decorate([
57
+ (0, typeorm_1.Column)({ type: 'int', nullable: true }),
58
+ (0, type_graphql_1.Field)(type => type_graphql_1.Int, { nullable: true }),
59
+ tslib_1.__metadata("design:type", Number)
60
+ ], OperationalLocation.prototype, "capacity", void 0);
61
+ tslib_1.__decorate([
62
+ (0, typeorm_1.Column)({ type: 'int', nullable: true }),
63
+ (0, type_graphql_1.Field)(type => type_graphql_1.Int, { nullable: true }),
64
+ tslib_1.__metadata("design:type", Number)
65
+ ], OperationalLocation.prototype, "parallelism", void 0);
66
+ tslib_1.__decorate([
67
+ (0, typeorm_1.Column)({ nullable: true }),
68
+ (0, type_graphql_1.Field)({ nullable: true }),
69
+ tslib_1.__metadata("design:type", String)
70
+ ], OperationalLocation.prototype, "parentId", void 0);
71
+ tslib_1.__decorate([
72
+ (0, typeorm_1.Column)({ type: 'simple-json', nullable: true }),
73
+ (0, type_graphql_1.Field)(type => String, { nullable: true, description: 'ResourceProperty[] as JSON text' }),
74
+ tslib_1.__metadata("design:type", Array)
75
+ ], OperationalLocation.prototype, "properties", void 0);
76
+ tslib_1.__decorate([
77
+ (0, typeorm_1.Column)({ type: 'simple-json', nullable: true }),
78
+ (0, type_graphql_1.Field)(type => [String], { nullable: true }),
79
+ tslib_1.__metadata("design:type", Array)
80
+ ], OperationalLocation.prototype, "testSpecificationIds", void 0);
81
+ tslib_1.__decorate([
82
+ (0, typeorm_1.Column)({ nullable: true }),
83
+ (0, type_graphql_1.Field)({ nullable: true }),
84
+ tslib_1.__metadata("design:type", Date
85
+ /**
86
+ * 언제까지 유효한가 — 표준 `EffectiveEndDate`.
87
+ *
88
+ * **없앨 때 행을 지우지 않고 이 칸을 채운다.** 지우면 그것을 가리키는 지난 기록이 가리킬 것을 잃는다.
89
+ */
90
+ )
91
+ ], OperationalLocation.prototype, "effectiveStart", void 0);
92
+ tslib_1.__decorate([
93
+ (0, typeorm_1.Column)({ nullable: true }),
94
+ (0, type_graphql_1.Field)({ nullable: true }),
95
+ tslib_1.__metadata("design:type", Date)
96
+ ], OperationalLocation.prototype, "effectiveEnd", void 0);
97
+ tslib_1.__decorate([
98
+ (0, typeorm_1.CreateDateColumn)(),
99
+ (0, type_graphql_1.Field)({ nullable: true }),
100
+ tslib_1.__metadata("design:type", Date)
101
+ ], OperationalLocation.prototype, "createdAt", void 0);
102
+ tslib_1.__decorate([
103
+ (0, typeorm_1.UpdateDateColumn)(),
104
+ (0, type_graphql_1.Field)({ nullable: true }),
105
+ tslib_1.__metadata("design:type", Date)
106
+ ], OperationalLocation.prototype, "updatedAt", void 0);
107
+ tslib_1.__decorate([
108
+ (0, typeorm_1.ManyToOne)(type => auth_base_1.User, { nullable: true }),
109
+ (0, type_graphql_1.Field)(type => auth_base_1.User, { nullable: true }),
110
+ tslib_1.__metadata("design:type", auth_base_1.User)
111
+ ], OperationalLocation.prototype, "creator", void 0);
112
+ tslib_1.__decorate([
113
+ (0, typeorm_1.RelationId)((location) => location.creator),
114
+ tslib_1.__metadata("design:type", String)
115
+ ], OperationalLocation.prototype, "creatorId", void 0);
116
+ tslib_1.__decorate([
117
+ (0, typeorm_1.ManyToOne)(type => auth_base_1.User, { nullable: true }),
118
+ (0, type_graphql_1.Field)(type => auth_base_1.User, { nullable: true }),
119
+ tslib_1.__metadata("design:type", auth_base_1.User)
120
+ ], OperationalLocation.prototype, "updater", void 0);
121
+ tslib_1.__decorate([
122
+ (0, typeorm_1.RelationId)((location) => location.updater),
123
+ tslib_1.__metadata("design:type", String)
124
+ ], OperationalLocation.prototype, "updaterId", void 0);
125
+ exports.OperationalLocation = OperationalLocation = tslib_1.__decorate([
126
+ (0, typeorm_1.Entity)({ name: 'ops_operational_location' }),
127
+ (0, typeorm_1.Index)('ix_ops_operational_location_0', (location) => [location.domain, location.name], {
128
+ unique: true
129
+ }),
130
+ (0, type_graphql_1.ObjectType)({ description: 'ISA-95 OperationalLocation — where resources are placed' })
131
+ ], OperationalLocation);
132
+ //# sourceMappingURL=operational-location.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operational-location.js","sourceRoot":"","sources":["../../../server/service/location/operational-location.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Column,\n CreateDateColumn,\n Entity,\n Index,\n ManyToOne,\n PrimaryGeneratedColumn,\n RelationId,\n UpdateDateColumn\n} from 'typeorm'\nimport { Field, ID, Int, ObjectType } from 'type-graphql'\n\nimport { Domain } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\n\n/**\n * 자리 — **ISA-95 `OperationalLocation`**.\n *\n * 표준 원문은 「자원이 놓이거나 놓일 것으로 예상되는 논리적·물리적 장소」다. 자기 계층을 재귀로 갖고,\n * 설비는 자기 자리를 이것으로 가리킨다. 자리와 설비를 나눠 두는 것은 표준의 구조다.\n *\n * ── 용량을 지어내지 않는다 ──────────────────────────────────────────────────\n * `capacity` 는 그 자리에 몇이 들어가는가다. 모르면 비워 둔다. 실측에서 임의로 1 을 넣었더니 물품\n * 하나에 포화 경고가 났다 — 없는 것보다 나쁜 수다.\n */\n@Entity({ name: 'ops_operational_location' })\n@Index('ix_ops_operational_location_0', (location: OperationalLocation) => [location.domain, location.name], {\n unique: true\n})\n@ObjectType({ description: 'ISA-95 OperationalLocation — where resources are placed' })\nexport class OperationalLocation {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID)\n readonly id: string\n\n @ManyToOne(type => Domain)\n @Field(type => Domain)\n domain?: Domain\n\n @RelationId((location: OperationalLocation) => location.domain)\n domainId?: string\n\n /** 표준 `ID` — 트윈으로 나갈 때 `locations[].id` 가 된다. */\n @Column()\n @Field()\n name: string\n\n @Column({ nullable: true })\n @Field({ nullable: true })\n description?: string\n\n /** 자리 타입 — 도메인 카탈로그가 정한 키(`raw-store` · `weld-station` 같은 것). */\n @Column()\n @Field()\n type: string\n\n /**\n * ISA-95 설비 계층 단 — `ProductionLine` · `WorkCell` · `StorageZone` · `ProcessCell` · `Unit` 등.\n *\n * 적지 않으면 타입으로 알아낸다. 적으면 그것이 기준이다 — 현장이 자기 계층을 더 잘 안다.\n */\n @Column({ nullable: true })\n @Field({ nullable: true })\n level?: string\n\n /** 이 자리에 몇이 들어가나. **모르면 비운다.** */\n @Column({ type: 'int', nullable: true })\n @Field(type => Int, { nullable: true })\n capacity?: number\n\n /** 동시에 몇을 처리하나(대기 이론의 서버 수). 표준에 없는 우리 축이다. */\n @Column({ type: 'int', nullable: true })\n @Field(type => Int, { nullable: true })\n parallelism?: number\n\n /** 상위 자리 — 표준 `OperationalLocationChild`(재귀)의 반대 방향. */\n @Column({ nullable: true })\n @Field({ nullable: true })\n parentId?: string\n\n /** 자리 속성 — 표준 `OperationalLocationProperty`. */\n @Column({ type: 'simple-json', nullable: true })\n @Field(type => String, { nullable: true, description: 'ResourceProperty[] as JSON text' })\n properties?: Record<string, unknown>[]\n\n /** 이 자리에 걸리는 `TestSpecification` 참조들 — 구역 온도 기준 같은 것이 여기 붙는다. */\n @Column({ type: 'simple-json', nullable: true })\n @Field(type => [String], { nullable: true })\n testSpecificationIds?: string[]\n\n /** 언제부터 유효한가 — 표준 `EffectiveStartDate`. */\n @Column({ nullable: true })\n @Field({ nullable: true })\n effectiveStart?: Date\n\n /**\n * 언제까지 유효한가 — 표준 `EffectiveEndDate`.\n *\n * **없앨 때 행을 지우지 않고 이 칸을 채운다.** 지우면 그것을 가리키는 지난 기록이 가리킬 것을 잃는다.\n */\n @Column({ nullable: true })\n @Field({ nullable: true })\n effectiveEnd?: Date\n\n @CreateDateColumn()\n @Field({ nullable: true })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true })\n updatedAt?: Date\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true })\n creator?: User\n\n @RelationId((location: OperationalLocation) => location.creator)\n creatorId?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true })\n updater?: User\n\n @RelationId((location: OperationalLocation) => location.updater)\n updaterId?: string\n}\n"]}
@@ -0,0 +1,29 @@
1
+ import { ObjectLiteral } from 'typeorm';
2
+ /**
3
+ * 마스터 열두 축의 **한 줄짜리 선언** — 축마다 다른 것만 적는다.
4
+ *
5
+ * ── 왜 표로 두나 ───────────────────────────────────────────────────────────
6
+ * 축이 열둘인데 조회와 저장은 모양이 같다. 축마다 리졸버를 통째로 베끼면 같은 코드가 열두 벌이 되고,
7
+ * 규칙 하나를 고칠 때 열두 곳을 고쳐야 한다. 그러다 한 곳을 빠뜨리면 그 축만 다르게 동작하는데
8
+ * 오류는 나지 않는다.
9
+ *
10
+ * 그래서 **다른 것만** 적는다 — 어느 표인가, 무엇으로 찾는가, 없앨 때 지우는가 끝을 채우는가.
11
+ *
12
+ * ── 왜 유효 기간 여부가 여기 있나 ──────────────────────────────────────────
13
+ * 지난 기록이 가리키는 축은 지우면 안 된다. 그것이 축마다 다르므로 축의 성질로 적는다. 정지 사유는
14
+ * 유효 기간이 있고, 등급도 있다. 지금 열둘 모두 유효 기간을 갖는다 — 그래도 칸을 둔다. 없는 축이
15
+ * 생기면 그때 이 표만 고치면 된다.
16
+ */
17
+ export interface MasterAxis {
18
+ /** GraphQL 이름의 바탕. `person` → `persons` · `updateMultiplePerson`. */
19
+ key: string;
20
+ entity: {
21
+ new (): ObjectLiteral;
22
+ };
23
+ /** 검색어가 걸리는 칸들. */
24
+ searchables: string[];
25
+ /** 없앨 때 행을 지우지 않고 `effectiveEnd` 를 채우나. */
26
+ hasEffectivePeriod: boolean;
27
+ }
28
+ export declare const MASTER_AXES: readonly MasterAxis[];
29
+ export declare function masterAxisOf(key: string): MasterAxis;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MASTER_AXES = void 0;
4
+ exports.masterAxisOf = masterAxisOf;
5
+ const equipment_1 = require("./equipment/equipment");
6
+ const equipment_class_1 = require("./equipment/equipment-class");
7
+ const stop_reason_1 = require("./equipment/stop-reason");
8
+ const material_class_1 = require("./material/material-class");
9
+ const material_definition_1 = require("./material/material-definition");
10
+ const operation_definition_1 = require("./operation/operation-definition");
11
+ const operational_location_1 = require("./location/operational-location");
12
+ const person_1 = require("./personnel/person");
13
+ const personnel_class_1 = require("./personnel/personnel-class");
14
+ const physical_asset_1 = require("./asset/physical-asset");
15
+ const physical_asset_class_1 = require("./asset/physical-asset-class");
16
+ const test_specification_1 = require("./test-spec/test-specification");
17
+ exports.MASTER_AXES = [
18
+ { key: 'personnelClass', entity: personnel_class_1.PersonnelClass, searchables: ['name', 'description'], hasEffectivePeriod: true },
19
+ { key: 'person', entity: person_1.Person, searchables: ['name', 'description'], hasEffectivePeriod: true },
20
+ { key: 'equipmentClass', entity: equipment_class_1.EquipmentClass, searchables: ['name', 'description'], hasEffectivePeriod: true },
21
+ { key: 'equipment', entity: equipment_1.Equipment, searchables: ['name', 'description'], hasEffectivePeriod: true },
22
+ { key: 'stopReason', entity: stop_reason_1.StopReason, searchables: ['name', 'description'], hasEffectivePeriod: true },
23
+ { key: 'physicalAssetClass', entity: physical_asset_class_1.PhysicalAssetClass, searchables: ['name', 'description'], hasEffectivePeriod: true },
24
+ { key: 'physicalAsset', entity: physical_asset_1.PhysicalAsset, searchables: ['name', 'description', 'identity'], hasEffectivePeriod: true },
25
+ { key: 'materialClass', entity: material_class_1.MaterialClass, searchables: ['name', 'description'], hasEffectivePeriod: true },
26
+ { key: 'materialDefinition', entity: material_definition_1.MaterialDefinition, searchables: ['name', 'description', 'identity'], hasEffectivePeriod: true },
27
+ { key: 'operationalLocation', entity: operational_location_1.OperationalLocation, searchables: ['name', 'description'], hasEffectivePeriod: true },
28
+ { key: 'operationDefinition', entity: operation_definition_1.OperationDefinition, searchables: ['name', 'description'], hasEffectivePeriod: true },
29
+ { key: 'testSpecification', entity: test_specification_1.TestSpecification, searchables: ['name', 'description'], hasEffectivePeriod: true }
30
+ ];
31
+ function masterAxisOf(key) {
32
+ const axis = exports.MASTER_AXES.find(candidate => candidate.key === key);
33
+ if (!axis) {
34
+ /* 없는 축을 조용히 지나치지 않는다 — 지나치면 그 축의 화면이 빈 목록을 보이고 아무도 모른다. */
35
+ throw new Error(`masterAxisOf: unknown master axis "${key}"`);
36
+ }
37
+ return axis;
38
+ }
39
+ //# sourceMappingURL=master-axis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"master-axis.js","sourceRoot":"","sources":["../../server/service/master-axis.ts"],"names":[],"mappings":";;;AAwDA,oCASC;AA/DD,qDAAiD;AACjD,iEAA4D;AAC5D,yDAAoD;AACpD,8DAAyD;AACzD,wEAAmE;AACnE,2EAAsE;AACtE,0EAAqE;AACrE,+CAA2C;AAC3C,iEAA4D;AAC5D,2DAAsD;AACtD,uEAAiE;AACjE,uEAAkE;AA4BrD,QAAA,WAAW,GAA0B;IAChD,EAAE,GAAG,EAAE,gBAAgB,EAAE,MAAM,EAAE,gCAAc,EAAE,WAAW,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE,kBAAkB,EAAE,IAAI,EAAE;IACjH,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,eAAM,EAAE,WAAW,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE,kBAAkB,EAAE,IAAI,EAAE;IACjG,EAAE,GAAG,EAAE,gBAAgB,EAAE,MAAM,EAAE,gCAAc,EAAE,WAAW,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE,kBAAkB,EAAE,IAAI,EAAE;IACjH,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,qBAAS,EAAE,WAAW,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE,kBAAkB,EAAE,IAAI,EAAE;IACvG,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,wBAAU,EAAE,WAAW,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE,kBAAkB,EAAE,IAAI,EAAE;IACzG,EAAE,GAAG,EAAE,oBAAoB,EAAE,MAAM,EAAE,yCAAkB,EAAE,WAAW,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE,kBAAkB,EAAE,IAAI,EAAE;IACzH,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,8BAAa,EAAE,WAAW,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,UAAU,CAAC,EAAE,kBAAkB,EAAE,IAAI,EAAE;IAC3H,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,8BAAa,EAAE,WAAW,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE,kBAAkB,EAAE,IAAI,EAAE;IAC/G,EAAE,GAAG,EAAE,oBAAoB,EAAE,MAAM,EAAE,wCAAkB,EAAE,WAAW,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,UAAU,CAAC,EAAE,kBAAkB,EAAE,IAAI,EAAE;IACrI,EAAE,GAAG,EAAE,qBAAqB,EAAE,MAAM,EAAE,0CAAmB,EAAE,WAAW,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE,kBAAkB,EAAE,IAAI,EAAE;IAC3H,EAAE,GAAG,EAAE,qBAAqB,EAAE,MAAM,EAAE,0CAAmB,EAAE,WAAW,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE,kBAAkB,EAAE,IAAI,EAAE;IAC3H,EAAE,GAAG,EAAE,mBAAmB,EAAE,MAAM,EAAE,sCAAiB,EAAE,WAAW,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE,kBAAkB,EAAE,IAAI,EAAE;CACxH,CAAA;AAED,SAAgB,YAAY,CAAC,GAAW;IACtC,MAAM,IAAI,GAAG,mBAAW,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,KAAK,GAAG,CAAC,CAAA;IAEjE,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,2DAA2D;QAC3D,MAAM,IAAI,KAAK,CAAC,sCAAsC,GAAG,GAAG,CAAC,CAAA;IAC/D,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC","sourcesContent":["import { ObjectLiteral } from 'typeorm'\n\nimport { Equipment } from './equipment/equipment'\nimport { EquipmentClass } from './equipment/equipment-class'\nimport { StopReason } from './equipment/stop-reason'\nimport { MaterialClass } from './material/material-class'\nimport { MaterialDefinition } from './material/material-definition'\nimport { OperationDefinition } from './operation/operation-definition'\nimport { OperationalLocation } from './location/operational-location'\nimport { Person } from './personnel/person'\nimport { PersonnelClass } from './personnel/personnel-class'\nimport { PhysicalAsset } from './asset/physical-asset'\nimport { PhysicalAssetClass } from './asset/physical-asset-class'\nimport { TestSpecification } from './test-spec/test-specification'\n\n/**\n * 마스터 열두 축의 **한 줄짜리 선언** — 축마다 다른 것만 적는다.\n *\n * ── 왜 표로 두나 ───────────────────────────────────────────────────────────\n * 축이 열둘인데 조회와 저장은 모양이 같다. 축마다 리졸버를 통째로 베끼면 같은 코드가 열두 벌이 되고,\n * 규칙 하나를 고칠 때 열두 곳을 고쳐야 한다. 그러다 한 곳을 빠뜨리면 그 축만 다르게 동작하는데\n * 오류는 나지 않는다.\n *\n * 그래서 **다른 것만** 적는다 — 어느 표인가, 무엇으로 찾는가, 없앨 때 지우는가 끝을 채우는가.\n *\n * ── 왜 유효 기간 여부가 여기 있나 ──────────────────────────────────────────\n * 지난 기록이 가리키는 축은 지우면 안 된다. 그것이 축마다 다르므로 축의 성질로 적는다. 정지 사유는\n * 유효 기간이 있고, 등급도 있다. 지금 열둘 모두 유효 기간을 갖는다 — 그래도 칸을 둔다. 없는 축이\n * 생기면 그때 이 표만 고치면 된다.\n */\n\nexport interface MasterAxis {\n /** GraphQL 이름의 바탕. `person` → `persons` · `updateMultiplePerson`. */\n key: string\n entity: { new (): ObjectLiteral }\n /** 검색어가 걸리는 칸들. */\n searchables: string[]\n /** 없앨 때 행을 지우지 않고 `effectiveEnd` 를 채우나. */\n hasEffectivePeriod: boolean\n}\n\nexport const MASTER_AXES: readonly MasterAxis[] = [\n { key: 'personnelClass', entity: PersonnelClass, searchables: ['name', 'description'], hasEffectivePeriod: true },\n { key: 'person', entity: Person, searchables: ['name', 'description'], hasEffectivePeriod: true },\n { key: 'equipmentClass', entity: EquipmentClass, searchables: ['name', 'description'], hasEffectivePeriod: true },\n { key: 'equipment', entity: Equipment, searchables: ['name', 'description'], hasEffectivePeriod: true },\n { key: 'stopReason', entity: StopReason, searchables: ['name', 'description'], hasEffectivePeriod: true },\n { key: 'physicalAssetClass', entity: PhysicalAssetClass, searchables: ['name', 'description'], hasEffectivePeriod: true },\n { key: 'physicalAsset', entity: PhysicalAsset, searchables: ['name', 'description', 'identity'], hasEffectivePeriod: true },\n { key: 'materialClass', entity: MaterialClass, searchables: ['name', 'description'], hasEffectivePeriod: true },\n { key: 'materialDefinition', entity: MaterialDefinition, searchables: ['name', 'description', 'identity'], hasEffectivePeriod: true },\n { key: 'operationalLocation', entity: OperationalLocation, searchables: ['name', 'description'], hasEffectivePeriod: true },\n { key: 'operationDefinition', entity: OperationDefinition, searchables: ['name', 'description'], hasEffectivePeriod: true },\n { key: 'testSpecification', entity: TestSpecification, searchables: ['name', 'description'], hasEffectivePeriod: true }\n]\n\nexport function masterAxisOf(key: string): MasterAxis {\n const axis = MASTER_AXES.find(candidate => candidate.key === key)\n\n if (!axis) {\n /* 없는 축을 조용히 지나치지 않는다 — 지나치면 그 축의 화면이 빈 목록을 보이고 아무도 모른다. */\n throw new Error(`masterAxisOf: unknown master axis \"${key}\"`)\n }\n\n return axis\n}\n"]}
@@ -0,0 +1,44 @@
1
+ import { EntityManager, ObjectLiteral } from 'typeorm';
2
+ import { Domain } from '@things-factory/shell';
3
+ /**
4
+ * 마스터를 채우고 고치는 **한 벌의 규칙** — 열두 축이 같은 함수를 쓴다.
5
+ *
6
+ * ── 왜 마스터는 그리드에서 고칠 수 있나 ────────────────────────────────────
7
+ * 업무 화면(실적 · 검사 · 처분)은 조회 전용이다. 그것은 **일어난 일의 기록**이라, 고칠 수 있으면
8
+ * 「그때 무엇이 있었나」가 「지금 무엇으로 적혀 있나」로 바뀐다.
9
+ *
10
+ * 마스터는 다르다. 「이 사람이 용접 자격을 갖는다」는 일어난 일이 아니라 **선언**이다. 선언은 바뀌고,
11
+ * 바뀐 것이 지금의 선언이다. 그래서 그리드에서 고친다.
12
+ *
13
+ * ── 지우는 것만 다르게 다룬다 ──────────────────────────────────────────────
14
+ * 유효 기간을 가진 축은 **행을 지우지 않는다.** 지우면 그것을 가리키는 지난 기록이 가리킬 것을 잃는다
15
+ * (어제 실적이 가리키던 설비가 사라지면 그 실적은 어느 설비의 것도 아니게 된다). 대신
16
+ * `effectiveEnd` 를 채워 오늘부터 유효하지 않게 한다.
17
+ *
18
+ * 유효 기간이 없는 축만 실제로 지운다.
19
+ */
20
+ /** 그리드가 보내는 표식. `+` 새로 만든 행 · `M` 고친 행 · `-` 지운 행. */
21
+ export type CuFlag = '+' | 'M' | '-';
22
+ export interface MasterPatch {
23
+ id?: string;
24
+ cuFlag?: string;
25
+ [key: string]: unknown;
26
+ }
27
+ type EntityClass = {
28
+ new (): ObjectLiteral;
29
+ };
30
+ export interface SaveMasterOptions {
31
+ /**
32
+ * 유효 기간을 갖는 축인가.
33
+ *
34
+ * 참이면 지우기가 **`effectiveEnd` 를 채우는 것**이 된다. 거짓이면 행을 지운다.
35
+ */
36
+ hasEffectivePeriod?: boolean;
37
+ }
38
+ /**
39
+ * 그리드가 보낸 변경을 한 번에 적용한다.
40
+ *
41
+ * 한 트랜잭션에서 처리한다 — 절반만 반영되면 그리드가 보여 주는 것과 저장된 것이 갈린다.
42
+ */
43
+ export declare function saveMasterPatches(manager: EntityManager, domain: Domain, entity: EntityClass, patches: readonly MasterPatch[], user: unknown, options?: SaveMasterOptions): Promise<ObjectLiteral[]>;
44
+ export {};
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.saveMasterPatches = saveMasterPatches;
4
+ const typeorm_1 = require("typeorm");
5
+ /**
6
+ * 그리드가 보낸 변경을 한 번에 적용한다.
7
+ *
8
+ * 한 트랜잭션에서 처리한다 — 절반만 반영되면 그리드가 보여 주는 것과 저장된 것이 갈린다.
9
+ */
10
+ async function saveMasterPatches(manager, domain, entity, patches, user, options = {}) {
11
+ const repository = manager.getRepository(entity);
12
+ const results = [];
13
+ const created = patches.filter(patch => flagOf(patch) === '+');
14
+ const updated = patches.filter(patch => flagOf(patch) === 'M');
15
+ const removed = patches.filter(patch => flagOf(patch) === '-');
16
+ for (const patch of created) {
17
+ /* 새 행의 `id` 는 그리드가 임시로 붙인 것이다 — 그대로 저장하면 그것이 진짜 키가 된다. */
18
+ const { cuFlag, id, ...values } = patch;
19
+ results.push(await repository.save({ ...values, domain, creator: user, updater: user }));
20
+ }
21
+ for (const patch of updated) {
22
+ const { cuFlag, id, ...values } = patch;
23
+ if (!id) {
24
+ throw new Error('saveMasterPatches: a changed row must carry its id');
25
+ }
26
+ const found = await repository.findOne({ where: { domain: { id: domain.id }, id } });
27
+ /*
28
+ * 없는 행을 고치라고 하면 만들지 않는다. 다른 사람이 지웠거나 다른 도메인의 행이고, 둘 다
29
+ * 조용히 새 행을 만들 일이 아니다.
30
+ */
31
+ if (!found) {
32
+ throw new Error(`saveMasterPatches: no such row to change — ${String(id)}`);
33
+ }
34
+ results.push(await repository.save({ ...found, ...values, updater: user }));
35
+ }
36
+ if (removed.length) {
37
+ await retire(repository, domain, removed, user, options);
38
+ }
39
+ return results;
40
+ }
41
+ /**
42
+ * 없앤다 — 유효 기간이 있으면 **끝을 채우고**, 없으면 지운다.
43
+ */
44
+ async function retire(repository, domain, removed, user, options) {
45
+ const ids = removed.map(patch => patch.id).filter(Boolean);
46
+ if (!ids.length) {
47
+ return;
48
+ }
49
+ if (!options.hasEffectivePeriod) {
50
+ await repository.delete({ domain: { id: domain.id }, id: (0, typeorm_1.In)(ids) });
51
+ return;
52
+ }
53
+ const rows = await repository.find({ where: { domain: { id: domain.id }, id: (0, typeorm_1.In)(ids) } });
54
+ const now = new Date();
55
+ for (const row of rows) {
56
+ /*
57
+ * 이미 끝이 적혀 있으면 그대로 둔다. 다시 오늘로 바꾸면 「언제부터 안 썼나」가 바뀐다.
58
+ */
59
+ if (row.effectiveEnd) {
60
+ continue;
61
+ }
62
+ await repository.save({ ...row, effectiveEnd: now, updater: user });
63
+ }
64
+ }
65
+ function flagOf(patch) {
66
+ const flag = String(patch.cuFlag ?? '').toUpperCase();
67
+ if (flag === '+' || flag === 'M' || flag === '-') {
68
+ return flag;
69
+ }
70
+ /* 표식이 없으면 고침으로 본다 — 그리드가 표식을 안 붙이는 경우가 있고, 만드는 쪽으로 두면 행이 늘어난다. */
71
+ return 'M';
72
+ }
73
+ //# sourceMappingURL=master-crud.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"master-crud.js","sourceRoot":"","sources":["../../server/service/master-crud.ts"],"names":[],"mappings":"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","sourcesContent":["import { EntityManager, In, ObjectLiteral, Repository } from 'typeorm'\n\nimport { Domain } from '@things-factory/shell'\n\n/**\n * 마스터를 채우고 고치는 **한 벌의 규칙** — 열두 축이 같은 함수를 쓴다.\n *\n * ── 왜 마스터는 그리드에서 고칠 수 있나 ────────────────────────────────────\n * 업무 화면(실적 · 검사 · 처분)은 조회 전용이다. 그것은 **일어난 일의 기록**이라, 고칠 수 있으면\n * 「그때 무엇이 있었나」가 「지금 무엇으로 적혀 있나」로 바뀐다.\n *\n * 마스터는 다르다. 「이 사람이 용접 자격을 갖는다」는 일어난 일이 아니라 **선언**이다. 선언은 바뀌고,\n * 바뀐 것이 지금의 선언이다. 그래서 그리드에서 고친다.\n *\n * ── 지우는 것만 다르게 다룬다 ──────────────────────────────────────────────\n * 유효 기간을 가진 축은 **행을 지우지 않는다.** 지우면 그것을 가리키는 지난 기록이 가리킬 것을 잃는다\n * (어제 실적이 가리키던 설비가 사라지면 그 실적은 어느 설비의 것도 아니게 된다). 대신\n * `effectiveEnd` 를 채워 오늘부터 유효하지 않게 한다.\n *\n * 유효 기간이 없는 축만 실제로 지운다.\n */\n\n/** 그리드가 보내는 표식. `+` 새로 만든 행 · `M` 고친 행 · `-` 지운 행. */\nexport type CuFlag = '+' | 'M' | '-'\n\nexport interface MasterPatch {\n id?: string\n cuFlag?: string\n [key: string]: unknown\n}\n\ntype EntityClass = { new (): ObjectLiteral }\n\nexport interface SaveMasterOptions {\n /**\n * 유효 기간을 갖는 축인가.\n *\n * 참이면 지우기가 **`effectiveEnd` 를 채우는 것**이 된다. 거짓이면 행을 지운다.\n */\n hasEffectivePeriod?: boolean\n}\n\n/**\n * 그리드가 보낸 변경을 한 번에 적용한다.\n *\n * 한 트랜잭션에서 처리한다 — 절반만 반영되면 그리드가 보여 주는 것과 저장된 것이 갈린다.\n */\nexport async function saveMasterPatches(\n manager: EntityManager,\n domain: Domain,\n entity: EntityClass,\n patches: readonly MasterPatch[],\n user: unknown,\n options: SaveMasterOptions = {}\n): Promise<ObjectLiteral[]> {\n const repository = manager.getRepository(entity)\n const results: ObjectLiteral[] = []\n\n const created = patches.filter(patch => flagOf(patch) === '+')\n const updated = patches.filter(patch => flagOf(patch) === 'M')\n const removed = patches.filter(patch => flagOf(patch) === '-')\n\n for (const patch of created) {\n /* 새 행의 `id` 는 그리드가 임시로 붙인 것이다 — 그대로 저장하면 그것이 진짜 키가 된다. */\n const { cuFlag, id, ...values } = patch\n\n results.push(await repository.save({ ...values, domain, creator: user, updater: user }))\n }\n\n for (const patch of updated) {\n const { cuFlag, id, ...values } = patch\n\n if (!id) {\n throw new Error('saveMasterPatches: a changed row must carry its id')\n }\n\n const found = await repository.findOne({ where: { domain: { id: domain.id }, id } })\n\n /*\n * 없는 행을 고치라고 하면 만들지 않는다. 다른 사람이 지웠거나 다른 도메인의 행이고, 둘 다\n * 조용히 새 행을 만들 일이 아니다.\n */\n if (!found) {\n throw new Error(`saveMasterPatches: no such row to change — ${String(id)}`)\n }\n\n results.push(await repository.save({ ...found, ...values, updater: user }))\n }\n\n if (removed.length) {\n await retire(repository, domain, removed, user, options)\n }\n\n return results\n}\n\n/**\n * 없앤다 — 유효 기간이 있으면 **끝을 채우고**, 없으면 지운다.\n */\nasync function retire(\n repository: Repository<ObjectLiteral>,\n domain: Domain,\n removed: readonly MasterPatch[],\n user: unknown,\n options: SaveMasterOptions\n): Promise<void> {\n const ids = removed.map(patch => patch.id).filter(Boolean) as string[]\n\n if (!ids.length) {\n return\n }\n\n if (!options.hasEffectivePeriod) {\n await repository.delete({ domain: { id: domain.id }, id: In(ids) })\n return\n }\n\n const rows = await repository.find({ where: { domain: { id: domain.id }, id: In(ids) } })\n const now = new Date()\n\n for (const row of rows) {\n /*\n * 이미 끝이 적혀 있으면 그대로 둔다. 다시 오늘로 바꾸면 「언제부터 안 썼나」가 바뀐다.\n */\n if (row.effectiveEnd) {\n continue\n }\n\n await repository.save({ ...row, effectiveEnd: now, updater: user })\n }\n}\n\nfunction flagOf(patch: MasterPatch): CuFlag {\n const flag = String(patch.cuFlag ?? '').toUpperCase()\n\n if (flag === '+' || flag === 'M' || flag === '-') {\n return flag\n }\n\n /* 표식이 없으면 고침으로 본다 — 그리드가 표식을 안 붙이는 경우가 있고, 만드는 쪽으로 두면 행이 늘어난다. */\n return 'M'\n}\n"]}
@@ -0,0 +1,12 @@
1
+ import { ObjectLiteral } from 'typeorm';
2
+ import { Domain, ListParam } from '@things-factory/shell';
3
+ /**
4
+ * 마스터 한 축을 목록으로 읽는다 — **열두 축이 같은 함수를 쓴다.**
5
+ *
6
+ * 총 건수를 함께 낸다. 화면이 「몇 건 중 몇 건을 보고 있나」를 말하려면 그 값이 있어야 하고, 없으면
7
+ * 잘린 목록과 「이게 전부」를 구별할 수 없다.
8
+ */
9
+ export declare function listMaster(axisKey: string, params: ListParam, domain: Domain): Promise<{
10
+ items: ObjectLiteral[];
11
+ total: number;
12
+ }>;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.listMaster = listMaster;
4
+ const shell_1 = require("@things-factory/shell");
5
+ const master_axis_1 = require("./master-axis");
6
+ /**
7
+ * 마스터 한 축을 목록으로 읽는다 — **열두 축이 같은 함수를 쓴다.**
8
+ *
9
+ * 총 건수를 함께 낸다. 화면이 「몇 건 중 몇 건을 보고 있나」를 말하려면 그 값이 있어야 하고, 없으면
10
+ * 잘린 목록과 「이게 전부」를 구별할 수 없다.
11
+ */
12
+ async function listMaster(axisKey, params, domain) {
13
+ const axis = (0, master_axis_1.masterAxisOf)(axisKey);
14
+ const queryBuilder = (0, shell_1.getQueryBuilderFromListParams)({
15
+ repository: (0, shell_1.getRepository)(axis.entity),
16
+ params,
17
+ domain,
18
+ searchables: axis.searchables,
19
+ alias: 'm'
20
+ });
21
+ const [items, total] = await queryBuilder.getManyAndCount();
22
+ return { items, total };
23
+ }
24
+ //# sourceMappingURL=master-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"master-list.js","sourceRoot":"","sources":["../../server/service/master-list.ts"],"names":[],"mappings":";;AAYA,gCAkBC;AA5BD,iDAAuG;AAEvG,+CAA4C;AAE5C;;;;;GAKG;AACI,KAAK,UAAU,UAAU,CAC9B,OAAe,EACf,MAAiB,EACjB,MAAc;IAEd,MAAM,IAAI,GAAG,IAAA,0BAAY,EAAC,OAAO,CAAC,CAAA;IAElC,MAAM,YAAY,GAAG,IAAA,qCAA6B,EAAC;QACjD,UAAU,EAAE,IAAA,qBAAa,EAAC,IAAI,CAAC,MAAM,CAAC;QACtC,MAAM;QACN,MAAM;QACN,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,KAAK,EAAE,GAAG;KACX,CAAC,CAAA;IAEF,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,YAAY,CAAC,eAAe,EAAE,CAAA;IAE3D,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;AACzB,CAAC","sourcesContent":["import { ObjectLiteral } from 'typeorm'\n\nimport { Domain, ListParam, getQueryBuilderFromListParams, getRepository } from '@things-factory/shell'\n\nimport { masterAxisOf } from './master-axis'\n\n/**\n * 마스터 한 축을 목록으로 읽는다 — **열두 축이 같은 함수를 쓴다.**\n *\n * 총 건수를 함께 낸다. 화면이 「몇 건 중 몇 건을 보고 있나」를 말하려면 그 값이 있어야 하고, 없으면\n * 잘린 목록과 「이게 전부」를 구별할 수 없다.\n */\nexport async function listMaster(\n axisKey: string,\n params: ListParam,\n domain: Domain\n): Promise<{ items: ObjectLiteral[]; total: number }> {\n const axis = masterAxisOf(axisKey)\n\n const queryBuilder = getQueryBuilderFromListParams({\n repository: getRepository(axis.entity),\n params,\n domain,\n searchables: axis.searchables,\n alias: 'm'\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import { MaterialClass } from './material-class';
2
+ import { MaterialDefinition } from './material-definition';
3
+ import { MaterialQuery } from './material-query';
4
+ import { MaterialClassResolver, MaterialDefinitionResolver } from './material-master-resolver';
5
+ export declare const entities: (typeof MaterialClass | typeof MaterialDefinition)[];
6
+ export declare const resolvers: (typeof MaterialClassResolver | typeof MaterialDefinitionResolver | typeof MaterialQuery)[];
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolvers = exports.entities = void 0;
4
+ const material_class_1 = require("./material-class");
5
+ const material_definition_1 = require("./material-definition");
6
+ const material_query_1 = require("./material-query");
7
+ const material_master_resolver_1 = require("./material-master-resolver");
8
+ exports.entities = [material_class_1.MaterialClass, material_definition_1.MaterialDefinition];
9
+ exports.resolvers = [material_query_1.MaterialQuery, material_master_resolver_1.MaterialClassResolver, material_master_resolver_1.MaterialDefinitionResolver];
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/service/material/index.ts"],"names":[],"mappings":";;;AAAA,qDAAgD;AAChD,+DAA0D;AAC1D,qDAAgD;AAChD,yEAA8F;AAEjF,QAAA,QAAQ,GAAG,CAAC,8BAAa,EAAE,wCAAkB,CAAC,CAAA;AAC9C,QAAA,SAAS,GAAG,CAAC,8BAAa,EAAE,gDAAqB,EAAE,qDAA0B,CAAC,CAAA","sourcesContent":["import { MaterialClass } from './material-class'\nimport { MaterialDefinition } from './material-definition'\nimport { MaterialQuery } from './material-query'\nimport { MaterialClassResolver, MaterialDefinitionResolver } from './material-master-resolver'\n\nexport const entities = [MaterialClass, MaterialDefinition]\nexport const resolvers = [MaterialQuery, MaterialClassResolver, MaterialDefinitionResolver]\n"]}
@@ -0,0 +1,34 @@
1
+ import { Domain } from '@things-factory/shell';
2
+ import { User } from '@things-factory/auth-base';
3
+ /**
4
+ * 품목 등급 — **ISA-95 `MaterialClass`**.
5
+ *
6
+ * 「원자재」·「완제품」처럼 품목을 묶는 상위 개념이다. 레시피가 특정 품번 대신 등급으로 투입을 적을 수 있고,
7
+ * 화면이 재고를 그 단위로 모은다.
8
+ *
9
+ * 구조는 인원 등급 · 설비 등급과 같다(표준이 넷을 같은 모양으로 정의한다).
10
+ */
11
+ export declare class MaterialClass {
12
+ readonly id: string;
13
+ domain?: Domain;
14
+ domainId?: string;
15
+ /** 표준 `MaterialClassID`. */
16
+ name: string;
17
+ description?: string;
18
+ /** 상위 등급들 — 표준 `MaterialClassBaseID`(복수). 「6축 용접기」가 「용접기」를 상속한다. */
19
+ baseIds?: string[];
20
+ /** 이 등급의 적격을 정하는 `TestSpecification` 참조들 — 표준 `TestSpecificationID`. */
21
+ testSpecificationIds?: string[];
22
+ /** 등급 속성 — 표준 `MaterialClassProperty`. */
23
+ properties?: Record<string, unknown>[];
24
+ /** 언제부터 유효한가 — 표준 `EffectiveStartDate`. */
25
+ effectiveStart?: Date;
26
+ /** 언제까지 유효한가 — 표준 `EffectiveEndDate`. */
27
+ effectiveEnd?: Date;
28
+ createdAt?: Date;
29
+ updatedAt?: Date;
30
+ creator?: User;
31
+ creatorId?: string;
32
+ updater?: User;
33
+ updaterId?: string;
34
+ }
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MaterialClass = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const typeorm_1 = require("typeorm");
6
+ const type_graphql_1 = require("type-graphql");
7
+ const shell_1 = require("@things-factory/shell");
8
+ const auth_base_1 = require("@things-factory/auth-base");
9
+ /**
10
+ * 품목 등급 — **ISA-95 `MaterialClass`**.
11
+ *
12
+ * 「원자재」·「완제품」처럼 품목을 묶는 상위 개념이다. 레시피가 특정 품번 대신 등급으로 투입을 적을 수 있고,
13
+ * 화면이 재고를 그 단위로 모은다.
14
+ *
15
+ * 구조는 인원 등급 · 설비 등급과 같다(표준이 넷을 같은 모양으로 정의한다).
16
+ */
17
+ let MaterialClass = class MaterialClass {
18
+ };
19
+ exports.MaterialClass = MaterialClass;
20
+ tslib_1.__decorate([
21
+ (0, typeorm_1.PrimaryGeneratedColumn)('uuid'),
22
+ (0, type_graphql_1.Field)(type => type_graphql_1.ID),
23
+ tslib_1.__metadata("design:type", String)
24
+ ], MaterialClass.prototype, "id", void 0);
25
+ tslib_1.__decorate([
26
+ (0, typeorm_1.ManyToOne)(type => shell_1.Domain),
27
+ (0, type_graphql_1.Field)(type => shell_1.Domain),
28
+ tslib_1.__metadata("design:type", shell_1.Domain)
29
+ ], MaterialClass.prototype, "domain", void 0);
30
+ tslib_1.__decorate([
31
+ (0, typeorm_1.RelationId)((klass) => klass.domain),
32
+ tslib_1.__metadata("design:type", String)
33
+ ], MaterialClass.prototype, "domainId", void 0);
34
+ tslib_1.__decorate([
35
+ (0, typeorm_1.Column)(),
36
+ (0, type_graphql_1.Field)(),
37
+ tslib_1.__metadata("design:type", String)
38
+ ], MaterialClass.prototype, "name", void 0);
39
+ tslib_1.__decorate([
40
+ (0, typeorm_1.Column)({ nullable: true }),
41
+ (0, type_graphql_1.Field)({ nullable: true }),
42
+ tslib_1.__metadata("design:type", String)
43
+ ], MaterialClass.prototype, "description", void 0);
44
+ tslib_1.__decorate([
45
+ (0, typeorm_1.Column)({ type: 'simple-json', nullable: true }),
46
+ (0, type_graphql_1.Field)(type => [String], { nullable: true }),
47
+ tslib_1.__metadata("design:type", Array)
48
+ ], MaterialClass.prototype, "baseIds", void 0);
49
+ tslib_1.__decorate([
50
+ (0, typeorm_1.Column)({ type: 'simple-json', nullable: true }),
51
+ (0, type_graphql_1.Field)(type => [String], { nullable: true }),
52
+ tslib_1.__metadata("design:type", Array)
53
+ ], MaterialClass.prototype, "testSpecificationIds", void 0);
54
+ tslib_1.__decorate([
55
+ (0, typeorm_1.Column)({ type: 'simple-json', nullable: true }),
56
+ (0, type_graphql_1.Field)(type => String, { nullable: true, description: 'ResourceProperty[] as JSON text' }),
57
+ tslib_1.__metadata("design:type", Array)
58
+ ], MaterialClass.prototype, "properties", void 0);
59
+ tslib_1.__decorate([
60
+ (0, typeorm_1.Column)({ nullable: true }),
61
+ (0, type_graphql_1.Field)({ nullable: true }),
62
+ tslib_1.__metadata("design:type", Date
63
+ /** 언제까지 유효한가 — 표준 `EffectiveEndDate`. */
64
+ )
65
+ ], MaterialClass.prototype, "effectiveStart", void 0);
66
+ tslib_1.__decorate([
67
+ (0, typeorm_1.Column)({ nullable: true }),
68
+ (0, type_graphql_1.Field)({ nullable: true }),
69
+ tslib_1.__metadata("design:type", Date)
70
+ ], MaterialClass.prototype, "effectiveEnd", void 0);
71
+ tslib_1.__decorate([
72
+ (0, typeorm_1.CreateDateColumn)(),
73
+ (0, type_graphql_1.Field)({ nullable: true }),
74
+ tslib_1.__metadata("design:type", Date)
75
+ ], MaterialClass.prototype, "createdAt", void 0);
76
+ tslib_1.__decorate([
77
+ (0, typeorm_1.UpdateDateColumn)(),
78
+ (0, type_graphql_1.Field)({ nullable: true }),
79
+ tslib_1.__metadata("design:type", Date)
80
+ ], MaterialClass.prototype, "updatedAt", void 0);
81
+ tslib_1.__decorate([
82
+ (0, typeorm_1.ManyToOne)(type => auth_base_1.User, { nullable: true }),
83
+ (0, type_graphql_1.Field)(type => auth_base_1.User, { nullable: true }),
84
+ tslib_1.__metadata("design:type", auth_base_1.User)
85
+ ], MaterialClass.prototype, "creator", void 0);
86
+ tslib_1.__decorate([
87
+ (0, typeorm_1.RelationId)((klass) => klass.creator),
88
+ tslib_1.__metadata("design:type", String)
89
+ ], MaterialClass.prototype, "creatorId", void 0);
90
+ tslib_1.__decorate([
91
+ (0, typeorm_1.ManyToOne)(type => auth_base_1.User, { nullable: true }),
92
+ (0, type_graphql_1.Field)(type => auth_base_1.User, { nullable: true }),
93
+ tslib_1.__metadata("design:type", auth_base_1.User)
94
+ ], MaterialClass.prototype, "updater", void 0);
95
+ tslib_1.__decorate([
96
+ (0, typeorm_1.RelationId)((klass) => klass.updater),
97
+ tslib_1.__metadata("design:type", String)
98
+ ], MaterialClass.prototype, "updaterId", void 0);
99
+ exports.MaterialClass = MaterialClass = tslib_1.__decorate([
100
+ (0, typeorm_1.Entity)({ name: 'ops_material_class' }),
101
+ (0, typeorm_1.Index)('ix_ops_material_class_0', (klass) => [klass.domain, klass.name], { unique: true }),
102
+ (0, type_graphql_1.ObjectType)({ description: 'ISA-95 MaterialClass — a grouping of material definitions' })
103
+ ], MaterialClass);
104
+ //# sourceMappingURL=material-class.js.map