@things-factory/work-shift 10.1.33 → 10.1.35
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/dist-client/pages/work-shift.d.ts +18 -102
- package/dist-client/pages/work-shift.js +165 -781
- package/dist-client/pages/work-shift.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/controllers/work-shift-range.d.ts +25 -9
- package/dist-server/controllers/work-shift-range.js +49 -196
- package/dist-server/controllers/work-shift-range.js.map +1 -1
- package/dist-server/controllers/work-shift-schedule.d.ts +2 -0
- package/dist-server/controllers/work-shift-schedule.js +9 -18
- package/dist-server/controllers/work-shift-schedule.js.map +1 -1
- package/dist-server/service/index.d.ts +5 -2
- package/dist-server/service/index.js +3 -0
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/work-shift/index.d.ts +4 -4
- package/dist-server/service/work-shift/index.js +4 -3
- package/dist-server/service/work-shift/index.js.map +1 -1
- package/dist-server/service/work-shift/shift-occurrence.d.ts +19 -0
- package/dist-server/service/work-shift/shift-occurrence.js +34 -0
- package/dist-server/service/work-shift/shift-occurrence.js.map +1 -0
- package/dist-server/service/work-shift/work-shift-arrangement.d.ts +10 -0
- package/dist-server/service/work-shift/work-shift-arrangement.js +40 -0
- package/dist-server/service/work-shift/work-shift-arrangement.js.map +1 -0
- package/dist-server/service/work-shift/work-shift-content.d.ts +15 -0
- package/dist-server/service/work-shift/work-shift-content.js +55 -0
- package/dist-server/service/work-shift/work-shift-content.js.map +1 -0
- package/dist-server/service/work-shift/work-shift-lifecycle-resolver.d.ts +60 -0
- package/dist-server/service/work-shift/work-shift-lifecycle-resolver.js +77 -0
- package/dist-server/service/work-shift/work-shift-lifecycle-resolver.js.map +1 -0
- package/dist-server/service/work-shift/work-shift-lifecycle.d.ts +130 -0
- package/dist-server/service/work-shift/work-shift-lifecycle.js +508 -0
- package/dist-server/service/work-shift/work-shift-lifecycle.js.map +1 -0
- package/dist-server/service/work-shift/work-shift-mutation.js +9 -42
- package/dist-server/service/work-shift/work-shift-mutation.js.map +1 -1
- package/dist-server/service/work-shift/work-shift-query.js +30 -15
- package/dist-server/service/work-shift/work-shift-query.js.map +1 -1
- package/dist-server/service/work-shift/work-shift-revision-service.d.ts +29 -65
- package/dist-server/service/work-shift/work-shift-revision-service.js +67 -167
- package/dist-server/service/work-shift/work-shift-revision-service.js.map +1 -1
- package/dist-server/service/work-shift/work-shift-revision.d.ts +78 -62
- package/dist-server/service/work-shift/work-shift-revision.js +303 -82
- package/dist-server/service/work-shift/work-shift-revision.js.map +1 -1
- package/dist-server/service/work-shift/work-shift-type.d.ts +0 -5
- package/dist-server/service/work-shift/work-shift-type.js +1 -16
- package/dist-server/service/work-shift/work-shift-type.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/helps/page/work-shift.ko.md +19 -3
- package/helps/page/work-shift.md +17 -9
- package/package.json +8 -5
- package/dist-server/service/work-shift/work-shift-revision-query.d.ts +0 -20
- package/dist-server/service/work-shift/work-shift-revision-query.js +0 -74
- package/dist-server/service/work-shift/work-shift-revision-query.js.map +0 -1
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# 근무 교대
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
현재 편성과 변경안을 함께 관리합니다. 리비전 번호는 편성 전체의 개정 번호이며 교대 이름과는 다릅니다.
|
|
4
|
+
|
|
5
|
+
## 변경 절차
|
|
6
|
+
|
|
7
|
+
1. **변경안 작성**을 누르고 교대 이름, 시작·종료 시각, 전일/당일/익일, 근무 요일을 입력합니다.
|
|
8
|
+
2. 편성 시간대, 변경 사유와 적용 시작을 확인합니다. 적용 시작 입력 옆의 시간대는 입력·표시 기준이며 편성 시간대와 별개입니다.
|
|
9
|
+
3. **초안 저장** 후 **승인 요청**합니다. 비규제 현장은 정책에 따라 발행합니다. 저장만으로 현재 편성이 바뀌지 않습니다.
|
|
10
|
+
|
|
11
|
+
규제 현장은 결재선이 필요하며 작성자는 자기 변경을 승인할 수 없습니다. 상신 후 수정하려면 새 변경안을 작성합니다.
|
|
12
|
+
|
|
13
|
+
## 상태와 상세
|
|
14
|
+
|
|
15
|
+
현재 카드에서 지금 적용되는 편성을 보고, 이력에서 초안·승인대기·반려·현재·예약 적용과 적용 구간을 확인합니다. 리비전 번호를 누르면 내용과 전후 차이를, **결재 보기**를 누르면 결재 상태와 의견을 봅니다.
|
|
16
|
+
|
|
17
|
+
결재 화면의 변경 전·후 링크를 직접 누르면 해당 개정의 전체 내용이 공통 360 도크에 표시됩니다. 승인된 미래 변경은 적용 시각까지 예약 상태입니다. 반려된 변경은 적용되지 않습니다.
|
|
18
|
+
|
|
19
|
+
야간 교대의 요일은 조업일의 요일입니다. 예를 들어 금요일 22시~익일 06시는 토요일 새벽에도 금요일 교대입니다. 이미 기록된 실적은 당시 교대 근거를 유지하며 사용된 구간의 소급 변경은 거절될 수 있습니다.
|
|
20
|
+
|
|
21
|
+
휴일·정비일·위치별 교대 선택은 별도 설정입니다. 편성 승인이 그 설정까지 개정하지는 않습니다.
|
package/helps/page/work-shift.md
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Work shifts
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
자리만 잡아 둔 문서다. **내용은 전담 에이전트가 쓴다** — 여기서는 배치만 했다.
|
|
3
|
+
Manage the current arrangement and proposed changes together. A revision number identifies the whole arrangement, not a shift name.
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
· work-shift/work-shift.ts
|
|
5
|
+
## Change an arrangement
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
1. Select **Create change** and enter shift names, start/end clocks, previous/work/next-day offsets and weekdays.
|
|
8
|
+
2. Check the arrangement time zone, reason and effective start. The input/display time zone beside effective start is separate from the arrangement time zone.
|
|
9
|
+
3. **Save draft**, then **Request approval**. Non-regulated sites publish under their declared policy. Saving a draft does not change current values.
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
Regulated sites need an approval line and a different approver. Submitted content is frozen; corrections require a new draft.
|
|
12
|
+
|
|
13
|
+
## Read status and details
|
|
14
|
+
|
|
15
|
+
The current card shows the effective arrangement. History distinguishes drafts, pending approvals, rejection, current and scheduled revisions with effective intervals. Select a revision for its content and differences, or **Approval details** for decisions and comments.
|
|
16
|
+
|
|
17
|
+
Explicitly select a before/after link in approval to open that exact revision in the shared Entity360 dock. Approved future revisions remain scheduled until their effective instant. Rejected changes do not apply.
|
|
18
|
+
|
|
19
|
+
Weekdays belong to the work date: Friday 22:00–next-day 06:00 still belongs to Friday on Saturday morning. Recorded executions retain their original basis, and retroactive changes affecting them may be refused.
|
|
20
|
+
|
|
21
|
+
Holidays, maintenance periods and location-specific shift selection remain separate settings. Approval here does not revise those settings.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@things-factory/work-shift",
|
|
3
|
-
"version": "10.1.
|
|
3
|
+
"version": "10.1.35",
|
|
4
4
|
"main": "dist-server/index.js",
|
|
5
5
|
"browser": "dist-client/index.js",
|
|
6
6
|
"things-factory": true,
|
|
@@ -25,13 +25,16 @@
|
|
|
25
25
|
"clean:server": "npx rimraf dist-server",
|
|
26
26
|
"clean": "npm run clean:server && npm run clean:client",
|
|
27
27
|
"migration:create": "node ../../node_modules/typeorm/cli.js migration:create ./server/migrations/migration",
|
|
28
|
-
"test": "
|
|
28
|
+
"test": "npm run test:unit && npm run test:db",
|
|
29
|
+
"test:unit": "node --import ./test/resolve-ts-siblings.mjs --test --test-force-exit test/*.test.ts",
|
|
30
|
+
"test:db": "npm run build:server && node --test --test-force-exit test/*.db.test.cjs"
|
|
29
31
|
},
|
|
30
32
|
"dependencies": {
|
|
31
|
-
"@things-factory/auth-base": "^10.1.
|
|
33
|
+
"@things-factory/auth-base": "^10.1.34",
|
|
32
34
|
"@things-factory/env": "^10.1.20",
|
|
33
|
-
"@things-factory/
|
|
35
|
+
"@things-factory/ops-master": "^10.1.35",
|
|
36
|
+
"@things-factory/shell": "^10.1.34",
|
|
34
37
|
"moment-timezone": "^0.5.40"
|
|
35
38
|
},
|
|
36
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "396f43b648b704f1938a2d890ab2f6efa33fdb86"
|
|
37
40
|
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { User } from '@things-factory/auth-base';
|
|
2
|
-
import { Domain, ListParam } from '@things-factory/shell';
|
|
3
|
-
import { WorkShiftRevision } from './work-shift-revision';
|
|
4
|
-
import { WorkShiftRevisionList } from './work-shift-type';
|
|
5
|
-
/**
|
|
6
|
-
* 지나간 편성을 읽는다. **읽기만 있다** — 지나간 것은 고치는 것이 아니다.
|
|
7
|
-
*/
|
|
8
|
-
export declare class WorkShiftRevisionQuery {
|
|
9
|
-
workShiftRevisions(params: ListParam, context: ResolverContext): Promise<WorkShiftRevisionList>;
|
|
10
|
-
/**
|
|
11
|
-
* 편성 한 벌을 **JSON 글자로** 내보낸다.
|
|
12
|
-
*
|
|
13
|
-
* 이 칸은 `simple-json` 이라 값이 배열이다. 스키마에 `String` 으로 적어 두고 배열을 그대로 내보내면
|
|
14
|
-
* GraphQL 이 「String cannot represent value」로 응답을 통째로 버린다 — 화면에서 예고를 넣고 나서야
|
|
15
|
-
* 드러났다. 목록이 비어 있는 동안에는 이 자리를 지나지 않기 때문이다.
|
|
16
|
-
*/
|
|
17
|
-
shifts(revision: WorkShiftRevision): string;
|
|
18
|
-
domain(revision: WorkShiftRevision): Promise<Domain>;
|
|
19
|
-
creator(revision: WorkShiftRevision): Promise<User | null>;
|
|
20
|
-
}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.WorkShiftRevisionQuery = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const type_graphql_1 = require("type-graphql");
|
|
6
|
-
const auth_base_1 = require("@things-factory/auth-base");
|
|
7
|
-
const shell_1 = require("@things-factory/shell");
|
|
8
|
-
const work_shift_revision_1 = require("./work-shift-revision");
|
|
9
|
-
const work_shift_type_1 = require("./work-shift-type");
|
|
10
|
-
/**
|
|
11
|
-
* 지나간 편성을 읽는다. **읽기만 있다** — 지나간 것은 고치는 것이 아니다.
|
|
12
|
-
*/
|
|
13
|
-
let WorkShiftRevisionQuery = class WorkShiftRevisionQuery {
|
|
14
|
-
async workShiftRevisions(params, context) {
|
|
15
|
-
const { domain } = context.state;
|
|
16
|
-
const queryBuilder = (0, shell_1.getQueryBuilderFromListParams)({
|
|
17
|
-
repository: (0, shell_1.getRepository)(work_shift_revision_1.WorkShiftRevision),
|
|
18
|
-
params,
|
|
19
|
-
domain
|
|
20
|
-
});
|
|
21
|
-
const [items, total] = await queryBuilder.getManyAndCount();
|
|
22
|
-
return { items, total };
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* 편성 한 벌을 **JSON 글자로** 내보낸다.
|
|
26
|
-
*
|
|
27
|
-
* 이 칸은 `simple-json` 이라 값이 배열이다. 스키마에 `String` 으로 적어 두고 배열을 그대로 내보내면
|
|
28
|
-
* GraphQL 이 「String cannot represent value」로 응답을 통째로 버린다 — 화면에서 예고를 넣고 나서야
|
|
29
|
-
* 드러났다. 목록이 비어 있는 동안에는 이 자리를 지나지 않기 때문이다.
|
|
30
|
-
*/
|
|
31
|
-
shifts(revision) {
|
|
32
|
-
return JSON.stringify(revision.shifts ?? []);
|
|
33
|
-
}
|
|
34
|
-
async domain(revision) {
|
|
35
|
-
return await (0, shell_1.getRepository)(shell_1.Domain).findOneBy({ id: revision.domainId });
|
|
36
|
-
}
|
|
37
|
-
async creator(revision) {
|
|
38
|
-
return revision.creatorId ? await (0, shell_1.getRepository)(auth_base_1.User).findOneBy({ id: revision.creatorId }) : null;
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
exports.WorkShiftRevisionQuery = WorkShiftRevisionQuery;
|
|
42
|
-
tslib_1.__decorate([
|
|
43
|
-
(0, type_graphql_1.Query)(returns => work_shift_type_1.WorkShiftRevisionList, { description: 'To fetch work shift arrangements that used to be in force' }),
|
|
44
|
-
tslib_1.__param(0, (0, type_graphql_1.Args)(type => shell_1.ListParam)),
|
|
45
|
-
tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
|
|
46
|
-
tslib_1.__metadata("design:type", Function),
|
|
47
|
-
tslib_1.__metadata("design:paramtypes", [shell_1.ListParam, Object]),
|
|
48
|
-
tslib_1.__metadata("design:returntype", Promise)
|
|
49
|
-
], WorkShiftRevisionQuery.prototype, "workShiftRevisions", null);
|
|
50
|
-
tslib_1.__decorate([
|
|
51
|
-
(0, type_graphql_1.FieldResolver)(type => String),
|
|
52
|
-
tslib_1.__param(0, (0, type_graphql_1.Root)()),
|
|
53
|
-
tslib_1.__metadata("design:type", Function),
|
|
54
|
-
tslib_1.__metadata("design:paramtypes", [work_shift_revision_1.WorkShiftRevision]),
|
|
55
|
-
tslib_1.__metadata("design:returntype", String)
|
|
56
|
-
], WorkShiftRevisionQuery.prototype, "shifts", null);
|
|
57
|
-
tslib_1.__decorate([
|
|
58
|
-
(0, type_graphql_1.FieldResolver)(type => shell_1.Domain),
|
|
59
|
-
tslib_1.__param(0, (0, type_graphql_1.Root)()),
|
|
60
|
-
tslib_1.__metadata("design:type", Function),
|
|
61
|
-
tslib_1.__metadata("design:paramtypes", [work_shift_revision_1.WorkShiftRevision]),
|
|
62
|
-
tslib_1.__metadata("design:returntype", Promise)
|
|
63
|
-
], WorkShiftRevisionQuery.prototype, "domain", null);
|
|
64
|
-
tslib_1.__decorate([
|
|
65
|
-
(0, type_graphql_1.FieldResolver)(type => auth_base_1.User, { nullable: true }),
|
|
66
|
-
tslib_1.__param(0, (0, type_graphql_1.Root)()),
|
|
67
|
-
tslib_1.__metadata("design:type", Function),
|
|
68
|
-
tslib_1.__metadata("design:paramtypes", [work_shift_revision_1.WorkShiftRevision]),
|
|
69
|
-
tslib_1.__metadata("design:returntype", Promise)
|
|
70
|
-
], WorkShiftRevisionQuery.prototype, "creator", null);
|
|
71
|
-
exports.WorkShiftRevisionQuery = WorkShiftRevisionQuery = tslib_1.__decorate([
|
|
72
|
-
(0, type_graphql_1.Resolver)(work_shift_revision_1.WorkShiftRevision)
|
|
73
|
-
], WorkShiftRevisionQuery);
|
|
74
|
-
//# sourceMappingURL=work-shift-revision-query.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"work-shift-revision-query.js","sourceRoot":"","sources":["../../../server/service/work-shift/work-shift-revision-query.ts"],"names":[],"mappings":";;;;AAAA,+CAA8E;AAE9E,yDAAgD;AAChD,iDAAuG;AAEvG,+DAAyD;AACzD,uDAAyD;AAEzD;;GAEG;AAEI,IAAM,sBAAsB,GAA5B,MAAM,sBAAsB;IAE3B,AAAN,KAAK,CAAC,kBAAkB,CACG,MAAiB,EACnC,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAEhC,MAAM,YAAY,GAAG,IAAA,qCAA6B,EAAC;YACjD,UAAU,EAAE,IAAA,qBAAa,EAAC,uCAAiB,CAAC;YAC5C,MAAM;YACN,MAAM;SACP,CAAC,CAAA;QAEF,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,YAAY,CAAC,eAAe,EAAE,CAAA;QAE3D,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;IACzB,CAAC;IAED;;;;;;OAMG;IAEH,MAAM,CAAS,QAA2B;QACxC,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC,CAAA;IAC9C,CAAC;IAGK,AAAN,KAAK,CAAC,MAAM,CAAS,QAA2B;QAC9C,OAAO,MAAM,IAAA,qBAAa,EAAC,cAAM,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAA;IACzE,CAAC;IAGK,AAAN,KAAK,CAAC,OAAO,CAAS,QAA2B;QAC/C,OAAO,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,IAAA,qBAAa,EAAC,gBAAI,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACpG,CAAC;CACF,CAAA;AAxCY,wDAAsB;AAE3B;IADL,IAAA,oBAAK,EAAC,OAAO,CAAC,EAAE,CAAC,uCAAqB,EAAE,EAAE,WAAW,EAAE,2DAA2D,EAAE,CAAC;IAEnH,mBAAA,IAAA,mBAAI,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAS,CAAC,CAAA;IACvB,mBAAA,IAAA,kBAAG,GAAE,CAAA;;6CAD2B,iBAAS;;gEAc3C;AAUD;IADC,IAAA,4BAAa,EAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC;IACtB,mBAAA,IAAA,mBAAI,GAAE,CAAA;;6CAAW,uCAAiB;;oDAEzC;AAGK;IADL,IAAA,4BAAa,EAAC,IAAI,CAAC,EAAE,CAAC,cAAM,CAAC;IAChB,mBAAA,IAAA,mBAAI,GAAE,CAAA;;6CAAW,uCAAiB;;oDAE/C;AAGK;IADL,IAAA,4BAAa,EAAC,IAAI,CAAC,EAAE,CAAC,gBAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACjC,mBAAA,IAAA,mBAAI,GAAE,CAAA;;6CAAW,uCAAiB;;qDAEhD;iCAvCU,sBAAsB;IADlC,IAAA,uBAAQ,EAAC,uCAAiB,CAAC;GACf,sBAAsB,CAwClC","sourcesContent":["import { Args, Ctx, FieldResolver, Query, Resolver, Root } from 'type-graphql'\n\nimport { User } from '@things-factory/auth-base'\nimport { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'\n\nimport { WorkShiftRevision } from './work-shift-revision'\nimport { WorkShiftRevisionList } from './work-shift-type'\n\n/**\n * 지나간 편성을 읽는다. **읽기만 있다** — 지나간 것은 고치는 것이 아니다.\n */\n@Resolver(WorkShiftRevision)\nexport class WorkShiftRevisionQuery {\n @Query(returns => WorkShiftRevisionList, { description: 'To fetch work shift arrangements that used to be in force' })\n async workShiftRevisions(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<WorkShiftRevisionList> {\n const { domain } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n repository: getRepository(WorkShiftRevision),\n params,\n domain\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n /**\n * 편성 한 벌을 **JSON 글자로** 내보낸다.\n *\n * 이 칸은 `simple-json` 이라 값이 배열이다. 스키마에 `String` 으로 적어 두고 배열을 그대로 내보내면\n * GraphQL 이 「String cannot represent value」로 응답을 통째로 버린다 — 화면에서 예고를 넣고 나서야\n * 드러났다. 목록이 비어 있는 동안에는 이 자리를 지나지 않기 때문이다.\n */\n @FieldResolver(type => String)\n shifts(@Root() revision: WorkShiftRevision): string {\n return JSON.stringify(revision.shifts ?? [])\n }\n\n @FieldResolver(type => Domain)\n async domain(@Root() revision: WorkShiftRevision): Promise<Domain> {\n return await getRepository(Domain).findOneBy({ id: revision.domainId })\n }\n\n @FieldResolver(type => User, { nullable: true })\n async creator(@Root() revision: WorkShiftRevision): Promise<User | null> {\n return revision.creatorId ? await getRepository(User).findOneBy({ id: revision.creatorId }) : null\n }\n}\n"]}
|