@things-factory/integration-base 10.0.0-zeta.3 → 10.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-server/controllers/scenario-controller.d.ts +2 -2
- package/dist-server/controllers/scenario-controller.js +19 -8
- package/dist-server/controllers/scenario-controller.js.map +1 -1
- package/dist-server/engine/analyzer/analyze-integration.js +6 -2
- package/dist-server/engine/analyzer/analyze-integration.js.map +1 -1
- package/dist-server/engine/connector/operato-connector.js +4 -1
- package/dist-server/engine/connector/operato-connector.js.map +1 -1
- package/dist-server/engine/scenario-engine.js +7 -2
- package/dist-server/engine/scenario-engine.js.map +1 -1
- package/dist-server/engine/task/pick-pending-scenario.js +6 -1
- package/dist-server/engine/task/pick-pending-scenario.js.map +1 -1
- package/dist-server/engine/task/stop-scenario.js +1 -1
- package/dist-server/engine/task/stop-scenario.js.map +1 -1
- package/dist-server/engine/task/sub-scenario.js +6 -1
- package/dist-server/engine/task/sub-scenario.js.map +1 -1
- package/dist-server/engine/task/switch-range-scenario.js +6 -1
- package/dist-server/engine/task/switch-range-scenario.js.map +1 -1
- package/dist-server/engine/task/switch-scenario.js +6 -1
- package/dist-server/engine/task/switch-scenario.js.map +1 -1
- package/dist-server/routers/scenario-schedule-callback-router.js +4 -1
- package/dist-server/routers/scenario-schedule-callback-router.js.map +1 -1
- package/dist-server/routers/scenario-view-router.js +4 -3
- package/dist-server/routers/scenario-view-router.js.map +1 -1
- package/dist-server/service/index.d.ts +4 -1
- package/dist-server/service/index.js +4 -1
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/scenario/event-subscriber.d.ts +22 -0
- package/dist-server/service/scenario/event-subscriber.js +49 -0
- package/dist-server/service/scenario/event-subscriber.js.map +1 -0
- package/dist-server/service/scenario/index.d.ts +6 -2
- package/dist-server/service/scenario/index.js +7 -3
- package/dist-server/service/scenario/index.js.map +1 -1
- package/dist-server/service/scenario/resolve-steps.d.ts +43 -0
- package/dist-server/service/scenario/resolve-steps.js +101 -0
- package/dist-server/service/scenario/resolve-steps.js.map +1 -0
- package/dist-server/service/scenario/scenario-history.d.ts +44 -0
- package/dist-server/service/scenario/scenario-history.js +167 -0
- package/dist-server/service/scenario/scenario-history.js.map +1 -0
- package/dist-server/service/scenario/scenario-mutation.d.ts +2 -0
- package/dist-server/service/scenario/scenario-mutation.js +150 -36
- package/dist-server/service/scenario/scenario-mutation.js.map +1 -1
- package/dist-server/service/scenario/scenario-query.js +8 -14
- package/dist-server/service/scenario/scenario-query.js.map +1 -1
- package/dist-server/service/scenario/scenario-version-diff.d.ts +8 -0
- package/dist-server/service/scenario/scenario-version-diff.js +107 -0
- package/dist-server/service/scenario/scenario-version-diff.js.map +1 -0
- package/dist-server/service/scenario/scenario-version-query.d.ts +11 -0
- package/dist-server/service/scenario/scenario-version-query.js +135 -0
- package/dist-server/service/scenario/scenario-version-query.js.map +1 -0
- package/dist-server/service/scenario/scenario-version-type.d.ts +18 -0
- package/dist-server/service/scenario/scenario-version-type.js +79 -0
- package/dist-server/service/scenario/scenario-version-type.js.map +1 -0
- package/dist-server/service/scenario/scenario.d.ts +23 -0
- package/dist-server/service/scenario/scenario.js +18 -3
- package/dist-server/service/scenario/scenario.js.map +1 -1
- package/dist-server/service/scenario-instance/scenario-instance-mutation.d.ts +2 -2
- package/dist-server/service/scenario-instance/scenario-instance-mutation.js +8 -6
- package/dist-server/service/scenario-instance/scenario-instance-mutation.js.map +1 -1
- package/dist-server/service/step/step-mutation.js +26 -13
- package/dist-server/service/step/step-mutation.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/dist-server/utils/version-text-column.d.ts +16 -0
- package/dist-server/utils/version-text-column.js +67 -0
- package/dist-server/utils/version-text-column.js.map +1 -0
- package/package.json +12 -11
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ScenarioHistory = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const type_graphql_1 = require("type-graphql");
|
|
6
|
+
const typeorm_1 = require("typeorm");
|
|
7
|
+
const typeorm_history_1 = require("@operato/typeorm-history");
|
|
8
|
+
const auth_base_1 = require("@things-factory/auth-base");
|
|
9
|
+
const shell_1 = require("@things-factory/shell");
|
|
10
|
+
const env_1 = require("@things-factory/env");
|
|
11
|
+
const step_type_1 = require("../step/step-type");
|
|
12
|
+
const version_text_column_1 = require("../../utils/version-text-column");
|
|
13
|
+
const ORMCONFIG = env_1.config.get('ormconfig', {});
|
|
14
|
+
const DATABASE_TYPE = ORMCONFIG.type;
|
|
15
|
+
/**
|
|
16
|
+
* 시나리오의 릴리즈(배포) 시점 불변 스냅샷.
|
|
17
|
+
*
|
|
18
|
+
* board-service 의 BoardHistory 와 동형(@operato/typeorm-history).
|
|
19
|
+
* ScenarioHistoryEntitySubscriber 가 Scenario 저장 시 publishState === 'released' 인 경우에만
|
|
20
|
+
* 이 레코드를 생성한다. steps 는 Scenario 의 일반 컬럼이므로 자동 복사된다(별도 직렬화 불필요).
|
|
21
|
+
*/
|
|
22
|
+
let ScenarioHistory = class ScenarioHistory {
|
|
23
|
+
constructor() {
|
|
24
|
+
this.version = 1;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
exports.ScenarioHistory = ScenarioHistory;
|
|
28
|
+
tslib_1.__decorate([
|
|
29
|
+
(0, typeorm_1.PrimaryGeneratedColumn)('uuid'),
|
|
30
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.ID, { description: 'Unique identifier for the scenario history record.' }),
|
|
31
|
+
tslib_1.__metadata("design:type", String)
|
|
32
|
+
], ScenarioHistory.prototype, "id", void 0);
|
|
33
|
+
tslib_1.__decorate([
|
|
34
|
+
(0, typeorm_1.Column)({ nullable: true, default: 1 }),
|
|
35
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.Int, { nullable: true, description: 'The released version number of this snapshot.' }),
|
|
36
|
+
tslib_1.__metadata("design:type", Number)
|
|
37
|
+
], ScenarioHistory.prototype, "version", void 0);
|
|
38
|
+
tslib_1.__decorate([
|
|
39
|
+
(0, typeorm_1.ManyToOne)(type => shell_1.Domain),
|
|
40
|
+
(0, type_graphql_1.Field)(type => shell_1.Domain, { nullable: true, description: 'The domain this scenario belonged to.' }),
|
|
41
|
+
tslib_1.__metadata("design:type", shell_1.Domain)
|
|
42
|
+
], ScenarioHistory.prototype, "domain", void 0);
|
|
43
|
+
tslib_1.__decorate([
|
|
44
|
+
(0, typeorm_1.RelationId)((h) => h.domain),
|
|
45
|
+
tslib_1.__metadata("design:type", String)
|
|
46
|
+
], ScenarioHistory.prototype, "domainId", void 0);
|
|
47
|
+
tslib_1.__decorate([
|
|
48
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
49
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'The name of the scenario at this point in history.' }),
|
|
50
|
+
tslib_1.__metadata("design:type", String)
|
|
51
|
+
], ScenarioHistory.prototype, "name", void 0);
|
|
52
|
+
tslib_1.__decorate([
|
|
53
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
54
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'The description of the scenario at this point in history.' }),
|
|
55
|
+
tslib_1.__metadata("design:type", String)
|
|
56
|
+
], ScenarioHistory.prototype, "description", void 0);
|
|
57
|
+
tslib_1.__decorate([
|
|
58
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
59
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'The type of the scenario at this point in history.' }),
|
|
60
|
+
tslib_1.__metadata("design:type", String)
|
|
61
|
+
], ScenarioHistory.prototype, "type", void 0);
|
|
62
|
+
tslib_1.__decorate([
|
|
63
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
64
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'The schedule of the scenario at this point in history.' }),
|
|
65
|
+
tslib_1.__metadata("design:type", String)
|
|
66
|
+
], ScenarioHistory.prototype, "schedule", void 0);
|
|
67
|
+
tslib_1.__decorate([
|
|
68
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
69
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'The timezone of the scenario at this point in history.' }),
|
|
70
|
+
tslib_1.__metadata("design:type", String)
|
|
71
|
+
], ScenarioHistory.prototype, "timezone", void 0);
|
|
72
|
+
tslib_1.__decorate([
|
|
73
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
74
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.Int, { nullable: true, description: 'The time-to-live of scenario instances at this point.' }),
|
|
75
|
+
tslib_1.__metadata("design:type", Number)
|
|
76
|
+
], ScenarioHistory.prototype, "ttl", void 0);
|
|
77
|
+
tslib_1.__decorate([
|
|
78
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
79
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'The iteration mode of the scenario at this point in history.' }),
|
|
80
|
+
tslib_1.__metadata("design:type", String)
|
|
81
|
+
], ScenarioHistory.prototype, "iteration", void 0);
|
|
82
|
+
tslib_1.__decorate([
|
|
83
|
+
(0, typeorm_1.Column)({ type: 'simple-json', nullable: true }),
|
|
84
|
+
(0, type_graphql_1.Field)(type => auth_base_1.PrivilegeObject, { nullable: true, description: 'Privilege required to execute the scenario.' }),
|
|
85
|
+
tslib_1.__metadata("design:type", auth_base_1.PrivilegeObject)
|
|
86
|
+
], ScenarioHistory.prototype, "privilege", void 0);
|
|
87
|
+
tslib_1.__decorate([
|
|
88
|
+
(0, typeorm_1.ManyToOne)(type => auth_base_1.Role),
|
|
89
|
+
(0, type_graphql_1.Field)(type => auth_base_1.Role, { nullable: true, description: 'Role required to execute the scenario at this point.' }),
|
|
90
|
+
tslib_1.__metadata("design:type", auth_base_1.Role)
|
|
91
|
+
], ScenarioHistory.prototype, "role", void 0);
|
|
92
|
+
tslib_1.__decorate([
|
|
93
|
+
(0, typeorm_1.RelationId)((h) => h.role),
|
|
94
|
+
tslib_1.__metadata("design:type", String)
|
|
95
|
+
], ScenarioHistory.prototype, "roleId", void 0);
|
|
96
|
+
tslib_1.__decorate([
|
|
97
|
+
(0, typeorm_1.Column)((0, version_text_column_1.jsonTextColumn)()),
|
|
98
|
+
(0, type_graphql_1.Field)(type => [step_type_1.Step], { nullable: true, description: 'The steps of the scenario captured in this version.' }),
|
|
99
|
+
tslib_1.__metadata("design:type", Array)
|
|
100
|
+
], ScenarioHistory.prototype, "steps", void 0);
|
|
101
|
+
tslib_1.__decorate([
|
|
102
|
+
(0, typeorm_1.Column)((0, version_text_column_1.largeTextColumn)()),
|
|
103
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'The release note/comment left when this version was published.' }),
|
|
104
|
+
tslib_1.__metadata("design:type", String)
|
|
105
|
+
], ScenarioHistory.prototype, "comment", void 0);
|
|
106
|
+
tslib_1.__decorate([
|
|
107
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
108
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'The creation timestamp of the original scenario.' }),
|
|
109
|
+
tslib_1.__metadata("design:type", Date)
|
|
110
|
+
], ScenarioHistory.prototype, "createdAt", void 0);
|
|
111
|
+
tslib_1.__decorate([
|
|
112
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
113
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'The update timestamp of the scenario at this point in history.' }),
|
|
114
|
+
tslib_1.__metadata("design:type", Date)
|
|
115
|
+
], ScenarioHistory.prototype, "updatedAt", 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, description: 'The user who created the original scenario.' }),
|
|
119
|
+
tslib_1.__metadata("design:type", auth_base_1.User)
|
|
120
|
+
], ScenarioHistory.prototype, "creator", void 0);
|
|
121
|
+
tslib_1.__decorate([
|
|
122
|
+
(0, typeorm_1.RelationId)((h) => h.creator),
|
|
123
|
+
tslib_1.__metadata("design:type", String)
|
|
124
|
+
], ScenarioHistory.prototype, "creatorId", void 0);
|
|
125
|
+
tslib_1.__decorate([
|
|
126
|
+
(0, typeorm_1.ManyToOne)(type => auth_base_1.User, { nullable: true }),
|
|
127
|
+
(0, type_graphql_1.Field)(type => auth_base_1.User, { nullable: true, description: 'The user who published this version.' }),
|
|
128
|
+
tslib_1.__metadata("design:type", auth_base_1.User)
|
|
129
|
+
], ScenarioHistory.prototype, "updater", void 0);
|
|
130
|
+
tslib_1.__decorate([
|
|
131
|
+
(0, typeorm_1.RelationId)((h) => h.updater),
|
|
132
|
+
tslib_1.__metadata("design:type", String)
|
|
133
|
+
], ScenarioHistory.prototype, "updaterId", void 0);
|
|
134
|
+
tslib_1.__decorate([
|
|
135
|
+
(0, typeorm_history_1.HistoryOriginalIdColumn)(),
|
|
136
|
+
(0, type_graphql_1.Field)({ description: 'The ID of the original scenario this history record belongs to.' }),
|
|
137
|
+
tslib_1.__metadata("design:type", String)
|
|
138
|
+
], ScenarioHistory.prototype, "originalId", void 0);
|
|
139
|
+
tslib_1.__decorate([
|
|
140
|
+
(0, typeorm_history_1.HistoryActionColumn)({
|
|
141
|
+
nullable: false,
|
|
142
|
+
type: DATABASE_TYPE == 'postgres' || DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
|
|
143
|
+
? 'enum'
|
|
144
|
+
: DATABASE_TYPE == 'oracle'
|
|
145
|
+
? 'varchar2'
|
|
146
|
+
: DATABASE_TYPE == 'mssql'
|
|
147
|
+
? 'nvarchar'
|
|
148
|
+
: 'varchar',
|
|
149
|
+
enum: DATABASE_TYPE == 'postgres' || DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
|
|
150
|
+
? typeorm_history_1.HistoryActionType
|
|
151
|
+
: undefined,
|
|
152
|
+
length: DATABASE_TYPE == 'postgres' || DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb' ? undefined : 10
|
|
153
|
+
}),
|
|
154
|
+
(0, type_graphql_1.Field)(type => String, { description: 'The action that created this history record.' }),
|
|
155
|
+
tslib_1.__metadata("design:type", String)
|
|
156
|
+
], ScenarioHistory.prototype, "action", void 0);
|
|
157
|
+
exports.ScenarioHistory = ScenarioHistory = tslib_1.__decorate([
|
|
158
|
+
(0, typeorm_1.Entity)(),
|
|
159
|
+
(0, typeorm_1.Index)('ix_scenario_history_0', (h) => [h.originalId, h.version], { unique: true })
|
|
160
|
+
// 참고: board 의 BoardHistory 는 HistoryEntityInterface<Board> 를 implements 하지만,
|
|
161
|
+
// Scenario 에는 start()/stop() 메서드가 있어 그 인터페이스가 메서드까지 요구한다(Board 엔 없음).
|
|
162
|
+
// implements 절은 타입 주석일 뿐이고 서브스크라이버는 @HistoryOriginalIdColumn/@HistoryActionColumn
|
|
163
|
+
// 데코레이터가 만든 컬럼 메타데이터에 의존하므로, 여기서는 implements 를 생략한다.
|
|
164
|
+
,
|
|
165
|
+
(0, type_graphql_1.ObjectType)({ description: 'Stores released (published) version snapshots of scenarios.' })
|
|
166
|
+
], ScenarioHistory);
|
|
167
|
+
//# sourceMappingURL=scenario-history.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scenario-history.js","sourceRoot":"","sources":["../../../server/service/scenario/scenario-history.ts"],"names":[],"mappings":"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","sourcesContent":["import { Field, ID, Int, ObjectType } from 'type-graphql'\nimport { Column, Entity, Index, ManyToOne, PrimaryGeneratedColumn, RelationId } from 'typeorm'\n\nimport { HistoryActionColumn, HistoryActionType, HistoryOriginalIdColumn } from '@operato/typeorm-history'\nimport { PrivilegeObject, Role, User } from '@things-factory/auth-base'\nimport { Domain } from '@things-factory/shell'\nimport { config } from '@things-factory/env'\n\nimport { Step } from '../step/step-type'\nimport { jsonTextColumn, largeTextColumn } from '../../utils/version-text-column'\n\nconst ORMCONFIG = config.get('ormconfig', {})\nconst DATABASE_TYPE = ORMCONFIG.type\n\n/**\n * 시나리오의 릴리즈(배포) 시점 불변 스냅샷.\n *\n * board-service 의 BoardHistory 와 동형(@operato/typeorm-history).\n * ScenarioHistoryEntitySubscriber 가 Scenario 저장 시 publishState === 'released' 인 경우에만\n * 이 레코드를 생성한다. steps 는 Scenario 의 일반 컬럼이므로 자동 복사된다(별도 직렬화 불필요).\n */\n@Entity()\n@Index('ix_scenario_history_0', (h: ScenarioHistory) => [h.originalId, h.version], { unique: true })\n// 참고: board 의 BoardHistory 는 HistoryEntityInterface<Board> 를 implements 하지만,\n// Scenario 에는 start()/stop() 메서드가 있어 그 인터페이스가 메서드까지 요구한다(Board 엔 없음).\n// implements 절은 타입 주석일 뿐이고 서브스크라이버는 @HistoryOriginalIdColumn/@HistoryActionColumn\n// 데코레이터가 만든 컬럼 메타데이터에 의존하므로, 여기서는 implements 를 생략한다.\n@ObjectType({ description: 'Stores released (published) version snapshots of scenarios.' })\nexport class ScenarioHistory {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID, { description: 'Unique identifier for the scenario history record.' })\n readonly id: string\n\n @Column({ nullable: true, default: 1 })\n @Field(type => Int, { nullable: true, description: 'The released version number of this snapshot.' })\n version?: number = 1\n\n @ManyToOne(type => Domain)\n @Field(type => Domain, { nullable: true, description: 'The domain this scenario belonged to.' })\n domain?: Domain\n\n @RelationId((h: ScenarioHistory) => h.domain)\n domainId?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'The name of the scenario at this point in history.' })\n name?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'The description of the scenario at this point in history.' })\n description?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'The type of the scenario at this point in history.' })\n type?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'The schedule of the scenario at this point in history.' })\n schedule?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'The timezone of the scenario at this point in history.' })\n timezone?: string\n\n @Column({ nullable: true })\n @Field(type => Int, { nullable: true, description: 'The time-to-live of scenario instances at this point.' })\n ttl?: number\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'The iteration mode of the scenario at this point in history.' })\n iteration?: string\n\n @Column({ type: 'simple-json', nullable: true })\n @Field(type => PrivilegeObject, { nullable: true, description: 'Privilege required to execute the scenario.' })\n privilege?: PrivilegeObject\n\n @ManyToOne(type => Role)\n @Field(type => Role, { nullable: true, description: 'Role required to execute the scenario at this point.' })\n role?: Role\n\n @RelationId((h: ScenarioHistory) => h.role)\n roleId?: string\n\n /**\n * 이 버전 스냅샷의 스텝 배열(JSON). Scenario.steps 와 동일 형식이라 서브스크라이버가 자동 복사한다.\n */\n @Column(jsonTextColumn())\n @Field(type => [Step], { nullable: true, description: 'The steps of the scenario captured in this version.' })\n steps?: Step[]\n\n /**\n * 릴리즈 시 남기는 코멘트(변경 요약 등). Scenario 의 컬럼이 아니므로\n * ScenarioHistoryEntitySubscriber 가 entity.__releaseComment 로부터 주입한다.\n */\n @Column(largeTextColumn())\n @Field({ nullable: true, description: 'The release note/comment left when this version was published.' })\n comment?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'The creation timestamp of the original scenario.' })\n createdAt?: Date\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'The update timestamp of the scenario at this point in history.' })\n updatedAt?: Date\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'The user who created the original scenario.' })\n creator?: User\n\n @RelationId((h: ScenarioHistory) => h.creator)\n creatorId?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'The user who published this version.' })\n updater?: User\n\n @RelationId((h: ScenarioHistory) => h.updater)\n updaterId?: string\n\n @HistoryOriginalIdColumn()\n @Field({ description: 'The ID of the original scenario this history record belongs to.' })\n public originalId!: string\n\n @HistoryActionColumn({\n nullable: false,\n type:\n DATABASE_TYPE == 'postgres' || DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'\n ? 'enum'\n : DATABASE_TYPE == 'oracle'\n ? 'varchar2'\n : DATABASE_TYPE == 'mssql'\n ? 'nvarchar'\n : 'varchar',\n enum:\n DATABASE_TYPE == 'postgres' || DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'\n ? HistoryActionType\n : undefined,\n length: DATABASE_TYPE == 'postgres' || DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb' ? undefined : 10\n })\n @Field(type => String, { description: 'The action that created this history record.' })\n public action!: HistoryActionType\n}\n"]}
|
|
@@ -10,4 +10,6 @@ export declare class ScenarioMutation {
|
|
|
10
10
|
copyScenarios(ids: string[], context: ResolverContext): Promise<Scenario[]>;
|
|
11
11
|
startScenarioSchedule(scenarioId: string, context: ResolverContext): Promise<Scenario>;
|
|
12
12
|
stopScenarioSchedule(scenarioId: string, context: ResolverContext): Promise<Scenario | undefined>;
|
|
13
|
+
releaseScenario(id: string, context: ResolverContext, comment?: string): Promise<Scenario>;
|
|
14
|
+
revertScenarioVersion(id: string, version: number, context: ResolverContext): Promise<Scenario>;
|
|
13
15
|
}
|
|
@@ -5,9 +5,11 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const type_graphql_1 = require("type-graphql");
|
|
6
6
|
const typeorm_1 = require("typeorm");
|
|
7
7
|
const scheduler_client_1 = require("@things-factory/scheduler-client");
|
|
8
|
-
const step_type_1 = require("../step/step-type");
|
|
9
8
|
const scenario_1 = require("./scenario");
|
|
9
|
+
const scenario_history_1 = require("./scenario-history");
|
|
10
10
|
const scenario_type_1 = require("./scenario-type");
|
|
11
|
+
const resolve_steps_1 = require("./resolve-steps");
|
|
12
|
+
const scenario_version_diff_1 = require("./scenario-version-diff");
|
|
11
13
|
const crypto = require('crypto');
|
|
12
14
|
let ScenarioMutation = class ScenarioMutation {
|
|
13
15
|
async createScenario(scenario, context) {
|
|
@@ -33,6 +35,8 @@ let ScenarioMutation = class ScenarioMutation {
|
|
|
33
35
|
return await repository.save({
|
|
34
36
|
...scenario,
|
|
35
37
|
...patch,
|
|
38
|
+
// 콘텐츠 편집 → draft 로 표시(재릴리즈 필요). 스케줄 mutation 등은 이 경로를 타지 않음.
|
|
39
|
+
publishState: 'draft',
|
|
36
40
|
updater: user
|
|
37
41
|
});
|
|
38
42
|
}
|
|
@@ -71,6 +75,7 @@ let ScenarioMutation = class ScenarioMutation {
|
|
|
71
75
|
const result = await scenarioRepo.save({
|
|
72
76
|
...scenario,
|
|
73
77
|
...newRecord,
|
|
78
|
+
publishState: 'draft',
|
|
74
79
|
updater: user
|
|
75
80
|
});
|
|
76
81
|
results.push({ ...result, cuFlag: 'M' });
|
|
@@ -131,15 +136,25 @@ let ScenarioMutation = class ScenarioMutation {
|
|
|
131
136
|
creator: user
|
|
132
137
|
});
|
|
133
138
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
139
|
+
// [버전관리 / Option A] steps 는 Scenario.steps(JSON) 컬럼에 기록(별도 Step 행 생성 없음).
|
|
140
|
+
// 가져온 시나리오는 draft 작업본으로 취급한다.
|
|
141
|
+
const importedSteps = (scenario.steps || []).map((step, i) => ({
|
|
142
|
+
id: step.id || crypto.randomUUID(),
|
|
143
|
+
name: step.name,
|
|
144
|
+
description: step.description,
|
|
145
|
+
sequence: step.sequence ?? i,
|
|
146
|
+
task: step.task,
|
|
147
|
+
skip: step.skip,
|
|
148
|
+
log: step.log,
|
|
149
|
+
connection: step.connection,
|
|
150
|
+
params: step.params,
|
|
151
|
+
result: step.result
|
|
142
152
|
}));
|
|
153
|
+
savedScenario.steps = importedSteps;
|
|
154
|
+
savedScenario.publishState = 'draft';
|
|
155
|
+
await repository.save(savedScenario);
|
|
156
|
+
// [전환기 dual-write] 구버전 롤백 대비 Step 테이블도 동기화.
|
|
157
|
+
await (0, resolve_steps_1.syncLegacyStepTable)(savedScenario, importedSteps, { domain, user }, tx);
|
|
143
158
|
}));
|
|
144
159
|
return true;
|
|
145
160
|
}
|
|
@@ -150,29 +165,19 @@ let ScenarioMutation = class ScenarioMutation {
|
|
|
150
165
|
id: (0, typeorm_1.In)(ids),
|
|
151
166
|
domain: { id: domain.id }
|
|
152
167
|
},
|
|
153
|
-
relations: ['domain'
|
|
168
|
+
relations: ['domain']
|
|
154
169
|
});
|
|
155
170
|
if (originals.length == 0) {
|
|
156
171
|
return [];
|
|
157
172
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
sequence: step.sequence,
|
|
167
|
-
task: step.task,
|
|
168
|
-
connection: step.connection,
|
|
169
|
-
params: step.params,
|
|
170
|
-
domain,
|
|
171
|
-
creator: user,
|
|
172
|
-
updater: user
|
|
173
|
-
};
|
|
174
|
-
}));
|
|
175
|
-
return {
|
|
173
|
+
// [버전관리 / Option A] steps 는 Scenario.steps(JSON) 컬럼으로 복사한다(별도 Step 행 생성 없음).
|
|
174
|
+
// 사본은 항상 draft(version 0) 로 시작한다.
|
|
175
|
+
const newCopys = [];
|
|
176
|
+
for (const scenario of originals) {
|
|
177
|
+
const scenarioId = crypto.randomUUID();
|
|
178
|
+
const srcSteps = await (0, resolve_steps_1.resolveScenarioSteps)(scenario, tx);
|
|
179
|
+
const steps = srcSteps.map(step => ({ ...step, id: crypto.randomUUID() }));
|
|
180
|
+
newCopys.push({
|
|
176
181
|
id: scenarioId,
|
|
177
182
|
name: scenario.name + ' (' + scenarioId + ')',
|
|
178
183
|
type: scenario.type,
|
|
@@ -180,17 +185,20 @@ let ScenarioMutation = class ScenarioMutation {
|
|
|
180
185
|
active: false,
|
|
181
186
|
schedule: scenario.schedule,
|
|
182
187
|
timezone: scenario.timezone,
|
|
188
|
+
steps,
|
|
189
|
+
publishState: 'draft',
|
|
190
|
+
version: 0,
|
|
183
191
|
domain,
|
|
184
192
|
creator: user,
|
|
185
193
|
updater: user
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
scenario.steps
|
|
192
|
-
|
|
193
|
-
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
const copied = await tx.getRepository(scenario_1.Scenario).save(newCopys);
|
|
197
|
+
// [전환기 dual-write] 구버전 롤백 대비 각 사본의 Step 테이블도 동기화.
|
|
198
|
+
for (const scenario of copied) {
|
|
199
|
+
await (0, resolve_steps_1.syncLegacyStepTable)(scenario, scenario.steps, { domain, user }, tx);
|
|
200
|
+
}
|
|
201
|
+
return copied;
|
|
194
202
|
}
|
|
195
203
|
async startScenarioSchedule(scenarioId, context) {
|
|
196
204
|
const { domain, user, tx } = context.state;
|
|
@@ -277,6 +285,84 @@ let ScenarioMutation = class ScenarioMutation {
|
|
|
277
285
|
console.error('stopScenarioSchedule', err);
|
|
278
286
|
}
|
|
279
287
|
}
|
|
288
|
+
async releaseScenario(id, context, comment) {
|
|
289
|
+
const { domain, user, tx } = context.state;
|
|
290
|
+
const repository = tx.getRepository(scenario_1.Scenario);
|
|
291
|
+
// relations 로드 — 스냅샷(ScenarioHistory)이 domain/creator/role 을 담아야 함.
|
|
292
|
+
// 특히 domain 이 null 이면 scenarioVersions 의 domain 필터에 걸리지 않아 이력이 안 보인다.
|
|
293
|
+
const scenario = await repository.findOne({
|
|
294
|
+
where: { domain: { id: domain.id }, id },
|
|
295
|
+
relations: ['domain', 'creator', 'role']
|
|
296
|
+
});
|
|
297
|
+
if (!scenario) {
|
|
298
|
+
throw new Error(context.t('error.scenario not found', { scenario: id }));
|
|
299
|
+
}
|
|
300
|
+
// 이미 released 상태(편집 없음)면 새 버전을 만들 이유가 없음 — 보드와 동일 규율.
|
|
301
|
+
if (scenario.publishState === 'released') {
|
|
302
|
+
throw new Error(`Scenario '${scenario.name}' is already released. Edit the draft before releasing a new version.`);
|
|
303
|
+
}
|
|
304
|
+
// 스냅샷에 담을 steps 확보(하위호환: JSON 없으면 레거시 Step 테이블에서). 동시에 draft JSON 자연 이관.
|
|
305
|
+
const steps = await (0, resolve_steps_1.resolveScenarioSteps)(scenario, tx);
|
|
306
|
+
// 다음 버전 번호 = 기존 히스토리 최대 + 1
|
|
307
|
+
const maxHistory = await tx
|
|
308
|
+
.getRepository(scenario_history_1.ScenarioHistory)
|
|
309
|
+
.createQueryBuilder('history')
|
|
310
|
+
.select('MAX(history.version)', 'max')
|
|
311
|
+
.where('history.originalId = :id', { id })
|
|
312
|
+
.getRawOne();
|
|
313
|
+
const nextVersion = maxHistory?.max ? Number(maxHistory.max) + 1 : 1;
|
|
314
|
+
// 코멘트 미제공 시 diff 요약으로 자동 초기값 생성(직전 릴리즈 대비, 최초 릴리즈는 빈 기준).
|
|
315
|
+
let releaseComment = comment;
|
|
316
|
+
if (releaseComment === undefined || releaseComment === null) {
|
|
317
|
+
const prev = await (0, resolve_steps_1.getLatestReleasedHistory)(scenario, tx);
|
|
318
|
+
const fieldDiffs = (0, scenario_version_diff_1.diffScenarioMeta)(prev || {}, { ...scenario, steps });
|
|
319
|
+
const stepDiffs = (0, scenario_version_diff_1.diffScenarioSteps)(prev?.steps || [], steps);
|
|
320
|
+
releaseComment = (0, scenario_version_diff_1.summarizeScenarioDiff)(fieldDiffs, stepDiffs);
|
|
321
|
+
}
|
|
322
|
+
// publishState='released' 저장 → ScenarioHistoryEntitySubscriber 가 스냅샷 생성(comment 포함).
|
|
323
|
+
// domain 을 명시(보드 releaseBoard 와 동일) — 스냅샷 domain 이 null 이 되지 않도록.
|
|
324
|
+
const released = await repository.save({
|
|
325
|
+
...scenario,
|
|
326
|
+
domain,
|
|
327
|
+
steps,
|
|
328
|
+
version: nextVersion,
|
|
329
|
+
publishState: 'released',
|
|
330
|
+
updater: user,
|
|
331
|
+
__releaseComment: releaseComment
|
|
332
|
+
});
|
|
333
|
+
return released;
|
|
334
|
+
}
|
|
335
|
+
async revertScenarioVersion(id, version, context) {
|
|
336
|
+
const { domain, user, tx } = context.state;
|
|
337
|
+
const repository = tx.getRepository(scenario_1.Scenario);
|
|
338
|
+
const scenario = await repository.findOne({ where: { domain: { id: domain.id }, id } });
|
|
339
|
+
if (!scenario) {
|
|
340
|
+
throw new Error(context.t('error.scenario not found', { scenario: id }));
|
|
341
|
+
}
|
|
342
|
+
const history = await tx.getRepository(scenario_history_1.ScenarioHistory).findOne({
|
|
343
|
+
where: { originalId: id, version }
|
|
344
|
+
});
|
|
345
|
+
if (!history) {
|
|
346
|
+
throw new Error(`Scenario version (${id}:${version}) is not found`);
|
|
347
|
+
}
|
|
348
|
+
// 과거 버전을 최신 드래프트로 복사 — 편집 가능한 draft 상태로.
|
|
349
|
+
const reverted = await repository.save({
|
|
350
|
+
...scenario,
|
|
351
|
+
description: history.description,
|
|
352
|
+
type: history.type,
|
|
353
|
+
schedule: history.schedule,
|
|
354
|
+
timezone: history.timezone,
|
|
355
|
+
ttl: history.ttl,
|
|
356
|
+
iteration: history.iteration,
|
|
357
|
+
privilege: history.privilege,
|
|
358
|
+
steps: history.steps,
|
|
359
|
+
publishState: 'draft',
|
|
360
|
+
updater: user
|
|
361
|
+
});
|
|
362
|
+
// [전환기 dual-write] 구버전 롤백 대비 Step 테이블도 복원된 draft 로 동기화.
|
|
363
|
+
await (0, resolve_steps_1.syncLegacyStepTable)(reverted, history.steps || [], { domain, user }, tx);
|
|
364
|
+
return reverted;
|
|
365
|
+
}
|
|
280
366
|
};
|
|
281
367
|
exports.ScenarioMutation = ScenarioMutation;
|
|
282
368
|
tslib_1.__decorate([
|
|
@@ -376,6 +462,34 @@ tslib_1.__decorate([
|
|
|
376
462
|
tslib_1.__metadata("design:paramtypes", [String, Object]),
|
|
377
463
|
tslib_1.__metadata("design:returntype", Promise)
|
|
378
464
|
], ScenarioMutation.prototype, "stopScenarioSchedule", null);
|
|
465
|
+
tslib_1.__decorate([
|
|
466
|
+
(0, type_graphql_1.Directive)('@transaction'),
|
|
467
|
+
(0, type_graphql_1.Directive)('@privilege(category: "scenario", privilege: "mutation", domainOwnerGranted: true)'),
|
|
468
|
+
(0, type_graphql_1.Mutation)(returns => scenario_1.Scenario, {
|
|
469
|
+
description: 'Releases (publishes) a scenario, creating an immutable version snapshot. ' +
|
|
470
|
+
'Operational execution (schedule/auto-start) runs the latest released version.'
|
|
471
|
+
}),
|
|
472
|
+
tslib_1.__param(0, (0, type_graphql_1.Arg)('id')),
|
|
473
|
+
tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
|
|
474
|
+
tslib_1.__param(2, (0, type_graphql_1.Arg)('comment', { nullable: true })),
|
|
475
|
+
tslib_1.__metadata("design:type", Function),
|
|
476
|
+
tslib_1.__metadata("design:paramtypes", [String, Object, String]),
|
|
477
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
478
|
+
], ScenarioMutation.prototype, "releaseScenario", null);
|
|
479
|
+
tslib_1.__decorate([
|
|
480
|
+
(0, type_graphql_1.Directive)('@transaction'),
|
|
481
|
+
(0, type_graphql_1.Directive)('@privilege(category: "scenario", privilege: "mutation", domainOwnerGranted: true)'),
|
|
482
|
+
(0, type_graphql_1.Mutation)(returns => scenario_1.Scenario, {
|
|
483
|
+
description: 'Reverts a scenario to a released version by copying that version into the current draft. ' +
|
|
484
|
+
'The past version remains as an archive; this does not create a new version.'
|
|
485
|
+
}),
|
|
486
|
+
tslib_1.__param(0, (0, type_graphql_1.Arg)('id')),
|
|
487
|
+
tslib_1.__param(1, (0, type_graphql_1.Arg)('version', type => type_graphql_1.Int)),
|
|
488
|
+
tslib_1.__param(2, (0, type_graphql_1.Ctx)()),
|
|
489
|
+
tslib_1.__metadata("design:type", Function),
|
|
490
|
+
tslib_1.__metadata("design:paramtypes", [String, Number, Object]),
|
|
491
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
492
|
+
], ScenarioMutation.prototype, "revertScenarioVersion", null);
|
|
379
493
|
exports.ScenarioMutation = ScenarioMutation = tslib_1.__decorate([
|
|
380
494
|
(0, type_graphql_1.Resolver)(scenario_1.Scenario)
|
|
381
495
|
], ScenarioMutation);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scenario-mutation.js","sourceRoot":"","sources":["../../../server/service/scenario/scenario-mutation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'\nimport { In } from 'typeorm'\n\nimport {\n Application,\n getCallbackBaseWithDomainContext,\n registerSchedule,\n unregisterSchedule\n} from '@things-factory/scheduler-client'\n\nimport { Step } from '../step/step-type'\nimport { Scenario } from './scenario'\nimport { NewScenario, ScenarioPatch } from './scenario-type'\n\nconst crypto = require('crypto')\n\n@Resolver(Scenario)\nexport class ScenarioMutation {\n @Directive('@transaction')\n @Directive('@privilege(category: \"scenario\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Scenario, { description: 'Creates a new scenario.' })\n async createScenario(\n @Arg('scenario', type => NewScenario) scenario: NewScenario,\n @Ctx() context: ResolverContext\n ): Promise<Scenario> {\n const { domain, user, tx } = context.state\n\n return await tx.getRepository(Scenario).save({\n ...scenario,\n domain,\n creator: user,\n updater: user\n })\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"scenario\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Scenario, { description: 'Updates an existing scenario.' })\n async updateScenario(\n @Arg('name') name: string,\n @Arg('patch', type => ScenarioPatch) patch: ScenarioPatch,\n @Ctx() context: ResolverContext\n ): Promise<Scenario> {\n const { domain, user, tx } = context.state\n\n const repository = tx.getRepository(Scenario)\n const scenario = await repository.findOne({\n where: { domain: { id: domain.id }, name }\n })\n\n if (!scenario) {\n throw new Error(\n context.t('error.scenario not found', {\n scenario: name\n })\n )\n }\n\n return await repository.save({\n ...scenario,\n ...patch,\n updater: user\n })\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"scenario\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => [Scenario], {\n description: 'Updates multiple scenarios at once. Can be used to create or update records.'\n })\n async updateMultipleScenario(\n @Arg('patches', type => [ScenarioPatch]) patches: ScenarioPatch[],\n @Ctx() context: ResolverContext\n ): Promise<Scenario[]> {\n const { domain, user, tx } = context.state\n\n let results = []\n const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')\n const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')\n const scenarioRepo = tx.getRepository(Scenario)\n\n if (_createRecords.length > 0) {\n for (let i = 0; i < _createRecords.length; i++) {\n const newRecord = _createRecords[i]\n\n const result = await scenarioRepo.save({\n ...newRecord,\n domain,\n creator: user,\n updater: user\n })\n\n results.push({ ...result, cuFlag: '+' })\n }\n }\n\n if (_updateRecords.length > 0) {\n for (let i = 0; i < _updateRecords.length; i++) {\n const newRecord = _updateRecords[i]\n const scenario = await scenarioRepo.findOneBy({ id: newRecord.id })\n\n if (!scenario) {\n throw new Error(`Scenario '${newRecord.id}' not found`)\n }\n\n // Inheritance read-only 가드 — 다른 도메인 소유 scenario 의 row 직접 update 차단.\n // 자식이 부모 scenario.id 로 patch 보내면 upsert 가 부모 row 변경할 위험.\n // 자식별 변경은 copyScenarios 로 자기 도메인 사본 생성 후 수정.\n if (scenario.domainId !== domain.id) {\n throw new Error(\n `Cannot modify inherited scenario '${scenario.name}' (owned by another domain). ` +\n `Use copyScenarios to clone into current domain first, or modify step params via EnvVar override on useDomainAttribute fields.`\n )\n }\n\n const result = await scenarioRepo.save({\n ...scenario,\n ...newRecord,\n updater: user\n })\n\n results.push({ ...result, cuFlag: 'M' })\n }\n }\n\n return results\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"scenario\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'Deletes a single scenario by its name.' })\n async deleteScenario(@Arg('name') name: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { domain, tx } = context.state\n\n await tx.getRepository(Scenario).delete({ domain: { id: domain.id }, name })\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"scenario\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'Deletes multiple scenarios by their IDs.' })\n async deleteScenarios(\n @Arg('ids', type => [String]) ids: string[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, tx } = context.state\n\n await tx.getRepository(Scenario).delete({\n domain: { id: domain.id },\n id: In(ids)\n })\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"scenario\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, {\n description:\n 'Imports multiple scenarios, including their steps. This can overwrite existing scenarios if IDs match.'\n })\n async importScenarios(\n @Arg('scenarios', type => [ScenarioPatch]) scenarios: Scenario[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { tx, domain, user } = context.state\n\n const repository = tx.getRepository(Scenario)\n\n await Promise.all(\n scenarios.map(async (scenario: Scenario) => {\n const { id, name } = scenario\n var savedScenario\n\n if (id) {\n const sameId = await repository.findOneBy({ id })\n\n if (sameId) {\n if (sameId.domainId != domain.id) {\n throw `Scenario with id '${id}:${name}' is already taken by another domain`\n }\n\n const sameName = await repository.findOneBy({ domain: { id: domain.id }, name })\n if (sameName && sameName.id != id) {\n throw `Scenario Name '${name}' is already taken by another scenario`\n }\n\n savedScenario = await repository.save({\n ...sameId,\n ...scenario,\n domain,\n updater: user\n })\n } else {\n savedScenario = await repository.save({\n ...scenario,\n domain,\n updater: user,\n creator: user\n })\n }\n } else {\n savedScenario = await repository.save({\n ...scenario,\n domain,\n updater: user,\n creator: user\n })\n }\n\n await tx.getRepository(Step).delete({ domain: { id: domain.id }, scenario: { id: savedScenario.id } })\n await tx.getRepository(Step).save(\n scenario.steps.map((step: Step) => {\n return {\n ...step,\n domain,\n scenario: savedScenario,\n updater: user\n }\n })\n )\n })\n )\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"scenario\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => [Scenario], {\n description: 'Copies multiple existing scenarios within the same domain, creating new scenarios with new IDs.'\n })\n async copyScenarios(\n @Arg('ids', type => [String]) ids: string[],\n @Ctx() context: ResolverContext\n ): Promise<Scenario[]> {\n const { domain, user, tx } = context.state\n\n const originals = await tx.getRepository(Scenario).find({\n where: {\n id: In(ids),\n domain: { id: domain.id }\n },\n relations: ['domain', 'steps']\n })\n\n if (originals.length == 0) {\n return []\n }\n\n var newSteps = []\n\n var newCopys = originals.map(scenario => {\n let scenarioId = crypto.randomUUID()\n newSteps.push(\n ...scenario.steps.map(step => {\n return {\n scenario: scenarioId,\n name: step.name,\n description: step.description,\n sequence: step.sequence,\n task: step.task,\n connection: step.connection,\n params: step.params,\n\n domain,\n creator: user,\n updater: user\n }\n })\n )\n\n return {\n id: scenarioId,\n name: scenario.name + ' (' + scenarioId + ')',\n type: scenario.type,\n description: scenario.description,\n active: false,\n schedule: scenario.schedule,\n timezone: scenario.timezone,\n\n domain,\n creator: user,\n updater: user\n }\n })\n\n var copiedScenarios = await tx.getRepository(Scenario).save(newCopys)\n var copiedSteps = await tx.getRepository(Step).save(newSteps)\n\n return copiedScenarios.map(scenario => {\n scenario.steps = copiedSteps.filter(step => step.scenario == scenario.id)\n return scenario\n })\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"scenario\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Scenario, { description: 'Starts the schedule for a specific scenario, if one is defined.' })\n async startScenarioSchedule(\n @Arg('scenarioId') scenarioId: string,\n @Ctx() context: ResolverContext\n ): Promise<Scenario> {\n const { domain, user, tx } = context.state\n\n var repository = tx.getRepository(Scenario)\n var scenario = await repository.findOne({\n where: { domain: { id: domain.id }, id: scenarioId }\n })\n\n if (!scenario) {\n throw new Error(\n context.t('error.scenario not found', {\n scenario: scenarioId\n })\n )\n }\n\n if (!scenario.schedule) {\n throw new Error(\n context.t('error.schedule is not set', {\n scenario: scenario.name\n })\n )\n }\n\n if (!scenario.timezone) {\n throw new Error(\n context.t('error.timezone is not set', {\n scenario: scenario.name\n })\n )\n }\n\n try {\n var handle = await registerSchedule({\n name: scenario.name,\n client: {\n application: Application,\n group: `${domain.id}`,\n type: 'scenario',\n key: scenario.id,\n operation: 'start'\n },\n type: 'cron',\n schedule: scenario.schedule,\n timezone: scenario.timezone,\n task: {\n type: 'rest',\n connection: {\n host: `${getCallbackBaseWithDomainContext(domain)}/callback-schedule-for-scenario`,\n headers: {\n 'Content-Type': 'application/json',\n accept: '*/*'\n }\n },\n data: {\n domainId: domain.id,\n userId: user.id,\n scenarioId\n },\n history_check: true,\n failed_policy: 'retry_dlq',\n max_retry_count: -1,\n retry_period: 60\n }\n })\n\n return await repository.save({\n ...scenario,\n scheduleId: handle\n })\n } catch (err) {\n console.error('startScenarioSchedule', err)\n }\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"scenario\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Scenario, { description: 'Stops the schedule for a specific scenario.' })\n async stopScenarioSchedule(\n @Arg('scenarioId') scenarioId: string,\n @Ctx() context: ResolverContext\n ): Promise<Scenario | undefined> {\n const { domain, tx } = context.state\n\n var repository = tx.getRepository(Scenario)\n var scenario = await repository.findOne({\n where: { domain: { id: domain.id }, id: scenarioId }\n })\n\n if (!scenario) {\n throw new Error(\n context.t('error.scenario not found', {\n scenario: scenarioId\n })\n )\n }\n\n try {\n await unregisterSchedule(scenario.scheduleId)\n\n return await repository.save({\n ...scenario,\n scheduleId: null\n })\n } catch (err) {\n console.error('stopScenarioSchedule', err)\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"scenario-mutation.js","sourceRoot":"","sources":["../../../server/service/scenario/scenario-mutation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Arg, Ctx, Directive, Int, Mutation, Resolver } from 'type-graphql'\nimport { In } from 'typeorm'\n\nimport {\n Application,\n getCallbackBaseWithDomainContext,\n registerSchedule,\n unregisterSchedule\n} from '@things-factory/scheduler-client'\n\nimport { Scenario } from './scenario'\nimport { ScenarioHistory } from './scenario-history'\nimport { NewScenario, ScenarioPatch } from './scenario-type'\nimport { resolveScenarioSteps, getLatestReleasedHistory, syncLegacyStepTable } from './resolve-steps'\nimport { diffScenarioMeta, diffScenarioSteps, summarizeScenarioDiff } from './scenario-version-diff'\n\nconst crypto = require('crypto')\n\n@Resolver(Scenario)\nexport class ScenarioMutation {\n @Directive('@transaction')\n @Directive('@privilege(category: \"scenario\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Scenario, { description: 'Creates a new scenario.' })\n async createScenario(\n @Arg('scenario', type => NewScenario) scenario: NewScenario,\n @Ctx() context: ResolverContext\n ): Promise<Scenario> {\n const { domain, user, tx } = context.state\n\n return await tx.getRepository(Scenario).save({\n ...scenario,\n domain,\n creator: user,\n updater: user\n })\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"scenario\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Scenario, { description: 'Updates an existing scenario.' })\n async updateScenario(\n @Arg('name') name: string,\n @Arg('patch', type => ScenarioPatch) patch: ScenarioPatch,\n @Ctx() context: ResolverContext\n ): Promise<Scenario> {\n const { domain, user, tx } = context.state\n\n const repository = tx.getRepository(Scenario)\n const scenario = await repository.findOne({\n where: { domain: { id: domain.id }, name }\n })\n\n if (!scenario) {\n throw new Error(\n context.t('error.scenario not found', {\n scenario: name\n })\n )\n }\n\n return await repository.save({\n ...scenario,\n ...patch,\n // 콘텐츠 편집 → draft 로 표시(재릴리즈 필요). 스케줄 mutation 등은 이 경로를 타지 않음.\n publishState: 'draft',\n updater: user\n })\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"scenario\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => [Scenario], {\n description: 'Updates multiple scenarios at once. Can be used to create or update records.'\n })\n async updateMultipleScenario(\n @Arg('patches', type => [ScenarioPatch]) patches: ScenarioPatch[],\n @Ctx() context: ResolverContext\n ): Promise<Scenario[]> {\n const { domain, user, tx } = context.state\n\n let results = []\n const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')\n const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')\n const scenarioRepo = tx.getRepository(Scenario)\n\n if (_createRecords.length > 0) {\n for (let i = 0; i < _createRecords.length; i++) {\n const newRecord = _createRecords[i]\n\n const result = await scenarioRepo.save({\n ...newRecord,\n domain,\n creator: user,\n updater: user\n })\n\n results.push({ ...result, cuFlag: '+' })\n }\n }\n\n if (_updateRecords.length > 0) {\n for (let i = 0; i < _updateRecords.length; i++) {\n const newRecord = _updateRecords[i]\n const scenario = await scenarioRepo.findOneBy({ id: newRecord.id })\n\n if (!scenario) {\n throw new Error(`Scenario '${newRecord.id}' not found`)\n }\n\n // Inheritance read-only 가드 — 다른 도메인 소유 scenario 의 row 직접 update 차단.\n // 자식이 부모 scenario.id 로 patch 보내면 upsert 가 부모 row 변경할 위험.\n // 자식별 변경은 copyScenarios 로 자기 도메인 사본 생성 후 수정.\n if (scenario.domainId !== domain.id) {\n throw new Error(\n `Cannot modify inherited scenario '${scenario.name}' (owned by another domain). ` +\n `Use copyScenarios to clone into current domain first, or modify step params via EnvVar override on useDomainAttribute fields.`\n )\n }\n\n const result = await scenarioRepo.save({\n ...scenario,\n ...newRecord,\n publishState: 'draft',\n updater: user\n })\n\n results.push({ ...result, cuFlag: 'M' })\n }\n }\n\n return results\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"scenario\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'Deletes a single scenario by its name.' })\n async deleteScenario(@Arg('name') name: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { domain, tx } = context.state\n\n await tx.getRepository(Scenario).delete({ domain: { id: domain.id }, name })\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"scenario\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'Deletes multiple scenarios by their IDs.' })\n async deleteScenarios(\n @Arg('ids', type => [String]) ids: string[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, tx } = context.state\n\n await tx.getRepository(Scenario).delete({\n domain: { id: domain.id },\n id: In(ids)\n })\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"scenario\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, {\n description:\n 'Imports multiple scenarios, including their steps. This can overwrite existing scenarios if IDs match.'\n })\n async importScenarios(\n @Arg('scenarios', type => [ScenarioPatch]) scenarios: Scenario[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { tx, domain, user } = context.state\n\n const repository = tx.getRepository(Scenario)\n\n await Promise.all(\n scenarios.map(async (scenario: Scenario) => {\n const { id, name } = scenario\n var savedScenario\n\n if (id) {\n const sameId = await repository.findOneBy({ id })\n\n if (sameId) {\n if (sameId.domainId != domain.id) {\n throw `Scenario with id '${id}:${name}' is already taken by another domain`\n }\n\n const sameName = await repository.findOneBy({ domain: { id: domain.id }, name })\n if (sameName && sameName.id != id) {\n throw `Scenario Name '${name}' is already taken by another scenario`\n }\n\n savedScenario = await repository.save({\n ...sameId,\n ...scenario,\n domain,\n updater: user\n })\n } else {\n savedScenario = await repository.save({\n ...scenario,\n domain,\n updater: user,\n creator: user\n })\n }\n } else {\n savedScenario = await repository.save({\n ...scenario,\n domain,\n updater: user,\n creator: user\n })\n }\n\n // [버전관리 / Option A] steps 는 Scenario.steps(JSON) 컬럼에 기록(별도 Step 행 생성 없음).\n // 가져온 시나리오는 draft 작업본으로 취급한다.\n const importedSteps = (scenario.steps || []).map((step: any, i: number) => ({\n id: step.id || crypto.randomUUID(),\n name: step.name,\n description: step.description,\n sequence: step.sequence ?? i,\n task: step.task,\n skip: step.skip,\n log: step.log,\n connection: step.connection,\n params: step.params,\n result: step.result\n }))\n\n savedScenario.steps = importedSteps\n savedScenario.publishState = 'draft'\n await repository.save(savedScenario)\n\n // [전환기 dual-write] 구버전 롤백 대비 Step 테이블도 동기화.\n await syncLegacyStepTable(savedScenario, importedSteps, { domain, user }, tx)\n })\n )\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"scenario\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => [Scenario], {\n description: 'Copies multiple existing scenarios within the same domain, creating new scenarios with new IDs.'\n })\n async copyScenarios(\n @Arg('ids', type => [String]) ids: string[],\n @Ctx() context: ResolverContext\n ): Promise<Scenario[]> {\n const { domain, user, tx } = context.state\n\n const originals = await tx.getRepository(Scenario).find({\n where: {\n id: In(ids),\n domain: { id: domain.id }\n },\n relations: ['domain']\n })\n\n if (originals.length == 0) {\n return []\n }\n\n // [버전관리 / Option A] steps 는 Scenario.steps(JSON) 컬럼으로 복사한다(별도 Step 행 생성 없음).\n // 사본은 항상 draft(version 0) 로 시작한다.\n const newCopys = []\n for (const scenario of originals) {\n const scenarioId = crypto.randomUUID()\n const srcSteps = await resolveScenarioSteps(scenario, tx)\n const steps = srcSteps.map(step => ({ ...step, id: crypto.randomUUID() }))\n\n newCopys.push({\n id: scenarioId,\n name: scenario.name + ' (' + scenarioId + ')',\n type: scenario.type,\n description: scenario.description,\n active: false,\n schedule: scenario.schedule,\n timezone: scenario.timezone,\n steps,\n publishState: 'draft',\n version: 0,\n\n domain,\n creator: user,\n updater: user\n })\n }\n\n const copied = await tx.getRepository(Scenario).save(newCopys)\n\n // [전환기 dual-write] 구버전 롤백 대비 각 사본의 Step 테이블도 동기화.\n for (const scenario of copied) {\n await syncLegacyStepTable(scenario, scenario.steps as any[], { domain, user }, tx)\n }\n\n return copied\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"scenario\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Scenario, { description: 'Starts the schedule for a specific scenario, if one is defined.' })\n async startScenarioSchedule(\n @Arg('scenarioId') scenarioId: string,\n @Ctx() context: ResolverContext\n ): Promise<Scenario> {\n const { domain, user, tx } = context.state\n\n var repository = tx.getRepository(Scenario)\n var scenario = await repository.findOne({\n where: { domain: { id: domain.id }, id: scenarioId }\n })\n\n if (!scenario) {\n throw new Error(\n context.t('error.scenario not found', {\n scenario: scenarioId\n })\n )\n }\n\n if (!scenario.schedule) {\n throw new Error(\n context.t('error.schedule is not set', {\n scenario: scenario.name\n })\n )\n }\n\n if (!scenario.timezone) {\n throw new Error(\n context.t('error.timezone is not set', {\n scenario: scenario.name\n })\n )\n }\n\n try {\n var handle = await registerSchedule({\n name: scenario.name,\n client: {\n application: Application,\n group: `${domain.id}`,\n type: 'scenario',\n key: scenario.id,\n operation: 'start'\n },\n type: 'cron',\n schedule: scenario.schedule,\n timezone: scenario.timezone,\n task: {\n type: 'rest',\n connection: {\n host: `${getCallbackBaseWithDomainContext(domain)}/callback-schedule-for-scenario`,\n headers: {\n 'Content-Type': 'application/json',\n accept: '*/*'\n }\n },\n data: {\n domainId: domain.id,\n userId: user.id,\n scenarioId\n },\n history_check: true,\n failed_policy: 'retry_dlq',\n max_retry_count: -1,\n retry_period: 60\n }\n })\n\n return await repository.save({\n ...scenario,\n scheduleId: handle\n })\n } catch (err) {\n console.error('startScenarioSchedule', err)\n }\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"scenario\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Scenario, { description: 'Stops the schedule for a specific scenario.' })\n async stopScenarioSchedule(\n @Arg('scenarioId') scenarioId: string,\n @Ctx() context: ResolverContext\n ): Promise<Scenario | undefined> {\n const { domain, tx } = context.state\n\n var repository = tx.getRepository(Scenario)\n var scenario = await repository.findOne({\n where: { domain: { id: domain.id }, id: scenarioId }\n })\n\n if (!scenario) {\n throw new Error(\n context.t('error.scenario not found', {\n scenario: scenarioId\n })\n )\n }\n\n try {\n await unregisterSchedule(scenario.scheduleId)\n\n return await repository.save({\n ...scenario,\n scheduleId: null\n })\n } catch (err) {\n console.error('stopScenarioSchedule', err)\n }\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"scenario\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Scenario, {\n description:\n 'Releases (publishes) a scenario, creating an immutable version snapshot. ' +\n 'Operational execution (schedule/auto-start) runs the latest released version.'\n })\n async releaseScenario(\n @Arg('id') id: string,\n @Ctx() context: ResolverContext,\n @Arg('comment', { nullable: true }) comment?: string\n ): Promise<Scenario> {\n const { domain, user, tx } = context.state\n\n const repository = tx.getRepository(Scenario)\n // relations 로드 — 스냅샷(ScenarioHistory)이 domain/creator/role 을 담아야 함.\n // 특히 domain 이 null 이면 scenarioVersions 의 domain 필터에 걸리지 않아 이력이 안 보인다.\n const scenario = await repository.findOne({\n where: { domain: { id: domain.id }, id },\n relations: ['domain', 'creator', 'role']\n })\n\n if (!scenario) {\n throw new Error(context.t('error.scenario not found', { scenario: id }))\n }\n\n // 이미 released 상태(편집 없음)면 새 버전을 만들 이유가 없음 — 보드와 동일 규율.\n if (scenario.publishState === 'released') {\n throw new Error(`Scenario '${scenario.name}' is already released. Edit the draft before releasing a new version.`)\n }\n\n // 스냅샷에 담을 steps 확보(하위호환: JSON 없으면 레거시 Step 테이블에서). 동시에 draft JSON 자연 이관.\n const steps = await resolveScenarioSteps(scenario, tx)\n\n // 다음 버전 번호 = 기존 히스토리 최대 + 1\n const maxHistory = await tx\n .getRepository(ScenarioHistory)\n .createQueryBuilder('history')\n .select('MAX(history.version)', 'max')\n .where('history.originalId = :id', { id })\n .getRawOne()\n const nextVersion = maxHistory?.max ? Number(maxHistory.max) + 1 : 1\n\n // 코멘트 미제공 시 diff 요약으로 자동 초기값 생성(직전 릴리즈 대비, 최초 릴리즈는 빈 기준).\n let releaseComment = comment\n if (releaseComment === undefined || releaseComment === null) {\n const prev = await getLatestReleasedHistory(scenario, tx)\n const fieldDiffs = diffScenarioMeta(prev || {}, { ...scenario, steps })\n const stepDiffs = diffScenarioSteps((prev?.steps as any[]) || [], steps)\n releaseComment = summarizeScenarioDiff(fieldDiffs, stepDiffs)\n }\n\n // publishState='released' 저장 → ScenarioHistoryEntitySubscriber 가 스냅샷 생성(comment 포함).\n // domain 을 명시(보드 releaseBoard 와 동일) — 스냅샷 domain 이 null 이 되지 않도록.\n const released = await repository.save({\n ...scenario,\n domain,\n steps,\n version: nextVersion,\n publishState: 'released',\n updater: user,\n __releaseComment: releaseComment\n } as any)\n\n return released\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"scenario\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Scenario, {\n description:\n 'Reverts a scenario to a released version by copying that version into the current draft. ' +\n 'The past version remains as an archive; this does not create a new version.'\n })\n async revertScenarioVersion(\n @Arg('id') id: string,\n @Arg('version', type => Int) version: number,\n @Ctx() context: ResolverContext\n ): Promise<Scenario> {\n const { domain, user, tx } = context.state\n\n const repository = tx.getRepository(Scenario)\n const scenario = await repository.findOne({ where: { domain: { id: domain.id }, id } })\n\n if (!scenario) {\n throw new Error(context.t('error.scenario not found', { scenario: id }))\n }\n\n const history = await tx.getRepository(ScenarioHistory).findOne({\n where: { originalId: id, version }\n })\n\n if (!history) {\n throw new Error(`Scenario version (${id}:${version}) is not found`)\n }\n\n // 과거 버전을 최신 드래프트로 복사 — 편집 가능한 draft 상태로.\n const reverted = await repository.save({\n ...scenario,\n description: history.description,\n type: history.type,\n schedule: history.schedule,\n timezone: history.timezone,\n ttl: history.ttl,\n iteration: history.iteration,\n privilege: history.privilege,\n steps: history.steps,\n publishState: 'draft',\n updater: user\n } as any)\n\n // [전환기 dual-write] 구버전 롤백 대비 Step 테이블도 복원된 draft 로 동기화.\n await syncLegacyStepTable(reverted, (history.steps as any[]) || [], { domain, user }, tx)\n\n return reverted\n }\n}\n"]}
|