@things-factory/process 6.0.57

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 (212) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/assets/images/hatiolab-logo.png +0 -0
  3. package/client/actions/main.ts +1 -0
  4. package/client/bootstrap.ts +8 -0
  5. package/client/index.ts +1 -0
  6. package/client/pages/main.ts +25 -0
  7. package/client/pages/process/process-importer.ts +97 -0
  8. package/client/pages/process/process-list-page.ts +348 -0
  9. package/client/pages/process-instance/process-instance-importer.ts +97 -0
  10. package/client/pages/process-instance/process-instance-list-page.ts +348 -0
  11. package/client/pages/process-thread/process-thread-importer.ts +97 -0
  12. package/client/pages/process-thread/process-thread-list-page.ts +348 -0
  13. package/client/reducers/main.ts +17 -0
  14. package/client/route.ts +19 -0
  15. package/client/tsconfig.json +11 -0
  16. package/dist-client/actions/main.d.ts +1 -0
  17. package/dist-client/actions/main.js +2 -0
  18. package/dist-client/actions/main.js.map +1 -0
  19. package/dist-client/bootstrap.d.ts +1 -0
  20. package/dist-client/bootstrap.js +8 -0
  21. package/dist-client/bootstrap.js.map +1 -0
  22. package/dist-client/index.d.ts +1 -0
  23. package/dist-client/index.js +2 -0
  24. package/dist-client/index.js.map +1 -0
  25. package/dist-client/pages/main.d.ts +1 -0
  26. package/dist-client/pages/main.js +27 -0
  27. package/dist-client/pages/main.js.map +1 -0
  28. package/dist-client/pages/process/process-importer.d.ts +22 -0
  29. package/dist-client/pages/process/process-importer.js +100 -0
  30. package/dist-client/pages/process/process-importer.js.map +1 -0
  31. package/dist-client/pages/process/process-list-page.d.ts +62 -0
  32. package/dist-client/pages/process/process-list-page.js +326 -0
  33. package/dist-client/pages/process/process-list-page.js.map +1 -0
  34. package/dist-client/pages/process-instance/process-instance-importer.d.ts +22 -0
  35. package/dist-client/pages/process-instance/process-instance-importer.js +100 -0
  36. package/dist-client/pages/process-instance/process-instance-importer.js.map +1 -0
  37. package/dist-client/pages/process-instance/process-instance-list-page.d.ts +62 -0
  38. package/dist-client/pages/process-instance/process-instance-list-page.js +326 -0
  39. package/dist-client/pages/process-instance/process-instance-list-page.js.map +1 -0
  40. package/dist-client/pages/process-thread/process-thread-importer.d.ts +22 -0
  41. package/dist-client/pages/process-thread/process-thread-importer.js +100 -0
  42. package/dist-client/pages/process-thread/process-thread-importer.js.map +1 -0
  43. package/dist-client/pages/process-thread/process-thread-list-page.d.ts +62 -0
  44. package/dist-client/pages/process-thread/process-thread-list-page.js +326 -0
  45. package/dist-client/pages/process-thread/process-thread-list-page.js.map +1 -0
  46. package/dist-client/reducers/main.d.ts +6 -0
  47. package/dist-client/reducers/main.js +14 -0
  48. package/dist-client/reducers/main.js.map +1 -0
  49. package/dist-client/route.d.ts +1 -0
  50. package/dist-client/route.js +17 -0
  51. package/dist-client/route.js.map +1 -0
  52. package/dist-client/tsconfig.tsbuildinfo +1 -0
  53. package/dist-server/controllers/common.js +70 -0
  54. package/dist-server/controllers/common.js.map +1 -0
  55. package/dist-server/controllers/index.js +1 -0
  56. package/dist-server/controllers/index.js.map +1 -0
  57. package/dist-server/controllers/process-instance/abort.js +54 -0
  58. package/dist-server/controllers/process-instance/abort.js.map +1 -0
  59. package/dist-server/controllers/process-instance/assign.js +41 -0
  60. package/dist-server/controllers/process-instance/assign.js.map +1 -0
  61. package/dist-server/controllers/process-instance/draft.js +74 -0
  62. package/dist-server/controllers/process-instance/draft.js.map +1 -0
  63. package/dist-server/controllers/process-instance/end.js +54 -0
  64. package/dist-server/controllers/process-instance/end.js.map +1 -0
  65. package/dist-server/controllers/process-instance/index.js +6 -0
  66. package/dist-server/controllers/process-instance/index.js.map +1 -0
  67. package/dist-server/controllers/process-instance/issue.js +105 -0
  68. package/dist-server/controllers/process-instance/issue.js.map +1 -0
  69. package/dist-server/controllers/process-instance/pick.js +33 -0
  70. package/dist-server/controllers/process-instance/pick.js.map +1 -0
  71. package/dist-server/controllers/process-thread/_abort.js +11 -0
  72. package/dist-server/controllers/process-thread/_abort.js.map +1 -0
  73. package/dist-server/controllers/process-thread/abort.js +36 -0
  74. package/dist-server/controllers/process-thread/abort.js.map +1 -0
  75. package/dist-server/controllers/process-thread/delegate.js +36 -0
  76. package/dist-server/controllers/process-thread/delegate.js.map +1 -0
  77. package/dist-server/controllers/process-thread/end.js +35 -0
  78. package/dist-server/controllers/process-thread/end.js.map +1 -0
  79. package/dist-server/controllers/process-thread/index.js +7 -0
  80. package/dist-server/controllers/process-thread/index.js.map +1 -0
  81. package/dist-server/controllers/process-thread/restart.js +36 -0
  82. package/dist-server/controllers/process-thread/restart.js.map +1 -0
  83. package/dist-server/controllers/process-thread/save.js +38 -0
  84. package/dist-server/controllers/process-thread/save.js.map +1 -0
  85. package/dist-server/controllers/process-thread/start.js +32 -0
  86. package/dist-server/controllers/process-thread/start.js.map +1 -0
  87. package/dist-server/controllers/process-thread/submit.js +37 -0
  88. package/dist-server/controllers/process-thread/submit.js.map +1 -0
  89. package/dist-server/index.js +7 -0
  90. package/dist-server/index.js.map +1 -0
  91. package/dist-server/middlewares/index.js +8 -0
  92. package/dist-server/middlewares/index.js.map +1 -0
  93. package/dist-server/migrations/index.js +12 -0
  94. package/dist-server/migrations/index.js.map +1 -0
  95. package/dist-server/routes.js +25 -0
  96. package/dist-server/routes.js.map +1 -0
  97. package/dist-server/service/index.js +33 -0
  98. package/dist-server/service/index.js.map +1 -0
  99. package/dist-server/service/process/event-subscriber.js +21 -0
  100. package/dist-server/service/process/event-subscriber.js.map +1 -0
  101. package/dist-server/service/process/index.js +12 -0
  102. package/dist-server/service/process/index.js.map +1 -0
  103. package/dist-server/service/process/process-history.js +113 -0
  104. package/dist-server/service/process/process-history.js.map +1 -0
  105. package/dist-server/service/process/process-model-type.js +138 -0
  106. package/dist-server/service/process/process-model-type.js.map +1 -0
  107. package/dist-server/service/process/process-mutation.js +179 -0
  108. package/dist-server/service/process/process-mutation.js.map +1 -0
  109. package/dist-server/service/process/process-query.js +160 -0
  110. package/dist-server/service/process/process-query.js.map +1 -0
  111. package/dist-server/service/process/process-search-key-item-type.js +28 -0
  112. package/dist-server/service/process/process-search-key-item-type.js.map +1 -0
  113. package/dist-server/service/process/process-type.js +91 -0
  114. package/dist-server/service/process/process-type.js.map +1 -0
  115. package/dist-server/service/process/process.js +112 -0
  116. package/dist-server/service/process/process.js.map +1 -0
  117. package/dist-server/service/process-instance/event-subscriber.js +43 -0
  118. package/dist-server/service/process-instance/event-subscriber.js.map +1 -0
  119. package/dist-server/service/process-instance/index.js +13 -0
  120. package/dist-server/service/process-instance/index.js.map +1 -0
  121. package/dist-server/service/process-instance/process-instance-history.js +173 -0
  122. package/dist-server/service/process-instance/process-instance-history.js.map +1 -0
  123. package/dist-server/service/process-instance/process-instance-mutation.js +44 -0
  124. package/dist-server/service/process-instance/process-instance-mutation.js.map +1 -0
  125. package/dist-server/service/process-instance/process-instance-query.js +176 -0
  126. package/dist-server/service/process-instance/process-instance-query.js.map +1 -0
  127. package/dist-server/service/process-instance/process-instance-subscription.js +54 -0
  128. package/dist-server/service/process-instance/process-instance-subscription.js.map +1 -0
  129. package/dist-server/service/process-instance/process-instance-type.js +103 -0
  130. package/dist-server/service/process-instance/process-instance-type.js.map +1 -0
  131. package/dist-server/service/process-instance/process-instance.js +177 -0
  132. package/dist-server/service/process-instance/process-instance.js.map +1 -0
  133. package/dist-server/service/process-stats/index.js +6 -0
  134. package/dist-server/service/process-stats/index.js.map +1 -0
  135. package/dist-server/service/process-stats/process-stats-query.js +61 -0
  136. package/dist-server/service/process-stats/process-stats-query.js.map +1 -0
  137. package/dist-server/service/process-stats/process-stats-type.js +43 -0
  138. package/dist-server/service/process-stats/process-stats-type.js.map +1 -0
  139. package/dist-server/service/process-summary/index.js +8 -0
  140. package/dist-server/service/process-summary/index.js.map +1 -0
  141. package/dist-server/service/process-summary/process-summary-query.js +109 -0
  142. package/dist-server/service/process-summary/process-summary-query.js.map +1 -0
  143. package/dist-server/service/process-summary/process-summary.js +28 -0
  144. package/dist-server/service/process-summary/process-summary.js.map +1 -0
  145. package/dist-server/service/process-thread/event-subscriber.js +31 -0
  146. package/dist-server/service/process-thread/event-subscriber.js.map +1 -0
  147. package/dist-server/service/process-thread/index.js +12 -0
  148. package/dist-server/service/process-thread/index.js.map +1 -0
  149. package/dist-server/service/process-thread/process-thread-history.js +194 -0
  150. package/dist-server/service/process-thread/process-thread-history.js.map +1 -0
  151. package/dist-server/service/process-thread/process-thread-mutation.js +45 -0
  152. package/dist-server/service/process-thread/process-thread-mutation.js.map +1 -0
  153. package/dist-server/service/process-thread/process-thread-query.js +92 -0
  154. package/dist-server/service/process-thread/process-thread-query.js.map +1 -0
  155. package/dist-server/service/process-thread/process-thread-subscription.js +45 -0
  156. package/dist-server/service/process-thread/process-thread-subscription.js.map +1 -0
  157. package/dist-server/service/process-thread/process-thread-type.js +21 -0
  158. package/dist-server/service/process-thread/process-thread-type.js.map +1 -0
  159. package/dist-server/service/process-thread/process-thread.js +101 -0
  160. package/dist-server/service/process-thread/process-thread.js.map +1 -0
  161. package/dist-server/tsconfig.tsbuildinfo +1 -0
  162. package/helps/process/process-instance.md +160 -0
  163. package/helps/process/process-thread.md +160 -0
  164. package/helps/process/process.md +160 -0
  165. package/package.json +44 -0
  166. package/server/controllers/common.ts +90 -0
  167. package/server/controllers/index.ts +0 -0
  168. package/server/controllers/process-instance/abort.ts +75 -0
  169. package/server/controllers/process-instance/end.ts +74 -0
  170. package/server/controllers/process-instance/index.ts +2 -0
  171. package/server/controllers/process-thread/_abort.ts +20 -0
  172. package/server/controllers/process-thread/abort.ts +48 -0
  173. package/server/controllers/process-thread/end.ts +54 -0
  174. package/server/controllers/process-thread/index.ts +3 -0
  175. package/server/controllers/process-thread/start.ts +49 -0
  176. package/server/index.ts +4 -0
  177. package/server/middlewares/index.ts +3 -0
  178. package/server/migrations/index.ts +9 -0
  179. package/server/routes.ts +28 -0
  180. package/server/service/index.ts +32 -0
  181. package/server/service/process/event-subscriber.ts +17 -0
  182. package/server/service/process/index.ts +9 -0
  183. package/server/service/process/process-history.ts +102 -0
  184. package/server/service/process/process-mutation.ts +210 -0
  185. package/server/service/process/process-query.ts +117 -0
  186. package/server/service/process/process-search-key-item-type.ts +16 -0
  187. package/server/service/process/process-type.ts +65 -0
  188. package/server/service/process/process.ts +97 -0
  189. package/server/service/process-instance/event-subscriber.ts +44 -0
  190. package/server/service/process-instance/index.ts +10 -0
  191. package/server/service/process-instance/process-instance-history.ts +148 -0
  192. package/server/service/process-instance/process-instance-mutation.ts +33 -0
  193. package/server/service/process-instance/process-instance-query.ts +138 -0
  194. package/server/service/process-instance/process-instance-subscription.ts +52 -0
  195. package/server/service/process-instance/process-instance-type.ts +71 -0
  196. package/server/service/process-instance/process-instance.ts +147 -0
  197. package/server/service/process-stats/index.ts +3 -0
  198. package/server/service/process-stats/process-stats-query.ts +57 -0
  199. package/server/service/process-stats/process-stats-type.ts +31 -0
  200. package/server/service/process-thread/event-subscriber.ts +31 -0
  201. package/server/service/process-thread/index.ts +9 -0
  202. package/server/service/process-thread/process-thread-mutation.ts +34 -0
  203. package/server/service/process-thread/process-thread-query.ts +58 -0
  204. package/server/service/process-thread/process-thread-subscription.ts +41 -0
  205. package/server/service/process-thread/process-thread-type.ts +15 -0
  206. package/server/service/process-thread/process-thread.ts +90 -0
  207. package/server/tsconfig.json +10 -0
  208. package/things-factory.config.js +13 -0
  209. package/translations/en.json +1 -0
  210. package/translations/ko.json +1 -0
  211. package/translations/ms.json +1 -0
  212. package/translations/zh.json +1 -0
