@things-factory/process 8.0.0-beta.9 → 8.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/client/actions/main.ts +1 -0
  2. package/client/bootstrap.ts +8 -0
  3. package/client/index.ts +1 -0
  4. package/client/pages/event/event-importer.ts +86 -0
  5. package/client/pages/event/event-list-page.ts +324 -0
  6. package/client/pages/gateway/gateway-importer.ts +87 -0
  7. package/client/pages/gateway/gateway-list-page.ts +323 -0
  8. package/client/pages/main.ts +25 -0
  9. package/client/pages/process/process-importer.ts +87 -0
  10. package/client/pages/process/process-list-page.ts +324 -0
  11. package/client/pages/process-instance/process-instance-importer.ts +87 -0
  12. package/client/pages/process-instance/process-instance-list-page.ts +323 -0
  13. package/client/pages/process-thread/process-thread-importer.ts +87 -0
  14. package/client/pages/process-thread/process-thread-list-page.ts +323 -0
  15. package/client/reducers/main.ts +17 -0
  16. package/client/route.ts +27 -0
  17. package/client/tsconfig.json +13 -0
  18. package/dist-client/tsconfig.tsbuildinfo +1 -1
  19. package/dist-server/tsconfig.tsbuildinfo +1 -1
  20. package/package.json +14 -14
  21. package/server/controllers/common.ts +90 -0
  22. package/server/controllers/index.ts +0 -0
  23. package/server/controllers/process-instance/abort.ts +75 -0
  24. package/server/controllers/process-instance/end.ts +74 -0
  25. package/server/controllers/process-instance/index.ts +2 -0
  26. package/server/controllers/process-thread/_abort.ts +20 -0
  27. package/server/controllers/process-thread/abort.ts +48 -0
  28. package/server/controllers/process-thread/end.ts +54 -0
  29. package/server/controllers/process-thread/index.ts +3 -0
  30. package/server/controllers/process-thread/start.ts +49 -0
  31. package/server/index.ts +4 -0
  32. package/server/middlewares/index.ts +3 -0
  33. package/server/migrations/index.ts +9 -0
  34. package/server/routes.ts +80 -0
  35. package/server/service/index.ts +44 -0
  36. package/server/service/process/event-subscriber.ts +17 -0
  37. package/server/service/process/index.ts +9 -0
  38. package/server/service/process/process-history.ts +108 -0
  39. package/server/service/process/process-mutation.ts +210 -0
  40. package/server/service/process/process-query.ts +120 -0
  41. package/server/service/process/process-search-key-item-type.ts +16 -0
  42. package/server/service/process/process-type.ts +65 -0
  43. package/server/service/process/process.ts +97 -0
  44. package/server/service/process-instance/event-subscriber.ts +44 -0
  45. package/server/service/process-instance/index.ts +10 -0
  46. package/server/service/process-instance/process-instance-history.ts +154 -0
  47. package/server/service/process-instance/process-instance-mutation.ts +33 -0
  48. package/server/service/process-instance/process-instance-query.ts +141 -0
  49. package/server/service/process-instance/process-instance-subscription.ts +46 -0
  50. package/server/service/process-instance/process-instance-type.ts +71 -0
  51. package/server/service/process-instance/process-instance.ts +147 -0
  52. package/server/service/process-stats/index.ts +3 -0
  53. package/server/service/process-stats/process-stats-query.ts +57 -0
  54. package/server/service/process-stats/process-stats-type.ts +31 -0
  55. package/server/service/process-thread/event-subscriber.ts +31 -0
  56. package/server/service/process-thread/index.ts +9 -0
  57. package/server/service/process-thread/process-thread-mutation.ts +34 -0
  58. package/server/service/process-thread/process-thread-query.ts +61 -0
  59. package/server/service/process-thread/process-thread-subscription.ts +42 -0
  60. package/server/service/process-thread/process-thread-type.ts +15 -0
  61. package/server/service/process-thread/process-thread.ts +90 -0
  62. package/server/tsconfig.json +10 -0
