@things-factory/station 10.1.33
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.
- package/README.md +124 -0
- package/dist-client/index.d.ts +11 -0
- package/dist-client/index.js +13 -0
- package/dist-client/index.js.map +1 -0
- package/dist-client/station/scene/index.d.ts +11 -0
- package/dist-client/station/scene/index.js +12 -0
- package/dist-client/station/scene/index.js.map +1 -0
- package/dist-client/station/scene/station-context-binding.d.ts +25 -0
- package/dist-client/station/scene/station-context-binding.js +39 -0
- package/dist-client/station/scene/station-context-binding.js.map +1 -0
- package/dist-client/station/scene/station-context-scene.d.ts +28 -0
- package/dist-client/station/scene/station-context-scene.js +138 -0
- package/dist-client/station/scene/station-context-scene.js.map +1 -0
- package/dist-client/station/scene/station-counts-scene.d.ts +6 -0
- package/dist-client/station/scene/station-counts-scene.js +51 -0
- package/dist-client/station/scene/station-counts-scene.js.map +1 -0
- package/dist-client/station/scene/station-field-scene.d.ts +6 -0
- package/dist-client/station/scene/station-field-scene.js +89 -0
- package/dist-client/station/scene/station-field-scene.js.map +1 -0
- package/dist-client/station/scene/station-icons.d.ts +82 -0
- package/dist-client/station/scene/station-icons.js +131 -0
- package/dist-client/station/scene/station-icons.js.map +1 -0
- package/dist-client/station/scene/station-numpad-scene.d.ts +9 -0
- package/dist-client/station/scene/station-numpad-scene.js +144 -0
- package/dist-client/station/scene/station-numpad-scene.js.map +1 -0
- package/dist-client/station/scene/station-scene-style.d.ts +51 -0
- package/dist-client/station/scene/station-scene-style.js +108 -0
- package/dist-client/station/scene/station-scene-style.js.map +1 -0
- package/dist-client/station/scene/station-scene.d.ts +295 -0
- package/dist-client/station/scene/station-scene.js +68 -0
- package/dist-client/station/scene/station-scene.js.map +1 -0
- package/dist-client/station/scene/station-who-scene.d.ts +6 -0
- package/dist-client/station/scene/station-who-scene.js +48 -0
- package/dist-client/station/scene/station-who-scene.js.map +1 -0
- package/dist-client/station/scene/station-work-panel-scene.d.ts +28 -0
- package/dist-client/station/scene/station-work-panel-scene.js +37 -0
- package/dist-client/station/scene/station-work-panel-scene.js.map +1 -0
- package/dist-client/station/station-board-binding.d.ts +16 -0
- package/dist-client/station/station-board-binding.js +20 -0
- package/dist-client/station/station-board-binding.js.map +1 -0
- package/dist-client/station/station-context.d.ts +178 -0
- package/dist-client/station/station-context.js +30 -0
- package/dist-client/station/station-context.js.map +1 -0
- package/dist-client/station/station-palette.d.ts +34 -0
- package/dist-client/station/station-palette.js +119 -0
- package/dist-client/station/station-palette.js.map +1 -0
- package/dist-client/station/station-runtime.d.ts +47 -0
- package/dist-client/station/station-runtime.js +47 -0
- package/dist-client/station/station-runtime.js.map +1 -0
- package/dist-client/station/station-scene-context.d.ts +68 -0
- package/dist-client/station/station-scene-context.js +62 -0
- package/dist-client/station/station-scene-context.js.map +1 -0
- package/dist-client/station/station-screen-flow.d.ts +16 -0
- package/dist-client/station/station-screen-flow.js +58 -0
- package/dist-client/station/station-screen-flow.js.map +1 -0
- package/dist-client/station/station-tile-registry.d.ts +89 -0
- package/dist-client/station/station-tile-registry.js +86 -0
- package/dist-client/station/station-tile-registry.js.map +1 -0
- package/dist-client/station/station-work-panel-view.d.ts +23 -0
- package/dist-client/station/station-work-panel-view.js +125 -0
- package/dist-client/station/station-work-panel-view.js.map +1 -0
- package/dist-client/station/station-work-runtime.d.ts +47 -0
- package/dist-client/station/station-work-runtime.js +161 -0
- package/dist-client/station/station-work-runtime.js.map +1 -0
- package/dist-client/station/station-work-scenarios.d.ts +41 -0
- package/dist-client/station/station-work-scenarios.js +59 -0
- package/dist-client/station/station-work-scenarios.js.map +1 -0
- package/dist-client/station/task-counts.d.ts +32 -0
- package/dist-client/station/task-counts.js +26 -0
- package/dist-client/station/task-counts.js.map +1 -0
- package/dist-client/tsconfig.tsbuildinfo +1 -0
- package/dist-server/activities/activity-station-screen-control-withdrawal.d.ts +62 -0
- package/dist-server/activities/activity-station-screen-control-withdrawal.js +147 -0
- package/dist-server/activities/activity-station-screen-control-withdrawal.js.map +1 -0
- package/dist-server/activities/activity-station-screen-release.d.ts +81 -0
- package/dist-server/activities/activity-station-screen-release.js +147 -0
- package/dist-server/activities/activity-station-screen-release.js.map +1 -0
- package/dist-server/activities/index.d.ts +49 -0
- package/dist-server/activities/index.js +21 -0
- package/dist-server/activities/index.js.map +1 -0
- package/dist-server/index.d.ts +3 -0
- package/dist-server/index.js +8 -0
- package/dist-server/index.js.map +1 -0
- package/dist-server/service/index.d.ts +23 -0
- package/dist-server/service/index.js +41 -0
- package/dist-server/service/index.js.map +1 -0
- package/dist-server/service/station/deletion-changes.d.ts +14 -0
- package/dist-server/service/station/deletion-changes.js +25 -0
- package/dist-server/service/station/deletion-changes.js.map +1 -0
- package/dist-server/service/station/index.d.ts +13 -0
- package/dist-server/service/station/index.js +25 -0
- package/dist-server/service/station/index.js.map +1 -0
- package/dist-server/service/station/reversibility.d.ts +21 -0
- package/dist-server/service/station/reversibility.js +24 -0
- package/dist-server/service/station/reversibility.js.map +1 -0
- package/dist-server/service/station/screen-model-digest.d.ts +60 -0
- package/dist-server/service/station/screen-model-digest.js +97 -0
- package/dist-server/service/station/screen-model-digest.js.map +1 -0
- package/dist-server/service/station/staged-material.d.ts +62 -0
- package/dist-server/service/station/staged-material.js +44 -0
- package/dist-server/service/station/staged-material.js.map +1 -0
- package/dist-server/service/station/station-argument-sources.d.ts +31 -0
- package/dist-server/service/station/station-argument-sources.js +66 -0
- package/dist-server/service/station/station-argument-sources.js.map +1 -0
- package/dist-server/service/station/station-assignment-choice.d.ts +81 -0
- package/dist-server/service/station/station-assignment-choice.js +105 -0
- package/dist-server/service/station/station-assignment-choice.js.map +1 -0
- package/dist-server/service/station/station-assignment-resolver.d.ts +104 -0
- package/dist-server/service/station/station-assignment-resolver.js +426 -0
- package/dist-server/service/station/station-assignment-resolver.js.map +1 -0
- package/dist-server/service/station/station-assignment-service.d.ts +33 -0
- package/dist-server/service/station/station-assignment-service.js +64 -0
- package/dist-server/service/station/station-assignment-service.js.map +1 -0
- package/dist-server/service/station/station-axes.d.ts +9 -0
- package/dist-server/service/station/station-axes.js +16 -0
- package/dist-server/service/station/station-axes.js.map +1 -0
- package/dist-server/service/station/station-flow.d.ts +156 -0
- package/dist-server/service/station/station-flow.js +255 -0
- package/dist-server/service/station/station-flow.js.map +1 -0
- package/dist-server/service/station/station-generate.d.ts +76 -0
- package/dist-server/service/station/station-generate.js +178 -0
- package/dist-server/service/station/station-generate.js.map +1 -0
- package/dist-server/service/station/station-product.d.ts +123 -0
- package/dist-server/service/station/station-product.js +77 -0
- package/dist-server/service/station/station-product.js.map +1 -0
- package/dist-server/service/station/station-runtime-binding.d.ts +6 -0
- package/dist-server/service/station/station-runtime-binding.js +46 -0
- package/dist-server/service/station/station-runtime-binding.js.map +1 -0
- package/dist-server/service/station/station-screen-assignment.d.ts +94 -0
- package/dist-server/service/station/station-screen-assignment.js +154 -0
- package/dist-server/service/station/station-screen-assignment.js.map +1 -0
- package/dist-server/service/station/station-screen-control-withdrawal-resolver.d.ts +37 -0
- package/dist-server/service/station/station-screen-control-withdrawal-resolver.js +130 -0
- package/dist-server/service/station/station-screen-control-withdrawal-resolver.js.map +1 -0
- package/dist-server/service/station/station-screen-control-withdrawal.d.ts +104 -0
- package/dist-server/service/station/station-screen-control-withdrawal.js +128 -0
- package/dist-server/service/station/station-screen-control-withdrawal.js.map +1 -0
- package/dist-server/service/station/station-screen-draft-resolver.d.ts +47 -0
- package/dist-server/service/station/station-screen-draft-resolver.js +153 -0
- package/dist-server/service/station/station-screen-draft-resolver.js.map +1 -0
- package/dist-server/service/station/station-screen-layout.d.ts +119 -0
- package/dist-server/service/station/station-screen-layout.js +202 -0
- package/dist-server/service/station/station-screen-layout.js.map +1 -0
- package/dist-server/service/station/station-screen-list-resolver.d.ts +69 -0
- package/dist-server/service/station/station-screen-list-resolver.js +215 -0
- package/dist-server/service/station/station-screen-list-resolver.js.map +1 -0
- package/dist-server/service/station/station-screen-publish-subscriber.d.ts +22 -0
- package/dist-server/service/station/station-screen-publish-subscriber.js +90 -0
- package/dist-server/service/station/station-screen-publish-subscriber.js.map +1 -0
- package/dist-server/service/station/station-screen-release-gate.d.ts +66 -0
- package/dist-server/service/station/station-screen-release-gate.js +67 -0
- package/dist-server/service/station/station-screen-release-gate.js.map +1 -0
- package/dist-server/service/station/station-screen-release-record.d.ts +62 -0
- package/dist-server/service/station/station-screen-release-record.js +139 -0
- package/dist-server/service/station/station-screen-release-record.js.map +1 -0
- package/dist-server/service/station/station-screen-release-signature.d.ts +23 -0
- package/dist-server/service/station/station-screen-release-signature.js +32 -0
- package/dist-server/service/station/station-screen-release-signature.js.map +1 -0
- package/dist-server/service/station/station-screen-scorecard.d.ts +15 -0
- package/dist-server/service/station/station-screen-scorecard.js +35 -0
- package/dist-server/service/station/station-screen-scorecard.js.map +1 -0
- package/dist-server/service/station/station-screen-spec-resolver.d.ts +36 -0
- package/dist-server/service/station/station-screen-spec-resolver.js +202 -0
- package/dist-server/service/station/station-screen-spec-resolver.js.map +1 -0
- package/dist-server/service/station/station-screen-spec.d.ts +104 -0
- package/dist-server/service/station/station-screen-spec.js +114 -0
- package/dist-server/service/station/station-screen-spec.js.map +1 -0
- package/dist-server/service/station/station-screen-thumbnail.d.ts +11 -0
- package/dist-server/service/station/station-screen-thumbnail.js +36 -0
- package/dist-server/service/station/station-screen-thumbnail.js.map +1 -0
- package/dist-server/service/station/station-service-resolver.d.ts +27 -0
- package/dist-server/service/station/station-service-resolver.js +95 -0
- package/dist-server/service/station/station-service-resolver.js.map +1 -0
- package/dist-server/tsconfig.tsbuildinfo +1 -0
- package/package.json +44 -0
- package/shared/station-axes.d.ts +4 -0
- package/shared/station-axes.js +155 -0
- package/shared/station-screen-flow-check.d.ts +12 -0
- package/shared/station-screen-flow-check.js +74 -0
- package/things-scene.config.js +15 -0
- package/translations/en.json +42 -0
- package/translations/ja.json +42 -0
- package/translations/ko.json +42 -0
- package/translations/ms.json +42 -0
- package/translations/zh.json +42 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { StationScreenAssignment } from './station-screen-assignment';
|
|
2
|
+
export declare class StationAssignmentChoiceType {
|
|
3
|
+
name: string;
|
|
4
|
+
boardId: string;
|
|
5
|
+
/**
|
|
6
|
+
* 무엇으로 골랐나.
|
|
7
|
+
*
|
|
8
|
+
* 「왜 이 화면인가」에 답하려고 함께 낸다. 이것이 없으면 배정이 여러 줄일 때 관리자가 자기가 고친 줄이
|
|
9
|
+
* 이 태블릿에 걸리는 줄인지 확인할 방법이 없다.
|
|
10
|
+
*/
|
|
11
|
+
matchedOn: string[];
|
|
12
|
+
/**
|
|
13
|
+
* 같은 만큼 구체적인데 아무것도 가려 주지 못한 다른 배정들.
|
|
14
|
+
*
|
|
15
|
+
* 비어 있는 것이 정상이다. 비어 있지 않으면 **공장이 같은 물음에 답을 둘 갖고 있다**는 뜻이고, 그리는
|
|
16
|
+
* 화면은 정해져 있지만 임의로 정해진 것이다 — 누군가 우선순위를 적어야 한다. 조용히 한쪽을 버리면
|
|
17
|
+
* 관리자는 다른 줄을 고쳐도 아무 일이 안 일어나는 것을 겪는다.
|
|
18
|
+
*/
|
|
19
|
+
ambiguousWith: string[];
|
|
20
|
+
}
|
|
21
|
+
export declare class StationAssignmentRowType {
|
|
22
|
+
name: string;
|
|
23
|
+
description?: string;
|
|
24
|
+
boardId: string;
|
|
25
|
+
/**
|
|
26
|
+
* 그 화면이 지금 현장에 나가 있는 판.
|
|
27
|
+
*
|
|
28
|
+
* 없으면 **나간 판이 없다**는 뜻이고, 그러면 이 배정은 아무것도 못 그린다 — 아래 `usable` 이 그것을
|
|
29
|
+
* 말한다. 초안이 있어도 대신 내밀지 않는다: 작업대가 그리다 만 화면 앞에서 실적을 남기게 된다.
|
|
30
|
+
*/
|
|
31
|
+
boardName?: string;
|
|
32
|
+
equipmentName?: string;
|
|
33
|
+
equipmentClassId?: string;
|
|
34
|
+
workCenterName?: string;
|
|
35
|
+
operationKey?: string;
|
|
36
|
+
routeKey?: string;
|
|
37
|
+
materialClassId?: string;
|
|
38
|
+
personnelClassId?: string;
|
|
39
|
+
priority?: number;
|
|
40
|
+
effectiveStart?: Date;
|
|
41
|
+
effectiveEnd?: Date;
|
|
42
|
+
/**
|
|
43
|
+
* 지금 이 줄이 화면을 그릴 수 있나.
|
|
44
|
+
*
|
|
45
|
+
* ── 왜 선언 옆에 현실을 함께 적나 ────────────────────────────────────────
|
|
46
|
+
* 없어진 보드를 가리키는 배정은 **목록에는 멀쩡히 서 있고 현장에는 아무것도 안 뜬다.** 유효 기간이
|
|
47
|
+
* 지난 줄도 같다. 화면이 그것을 말하지 않으면 관리자는 자기가 적은 것이 왜 안 먹는지 알 길이 없다.
|
|
48
|
+
*/
|
|
49
|
+
usable: boolean;
|
|
50
|
+
/** 못 쓰면 왜 못 쓰나 — 사용자가 읽을 문장. 쓸 수 있으면 없다. */
|
|
51
|
+
because?: string;
|
|
52
|
+
}
|
|
53
|
+
export declare class StationAssignmentSetupType {
|
|
54
|
+
screens: StationAssignmentRowType[];
|
|
55
|
+
/**
|
|
56
|
+
* 아무 축도 걸지 않은 배정의 이름들.
|
|
57
|
+
*
|
|
58
|
+
* 하나면 「그 밖의 모든 작업대」라는 뜻이라 쓸모가 있다. **둘 이상이면 둘 다 모든 작업대에 들어맞고**
|
|
59
|
+
* 언제나 동점이다 — 우선순위 없이는 이름순으로 갈린다. 화면이 짚어 준다.
|
|
60
|
+
*/
|
|
61
|
+
unconstrained: string[];
|
|
62
|
+
}
|
|
63
|
+
export declare class StationAssignmentInput {
|
|
64
|
+
name: string;
|
|
65
|
+
description?: string;
|
|
66
|
+
boardId: string;
|
|
67
|
+
equipmentName?: string;
|
|
68
|
+
equipmentClassId?: string;
|
|
69
|
+
workCenterName?: string;
|
|
70
|
+
operationKey?: string;
|
|
71
|
+
routeKey?: string;
|
|
72
|
+
materialClassId?: string;
|
|
73
|
+
personnelClassId?: string;
|
|
74
|
+
priority?: number;
|
|
75
|
+
effectiveStart?: Date;
|
|
76
|
+
effectiveEnd?: Date;
|
|
77
|
+
}
|
|
78
|
+
export declare class StationAssignmentResolver {
|
|
79
|
+
/**
|
|
80
|
+
* 이 작업대가 지금 그릴 보드.
|
|
81
|
+
*
|
|
82
|
+
* **배정이 없으면 아무것도 돌려주지 않는다.** 기본 화면을 내놓지 않는 이유는, 배정하지 않아도 뭔가
|
|
83
|
+
* 뜨면 공장이 「배정은 안 해도 된다」를 배우고, 그 뒤로는 벽에 걸린 것을 아무도 믿지 않게 되기 때문이다.
|
|
84
|
+
*/
|
|
85
|
+
stationAssignment(equipmentName: string, context: any, operationKey?: string, operatorName?: string, jobOrderName?: string): Promise<StationAssignmentChoiceType | undefined>;
|
|
86
|
+
/**
|
|
87
|
+
* 배정 전부 — **선언 옆에 현실을 함께.**
|
|
88
|
+
*
|
|
89
|
+
* ── 목록의 순서는 승부가 아니다 ─────────────────────────────────────────
|
|
90
|
+
* 이기는 것은 얼마나 구체적인가이고 우선순위는 동점일 때만 쓴다. 목록이 승부를 말하는 척하면 관리자가
|
|
91
|
+
* 맨 위 줄이 이긴다고 읽는다. 그래서 이름순으로만 낸다 — 어느 줄이 이기는지는 **물어봐야** 안다
|
|
92
|
+
* (`stationScreen`).
|
|
93
|
+
*/
|
|
94
|
+
stationAssignmentSetup(context: any): Promise<StationAssignmentSetupType>;
|
|
95
|
+
/**
|
|
96
|
+
* 배정을 적거나 고친다.
|
|
97
|
+
*
|
|
98
|
+
* ── 왜 만드는 문이 함께 있어야 하나 ──────────────────────────────────────
|
|
99
|
+
* 읽는 질의만 두면 배정을 만들 길이 SQL 뿐이다. 이 제품에서 가장 잦은 결함이 **선언은 있고 길이 없는**
|
|
100
|
+
* 것이고, 관리 화면이 붙기 전이라도 문은 열려 있어야 한다.
|
|
101
|
+
*/
|
|
102
|
+
saveStationAssignment(context: any, patch: StationAssignmentInput): Promise<StationScreenAssignment>;
|
|
103
|
+
deleteStationAssignment(context: any, name: string): Promise<boolean>;
|
|
104
|
+
}
|
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StationAssignmentResolver = exports.StationAssignmentInput = exports.StationAssignmentSetupType = exports.StationAssignmentRowType = exports.StationAssignmentChoiceType = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const type_graphql_1 = require("type-graphql");
|
|
6
|
+
const shell_1 = require("@things-factory/shell");
|
|
7
|
+
const typeorm_1 = require("typeorm");
|
|
8
|
+
const ops_master_1 = require("@things-factory/ops-master");
|
|
9
|
+
const board_service_1 = require("@things-factory/board-service");
|
|
10
|
+
const station_screen_assignment_1 = require("./station-screen-assignment");
|
|
11
|
+
const station_assignment_service_1 = require("./station-assignment-service");
|
|
12
|
+
let StationAssignmentChoiceType = class StationAssignmentChoiceType {
|
|
13
|
+
};
|
|
14
|
+
exports.StationAssignmentChoiceType = StationAssignmentChoiceType;
|
|
15
|
+
tslib_1.__decorate([
|
|
16
|
+
(0, type_graphql_1.Field)({ description: 'the assignment that won' }),
|
|
17
|
+
tslib_1.__metadata("design:type", String)
|
|
18
|
+
], StationAssignmentChoiceType.prototype, "name", void 0);
|
|
19
|
+
tslib_1.__decorate([
|
|
20
|
+
(0, type_graphql_1.Field)({ description: 'the station screen to draw, by name' }),
|
|
21
|
+
tslib_1.__metadata("design:type", String)
|
|
22
|
+
], StationAssignmentChoiceType.prototype, "boardId", void 0);
|
|
23
|
+
tslib_1.__decorate([
|
|
24
|
+
(0, type_graphql_1.Field)(type => [String], { description: 'the axes this assignment constrained — why it was chosen' }),
|
|
25
|
+
tslib_1.__metadata("design:type", Array)
|
|
26
|
+
], StationAssignmentChoiceType.prototype, "matchedOn", void 0);
|
|
27
|
+
tslib_1.__decorate([
|
|
28
|
+
(0, type_graphql_1.Field)(type => [String], { description: 'equally specific assignments nothing separated — write a priority' }),
|
|
29
|
+
tslib_1.__metadata("design:type", Array)
|
|
30
|
+
], StationAssignmentChoiceType.prototype, "ambiguousWith", void 0);
|
|
31
|
+
exports.StationAssignmentChoiceType = StationAssignmentChoiceType = tslib_1.__decorate([
|
|
32
|
+
(0, type_graphql_1.ObjectType)({ description: 'Which board this station shows, and why that one' })
|
|
33
|
+
], StationAssignmentChoiceType);
|
|
34
|
+
/**
|
|
35
|
+
* Which axis values actually exist in the masters — **one pass, however many assignments.**
|
|
36
|
+
*
|
|
37
|
+
* ── Why the screen has to say this ─────────────────────────────────────────
|
|
38
|
+
* Every axis is typed. A mistyped one is stored, listed, and **matches nothing** — the assignment
|
|
39
|
+
* looks fine and the tablet shows nothing, with no way to tell which of the seven fields is wrong.
|
|
40
|
+
* The board was already checked this way; the axes are the ones people get wrong more often, since
|
|
41
|
+
* there are seven of them and they are keys, not names people remember.
|
|
42
|
+
*
|
|
43
|
+
* ── Checked here, not by narrowing the input ───────────────────────────────
|
|
44
|
+
* Dropdowns were the alternative. This catches values that arrived any other way too — a seed, an
|
|
45
|
+
* import, a hand-edited row — and does not need the whole equipment list in a select on a plant with
|
|
46
|
+
* a thousand machines.
|
|
47
|
+
*
|
|
48
|
+
* ── A class that exists but has no members is still valid ──────────────────
|
|
49
|
+
* So classes are checked against the class masters, not against membership. "Every welder gets this
|
|
50
|
+
* screen" is a fair thing to declare before the first welder is hired.
|
|
51
|
+
*
|
|
52
|
+
* ── `kind` counts as a class ───────────────────────────────────────────────
|
|
53
|
+
* Equipment membership is `equipmentClassIds ∪ {kind}` (the contract's own rule), so a value used as
|
|
54
|
+
* some machine's `kind` is a working selector even when no `EquipmentClass` row declares it.
|
|
55
|
+
* Complaining about it would be a false alarm, and false alarms kill the true ones.
|
|
56
|
+
*/
|
|
57
|
+
async function axesThatExist(domainId, rows) {
|
|
58
|
+
const values = (pick) => [...new Set(rows.map(pick).filter((one) => Boolean(one)))];
|
|
59
|
+
const namesOf = async (entity, names) => names.length
|
|
60
|
+
? new Set((await (0, shell_1.getRepository)(entity).find({
|
|
61
|
+
where: { domain: { id: domainId }, name: (0, typeorm_1.In)(names) },
|
|
62
|
+
select: ['name']
|
|
63
|
+
})).map((one) => one.name))
|
|
64
|
+
: new Set();
|
|
65
|
+
const equipmentClassNames = values(row => row.equipmentClassId);
|
|
66
|
+
const [equipment, equipmentClasses, kinds, lines, operations, routes, materialClasses, personnelClasses] = await Promise.all([
|
|
67
|
+
namesOf(ops_master_1.Equipment, values(row => row.equipmentName)),
|
|
68
|
+
namesOf(ops_master_1.EquipmentClass, equipmentClassNames),
|
|
69
|
+
/* `kind` is not a name column, so it is asked for separately. */
|
|
70
|
+
equipmentClassNames.length
|
|
71
|
+
? (0, shell_1.getRepository)(ops_master_1.Equipment)
|
|
72
|
+
.find({ where: { domain: { id: domainId }, kind: (0, typeorm_1.In)(equipmentClassNames) }, select: ['kind'] })
|
|
73
|
+
.then(found => new Set(found.map(one => one.kind)))
|
|
74
|
+
: Promise.resolve(new Set()),
|
|
75
|
+
namesOf(ops_master_1.OperationalLocation, values(row => row.workCenterName)),
|
|
76
|
+
namesOf(ops_master_1.OperationDefinition, values(row => row.operationKey)),
|
|
77
|
+
namesOf(ops_master_1.RouteDefinition, values(row => row.routeKey)),
|
|
78
|
+
namesOf(ops_master_1.MaterialClass, values(row => row.materialClassId)),
|
|
79
|
+
namesOf(ops_master_1.PersonnelClass, values(row => row.personnelClassId))
|
|
80
|
+
]);
|
|
81
|
+
return {
|
|
82
|
+
equipmentName: equipment,
|
|
83
|
+
equipmentClassId: new Set([...equipmentClasses, ...kinds]),
|
|
84
|
+
workCenterName: lines,
|
|
85
|
+
operationKey: operations,
|
|
86
|
+
routeKey: routes,
|
|
87
|
+
materialClassId: materialClasses,
|
|
88
|
+
personnelClassId: personnelClasses
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/** 어느 축이 어긋났는지 사용자의 말로. 축 이름을 그대로 보이지 않는다 — 화면이 번역한다. */
|
|
92
|
+
const AXIS_COMPLAINT = {
|
|
93
|
+
equipmentName: 'no equipment by that name',
|
|
94
|
+
equipmentClassId: 'no equipment class or kind by that name',
|
|
95
|
+
workCenterName: 'no location by that name',
|
|
96
|
+
operationKey: 'no operation by that name',
|
|
97
|
+
routeKey: 'no route by that name',
|
|
98
|
+
materialClassId: 'no material class by that name',
|
|
99
|
+
personnelClassId: 'no personnel class by that name'
|
|
100
|
+
};
|
|
101
|
+
let StationAssignmentRowType = class StationAssignmentRowType {
|
|
102
|
+
};
|
|
103
|
+
exports.StationAssignmentRowType = StationAssignmentRowType;
|
|
104
|
+
tslib_1.__decorate([
|
|
105
|
+
(0, type_graphql_1.Field)(),
|
|
106
|
+
tslib_1.__metadata("design:type", String)
|
|
107
|
+
], StationAssignmentRowType.prototype, "name", void 0);
|
|
108
|
+
tslib_1.__decorate([
|
|
109
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
110
|
+
tslib_1.__metadata("design:type", String)
|
|
111
|
+
], StationAssignmentRowType.prototype, "description", void 0);
|
|
112
|
+
tslib_1.__decorate([
|
|
113
|
+
(0, type_graphql_1.Field)({ description: 'the station screen to draw, by name' }),
|
|
114
|
+
tslib_1.__metadata("design:type", String)
|
|
115
|
+
], StationAssignmentRowType.prototype, "boardId", void 0);
|
|
116
|
+
tslib_1.__decorate([
|
|
117
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'the version currently released — absent when none is' }),
|
|
118
|
+
(0, type_graphql_1.Field)({ nullable: true, description: "the board's name, so the list reads as words not ids" }),
|
|
119
|
+
tslib_1.__metadata("design:type", String)
|
|
120
|
+
], StationAssignmentRowType.prototype, "boardName", void 0);
|
|
121
|
+
tslib_1.__decorate([
|
|
122
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
123
|
+
tslib_1.__metadata("design:type", String)
|
|
124
|
+
], StationAssignmentRowType.prototype, "equipmentName", void 0);
|
|
125
|
+
tslib_1.__decorate([
|
|
126
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
127
|
+
tslib_1.__metadata("design:type", String)
|
|
128
|
+
], StationAssignmentRowType.prototype, "equipmentClassId", void 0);
|
|
129
|
+
tslib_1.__decorate([
|
|
130
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
131
|
+
tslib_1.__metadata("design:type", String)
|
|
132
|
+
], StationAssignmentRowType.prototype, "workCenterName", void 0);
|
|
133
|
+
tslib_1.__decorate([
|
|
134
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
135
|
+
tslib_1.__metadata("design:type", String)
|
|
136
|
+
], StationAssignmentRowType.prototype, "operationKey", void 0);
|
|
137
|
+
tslib_1.__decorate([
|
|
138
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
139
|
+
tslib_1.__metadata("design:type", String)
|
|
140
|
+
], StationAssignmentRowType.prototype, "routeKey", void 0);
|
|
141
|
+
tslib_1.__decorate([
|
|
142
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
143
|
+
tslib_1.__metadata("design:type", String)
|
|
144
|
+
], StationAssignmentRowType.prototype, "materialClassId", void 0);
|
|
145
|
+
tslib_1.__decorate([
|
|
146
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
147
|
+
tslib_1.__metadata("design:type", String)
|
|
148
|
+
], StationAssignmentRowType.prototype, "personnelClassId", void 0);
|
|
149
|
+
tslib_1.__decorate([
|
|
150
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.Int, { nullable: true }),
|
|
151
|
+
tslib_1.__metadata("design:type", Number)
|
|
152
|
+
], StationAssignmentRowType.prototype, "priority", void 0);
|
|
153
|
+
tslib_1.__decorate([
|
|
154
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
155
|
+
tslib_1.__metadata("design:type", Date)
|
|
156
|
+
], StationAssignmentRowType.prototype, "effectiveStart", void 0);
|
|
157
|
+
tslib_1.__decorate([
|
|
158
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
159
|
+
tslib_1.__metadata("design:type", Date
|
|
160
|
+
/**
|
|
161
|
+
* 지금 이 줄이 화면을 그릴 수 있나.
|
|
162
|
+
*
|
|
163
|
+
* ── 왜 선언 옆에 현실을 함께 적나 ────────────────────────────────────────
|
|
164
|
+
* 없어진 보드를 가리키는 배정은 **목록에는 멀쩡히 서 있고 현장에는 아무것도 안 뜬다.** 유효 기간이
|
|
165
|
+
* 지난 줄도 같다. 화면이 그것을 말하지 않으면 관리자는 자기가 적은 것이 왜 안 먹는지 알 길이 없다.
|
|
166
|
+
*/
|
|
167
|
+
)
|
|
168
|
+
], StationAssignmentRowType.prototype, "effectiveEnd", void 0);
|
|
169
|
+
tslib_1.__decorate([
|
|
170
|
+
(0, type_graphql_1.Field)({ description: 'can this row draw anything right now' }),
|
|
171
|
+
tslib_1.__metadata("design:type", Boolean)
|
|
172
|
+
], StationAssignmentRowType.prototype, "usable", void 0);
|
|
173
|
+
tslib_1.__decorate([
|
|
174
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'why not, in words the reader can act on' }),
|
|
175
|
+
tslib_1.__metadata("design:type", String)
|
|
176
|
+
], StationAssignmentRowType.prototype, "because", void 0);
|
|
177
|
+
exports.StationAssignmentRowType = StationAssignmentRowType = tslib_1.__decorate([
|
|
178
|
+
(0, type_graphql_1.ObjectType)({ description: 'one screen assignment, with whether it can actually draw anything' })
|
|
179
|
+
], StationAssignmentRowType);
|
|
180
|
+
let StationAssignmentSetupType = class StationAssignmentSetupType {
|
|
181
|
+
};
|
|
182
|
+
exports.StationAssignmentSetupType = StationAssignmentSetupType;
|
|
183
|
+
tslib_1.__decorate([
|
|
184
|
+
(0, type_graphql_1.Field)(type => [StationAssignmentRowType]),
|
|
185
|
+
tslib_1.__metadata("design:type", Array)
|
|
186
|
+
], StationAssignmentSetupType.prototype, "screens", void 0);
|
|
187
|
+
tslib_1.__decorate([
|
|
188
|
+
(0, type_graphql_1.Field)(type => [String], { description: 'assignments that constrain nothing — more than one always ties' }),
|
|
189
|
+
tslib_1.__metadata("design:type", Array)
|
|
190
|
+
], StationAssignmentSetupType.prototype, "unconstrained", void 0);
|
|
191
|
+
exports.StationAssignmentSetupType = StationAssignmentSetupType = tslib_1.__decorate([
|
|
192
|
+
(0, type_graphql_1.ObjectType)({ description: 'every screen assignment, and what a person has to settle' })
|
|
193
|
+
], StationAssignmentSetupType);
|
|
194
|
+
let StationAssignmentInput = class StationAssignmentInput {
|
|
195
|
+
};
|
|
196
|
+
exports.StationAssignmentInput = StationAssignmentInput;
|
|
197
|
+
tslib_1.__decorate([
|
|
198
|
+
(0, type_graphql_1.Field)(),
|
|
199
|
+
tslib_1.__metadata("design:type", String)
|
|
200
|
+
], StationAssignmentInput.prototype, "name", void 0);
|
|
201
|
+
tslib_1.__decorate([
|
|
202
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
203
|
+
tslib_1.__metadata("design:type", String)
|
|
204
|
+
], StationAssignmentInput.prototype, "description", void 0);
|
|
205
|
+
tslib_1.__decorate([
|
|
206
|
+
(0, type_graphql_1.Field)({ description: 'the station screen to draw, by name' }),
|
|
207
|
+
tslib_1.__metadata("design:type", String)
|
|
208
|
+
], StationAssignmentInput.prototype, "boardId", void 0);
|
|
209
|
+
tslib_1.__decorate([
|
|
210
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
211
|
+
tslib_1.__metadata("design:type", String)
|
|
212
|
+
], StationAssignmentInput.prototype, "equipmentName", void 0);
|
|
213
|
+
tslib_1.__decorate([
|
|
214
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
215
|
+
tslib_1.__metadata("design:type", String)
|
|
216
|
+
], StationAssignmentInput.prototype, "equipmentClassId", void 0);
|
|
217
|
+
tslib_1.__decorate([
|
|
218
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
219
|
+
tslib_1.__metadata("design:type", String)
|
|
220
|
+
], StationAssignmentInput.prototype, "workCenterName", void 0);
|
|
221
|
+
tslib_1.__decorate([
|
|
222
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
223
|
+
tslib_1.__metadata("design:type", String)
|
|
224
|
+
], StationAssignmentInput.prototype, "operationKey", void 0);
|
|
225
|
+
tslib_1.__decorate([
|
|
226
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
227
|
+
tslib_1.__metadata("design:type", String)
|
|
228
|
+
], StationAssignmentInput.prototype, "routeKey", void 0);
|
|
229
|
+
tslib_1.__decorate([
|
|
230
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
231
|
+
tslib_1.__metadata("design:type", String)
|
|
232
|
+
], StationAssignmentInput.prototype, "materialClassId", void 0);
|
|
233
|
+
tslib_1.__decorate([
|
|
234
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
235
|
+
tslib_1.__metadata("design:type", String)
|
|
236
|
+
], StationAssignmentInput.prototype, "personnelClassId", void 0);
|
|
237
|
+
tslib_1.__decorate([
|
|
238
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.Int, { nullable: true, description: 'higher wins when neither screen is more specific' }),
|
|
239
|
+
tslib_1.__metadata("design:type", Number)
|
|
240
|
+
], StationAssignmentInput.prototype, "priority", void 0);
|
|
241
|
+
tslib_1.__decorate([
|
|
242
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
243
|
+
tslib_1.__metadata("design:type", Date)
|
|
244
|
+
], StationAssignmentInput.prototype, "effectiveStart", void 0);
|
|
245
|
+
tslib_1.__decorate([
|
|
246
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
247
|
+
tslib_1.__metadata("design:type", Date)
|
|
248
|
+
], StationAssignmentInput.prototype, "effectiveEnd", void 0);
|
|
249
|
+
exports.StationAssignmentInput = StationAssignmentInput = tslib_1.__decorate([
|
|
250
|
+
(0, type_graphql_1.InputType)({ description: 'which board a station shows, and when' })
|
|
251
|
+
], StationAssignmentInput);
|
|
252
|
+
let StationAssignmentResolver = class StationAssignmentResolver {
|
|
253
|
+
/**
|
|
254
|
+
* 이 작업대가 지금 그릴 보드.
|
|
255
|
+
*
|
|
256
|
+
* **배정이 없으면 아무것도 돌려주지 않는다.** 기본 화면을 내놓지 않는 이유는, 배정하지 않아도 뭔가
|
|
257
|
+
* 뜨면 공장이 「배정은 안 해도 된다」를 배우고, 그 뒤로는 벽에 걸린 것을 아무도 믿지 않게 되기 때문이다.
|
|
258
|
+
*/
|
|
259
|
+
async stationAssignment(equipmentName, context, operationKey, operatorName, jobOrderName) {
|
|
260
|
+
const { domain } = context.state;
|
|
261
|
+
const chosen = await (0, station_assignment_service_1.stationAssignmentFor)((0, shell_1.getRepository)(station_screen_assignment_1.StationScreenAssignment).manager, domain, equipmentName, {
|
|
262
|
+
operationKey,
|
|
263
|
+
operatorName,
|
|
264
|
+
jobOrderName
|
|
265
|
+
});
|
|
266
|
+
return chosen;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* 배정 전부 — **선언 옆에 현실을 함께.**
|
|
270
|
+
*
|
|
271
|
+
* ── 목록의 순서는 승부가 아니다 ─────────────────────────────────────────
|
|
272
|
+
* 이기는 것은 얼마나 구체적인가이고 우선순위는 동점일 때만 쓴다. 목록이 승부를 말하는 척하면 관리자가
|
|
273
|
+
* 맨 위 줄이 이긴다고 읽는다. 그래서 이름순으로만 낸다 — 어느 줄이 이기는지는 **물어봐야** 안다
|
|
274
|
+
* (`stationScreen`).
|
|
275
|
+
*/
|
|
276
|
+
async stationAssignmentSetup(context) {
|
|
277
|
+
const { domain } = context.state;
|
|
278
|
+
const now = new Date();
|
|
279
|
+
const rows = await (0, shell_1.getRepository)(station_screen_assignment_1.StationScreenAssignment).find({
|
|
280
|
+
where: { domain: { id: domain.id } },
|
|
281
|
+
order: { name: 'ASC' }
|
|
282
|
+
});
|
|
283
|
+
/*
|
|
284
|
+
* Does the board this row points at still exist?
|
|
285
|
+
*
|
|
286
|
+
* ── What is missing here, and why it is missing rather than guessed ──────────────────────
|
|
287
|
+
* The question that matters more is "has it ever been released", because a station draws the
|
|
288
|
+
* published snapshot and never the working copy — a board nobody released draws nothing while
|
|
289
|
+
* this row looks fine. Answering it needs `BoardHistory`, which board-service registers as an
|
|
290
|
+
* entity but does not export by name (`service/index.ts` exports `./board/board.js` only).
|
|
291
|
+
*
|
|
292
|
+
* `Board.state` cannot stand in: a released board that has since been edited reads 'draft'
|
|
293
|
+
* while its published version is still on the floor, and `Board.version` defaults to 1 whether
|
|
294
|
+
* or not a release ever happened. So the check is absent rather than approximated — a listing
|
|
295
|
+
* that paints a row green on a guess is worse than one that stays quiet.
|
|
296
|
+
*/
|
|
297
|
+
const boardIds = [...new Set(rows.map(row => row.boardId))];
|
|
298
|
+
const boards = boardIds.length ? await (0, shell_1.getRepository)(board_service_1.Board).find({ where: { domain: { id: domain.id }, id: (0, typeorm_1.In)(boardIds) } }) : [];
|
|
299
|
+
const nameOf = new Map(boards.map(one => [one.id, one.name]));
|
|
300
|
+
const exists = await axesThatExist(domain.id, rows);
|
|
301
|
+
const screens = rows.map(row => {
|
|
302
|
+
const boardName = nameOf.get(row.boardId);
|
|
303
|
+
const notYet = row.effectiveStart && row.effectiveStart.getTime() > now.getTime();
|
|
304
|
+
const over = row.effectiveEnd && row.effectiveEnd.getTime() <= now.getTime();
|
|
305
|
+
/*
|
|
306
|
+
* 어긋난 축을 **모두** 모은다. 하나만 말하면 고치고 저장한 뒤에 또 다른 것이 나온다 — 일곱 칸이
|
|
307
|
+
* 있는 화면에서 그것은 일곱 번의 왕복이다.
|
|
308
|
+
*/
|
|
309
|
+
const wrongAxes = Object.keys(AXIS_COMPLAINT)
|
|
310
|
+
.filter(axis => row[axis] && !exists[axis].has(row[axis]))
|
|
311
|
+
.map(axis => `${row[axis]}: ${AXIS_COMPLAINT[axis]}`);
|
|
312
|
+
return {
|
|
313
|
+
...row,
|
|
314
|
+
boardName,
|
|
315
|
+
/*
|
|
316
|
+
* 축이 어긋난 줄은 **쓸 수 없다.** 저장되고 목록에 서지만 아무 작업대에도 안 걸린다 — 「보드가
|
|
317
|
+
* 없어졌다」와 같은 부류이고, 말하지 않으면 관리자가 일곱 칸 중 어느 것이 틀렸는지 알 길이 없다.
|
|
318
|
+
*/
|
|
319
|
+
usable: Boolean(boardName) && !notYet && !over && !wrongAxes.length,
|
|
320
|
+
because: !boardName
|
|
321
|
+
? 'that board is gone — nothing will be drawn here'
|
|
322
|
+
: wrongAxes.length
|
|
323
|
+
? wrongAxes.join(' · ')
|
|
324
|
+
: notYet
|
|
325
|
+
? 'not in effect yet'
|
|
326
|
+
: over
|
|
327
|
+
? 'no longer in effect'
|
|
328
|
+
: undefined
|
|
329
|
+
};
|
|
330
|
+
});
|
|
331
|
+
return {
|
|
332
|
+
screens,
|
|
333
|
+
/*
|
|
334
|
+
* 아무 축도 안 건 배정들. 하나면 「그 밖의 모든 작업대」라 쓸모가 있고, **둘 이상이면 언제나 동점**
|
|
335
|
+
* 이다 — 우선순위 없이는 이름순으로 갈리고 아무도 그것을 예상하지 못한다.
|
|
336
|
+
*/
|
|
337
|
+
unconstrained: screens
|
|
338
|
+
.filter(row => !row.equipmentName && !row.equipmentClassId && !row.workCenterName && !row.operationKey && !row.routeKey && !row.materialClassId && !row.personnelClassId)
|
|
339
|
+
.map(row => row.name)
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* 배정을 적거나 고친다.
|
|
344
|
+
*
|
|
345
|
+
* ── 왜 만드는 문이 함께 있어야 하나 ──────────────────────────────────────
|
|
346
|
+
* 읽는 질의만 두면 배정을 만들 길이 SQL 뿐이다. 이 제품에서 가장 잦은 결함이 **선언은 있고 길이 없는**
|
|
347
|
+
* 것이고, 관리 화면이 붙기 전이라도 문은 열려 있어야 한다.
|
|
348
|
+
*/
|
|
349
|
+
async saveStationAssignment(context, patch) {
|
|
350
|
+
const { domain, user, tx } = context.state;
|
|
351
|
+
const repository = tx.getRepository(station_screen_assignment_1.StationScreenAssignment);
|
|
352
|
+
/*
|
|
353
|
+
* 끝이 시작보다 앞서면 이 배정은 **아무 때도 걸리지 않는다.** 그런데 목록에는 서 있어서, 관리자는
|
|
354
|
+
* 적어 두었는데 화면이 안 바뀌는 것을 겪고 원인을 찾을 데가 없다.
|
|
355
|
+
*/
|
|
356
|
+
if (patch.effectiveStart && patch.effectiveEnd && patch.effectiveEnd.getTime() <= patch.effectiveStart.getTime()) {
|
|
357
|
+
throw new shell_1.Refusal('time-range-end-not-after-start', {}, 'the end time is not after the start time. enter a later end time.');
|
|
358
|
+
}
|
|
359
|
+
const found = await repository.findOne({ where: { domain: { id: domain.id }, name: patch.name } });
|
|
360
|
+
return await repository.save({
|
|
361
|
+
...(found ?? {}),
|
|
362
|
+
...patch,
|
|
363
|
+
domain,
|
|
364
|
+
...(found ? { updater: user } : { creator: user, updater: user })
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
async deleteStationAssignment(context, name) {
|
|
368
|
+
const { domain, tx } = context.state;
|
|
369
|
+
const repository = tx.getRepository(station_screen_assignment_1.StationScreenAssignment);
|
|
370
|
+
const found = await repository.findOne({ where: { domain: { id: domain.id }, name } });
|
|
371
|
+
if (!found) {
|
|
372
|
+
return false;
|
|
373
|
+
}
|
|
374
|
+
await repository.remove(found);
|
|
375
|
+
return true;
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
exports.StationAssignmentResolver = StationAssignmentResolver;
|
|
379
|
+
tslib_1.__decorate([
|
|
380
|
+
(0, type_graphql_1.Directive)('@privilege(category: "station", privilege: "query", domainOwnerGranted: true)'),
|
|
381
|
+
(0, type_graphql_1.Query)(returns => StationAssignmentChoiceType, {
|
|
382
|
+
nullable: true,
|
|
383
|
+
description: 'the board assigned to this station right now — null when nothing is assigned'
|
|
384
|
+
}),
|
|
385
|
+
tslib_1.__param(0, (0, type_graphql_1.Arg)('equipmentName')),
|
|
386
|
+
tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
|
|
387
|
+
tslib_1.__param(2, (0, type_graphql_1.Arg)('operationKey', { nullable: true, description: 'the operation this station performs' })),
|
|
388
|
+
tslib_1.__param(3, (0, type_graphql_1.Arg)('operatorName', { nullable: true, description: 'who is scanned in — personnel class axes need it' })),
|
|
389
|
+
tslib_1.__param(4, (0, type_graphql_1.Arg)('jobOrderName', { nullable: true, description: 'the order picked but not yet started' })),
|
|
390
|
+
tslib_1.__metadata("design:type", Function),
|
|
391
|
+
tslib_1.__metadata("design:paramtypes", [String, Object, String, String, String]),
|
|
392
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
393
|
+
], StationAssignmentResolver.prototype, "stationAssignment", null);
|
|
394
|
+
tslib_1.__decorate([
|
|
395
|
+
(0, type_graphql_1.Directive)('@privilege(category: "station", privilege: "query", domainOwnerGranted: true)'),
|
|
396
|
+
(0, type_graphql_1.Query)(returns => StationAssignmentSetupType, { description: 'every screen assignment, with what a person must settle' }),
|
|
397
|
+
tslib_1.__param(0, (0, type_graphql_1.Ctx)()),
|
|
398
|
+
tslib_1.__metadata("design:type", Function),
|
|
399
|
+
tslib_1.__metadata("design:paramtypes", [Object]),
|
|
400
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
401
|
+
], StationAssignmentResolver.prototype, "stationAssignmentSetup", null);
|
|
402
|
+
tslib_1.__decorate([
|
|
403
|
+
(0, type_graphql_1.Directive)('@transaction'),
|
|
404
|
+
(0, type_graphql_1.Directive)('@privilege(category: "station", privilege: "mutation", domainOwnerGranted: true)'),
|
|
405
|
+
(0, type_graphql_1.Mutation)(returns => station_screen_assignment_1.StationScreenAssignment, { description: 'declare or change which board a station shows' }),
|
|
406
|
+
tslib_1.__param(0, (0, type_graphql_1.Ctx)()),
|
|
407
|
+
tslib_1.__param(1, (0, type_graphql_1.Arg)('patch', type => StationAssignmentInput)),
|
|
408
|
+
tslib_1.__metadata("design:type", Function),
|
|
409
|
+
tslib_1.__metadata("design:paramtypes", [Object, StationAssignmentInput]),
|
|
410
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
411
|
+
], StationAssignmentResolver.prototype, "saveStationAssignment", null);
|
|
412
|
+
tslib_1.__decorate([
|
|
413
|
+
(0, type_graphql_1.Directive)('@transaction'),
|
|
414
|
+
(0, type_graphql_1.Directive)('@privilege(category: "station", privilege: "mutation", domainOwnerGranted: true)'),
|
|
415
|
+
(0, type_graphql_1.Mutation)(returns => Boolean, { description: 'remove a screen assignment' }),
|
|
416
|
+
tslib_1.__param(0, (0, type_graphql_1.Ctx)()),
|
|
417
|
+
tslib_1.__param(1, (0, type_graphql_1.Arg)('name')),
|
|
418
|
+
tslib_1.__metadata("design:type", Function),
|
|
419
|
+
tslib_1.__metadata("design:paramtypes", [Object, String]),
|
|
420
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
421
|
+
], StationAssignmentResolver.prototype, "deleteStationAssignment", null);
|
|
422
|
+
exports.StationAssignmentResolver = StationAssignmentResolver = tslib_1.__decorate([
|
|
423
|
+
(0, type_graphql_1.Resolver)(station_screen_assignment_1.StationScreenAssignment),
|
|
424
|
+
(0, type_graphql_1.UseMiddleware)(shell_1.SpeakRefusals)
|
|
425
|
+
], StationAssignmentResolver);
|
|
426
|
+
//# sourceMappingURL=station-assignment-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"station-assignment-resolver.js","sourceRoot":"","sources":["../../../server/service/station/station-assignment-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import { Arg, Ctx, Directive, Field, InputType, Int, Mutation, ObjectType, Query, Resolver, UseMiddleware } from 'type-graphql'\n\nimport { getRepository, Refusal, SpeakRefusals } from '@things-factory/shell'\n\nimport { In } from 'typeorm'\n\nimport { Equipment, EquipmentClass, MaterialClass, OperationDefinition, OperationalLocation, PersonnelClass, RouteDefinition } from '@things-factory/ops-master'\n\nimport { Board } from '@things-factory/board-service'\n\nimport { StationScreenAssignment } from './station-screen-assignment'\nimport { stationAssignmentFor } from './station-assignment-service'\n\n@ObjectType({ description: 'Which board this station shows, and why that one' })\nexport class StationAssignmentChoiceType {\n @Field({ description: 'the assignment that won' })\n name: string\n\n @Field({ description: 'the station screen to draw, by name' })\n boardId: string\n\n /**\n * 무엇으로 골랐나.\n *\n * 「왜 이 화면인가」에 답하려고 함께 낸다. 이것이 없으면 배정이 여러 줄일 때 관리자가 자기가 고친 줄이\n * 이 태블릿에 걸리는 줄인지 확인할 방법이 없다.\n */\n @Field(type => [String], { description: 'the axes this assignment constrained — why it was chosen' })\n matchedOn: string[]\n\n /**\n * 같은 만큼 구체적인데 아무것도 가려 주지 못한 다른 배정들.\n *\n * 비어 있는 것이 정상이다. 비어 있지 않으면 **공장이 같은 물음에 답을 둘 갖고 있다**는 뜻이고, 그리는\n * 화면은 정해져 있지만 임의로 정해진 것이다 — 누군가 우선순위를 적어야 한다. 조용히 한쪽을 버리면\n * 관리자는 다른 줄을 고쳐도 아무 일이 안 일어나는 것을 겪는다.\n */\n @Field(type => [String], { description: 'equally specific assignments nothing separated — write a priority' })\n ambiguousWith: string[]\n}\n\n/**\n * Which axis values actually exist in the masters — **one pass, however many assignments.**\n *\n * ── Why the screen has to say this ─────────────────────────────────────────\n * Every axis is typed. A mistyped one is stored, listed, and **matches nothing** — the assignment\n * looks fine and the tablet shows nothing, with no way to tell which of the seven fields is wrong.\n * The board was already checked this way; the axes are the ones people get wrong more often, since\n * there are seven of them and they are keys, not names people remember.\n *\n * ── Checked here, not by narrowing the input ───────────────────────────────\n * Dropdowns were the alternative. This catches values that arrived any other way too — a seed, an\n * import, a hand-edited row — and does not need the whole equipment list in a select on a plant with\n * a thousand machines.\n *\n * ── A class that exists but has no members is still valid ──────────────────\n * So classes are checked against the class masters, not against membership. \"Every welder gets this\n * screen\" is a fair thing to declare before the first welder is hired.\n *\n * ── `kind` counts as a class ───────────────────────────────────────────────\n * Equipment membership is `equipmentClassIds ∪ {kind}` (the contract's own rule), so a value used as\n * some machine's `kind` is a working selector even when no `EquipmentClass` row declares it.\n * Complaining about it would be a false alarm, and false alarms kill the true ones.\n */\nasync function axesThatExist(domainId: string, rows: readonly StationScreenAssignment[]) {\n const values = (pick: (row: StationScreenAssignment) => string | undefined) => [...new Set(rows.map(pick).filter((one): one is string => Boolean(one)))]\n\n const namesOf = async (entity: any, names: string[]) =>\n names.length\n ? new Set(\n (\n await getRepository(entity).find({\n where: { domain: { id: domainId }, name: In(names) },\n select: ['name']\n })\n ).map((one: any) => one.name)\n )\n : new Set<string>()\n\n const equipmentClassNames = values(row => row.equipmentClassId)\n\n const [equipment, equipmentClasses, kinds, lines, operations, routes, materialClasses, personnelClasses] = await Promise.all([\n namesOf(\n Equipment,\n values(row => row.equipmentName)\n ),\n namesOf(EquipmentClass, equipmentClassNames),\n /* `kind` is not a name column, so it is asked for separately. */\n equipmentClassNames.length\n ? getRepository(Equipment)\n .find({ where: { domain: { id: domainId }, kind: In(equipmentClassNames) }, select: ['kind'] })\n .then(found => new Set(found.map(one => one.kind)))\n : Promise.resolve(new Set<string>()),\n namesOf(\n OperationalLocation,\n values(row => row.workCenterName)\n ),\n namesOf(\n OperationDefinition,\n values(row => row.operationKey)\n ),\n namesOf(\n RouteDefinition,\n values(row => row.routeKey)\n ),\n namesOf(\n MaterialClass,\n values(row => row.materialClassId)\n ),\n namesOf(\n PersonnelClass,\n values(row => row.personnelClassId)\n )\n ])\n\n return {\n equipmentName: equipment,\n equipmentClassId: new Set([...equipmentClasses, ...kinds]),\n workCenterName: lines,\n operationKey: operations,\n routeKey: routes,\n materialClassId: materialClasses,\n personnelClassId: personnelClasses\n }\n}\n\n/** 어느 축이 어긋났는지 사용자의 말로. 축 이름을 그대로 보이지 않는다 — 화면이 번역한다. */\nconst AXIS_COMPLAINT: Record<string, string> = {\n equipmentName: 'no equipment by that name',\n equipmentClassId: 'no equipment class or kind by that name',\n workCenterName: 'no location by that name',\n operationKey: 'no operation by that name',\n routeKey: 'no route by that name',\n materialClassId: 'no material class by that name',\n personnelClassId: 'no personnel class by that name'\n}\n\n@ObjectType({ description: 'one screen assignment, with whether it can actually draw anything' })\nexport class StationAssignmentRowType {\n @Field()\n name: string\n\n @Field({ nullable: true })\n description?: string\n\n @Field({ description: 'the station screen to draw, by name' })\n boardId: string\n\n /**\n * 그 화면이 지금 현장에 나가 있는 판.\n *\n * 없으면 **나간 판이 없다**는 뜻이고, 그러면 이 배정은 아무것도 못 그린다 — 아래 `usable` 이 그것을\n * 말한다. 초안이 있어도 대신 내밀지 않는다: 작업대가 그리다 만 화면 앞에서 실적을 남기게 된다.\n */\n @Field({ nullable: true, description: 'the version currently released — absent when none is' })\n @Field({ nullable: true, description: \"the board's name, so the list reads as words not ids\" })\n boardName?: string\n\n @Field({ nullable: true })\n equipmentName?: string\n\n @Field({ nullable: true })\n equipmentClassId?: string\n\n @Field({ nullable: true })\n workCenterName?: string\n\n @Field({ nullable: true })\n operationKey?: string\n\n @Field({ nullable: true })\n routeKey?: string\n\n @Field({ nullable: true })\n materialClassId?: string\n\n @Field({ nullable: true })\n personnelClassId?: string\n\n @Field(type => Int, { nullable: true })\n priority?: number\n\n @Field({ nullable: true })\n effectiveStart?: Date\n\n @Field({ nullable: true })\n effectiveEnd?: Date\n\n /**\n * 지금 이 줄이 화면을 그릴 수 있나.\n *\n * ── 왜 선언 옆에 현실을 함께 적나 ────────────────────────────────────────\n * 없어진 보드를 가리키는 배정은 **목록에는 멀쩡히 서 있고 현장에는 아무것도 안 뜬다.** 유효 기간이\n * 지난 줄도 같다. 화면이 그것을 말하지 않으면 관리자는 자기가 적은 것이 왜 안 먹는지 알 길이 없다.\n */\n @Field({ description: 'can this row draw anything right now' })\n usable: boolean\n\n /** 못 쓰면 왜 못 쓰나 — 사용자가 읽을 문장. 쓸 수 있으면 없다. */\n @Field({ nullable: true, description: 'why not, in words the reader can act on' })\n because?: string\n}\n\n@ObjectType({ description: 'every screen assignment, and what a person has to settle' })\nexport class StationAssignmentSetupType {\n @Field(type => [StationAssignmentRowType])\n screens: StationAssignmentRowType[]\n\n /**\n * 아무 축도 걸지 않은 배정의 이름들.\n *\n * 하나면 「그 밖의 모든 작업대」라는 뜻이라 쓸모가 있다. **둘 이상이면 둘 다 모든 작업대에 들어맞고**\n * 언제나 동점이다 — 우선순위 없이는 이름순으로 갈린다. 화면이 짚어 준다.\n */\n @Field(type => [String], { description: 'assignments that constrain nothing — more than one always ties' })\n unconstrained: string[]\n}\n\n@InputType({ description: 'which board a station shows, and when' })\nexport class StationAssignmentInput {\n @Field()\n name: string\n\n @Field({ nullable: true })\n description?: string\n\n @Field({ description: 'the station screen to draw, by name' })\n boardId: string\n\n @Field({ nullable: true })\n equipmentName?: string\n\n @Field({ nullable: true })\n equipmentClassId?: string\n\n @Field({ nullable: true })\n workCenterName?: string\n\n @Field({ nullable: true })\n operationKey?: string\n\n @Field({ nullable: true })\n routeKey?: string\n\n @Field({ nullable: true })\n materialClassId?: string\n\n @Field({ nullable: true })\n personnelClassId?: string\n\n @Field(type => Int, { nullable: true, description: 'higher wins when neither screen is more specific' })\n priority?: number\n\n @Field({ nullable: true })\n effectiveStart?: Date\n\n @Field({ nullable: true })\n effectiveEnd?: Date\n}\n\n@Resolver(StationScreenAssignment)\n@UseMiddleware(SpeakRefusals)\nexport class StationAssignmentResolver {\n /**\n * 이 작업대가 지금 그릴 보드.\n *\n * **배정이 없으면 아무것도 돌려주지 않는다.** 기본 화면을 내놓지 않는 이유는, 배정하지 않아도 뭔가\n * 뜨면 공장이 「배정은 안 해도 된다」를 배우고, 그 뒤로는 벽에 걸린 것을 아무도 믿지 않게 되기 때문이다.\n */\n @Directive('@privilege(category: \"station\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(returns => StationAssignmentChoiceType, {\n nullable: true,\n description: 'the board assigned to this station right now — null when nothing is assigned'\n })\n async stationAssignment(\n @Arg('equipmentName') equipmentName: string,\n @Ctx() context: any,\n @Arg('operationKey', { nullable: true, description: 'the operation this station performs' })\n operationKey?: string,\n @Arg('operatorName', { nullable: true, description: 'who is scanned in — personnel class axes need it' })\n operatorName?: string,\n @Arg('jobOrderName', { nullable: true, description: 'the order picked but not yet started' })\n jobOrderName?: string\n ): Promise<StationAssignmentChoiceType | undefined> {\n const { domain } = context.state\n\n const chosen = await stationAssignmentFor(getRepository(StationScreenAssignment).manager, domain, equipmentName, {\n operationKey,\n operatorName,\n jobOrderName\n })\n\n return chosen as StationAssignmentChoiceType | undefined\n }\n\n /**\n * 배정 전부 — **선언 옆에 현실을 함께.**\n *\n * ── 목록의 순서는 승부가 아니다 ─────────────────────────────────────────\n * 이기는 것은 얼마나 구체적인가이고 우선순위는 동점일 때만 쓴다. 목록이 승부를 말하는 척하면 관리자가\n * 맨 위 줄이 이긴다고 읽는다. 그래서 이름순으로만 낸다 — 어느 줄이 이기는지는 **물어봐야** 안다\n * (`stationScreen`).\n */\n @Directive('@privilege(category: \"station\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(returns => StationAssignmentSetupType, { description: 'every screen assignment, with what a person must settle' })\n async stationAssignmentSetup(@Ctx() context: any): Promise<StationAssignmentSetupType> {\n const { domain } = context.state\n const now = new Date()\n\n const rows = await getRepository(StationScreenAssignment).find({\n where: { domain: { id: domain.id } },\n order: { name: 'ASC' }\n })\n\n /*\n * Does the board this row points at still exist?\n *\n * ── What is missing here, and why it is missing rather than guessed ──────────────────────\n * The question that matters more is \"has it ever been released\", because a station draws the\n * published snapshot and never the working copy — a board nobody released draws nothing while\n * this row looks fine. Answering it needs `BoardHistory`, which board-service registers as an\n * entity but does not export by name (`service/index.ts` exports `./board/board.js` only).\n *\n * `Board.state` cannot stand in: a released board that has since been edited reads 'draft'\n * while its published version is still on the floor, and `Board.version` defaults to 1 whether\n * or not a release ever happened. So the check is absent rather than approximated — a listing\n * that paints a row green on a guess is worse than one that stays quiet.\n */\n const boardIds = [...new Set(rows.map(row => row.boardId))]\n\n const boards = boardIds.length ? await getRepository(Board).find({ where: { domain: { id: domain.id }, id: In(boardIds) } }) : []\n const nameOf = new Map(boards.map(one => [one.id, one.name]))\n\n const exists = await axesThatExist(domain.id, rows)\n\n const screens = rows.map(row => {\n const boardName = nameOf.get(row.boardId)\n const notYet = row.effectiveStart && row.effectiveStart.getTime() > now.getTime()\n const over = row.effectiveEnd && row.effectiveEnd.getTime() <= now.getTime()\n\n /*\n * 어긋난 축을 **모두** 모은다. 하나만 말하면 고치고 저장한 뒤에 또 다른 것이 나온다 — 일곱 칸이\n * 있는 화면에서 그것은 일곱 번의 왕복이다.\n */\n const wrongAxes = (Object.keys(AXIS_COMPLAINT) as (keyof typeof exists)[])\n .filter(axis => row[axis] && !exists[axis].has(row[axis] as string))\n .map(axis => `${row[axis]}: ${AXIS_COMPLAINT[axis]}`)\n\n return {\n ...row,\n boardName,\n /*\n * 축이 어긋난 줄은 **쓸 수 없다.** 저장되고 목록에 서지만 아무 작업대에도 안 걸린다 — 「보드가\n * 없어졌다」와 같은 부류이고, 말하지 않으면 관리자가 일곱 칸 중 어느 것이 틀렸는지 알 길이 없다.\n */\n usable: Boolean(boardName) && !notYet && !over && !wrongAxes.length,\n because: !boardName\n ? 'that board is gone — nothing will be drawn here'\n : wrongAxes.length\n ? wrongAxes.join(' · ')\n : notYet\n ? 'not in effect yet'\n : over\n ? 'no longer in effect'\n : undefined\n } as StationAssignmentRowType\n })\n\n return {\n screens,\n /*\n * 아무 축도 안 건 배정들. 하나면 「그 밖의 모든 작업대」라 쓸모가 있고, **둘 이상이면 언제나 동점**\n * 이다 — 우선순위 없이는 이름순으로 갈리고 아무도 그것을 예상하지 못한다.\n */\n unconstrained: screens\n .filter(\n row =>\n !row.equipmentName && !row.equipmentClassId && !row.workCenterName && !row.operationKey && !row.routeKey && !row.materialClassId && !row.personnelClassId\n )\n .map(row => row.name)\n }\n }\n\n /**\n * 배정을 적거나 고친다.\n *\n * ── 왜 만드는 문이 함께 있어야 하나 ──────────────────────────────────────\n * 읽는 질의만 두면 배정을 만들 길이 SQL 뿐이다. 이 제품에서 가장 잦은 결함이 **선언은 있고 길이 없는**\n * 것이고, 관리 화면이 붙기 전이라도 문은 열려 있어야 한다.\n */\n @Directive('@transaction')\n @Directive('@privilege(category: \"station\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => StationScreenAssignment, { description: 'declare or change which board a station shows' })\n async saveStationAssignment(@Ctx() context: any, @Arg('patch', type => StationAssignmentInput) patch: StationAssignmentInput): Promise<StationScreenAssignment> {\n const { domain, user, tx } = context.state\n const repository = tx.getRepository(StationScreenAssignment)\n\n /*\n * 끝이 시작보다 앞서면 이 배정은 **아무 때도 걸리지 않는다.** 그런데 목록에는 서 있어서, 관리자는\n * 적어 두었는데 화면이 안 바뀌는 것을 겪고 원인을 찾을 데가 없다.\n */\n if (patch.effectiveStart && patch.effectiveEnd && patch.effectiveEnd.getTime() <= patch.effectiveStart.getTime()) {\n throw new Refusal('time-range-end-not-after-start', {}, 'the end time is not after the start time. enter a later end time.')\n }\n\n const found = await repository.findOne({ where: { domain: { id: domain.id }, name: patch.name } })\n\n return await repository.save({\n ...(found ?? {}),\n ...patch,\n domain,\n ...(found ? { updater: user } : { creator: user, updater: user })\n } as any)\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"station\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'remove a screen assignment' })\n async deleteStationAssignment(@Ctx() context: any, @Arg('name') name: string): Promise<boolean> {\n const { domain, tx } = context.state\n const repository = tx.getRepository(StationScreenAssignment)\n\n const found = await repository.findOne({ where: { domain: { id: domain.id }, name } })\n\n if (!found) {\n return false\n }\n\n await repository.remove(found)\n\n return true\n }\n}\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { EntityManager } from 'typeorm';
|
|
2
|
+
import { Domain } from '@things-factory/shell';
|
|
3
|
+
import type { StationAssignmentChoice, StationAssignmentSituation } from './station-assignment-choice';
|
|
4
|
+
/**
|
|
5
|
+
* What this station is, in the words the assignment selects on.
|
|
6
|
+
*
|
|
7
|
+
* ── Read the situation from the same place the screen reads it ─────────────
|
|
8
|
+
* It comes from the product's declared ground reader, which is the same function the screen's own
|
|
9
|
+
* context is built on. One vocabulary answers both "which screen shows" and "what does it show" —
|
|
10
|
+
* gathered separately they would drift, and a factory could select on something the screen cannot
|
|
11
|
+
* display and never work out why the board is blank.
|
|
12
|
+
*
|
|
13
|
+
* Declared rather than imported so the machinery does not name this product (ADR-0083 decision 2).
|
|
14
|
+
*/
|
|
15
|
+
export declare function stationSituationOf(manager: EntityManager, domain: Domain, equipmentName: string, at?: {
|
|
16
|
+
operationKey?: string;
|
|
17
|
+
operatorName?: string;
|
|
18
|
+
jobOrderName?: string;
|
|
19
|
+
}): Promise<StationAssignmentSituation>;
|
|
20
|
+
/**
|
|
21
|
+
* Which board this station shows right now.
|
|
22
|
+
*
|
|
23
|
+
* ── Effectiveness is filtered here, matching is not ────────────────────────
|
|
24
|
+
* A row that does not apply today is not a candidate at all, so it is left out before the rule runs
|
|
25
|
+
* — keeping the pure rule about specificity and nothing else. The dates are the standard
|
|
26
|
+
* `EffectiveStartDate` / `EffectiveEndDate` pair the masters already use, and they are what lets a
|
|
27
|
+
* changeover be prepared in advance rather than switched by hand on the morning.
|
|
28
|
+
*/
|
|
29
|
+
export declare function stationAssignmentFor(manager: EntityManager, domain: Domain, equipmentName: string, at?: {
|
|
30
|
+
operationKey?: string;
|
|
31
|
+
operatorName?: string;
|
|
32
|
+
jobOrderName?: string;
|
|
33
|
+
}, now?: Date): Promise<StationAssignmentChoice | undefined>;
|