@@ -0,0 +1,117 @@
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() 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(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<ProcessList> {
53
+ var { domain, user } = context.state
54
+
55
+ /* 조회한 사용자가 assigner 역할을 가진 process-instance 리스트만 반환 */
56
+ user = await getRepository(User).findOne({
57
+ where: { id: user.id },
58
+ relations: ['roles']
59
+ })
60
+ const roles = user.roles.filter(role => role.domainId === domain.id).map(role => role.id)
61
+
62
+ if (!roles.length) {
63
+ return { items: [], total: 0 }
64
+ }
65
+
66
+ const [items, total] = await getQueryBuilderFromListParams({
67
+ repository: getRepository(Process),
68
+ params,
69
+ domain,
70
+ alias: 'process',
71
+ searchables: ['name', 'description']
72
+ })
73
+ .andWhere(`process.supervisoryRole IN (:...roles)`, { roles })
74
+ .getManyAndCount()
75
+
76
+ return { items, total }
77
+ }
78
+
79
+ @FieldResolver(type => Role)
80
+ async supervisoryRole(@Root() process: Process): Promise<Role> {
81
+ return (
82
+ process.supervisoryRole ||
83
+ (process.supervisoryRoleId &&
84
+ (await getRepository(Role).findOneBy({
85
+ id: process.supervisoryRoleId
86
+ })))
87
+ )
88
+ }
89
+
90
+ @FieldResolver(type => String)
91
+ async thumbnail(@Root() process: Process): Promise<string | undefined> {
92
+ const attachment: Attachment = await getRepository(Attachment).findOne({
93
+ where: {
94
+ domain: { id: process.domainId },
95
+ refType: Process.name,
96
+ refBy: process.id
97
+ }
98
+ })
99
+
100
+ return attachment?.fullpath
101
+ }
102
+
103
+ @FieldResolver(type => Domain)
104
+ async domain(@Root() process: Process): Promise<Domain> {
105
+ return await getRepository(Domain).findOneBy({ id: process.domainId })
106
+ }
107
+
108
+ @FieldResolver(type => User)
109
+ async updater(@Root() process: Process): Promise<User> {
110
+ return await getRepository(User).findOneBy({ id: process.updaterId })
111
+ }
112
+
113
+ @FieldResolver(type => User)
114
+ async creator(@Root() process: Process): Promise<User> {
115
+ return await getRepository(User).findOneBy({ id: process.creatorId })
116
+ }
117
+ }
@@ -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]
@@ -0,0 +1,148 @@
1
+ import { Field, ID, Int, 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, ScalarObject } from '@things-factory/shell'
13
+
14
+ import { ProcessInstance, ProcessInstanceStatus } from './process-instance'
15
+
16
+ const ORMCONFIG = config.get('ormconfig', {})
17
+ const DATABASE_TYPE = ORMCONFIG.type
18
+
19
+ @Entity()
20
+ @Index(
21
+ 'ix_process_instance_history_0',
22
+ (processInstanceHistory: ProcessInstanceHistory) => [
23
+ processInstanceHistory.originalId,
24
+ processInstanceHistory.version
25
+ ],
26
+ { unique: true }
27
+ )
28
+ @Index(
29
+ 'ix_process_instance_history_1',
30
+ (processInstanceHistory: ProcessInstanceHistory) => [
31
+ processInstanceHistory.domain,
32
+ processInstanceHistory.originalId,
33
+ processInstanceHistory.version
34
+ ],
35
+ { unique: true }
36
+ )
37
+ @ObjectType({ description: 'History Entity of ProcessInstance' })
38
+ export class ProcessInstanceHistory implements HistoryEntityInterface<ProcessInstance> {
39
+ @PrimaryGeneratedColumn('uuid')
40
+ @Field(type => ID)
41
+ readonly id: string
42
+
43
+ @Column({
44
+ nullable: true,
45
+ default: 1
46
+ })
47
+ @Field({ nullable: true })
48
+ version?: number = 1
49
+
50
+ @ManyToOne(type => Domain)
51
+ @Field({ nullable: true })
52
+ domain?: Domain
53
+
54
+ @RelationId((processInstance: ProcessInstance) => processInstance.domain)
55
+ domainId?: string
56
+
57
+ @Column()
58
+ @Field({ nullable: true })
59
+ name?: string
60
+
61
+ @Column({ nullable: true })
62
+ @Field({ nullable: true })
63
+ description?: string
64
+
65
+ @Column({ nullable: true, default: '' })
66
+ @Field({ nullable: true })
67
+ key01?: string = ''
68
+
69
+ @Column({ nullable: true, default: '' })
70
+ @Field({ nullable: true })
71
+ key02?: string = ''
72
+
73
+ @Column({ nullable: true, default: '' })
74
+ @Field({ nullable: true })
75
+ key03?: string = ''
76
+
77
+ @Column({ nullable: true, default: '' })
78
+ @Field({ nullable: true })
79
+ key04?: string = ''
80
+
81
+ @Column({ nullable: true, default: '' })
82
+ @Field({ nullable: true })
83
+ key05?: string = ''
84
+
85
+ @Column({ nullable: true })
86
+ @Field({ nullable: true })
87
+ state?: ProcessInstanceStatus
88
+
89
+ @Column({ nullable: true })
90
+ @Field({ nullable: true })
91
+ reason?: string
92
+
93
+ @Column({ nullable: true })
94
+ @Field({ nullable: true })
95
+ refBy?: string
96
+
97
+ @ManyToOne(type => Role, { nullable: true })
98
+ @Field(type => Role, { nullable: true })
99
+ supervisoryRole?: Role
100
+
101
+ @RelationId((processInstance: ProcessInstance) => processInstance.supervisoryRole)
102
+ supervisoryRoleId?: string
103
+
104
+ @Column({ nullable: true })
105
+ @Field({ nullable: true })
106
+ dueAt?: Date
107
+
108
+ @Column()
109
+ @Field({ nullable: true })
110
+ createdAt?: Date
111
+
112
+ @Column()
113
+ @Field({ nullable: true })
114
+ updatedAt?: Date
115
+
116
+ @Column({ nullable: true })
117
+ @Field({ nullable: true })
118
+ terminatedAt?: Date
119
+
120
+ @ManyToOne(type => User, { nullable: true })
121
+ @Field({ nullable: true })
122
+ creator?: User
123
+
124
+ @RelationId((processInstance: ProcessInstance) => processInstance.creator)
125
+ creatorId?: string
126
+
127
+ @ManyToOne(type => User, { nullable: true })
128
+ @Field({ nullable: true })
129
+ updater?: User
130
+
131
+ @RelationId((processInstance: ProcessInstance) => processInstance.updater)
132
+ updaterId?: string
133
+
134
+ @HistoryOriginalIdColumn()
135
+ public originalId!: string
136
+
137
+ @HistoryActionColumn({
138
+ nullable: false,
139
+ type:
140
+ DATABASE_TYPE == 'postgres' || DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
141
+ ? 'enum'
142
+ : DATABASE_TYPE == 'oracle'
143
+ ? 'varchar2'
144
+ : 'smallint',
145
+ enum: HistoryActionType
146
+ })
147
+ public action!: HistoryActionType
148
+ }
@@ -0,0 +1,33 @@
1
+ import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
2
+
3
+ import { ScalarObject } from '@things-factory/shell'
4
+
5
+ import { abort, end } from '../../controllers/process-instance'
6
+ import { ProcessInstance } from './process-instance'
7
+ import { ProcessInstanceIssue, ProcessInstanceDraft } from './process-instance-type'
8
+
9
+ @Resolver(ProcessInstance)
10
+ export class ProcessInstanceMutation {
11
+ @Directive('@transaction')
12
+ @Directive('@privilege(category: "process", privilege: "mutation", domainOwnerGranted: true)')
13
+ @Mutation(returns => ProcessInstance, { description: 'To end a ProcessInstance' })
14
+ async endProcessInstance(
15
+ @Arg('id') id: string,
16
+ @Arg('output', type => ScalarObject, { nullable: true }) output: { [key: string]: any },
17
+ @Arg('reason', { nullable: true }) reason: string,
18
+ @Ctx() context: ResolverContext
19
+ ): Promise<ProcessInstance> {
20
+ return await end({ id, output, reason }, context)
21
+ }
22
+
23
+ @Directive('@transaction')
24
+ @Directive('@privilege(category: "process", privilege: "mutation", domainOwnerGranted: true)')
25
+ @Mutation(returns => ProcessInstance, { description: 'To abort a ProcessInstance' })
26
+ async abortProcessInstance(
27
+ @Arg('id') id: string,
28
+ @Arg('reason', { nullable: true }) reason: string,
29
+ @Ctx() context: ResolverContext
30
+ ): Promise<ProcessInstance> {
31
+ return await abort({ id, reason }, context)
32
+ }
33
+ }
@@ -0,0 +1,138 @@
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 { ProcessThread } from '../process-thread/process-thread'
8
+ import { Process } from '../process/process'
9
+ import { ProcessInstance, ProcessInstanceStatus } from './process-instance'
10
+ import { ProcessInstanceList } from './process-instance-type'
11
+
12
+ @Resolver(ProcessInstance)
13
+ export class ProcessInstanceQuery {
14
+ @Directive('@privilege(category: "process-instance", privilege: "query", domainOwnerGranted: true)')
15
+ @Query(returns => ProcessInstance!, { nullable: true, description: 'To fetch a ProcessInstance' })
16
+ async processInstance(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<ProcessInstance> {
17
+ const { domain } = context.state
18
+
19
+ return await getRepository(ProcessInstance).findOne({
20
+ where: { domain: { id: domain.id }, id }
21
+ })
22
+ }
23
+
24
+ @Directive('@privilege(category: "process-instance", privilege: "query", domainOwnerGranted: true)')
25
+ @Query(returns => ProcessInstanceList, { description: 'To fetch multiple ProcessInstances' })
26
+ async processInstances(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<ProcessInstanceList> {
27
+ const { domain } = context.state
28
+
29
+ const [items, total] = await getQueryBuilderFromListParams({
30
+ domain,
31
+ params,
32
+ repository: getRepository(ProcessInstance),
33
+ searchables: ['name', 'description']
34
+ }).getManyAndCount()
35
+
36
+ return { items, total }
37
+ }
38
+
39
+ @Directive('@privilege(category: "process-instance", privilege: "query", domainOwnerGranted: true)')
40
+ @Query(returns => ProcessInstanceList, { description: 'To fetch multiple process instances by process' })
41
+ async processInstancesByProcess(
42
+ @Arg('processId') processId: string,
43
+ @Args() params: ListParam,
44
+ @Ctx() context: ResolverContext
45
+ ): Promise<ProcessInstanceList> {
46
+ const { domain } = context.state
47
+
48
+ const process = await getRepository(Process).findOneBy({ id: processId })
49
+ const searchables = process?.searchKeys?.map((item, index) => `key0${index + 1}`) || []
50
+
51
+ const queryBuilder = getQueryBuilderFromListParams({
52
+ repository: getRepository(ProcessInstance),
53
+ params,
54
+ domain,
55
+ alias: 'pi',
56
+ searchables: ['name', 'description'].concat(searchables)
57
+ }).where('pi.process = :process', { process: processId })
58
+
59
+ const [items, total] = await queryBuilder.getManyAndCount()
60
+
61
+ return { items, total }
62
+ }
63
+
64
+ @FieldResolver(type => Process)
65
+ async process(@Root() processInstance: ProcessInstance): Promise<Process> {
66
+ const { processId } = processInstance
67
+
68
+ return await getRepository(Process).findOneBy({ id: processId })
69
+ }
70
+
71
+ @FieldResolver(type => [ProcessThread])
72
+ async processThreads(
73
+ @Root() processInstance: ProcessInstance,
74
+ @Ctx() context: ResolverContext
75
+ ): Promise<ProcessThread[]> {
76
+ const { user } = context.state
77
+ const { supervisoryRoleId } = processInstance
78
+
79
+ if (supervisoryRoleId) {
80
+ /* only user having supervisoryRole can get whole processThreads */
81
+ const roles = (
82
+ (await getRepository(User).findOne({
83
+ where: { id: user.id },
84
+ relations: ['roles']
85
+ })) as User
86
+ ).roles.map(role => role.id)
87
+
88
+ if (!roles.includes(supervisoryRoleId)) {
89
+ return
90
+ }
91
+ }
92
+
93
+ return await getRepository(ProcessThread).findBy({
94
+ processInstance: { id: processInstance.id }
95
+ })
96
+ }
97
+
98
+ @FieldResolver(type => Role)
99
+ async supervisoryRole(@Root() processInstance: ProcessInstance): Promise<Role> {
100
+ return (
101
+ processInstance.supervisoryRole ||
102
+ (processInstance.supervisoryRoleId &&
103
+ (await getRepository(Role).findOneBy({
104
+ id: processInstance.supervisoryRoleId
105
+ })))
106
+ )
107
+ }
108
+
109
+ @FieldResolver(type => String)
110
+ async thumbnail(@Root() processInstance: ProcessInstance): Promise<string | undefined> {
111
+ const { processId } = processInstance
112
+ const attachment: Attachment =
113
+ processId &&
114
+ (await getRepository(Attachment).findOne({
115
+ where: {
116
+ domain: { id: processInstance.domainId },
117
+ refBy: processId
118
+ }
119
+ }))
120
+
121
+ return attachment?.fullpath
122
+ }
123
+
124
+ @FieldResolver(type => Domain)
125
+ async domain(@Root() processInstance: ProcessInstance): Promise<Domain> {
126
+ return await getRepository(Domain).findOneBy({ id: processInstance.domainId })
127
+ }
128
+
129
+ @FieldResolver(type => User)
130
+ async updater(@Root() processInstance: ProcessInstance): Promise<User> {
131
+ return processInstance.updater && (await getRepository(User).findOneBy({ id: processInstance.updaterId }))
132
+ }
133
+
134
+ @FieldResolver(type => User)
135
+ async creator(@Root() processInstance: ProcessInstance): Promise<User> {
136
+ return processInstance.creator && (await getRepository(User).findOneBy({ id: processInstance.creatorId }))
137
+ }
138
+ }