@@ -0,0 +1,108 @@
1
+ import { Field, ID, ObjectType } from 'type-graphql'
2
+ import { Column, Entity, Index, ManyToOne, PrimaryGeneratedColumn, RelationId } from 'typeorm'
3
+
4
+ import {
5
+ HistoryActionColumn,
6
+ HistoryActionType,
7
+ HistoryEntityInterface,
8
+ HistoryOriginalIdColumn
9
+ } from '@operato/typeorm-history'
10
+ import { Role, User } from '@things-factory/auth-base'
11
+ import { config } from '@things-factory/env'
12
+ import { Domain } from '@things-factory/shell'
13
+
14
+ import { Process, ProcessStatus } from './process'
15
+
16
+ const ORMCONFIG = config.get('ormconfig', {})
17
+ const DATABASE_TYPE = ORMCONFIG.type
18
+
19
+ @Entity()
20
+ @Index(
21
+ 'ix_process_history_0',
22
+ (processHistory: ProcessHistory) => [processHistory.originalId, processHistory.version],
23
+ { unique: true }
24
+ )
25
+ @Index(
26
+ 'ix_process_history_1',
27
+ (processHistory: ProcessHistory) => [processHistory.domain, processHistory.originalId, processHistory.version],
28
+ { unique: true }
29
+ )
30
+ @ObjectType({ description: 'History Entity of Process' })
31
+ export class ProcessHistory implements HistoryEntityInterface<Process> {
32
+ @PrimaryGeneratedColumn('uuid')
33
+ @Field(type => ID)
34
+ readonly id: string
35
+
36
+ @Column({ nullable: true, default: 1 })
37
+ @Field({ nullable: true })
38
+ version?: number = 1
39
+
40
+ @ManyToOne(type => Domain)
41
+ @Field(type => Domain)
42
+ domain?: Domain
43
+
44
+ @RelationId((process: Process) => process.domain)
45
+ domainId?: string
46
+
47
+ @Column()
48
+ @Field({ nullable: true })
49
+ name?: string
50
+
51
+ @Column({ nullable: true })
52
+ @Field({ nullable: true })
53
+ description?: string
54
+
55
+ @Column({ nullable: true })
56
+ @Field({ nullable: true })
57
+ state?: ProcessStatus
58
+
59
+ @ManyToOne(type => Role, { nullable: true })
60
+ @Field(type => Role, { nullable: true })
61
+ supervisoryRole?: Role
62
+
63
+ @RelationId((process: Process) => process.supervisoryRole)
64
+ supervisoryRoleId?: string
65
+
66
+ @Column()
67
+ @Field({ nullable: true })
68
+ createdAt?: Date
69
+
70
+ @Column()
71
+ @Field({ nullable: true })
72
+ updatedAt?: Date
73
+
74
+ @ManyToOne(type => User, { nullable: true })
75
+ @Field(type => User, { nullable: true })
76
+ creator?: User
77
+
78
+ @RelationId((process: Process) => process.creator)
79
+ creatorId?: string
80
+
81
+ @ManyToOne(type => User, { nullable: true })
82
+ @Field(type => User, { nullable: true })
83
+ updater?: User
84
+
85
+ @RelationId((process: Process) => process.updater)
86
+ updaterId?: string
87
+
88
+ @HistoryOriginalIdColumn()
89
+ public originalId!: string
90
+
91
+ @HistoryActionColumn({
92
+ nullable: false,
93
+ type:
94
+ DATABASE_TYPE == 'postgres' || DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
95
+ ? 'enum'
96
+ : DATABASE_TYPE == 'oracle'
97
+ ? 'varchar2'
98
+ : DATABASE_TYPE == 'mssql'
99
+ ? 'nvarchar'
100
+ : 'varchar',
101
+ enum:
102
+ DATABASE_TYPE == 'postgres' || DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
103
+ ? HistoryActionType
104
+ : undefined,
105
+ length: DATABASE_TYPE == 'postgres' || DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb' ? undefined : 10
106
+ })
107
+ public action!: HistoryActionType
108
+ }
@@ -0,0 +1,210 @@
1
+ import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
2
+ import { In } from 'typeorm'
3
+
4
+ import { createAttachment, deleteAttachmentsByRef } from '@things-factory/attachment-base'
5
+ import { Application, CallbackBase, registerSchedule, unregisterSchedule } from '@things-factory/scheduler-client'
6
+
7
+ import { Process } from './process'
8
+ import { ProcessPatch, NewProcess } from './process-type'
9
+
10
+ @Resolver(Process)
11
+ export class ProcessMutation {
12
+ @Directive('@transaction')
13
+ @Directive('@privilege(category: "process", privilege: "mutation", domainOwnerGranted: true)')
14
+ @Mutation(returns => Process, { description: 'To create new Process' })
15
+ async createProcess(@Arg('process') process: NewProcess, @Ctx() context: ResolverContext): Promise<Process> {
16
+ const { domain, user, tx } = context.state
17
+
18
+ const result = await tx.getRepository(Process).save({
19
+ ...process,
20
+ domain,
21
+ creator: user,
22
+ updater: user
23
+ })
24
+
25
+ if (process.thumbnail) {
26
+ await createAttachment(
27
+ null,
28
+ {
29
+ attachment: {
30
+ file: process.thumbnail,
31
+ refType: Process.name,
32
+ refBy: result.id
33
+ }
34
+ },
35
+ context
36
+ )
37
+ }
38
+
39
+ return result
40
+ }
41
+
42
+ @Directive('@transaction')
43
+ @Directive('@privilege(category: "process", privilege: "mutation", domainOwnerGranted: true)')
44
+ @Mutation(returns => Process, { description: 'To modify Process information' })
45
+ async updateProcess(
46
+ @Arg('id') id: string,
47
+ @Arg('patch') patch: ProcessPatch,
48
+ @Ctx() context: ResolverContext
49
+ ): Promise<Process> {
50
+ const { domain, user, tx } = context.state
51
+
52
+ const repository = tx.getRepository(Process)
53
+ const process = await repository.findOne({
54
+ where: { domain: { id: domain.id }, id },
55
+ /* history에 항상 반영될 수 있도록 relations가 있어야 함. */
56
+ relations: ['domain', 'issuerRole', 'supervisoryRole', 'creator', 'updater']
57
+ })
58
+
59
+ const result = await repository.save({
60
+ ...process,
61
+ ...patch,
62
+ updater: user
63
+ })
64
+
65
+ if (patch.thumbnail) {
66
+ await deleteAttachmentsByRef(null, { refBys: [result.id] }, context)
67
+ await createAttachment(
68
+ null,
69
+ {
70
+ attachment: {
71
+ file: patch.thumbnail,
72
+ refType: Process.name,
73
+ refBy: result.id
74
+ }
75
+ },
76
+ context
77
+ )
78
+ }
79
+
80
+ return result
81
+ }
82
+
83
+ @Directive('@transaction')
84
+ @Directive('@privilege(category: "process", privilege: "mutation", domainOwnerGranted: true)')
85
+ @Mutation(returns => [Process], { description: "To modify multiple Processes' information" })
86
+ async updateMultipleProcess(
87
+ @Arg('patches', type => [ProcessPatch]) patches: ProcessPatch[],
88
+ @Ctx() context: ResolverContext
89
+ ): Promise<Process[]> {
90
+ const { domain, user, tx } = context.state
91
+
92
+ let results = []
93
+ const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')
94
+ const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')
95
+ const processRepo = tx.getRepository(Process)
96
+
97
+ if (_createRecords.length > 0) {
98
+ for (let i = 0; i < _createRecords.length; i++) {
99
+ const newRecord = _createRecords[i]
100
+
101
+ const result = await processRepo.save({
102
+ ...newRecord,
103
+ domain,
104
+ creator: user,
105
+ updater: user
106
+ })
107
+
108
+ if (newRecord.thumbnail) {
109
+ await createAttachment(
110
+ null,
111
+ {
112
+ attachment: {
113
+ file: newRecord.thumbnail,
114
+ refType: Process.name,
115
+ refBy: result.id
116
+ }
117
+ },
118
+ context
119
+ )
120
+ }
121
+
122
+ results.push({ ...result, cuFlag: '+' })
123
+ }
124
+ }
125
+
126
+ if (_updateRecords.length > 0) {
127
+ for (let i = 0; i < _updateRecords.length; i++) {
128
+ const updateRecord = _updateRecords[i]
129
+ const process = await processRepo.findOne({
130
+ where: { id: updateRecord.id },
131
+ /* history에 항상 반영될 수 있도록 relations가 있어야 함. */
132
+ relations: ['domain', 'issuerRole', 'supervisoryRole', 'creator', 'updater']
133
+ })
134
+
135
+ const result = await processRepo.save({
136
+ ...process,
137
+ ...updateRecord,
138
+ updater: user
139
+ })
140
+
141
+ if (updateRecord.thumbnail) {
142
+ await deleteAttachmentsByRef(null, { refBys: [result.id] }, context)
143
+ await createAttachment(
144
+ null,
145
+ {
146
+ attachment: {
147
+ file: updateRecord.thumbnail,
148
+ refType: Process.name,
149
+ refBy: result.id
150
+ }
151
+ },
152
+ context
153
+ )
154
+ }
155
+
156
+ results.push({ ...result, cuFlag: 'M' })
157
+ }
158
+ }
159
+
160
+ return results
161
+ }
162
+
163
+ @Directive('@transaction')
164
+ @Directive('@privilege(category: "process", privilege: "mutation", domainOwnerGranted: true)')
165
+ @Mutation(returns => Boolean, { description: 'To delete Process' })
166
+ async deleteProcess(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {
167
+ const { domain, tx } = context.state
168
+
169
+ await tx.getRepository(Process).delete({ domain: { id: domain.id }, id })
170
+ await deleteAttachmentsByRef(null, { refBys: [id] }, context)
171
+
172
+ return true
173
+ }
174
+
175
+ @Directive('@transaction')
176
+ @Mutation(returns => Boolean, { description: 'To delete multiple Processes' })
177
+ async deleteProcesses(
178
+ @Arg('ids', type => [String]) ids: string[],
179
+ @Ctx() context: ResolverContext
180
+ ): Promise<boolean> {
181
+ const { domain, tx } = context.state
182
+
183
+ await tx.getRepository(Process).delete({
184
+ domain: { id: domain.id },
185
+ id: In(ids)
186
+ })
187
+
188
+ await deleteAttachmentsByRef(null, { refBys: ids }, context)
189
+
190
+ return true
191
+ }
192
+
193
+ @Directive('@transaction')
194
+ @Directive('@privilege(category: "process", privilege: "mutation", domainOwnerGranted: true)')
195
+ @Mutation(returns => Boolean, { description: 'To import multiple Processes' })
196
+ async importProcesses(
197
+ @Arg('processes', type => [ProcessPatch]) processes: ProcessPatch[],
198
+ @Ctx() context: ResolverContext
199
+ ): Promise<boolean> {
200
+ const { domain, tx } = context.state
201
+
202
+ await Promise.all(
203
+ processes.map(async (process: ProcessPatch) => {
204
+ const createdProcess: Process = await tx.getRepository(Process).save({ domain, ...process })
205
+ })
206
+ )
207
+
208
+ return true
209
+ }
210
+ }
@@ -0,0 +1,120 @@
1
+ import { Arg, Args, Ctx, Directive, FieldResolver, Query, Resolver, Root } from 'type-graphql'
2
+
3
+ import { Attachment } from '@things-factory/attachment-base'
4
+ import { Role, User } from '@things-factory/auth-base'
5
+ import { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'
6
+
7
+ import { Process } from './process'
8
+ import { ProcessList } from './process-type'
9
+
10
+ @Resolver(Process)
11
+ export class ProcessQuery {
12
+ @Directive('@privilege(category: "process", privilege: "query", domainOwnerGranted: true)')
13
+ @Query(returns => Process!, { nullable: true, description: 'To fetch a Process' })
14
+ async process(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<Process> {
15
+ const { domain } = context.state
16
+
17
+ return await getRepository(Process).findOne({
18
+ where: { domain: { id: domain.id }, id }
19
+ })
20
+ }
21
+
22
+ @Directive('@privilege(category: "process", privilege: "query", domainOwnerGranted: true)')
23
+ @Query(returns => Process!, { nullable: true, description: 'To fetch a Process by name' })
24
+ async processByName(@Arg('name') name: string, @Ctx() context: ResolverContext): Promise<Process> {
25
+ const { domain } = context.state
26
+
27
+ return await getRepository(Process).findOne({
28
+ where: { domain: { id: domain.id }, name }
29
+ })
30
+ }
31
+
32
+ @Directive('@privilege(category: "process", privilege: "query", domainOwnerGranted: true)')
33
+ @Query(returns => ProcessList, { description: 'To fetch multiple Processes' })
34
+ async processes(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<ProcessList> {
35
+ const { domain } = context.state
36
+
37
+ const queryBuilder = getQueryBuilderFromListParams({
38
+ domain,
39
+ params,
40
+ repository: getRepository(Process),
41
+ alias: 'process',
42
+ searchables: ['name', 'description', 'supervisoryRole']
43
+ })
44
+
45
+ const [items, total] = await queryBuilder.getManyAndCount()
46
+
47
+ return { items, total }
48
+ }
49
+
50
+ @Directive('@privilege(category: "process", privilege: "query", domainOwnerGranted: true)')
51
+ @Query(returns => ProcessList, { description: 'To fetch the list of processes that I can report on' })
52
+ async supervisableProcesses(
53
+ @Args(type => ListParam) params: ListParam,
54
+ @Ctx() context: ResolverContext
55
+ ): Promise<ProcessList> {
56
+ var { domain, user } = context.state
57
+
58
+ /* 조회한 사용자가 assigner 역할을 가진 process-instance 리스트만 반환 */
59
+ user = await getRepository(User).findOne({
60
+ where: { id: user.id },
61
+ relations: ['roles']
62
+ })
63
+ const roles = user.roles.filter(role => role.domainId === domain.id).map(role => role.id)
64
+
65
+ if (!roles.length) {
66
+ return { items: [], total: 0 }
67
+ }
68
+
69
+ const [items, total] = await getQueryBuilderFromListParams({
70
+ repository: getRepository(Process),
71
+ params,
72
+ domain,
73
+ alias: 'process',
74
+ searchables: ['name', 'description']
75
+ })
76
+ .andWhere(`process.supervisoryRole IN (:...roles)`, { roles })
77
+ .getManyAndCount()
78
+
79
+ return { items, total }
80
+ }
81
+
82
+ @FieldResolver(type => Role)
83
+ async supervisoryRole(@Root() process: Process): Promise<Role> {
84
+ return (
85
+ process.supervisoryRole ||
86
+ (process.supervisoryRoleId &&
87
+ (await getRepository(Role).findOneBy({
88
+ id: process.supervisoryRoleId
89
+ })))
90
+ )
91
+ }
92
+
93
+ @FieldResolver(type => String)
94
+ async thumbnail(@Root() process: Process): Promise<string | undefined> {
95
+ const attachment: Attachment = await getRepository(Attachment).findOne({
96
+ where: {
97
+ domain: { id: process.domainId },
98
+ refType: Process.name,
99
+ refBy: process.id
100
+ }
101
+ })
102
+
103
+ return attachment?.fullpath
104
+ }
105
+
106
+ @FieldResolver(type => Domain)
107
+ async domain(@Root() process: Process): Promise<Domain> {
108
+ return await getRepository(Domain).findOneBy({ id: process.domainId })
109
+ }
110
+
111
+ @FieldResolver(type => User)
112
+ async updater(@Root() process: Process): Promise<User> {
113
+ return await getRepository(User).findOneBy({ id: process.updaterId })
114
+ }
115
+
116
+ @FieldResolver(type => User)
117
+ async creator(@Root() process: Process): Promise<User> {
118
+ return await getRepository(User).findOneBy({ id: process.creatorId })
119
+ }
120
+ }
@@ -0,0 +1,16 @@
1
+ import { Field, ObjectType } from 'type-graphql'
2
+
3
+ @ObjectType({ description: 'Entity for ProcessSearchKeyItem' })
4
+ export class ProcessSearchKeyItem {
5
+ @Field()
6
+ name: string
7
+
8
+ @Field({ nullable: true })
9
+ description?: string
10
+
11
+ @Field({ nullable: true })
12
+ inputKey: string
13
+
14
+ @Field({ nullable: true })
15
+ tKey?: string
16
+ }
@@ -0,0 +1,65 @@
1
+ import type { FileUpload } from 'graphql-upload/GraphQLUpload.js'
2
+ import GraphQLUpload from 'graphql-upload/GraphQLUpload.js'
3
+ import { Field, ID, InputType, Int, ObjectType } from 'type-graphql'
4
+
5
+ import { ObjectRef, ScalarObject } from '@things-factory/shell'
6
+
7
+ import { Process, ProcessStatus } from './process'
8
+ import { ProcessSearchKeyItem } from './process-search-key-item-type'
9
+
10
+ @InputType()
11
+ export class NewProcess {
12
+ @Field()
13
+ name: string
14
+
15
+ @Field({ nullable: true })
16
+ description?: string
17
+
18
+ @Field(type => ScalarObject, { nullable: true })
19
+ searchKeys?: ProcessSearchKeyItem[]
20
+
21
+ @Field({ nullable: true })
22
+ state?: ProcessStatus
23
+
24
+ @Field(type => ObjectRef, { nullable: true })
25
+ supervisoryRole?: ObjectRef
26
+
27
+ @Field(type => GraphQLUpload, { nullable: true })
28
+ thumbnail?: FileUpload
29
+ }
30
+
31
+ @InputType()
32
+ export class ProcessPatch {
33
+ @Field(type => ID, { nullable: true })
34
+ id?: string
35
+
36
+ @Field({ nullable: true })
37
+ name?: string
38
+
39
+ @Field({ nullable: true })
40
+ description?: string
41
+
42
+ @Field(type => ScalarObject, { nullable: true })
43
+ searchKeys?: ProcessSearchKeyItem[]
44
+
45
+ @Field({ nullable: true })
46
+ state?: ProcessStatus
47
+
48
+ @Field(type => ObjectRef, { nullable: true })
49
+ supervisoryRole?: ObjectRef
50
+
51
+ @Field(type => GraphQLUpload, { nullable: true })
52
+ thumbnail?: FileUpload
53
+
54
+ @Field({ nullable: true })
55
+ cuFlag?: string
56
+ }
57
+
58
+ @ObjectType()
59
+ export class ProcessList {
60
+ @Field(type => [Process])
61
+ items: Process[]
62
+
63
+ @Field(type => Int)
64
+ total: number
65
+ }
@@ -0,0 +1,97 @@
1
+ import { Field, ID, ObjectType, registerEnumType } from 'type-graphql'
2
+ import {
3
+ Column,
4
+ CreateDateColumn,
5
+ Entity,
6
+ Index,
7
+ ManyToOne,
8
+ PrimaryGeneratedColumn,
9
+ RelationId,
10
+ UpdateDateColumn,
11
+ VersionColumn
12
+ } from 'typeorm'
13
+
14
+ import { Role, User } from '@things-factory/auth-base'
15
+ import { Domain } from '@things-factory/shell'
16
+
17
+ import { ProcessSearchKeyItem } from './process-search-key-item-type'
18
+
19
+ export enum ProcessStatus {
20
+ Draft = 'draft',
21
+ Released = 'released',
22
+ Deprecated = 'deprecated'
23
+ }
24
+
25
+ registerEnumType(ProcessStatus, {
26
+ name: 'ProcessStatus',
27
+ description: 'state enumeration of a process'
28
+ })
29
+
30
+ @Entity()
31
+ @Index('ix_process_0', (process: Process) => [process.domain, process.name], { unique: true })
32
+ @Index('ix_process_1', (process: Process) => [process.domain, process.state], { unique: false })
33
+ @ObjectType({ description: 'Entity for Process' })
34
+ export class Process {
35
+ @PrimaryGeneratedColumn('uuid')
36
+ @Field(type => ID)
37
+ readonly id: string
38
+
39
+ @VersionColumn()
40
+ @Field({ nullable: true })
41
+ version?: number = 1
42
+
43
+ @ManyToOne(type => Domain)
44
+ @Field(type => Domain, { nullable: true })
45
+ domain?: Domain
46
+
47
+ @RelationId((process: Process) => process.domain)
48
+ domainId?: string
49
+
50
+ @Column()
51
+ @Field({ nullable: true })
52
+ name?: string
53
+
54
+ @Column({ nullable: true })
55
+ @Field({ nullable: true })
56
+ description?: string
57
+
58
+ @Column({ nullable: true })
59
+ @Field({ nullable: true })
60
+ state?: ProcessStatus
61
+
62
+ @Column('simple-json', { nullable: true })
63
+ @Field(type => [ProcessSearchKeyItem], { nullable: true })
64
+ searchKeys?: ProcessSearchKeyItem[]
65
+
66
+ @ManyToOne(type => Role, { nullable: true })
67
+ @Field(type => Role, { nullable: true, description: 'The final authority on a given process.' })
68
+ supervisoryRole?: Role
69
+
70
+ @RelationId((process: Process) => process.supervisoryRole)
71
+ supervisoryRoleId?: string
72
+
73
+ @CreateDateColumn()
74
+ @Field({ nullable: true })
75
+ createdAt?: Date
76
+
77
+ @UpdateDateColumn()
78
+ @Field({ nullable: true })
79
+ updatedAt?: Date
80
+
81
+ @ManyToOne(type => User, { nullable: true })
82
+ @Field(type => User, { nullable: true })
83
+ creator?: User
84
+
85
+ @RelationId((process: Process) => process.creator)
86
+ creatorId?: string
87
+
88
+ @ManyToOne(type => User, { nullable: true })
89
+ @Field(type => User, { nullable: true })
90
+ updater?: User
91
+
92
+ @RelationId((process: Process) => process.updater)
93
+ updaterId?: string
94
+
95
+ @Field(type => String, { nullable: true })
96
+ thumbnail?: string
97
+ }
@@ -0,0 +1,44 @@
1
+ import { EventSubscriber, EntitySubscriberInterface, InsertEvent, UpdateEvent } from 'typeorm'
2
+
3
+ import { HistoryEntitySubscriber } from '@operato/typeorm-history'
4
+ import { pubsub } from '@things-factory/shell'
5
+
6
+ import { ProcessInstance } from './process-instance'
7
+ import { ProcessInstanceHistory } from './process-instance-history'
8
+
9
+ @EventSubscriber()
10
+ export class ProcessInstanceSubscriber implements EntitySubscriberInterface<ProcessInstance> {
11
+ listenTo() {
12
+ return ProcessInstance
13
+ }
14
+
15
+ async afterInsert(event: InsertEvent<ProcessInstance>): Promise<any | void> {
16
+ const { entity: processInstance, manager: tx } = event
17
+
18
+ pubsub.publish('process-instance', {
19
+ processInstance
20
+ })
21
+ }
22
+
23
+ async afterUpdate(event: UpdateEvent<ProcessInstance>): Promise<any | void> {
24
+ const { entity: processInstance, manager: tx } = event
25
+
26
+ pubsub.publish('process-instance', {
27
+ processInstance
28
+ })
29
+ }
30
+ }
31
+
32
+ @EventSubscriber()
33
+ export class ProcessInstanceHistoryEntitySubscriber extends HistoryEntitySubscriber<
34
+ ProcessInstance,
35
+ ProcessInstanceHistory
36
+ > {
37
+ public get entity() {
38
+ return ProcessInstance
39
+ }
40
+
41
+ public get historyEntity() {
42
+ return ProcessInstanceHistory
43
+ }
44
+ }
@@ -0,0 +1,10 @@
1
+ import { ProcessInstance } from './process-instance'
2
+ import { ProcessInstanceHistory } from './process-instance-history'
3
+ import { ProcessInstanceMutation } from './process-instance-mutation'
4
+ import { ProcessInstanceQuery } from './process-instance-query'
5
+ import { ProcessInstanceSubscription } from './process-instance-subscription'
6
+ import { ProcessInstanceHistoryEntitySubscriber, ProcessInstanceSubscriber } from './event-subscriber'
7
+
8
+ export const entities = [ProcessInstance, ProcessInstanceHistory]
9
+ export const resolvers = [ProcessInstanceQuery, ProcessInstanceMutation, ProcessInstanceSubscription]
10
+ export const subscribers = [ProcessInstanceSubscriber, ProcessInstanceHistoryEntitySubscriber]