@acorex-platform/framework-server 0.0.10

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 (935) hide show
  1. package/core/README.md +17 -0
  2. package/core/package.json +15 -0
  3. package/core/src/index.d.ts +2 -0
  4. package/core/src/index.js +6 -0
  5. package/core/src/index.js.map +1 -0
  6. package/core/src/lib/core.module.d.ts +2 -0
  7. package/core/src/lib/core.module.js +16 -0
  8. package/core/src/lib/core.module.js.map +1 -0
  9. package/core/src/lib/entity-storage/backends/logging.entity-storage.backend.d.ts +17 -0
  10. package/core/src/lib/entity-storage/backends/logging.entity-storage.backend.js +57 -0
  11. package/core/src/lib/entity-storage/backends/logging.entity-storage.backend.js.map +1 -0
  12. package/core/src/lib/entity-storage/entity-storage-backend.interface.d.ts +1 -0
  13. package/core/src/lib/entity-storage/entity-storage-backend.interface.js +3 -0
  14. package/core/src/lib/entity-storage/entity-storage-backend.interface.js.map +1 -0
  15. package/core/src/lib/entity-storage/entity-storage-logging.module.d.ts +4 -0
  16. package/core/src/lib/entity-storage/entity-storage-logging.module.js +28 -0
  17. package/core/src/lib/entity-storage/entity-storage-logging.module.js.map +1 -0
  18. package/core/src/lib/entity-storage/entity-storage-middleware.service.d.ts +45 -0
  19. package/core/src/lib/entity-storage/entity-storage-middleware.service.js +247 -0
  20. package/core/src/lib/entity-storage/entity-storage-middleware.service.js.map +1 -0
  21. package/core/src/lib/entity-storage/entity-storage-request-context.d.ts +6 -0
  22. package/core/src/lib/entity-storage/entity-storage-request-context.js +25 -0
  23. package/core/src/lib/entity-storage/entity-storage-request-context.js.map +1 -0
  24. package/core/src/lib/entity-storage/entity-storage.controller.d.ts +14 -0
  25. package/core/src/lib/entity-storage/entity-storage.controller.js +137 -0
  26. package/core/src/lib/entity-storage/entity-storage.controller.js.map +1 -0
  27. package/core/src/lib/entity-storage/entity-storage.module.d.ts +8 -0
  28. package/core/src/lib/entity-storage/entity-storage.module.js +47 -0
  29. package/core/src/lib/entity-storage/entity-storage.module.js.map +1 -0
  30. package/core/src/lib/entity-storage/entity-storage.tokens.d.ts +2 -0
  31. package/core/src/lib/entity-storage/entity-storage.tokens.js +7 -0
  32. package/core/src/lib/entity-storage/entity-storage.tokens.js.map +1 -0
  33. package/core/src/lib/entity-storage/entity-storage.types.d.ts +41 -0
  34. package/core/src/lib/entity-storage/entity-storage.types.js +4 -0
  35. package/core/src/lib/entity-storage/entity-storage.types.js.map +1 -0
  36. package/core/src/lib/entity-storage/errors/middleware-abort.error.d.ts +18 -0
  37. package/core/src/lib/entity-storage/errors/middleware-abort.error.js +36 -0
  38. package/core/src/lib/entity-storage/errors/middleware-abort.error.js.map +1 -0
  39. package/core/src/lib/entity-storage/index.d.ts +14 -0
  40. package/core/src/lib/entity-storage/index.js +18 -0
  41. package/core/src/lib/entity-storage/index.js.map +1 -0
  42. package/core/src/lib/entity-storage/middlewares/category-hierarchy-filter.middleware.d.ts +10 -0
  43. package/core/src/lib/entity-storage/middlewares/category-hierarchy-filter.middleware.js +57 -0
  44. package/core/src/lib/entity-storage/middlewares/category-hierarchy-filter.middleware.js.map +1 -0
  45. package/core/src/lib/entity-storage/middlewares/entity-storage-request-context.middleware.d.ts +9 -0
  46. package/core/src/lib/entity-storage/middlewares/entity-storage-request-context.middleware.js +22 -0
  47. package/core/src/lib/entity-storage/middlewares/entity-storage-request-context.middleware.js.map +1 -0
  48. package/core/src/lib/entity-storage/middlewares/request-log.middleware.d.ts +11 -0
  49. package/core/src/lib/entity-storage/middlewares/request-log.middleware.js +26 -0
  50. package/core/src/lib/entity-storage/middlewares/request-log.middleware.js.map +1 -0
  51. package/core/src/lib/entity-storage/utils/entity-route.util.d.ts +24 -0
  52. package/core/src/lib/entity-storage/utils/entity-route.util.js +96 -0
  53. package/core/src/lib/entity-storage/utils/entity-route.util.js.map +1 -0
  54. package/domain/abstract/package.json +11 -0
  55. package/domain/abstract/src/index.d.ts +17 -0
  56. package/domain/abstract/src/index.js +30 -0
  57. package/domain/abstract/src/index.js.map +1 -0
  58. package/domain/abstract/src/lib/definitions/aggregate-definition.types.d.ts +13 -0
  59. package/domain/abstract/src/lib/definitions/aggregate-definition.types.js +3 -0
  60. package/domain/abstract/src/lib/definitions/aggregate-definition.types.js.map +1 -0
  61. package/domain/abstract/src/lib/definitions/base.types.d.ts +32 -0
  62. package/domain/abstract/src/lib/definitions/base.types.js +17 -0
  63. package/domain/abstract/src/lib/definitions/base.types.js.map +1 -0
  64. package/domain/abstract/src/lib/definitions/command-registry.types.d.ts +16 -0
  65. package/domain/abstract/src/lib/definitions/command-registry.types.js +3 -0
  66. package/domain/abstract/src/lib/definitions/command-registry.types.js.map +1 -0
  67. package/domain/abstract/src/lib/definitions/entity-definition.types.d.ts +66 -0
  68. package/domain/abstract/src/lib/definitions/entity-definition.types.js +10 -0
  69. package/domain/abstract/src/lib/definitions/entity-definition.types.js.map +1 -0
  70. package/domain/abstract/src/lib/definitions/interface-definition.types.d.ts +27 -0
  71. package/domain/abstract/src/lib/definitions/interface-definition.types.js +3 -0
  72. package/domain/abstract/src/lib/definitions/interface-definition.types.js.map +1 -0
  73. package/domain/abstract/src/lib/definitions/menu-definition.types.d.ts +35 -0
  74. package/domain/abstract/src/lib/definitions/menu-definition.types.js +3 -0
  75. package/domain/abstract/src/lib/definitions/menu-definition.types.js.map +1 -0
  76. package/domain/abstract/src/lib/definitions/module-definition.types.d.ts +6 -0
  77. package/domain/abstract/src/lib/definitions/module-definition.types.js +3 -0
  78. package/domain/abstract/src/lib/definitions/module-definition.types.js.map +1 -0
  79. package/domain/abstract/src/lib/definitions/permission-definition.types.d.ts +24 -0
  80. package/domain/abstract/src/lib/definitions/permission-definition.types.js +3 -0
  81. package/domain/abstract/src/lib/definitions/permission-definition.types.js.map +1 -0
  82. package/domain/abstract/src/lib/definitions/plugin-definition.types.d.ts +14 -0
  83. package/domain/abstract/src/lib/definitions/plugin-definition.types.js +3 -0
  84. package/domain/abstract/src/lib/definitions/plugin-definition.types.js.map +1 -0
  85. package/domain/abstract/src/lib/definitions/property-definition.types.d.ts +32 -0
  86. package/domain/abstract/src/lib/definitions/property-definition.types.js +3 -0
  87. package/domain/abstract/src/lib/definitions/property-definition.types.js.map +1 -0
  88. package/domain/abstract/src/lib/definitions/query-registry.types.d.ts +15 -0
  89. package/domain/abstract/src/lib/definitions/query-registry.types.js +3 -0
  90. package/domain/abstract/src/lib/definitions/query-registry.types.js.map +1 -0
  91. package/domain/abstract/src/lib/definitions/relation-definition.types.d.ts +26 -0
  92. package/domain/abstract/src/lib/definitions/relation-definition.types.js +16 -0
  93. package/domain/abstract/src/lib/definitions/relation-definition.types.js.map +1 -0
  94. package/domain/abstract/src/lib/definitions/validation-definition.types.d.ts +19 -0
  95. package/domain/abstract/src/lib/definitions/validation-definition.types.js +3 -0
  96. package/domain/abstract/src/lib/definitions/validation-definition.types.js.map +1 -0
  97. package/domain/abstract/src/lib/definitions/widget-catalog.types.d.ts +7 -0
  98. package/domain/abstract/src/lib/definitions/widget-catalog.types.js +3 -0
  99. package/domain/abstract/src/lib/definitions/widget-catalog.types.js.map +1 -0
  100. package/domain/abstract/src/lib/interfaces/domain-definition-loader.interface.d.ts +10 -0
  101. package/domain/abstract/src/lib/interfaces/domain-definition-loader.interface.js +9 -0
  102. package/domain/abstract/src/lib/interfaces/domain-definition-loader.interface.js.map +1 -0
  103. package/domain/abstract/src/lib/interfaces/domain-definition.types.d.ts +12 -0
  104. package/domain/abstract/src/lib/interfaces/domain-definition.types.js +3 -0
  105. package/domain/abstract/src/lib/interfaces/domain-definition.types.js.map +1 -0
  106. package/domain/abstract/src/lib/types/domain-core.types.d.ts +15 -0
  107. package/domain/abstract/src/lib/types/domain-core.types.js +5 -0
  108. package/domain/abstract/src/lib/types/domain-core.types.js.map +1 -0
  109. package/domain/providers/package.json +19 -0
  110. package/domain/providers/src/index.d.ts +22 -0
  111. package/domain/providers/src/index.js +26 -0
  112. package/domain/providers/src/index.js.map +1 -0
  113. package/domain/providers/src/lib/domain-definition-jql-schema.d.ts +17 -0
  114. package/domain/providers/src/lib/domain-definition-jql-schema.js +95 -0
  115. package/domain/providers/src/lib/domain-definition-jql-schema.js.map +1 -0
  116. package/domain/providers/src/lib/domain-definition-jql-sources.d.ts +10 -0
  117. package/domain/providers/src/lib/domain-definition-jql-sources.js +82 -0
  118. package/domain/providers/src/lib/domain-definition-jql-sources.js.map +1 -0
  119. package/domain/providers/src/lib/domain-definition-jql.loader.d.ts +37 -0
  120. package/domain/providers/src/lib/domain-definition-jql.loader.js +219 -0
  121. package/domain/providers/src/lib/domain-definition-jql.loader.js.map +1 -0
  122. package/domain/providers/src/lib/domain-definition-store.constants.d.ts +17 -0
  123. package/domain/providers/src/lib/domain-definition-store.constants.js +22 -0
  124. package/domain/providers/src/lib/domain-definition-store.constants.js.map +1 -0
  125. package/domain/providers/src/lib/domain-entity-schema.loader.d.ts +11 -0
  126. package/domain/providers/src/lib/domain-entity-schema.loader.js +38 -0
  127. package/domain/providers/src/lib/domain-entity-schema.loader.js.map +1 -0
  128. package/domain/providers/src/lib/domain-entity-validator.module.d.ts +6 -0
  129. package/domain/providers/src/lib/domain-entity-validator.module.js +22 -0
  130. package/domain/providers/src/lib/domain-entity-validator.module.js.map +1 -0
  131. package/domain/providers/src/lib/domain-jql-instance.resolve.d.ts +6 -0
  132. package/domain/providers/src/lib/domain-jql-instance.resolve.js +18 -0
  133. package/domain/providers/src/lib/domain-jql-instance.resolve.js.map +1 -0
  134. package/domain/providers/src/lib/domain-middleware-entity-storage.bootstrap.d.ts +33 -0
  135. package/domain/providers/src/lib/domain-middleware-entity-storage.bootstrap.js +73 -0
  136. package/domain/providers/src/lib/domain-middleware-entity-storage.bootstrap.js.map +1 -0
  137. package/domain/providers/src/lib/domain-middleware.module.d.ts +6 -0
  138. package/domain/providers/src/lib/domain-middleware.module.js +80 -0
  139. package/domain/providers/src/lib/domain-middleware.module.js.map +1 -0
  140. package/domain/providers/src/lib/domain-provider.module.d.ts +7 -0
  141. package/domain/providers/src/lib/domain-provider.module.js +62 -0
  142. package/domain/providers/src/lib/domain-provider.module.js.map +1 -0
  143. package/domain/providers/src/lib/domain-provider.resolve.d.ts +6 -0
  144. package/domain/providers/src/lib/domain-provider.resolve.js +31 -0
  145. package/domain/providers/src/lib/domain-provider.resolve.js.map +1 -0
  146. package/domain/providers/src/lib/domain-provider.types.d.ts +1 -0
  147. package/domain/providers/src/lib/domain-provider.types.js +5 -0
  148. package/domain/providers/src/lib/domain-provider.types.js.map +1 -0
  149. package/domain/providers/src/lib/middlewares/category-resolver.middleware.d.ts +25 -0
  150. package/domain/providers/src/lib/middlewares/category-resolver.middleware.js +159 -0
  151. package/domain/providers/src/lib/middlewares/category-resolver.middleware.js.map +1 -0
  152. package/domain/providers/src/lib/middlewares/child-count.middleware.d.ts +14 -0
  153. package/domain/providers/src/lib/middlewares/child-count.middleware.js +74 -0
  154. package/domain/providers/src/lib/middlewares/child-count.middleware.js.map +1 -0
  155. package/domain/providers/src/lib/middlewares/domain-validation.middleware.d.ts +15 -0
  156. package/domain/providers/src/lib/middlewares/domain-validation.middleware.js +58 -0
  157. package/domain/providers/src/lib/middlewares/domain-validation.middleware.js.map +1 -0
  158. package/domain/providers/src/lib/middlewares/entity-get-by-diagnostic.middleware.d.ts +9 -0
  159. package/domain/providers/src/lib/middlewares/entity-get-by-diagnostic.middleware.js +27 -0
  160. package/domain/providers/src/lib/middlewares/entity-get-by-diagnostic.middleware.js.map +1 -0
  161. package/domain/providers/src/lib/middlewares/entity-mutation-diagnostic.middleware.d.ts +9 -0
  162. package/domain/providers/src/lib/middlewares/entity-mutation-diagnostic.middleware.js +27 -0
  163. package/domain/providers/src/lib/middlewares/entity-mutation-diagnostic.middleware.js.map +1 -0
  164. package/domain/providers/src/lib/middlewares/entity-query-filter-diagnostic.middleware.d.ts +9 -0
  165. package/domain/providers/src/lib/middlewares/entity-query-filter-diagnostic.middleware.js +28 -0
  166. package/domain/providers/src/lib/middlewares/entity-query-filter-diagnostic.middleware.js.map +1 -0
  167. package/domain/providers/src/lib/middlewares/lookup-resolver.middleware.d.ts +15 -0
  168. package/domain/providers/src/lib/middlewares/lookup-resolver.middleware.js +99 -0
  169. package/domain/providers/src/lib/middlewares/lookup-resolver.middleware.js.map +1 -0
  170. package/domain/providers/src/lib/middlewares/merge-detail-relation.middleware.d.ts +20 -0
  171. package/domain/providers/src/lib/middlewares/merge-detail-relation.middleware.js +263 -0
  172. package/domain/providers/src/lib/middlewares/merge-detail-relation.middleware.js.map +1 -0
  173. package/domain/providers/src/lib/middlewares/primary.middleware.d.ts +15 -0
  174. package/domain/providers/src/lib/middlewares/primary.middleware.js +94 -0
  175. package/domain/providers/src/lib/middlewares/primary.middleware.js.map +1 -0
  176. package/domain/providers/src/lib/middlewares/related-entity-cascade-delete.middleware.d.ts +15 -0
  177. package/domain/providers/src/lib/middlewares/related-entity-cascade-delete.middleware.js +47 -0
  178. package/domain/providers/src/lib/middlewares/related-entity-cascade-delete.middleware.js.map +1 -0
  179. package/domain/providers/src/lib/middlewares/status-default.middleware.d.ts +15 -0
  180. package/domain/providers/src/lib/middlewares/status-default.middleware.js +61 -0
  181. package/domain/providers/src/lib/middlewares/status-default.middleware.js.map +1 -0
  182. package/domain/providers/src/lib/services/related-entity-cascade.service.d.ts +26 -0
  183. package/domain/providers/src/lib/services/related-entity-cascade.service.js +166 -0
  184. package/domain/providers/src/lib/services/related-entity-cascade.service.js.map +1 -0
  185. package/domain/providers/src/lib/utils/domain-path.util.d.ts +4 -0
  186. package/domain/providers/src/lib/utils/domain-path.util.js +42 -0
  187. package/domain/providers/src/lib/utils/domain-path.util.js.map +1 -0
  188. package/domain/providers/src/lib/utils/domain-record.util.d.ts +4 -0
  189. package/domain/providers/src/lib/utils/domain-record.util.js +52 -0
  190. package/domain/providers/src/lib/utils/domain-record.util.js.map +1 -0
  191. package/domain/providers/src/lib/utils/expression-evaluator.util.d.ts +11 -0
  192. package/domain/providers/src/lib/utils/expression-evaluator.util.js +74 -0
  193. package/domain/providers/src/lib/utils/expression-evaluator.util.js.map +1 -0
  194. package/domain/providers/src/lib/utils/in-memory-query.util.d.ts +13 -0
  195. package/domain/providers/src/lib/utils/in-memory-query.util.js +91 -0
  196. package/domain/providers/src/lib/utils/in-memory-query.util.js.map +1 -0
  197. package/domain/providers/src/lib/utils/merge-detail-query.util.d.ts +28 -0
  198. package/domain/providers/src/lib/utils/merge-detail-query.util.js +119 -0
  199. package/domain/providers/src/lib/utils/merge-detail-query.util.js.map +1 -0
  200. package/domain/providers/src/lib/utils/parse-related-entity-cascade.util.d.ts +16 -0
  201. package/domain/providers/src/lib/utils/parse-related-entity-cascade.util.js +109 -0
  202. package/domain/providers/src/lib/utils/parse-related-entity-cascade.util.js.map +1 -0
  203. package/domain/providers/src/lib/utils/policy-field.util.d.ts +3 -0
  204. package/domain/providers/src/lib/utils/policy-field.util.js +95 -0
  205. package/domain/providers/src/lib/utils/policy-field.util.js.map +1 -0
  206. package/domain/providers/src/lib/validators/domain-entity.validator.d.ts +32 -0
  207. package/domain/providers/src/lib/validators/domain-entity.validator.js +281 -0
  208. package/domain/providers/src/lib/validators/domain-entity.validator.js.map +1 -0
  209. package/domain/seed/package.json +17 -0
  210. package/domain/seed/src/index.d.ts +5 -0
  211. package/domain/seed/src/index.js +9 -0
  212. package/domain/seed/src/index.js.map +1 -0
  213. package/domain/seed/src/lib/axp-entity-to-definition.converter.d.ts +9 -0
  214. package/domain/seed/src/lib/axp-entity-to-definition.converter.js +64 -0
  215. package/domain/seed/src/lib/axp-entity-to-definition.converter.js.map +1 -0
  216. package/domain/seed/src/lib/category-companion-entity.builder.d.ts +30 -0
  217. package/domain/seed/src/lib/category-companion-entity.builder.js +178 -0
  218. package/domain/seed/src/lib/category-companion-entity.builder.js.map +1 -0
  219. package/domain/seed/src/lib/collect-entity-factories.util.d.ts +7 -0
  220. package/domain/seed/src/lib/collect-entity-factories.util.js +25 -0
  221. package/domain/seed/src/lib/collect-entity-factories.util.js.map +1 -0
  222. package/domain/seed/src/lib/domain-definition-seed.provider.d.ts +13 -0
  223. package/domain/seed/src/lib/domain-definition-seed.provider.js +75 -0
  224. package/domain/seed/src/lib/domain-definition-seed.provider.js.map +1 -0
  225. package/domain/seed/src/lib/domain-seed.types.d.ts +8 -0
  226. package/domain/seed/src/lib/domain-seed.types.js +4 -0
  227. package/domain/seed/src/lib/domain-seed.types.js.map +1 -0
  228. package/file-storage/abstract/package.json +15 -0
  229. package/file-storage/abstract/src/index.d.ts +5 -0
  230. package/file-storage/abstract/src/index.js +9 -0
  231. package/file-storage/abstract/src/index.js.map +1 -0
  232. package/file-storage/abstract/src/lib/file-storage-backend.interface.d.ts +12 -0
  233. package/file-storage/abstract/src/lib/file-storage-backend.interface.js +4 -0
  234. package/file-storage/abstract/src/lib/file-storage-backend.interface.js.map +1 -0
  235. package/file-storage/abstract/src/lib/file-storage-engine.interface.d.ts +14 -0
  236. package/file-storage/abstract/src/lib/file-storage-engine.interface.js +5 -0
  237. package/file-storage/abstract/src/lib/file-storage-engine.interface.js.map +1 -0
  238. package/file-storage/abstract/src/lib/file-storage.mapper.d.ts +8 -0
  239. package/file-storage/abstract/src/lib/file-storage.mapper.js +54 -0
  240. package/file-storage/abstract/src/lib/file-storage.mapper.js.map +1 -0
  241. package/file-storage/abstract/src/lib/file-storage.tokens.d.ts +10 -0
  242. package/file-storage/abstract/src/lib/file-storage.tokens.js +16 -0
  243. package/file-storage/abstract/src/lib/file-storage.tokens.js.map +1 -0
  244. package/file-storage/abstract/src/lib/file-storage.types.d.ts +86 -0
  245. package/file-storage/abstract/src/lib/file-storage.types.js +4 -0
  246. package/file-storage/abstract/src/lib/file-storage.types.js.map +1 -0
  247. package/file-storage/database/package.json +17 -0
  248. package/file-storage/database/src/index.d.ts +3 -0
  249. package/file-storage/database/src/index.js +7 -0
  250. package/file-storage/database/src/index.js.map +1 -0
  251. package/file-storage/database/src/lib/database-file-storage-engine.module.d.ts +2 -0
  252. package/file-storage/database/src/lib/database-file-storage-engine.module.js +18 -0
  253. package/file-storage/database/src/lib/database-file-storage-engine.module.js.map +1 -0
  254. package/file-storage/database/src/lib/file-binary-blob-jql-source.d.ts +5 -0
  255. package/file-storage/database/src/lib/file-binary-blob-jql-source.js +40 -0
  256. package/file-storage/database/src/lib/file-binary-blob-jql-source.js.map +1 -0
  257. package/file-storage/database/src/lib/jql-binary-file-storage.engine.d.ts +13 -0
  258. package/file-storage/database/src/lib/jql-binary-file-storage.engine.js +59 -0
  259. package/file-storage/database/src/lib/jql-binary-file-storage.engine.js.map +1 -0
  260. package/file-storage/domain/package.json +14 -0
  261. package/file-storage/domain/src/index.d.ts +1 -0
  262. package/file-storage/domain/src/index.js +5 -0
  263. package/file-storage/domain/src/index.js.map +1 -0
  264. package/file-storage/domain/src/lib/contracts/root-config.d.ts +21 -0
  265. package/file-storage/domain/src/lib/contracts/root-config.js +26 -0
  266. package/file-storage/domain/src/lib/contracts/root-config.js.map +1 -0
  267. package/file-storage/domain/src/lib/file/file.entity.d.ts +2 -0
  268. package/file-storage/domain/src/lib/file/file.entity.js +145 -0
  269. package/file-storage/domain/src/lib/file/file.entity.js.map +1 -0
  270. package/file-storage/domain/src/lib/file/index.d.ts +1 -0
  271. package/file-storage/domain/src/lib/file/index.js +5 -0
  272. package/file-storage/domain/src/lib/file/index.js.map +1 -0
  273. package/file-storage/domain/src/lib/index.d.ts +2 -0
  274. package/file-storage/domain/src/lib/index.js +6 -0
  275. package/file-storage/domain/src/lib/index.js.map +1 -0
  276. package/file-storage/entity/package.json +19 -0
  277. package/file-storage/entity/src/index.d.ts +7 -0
  278. package/file-storage/entity/src/index.js +11 -0
  279. package/file-storage/entity/src/index.js.map +1 -0
  280. package/file-storage/entity/src/lib/entity-file-storage.module.d.ts +2 -0
  281. package/file-storage/entity/src/lib/entity-file-storage.module.js +19 -0
  282. package/file-storage/entity/src/lib/entity-file-storage.module.js.map +1 -0
  283. package/file-storage/entity/src/lib/file-entity-jql-source.d.ts +6 -0
  284. package/file-storage/entity/src/lib/file-entity-jql-source.js +55 -0
  285. package/file-storage/entity/src/lib/file-entity-jql-source.js.map +1 -0
  286. package/file-storage/entity/src/lib/file-entity.mapper.d.ts +3 -0
  287. package/file-storage/entity/src/lib/file-entity.mapper.js +52 -0
  288. package/file-storage/entity/src/lib/file-entity.mapper.js.map +1 -0
  289. package/file-storage/entity/src/lib/file-entity.repository.d.ts +15 -0
  290. package/file-storage/entity/src/lib/file-entity.repository.js +105 -0
  291. package/file-storage/entity/src/lib/file-entity.repository.js.map +1 -0
  292. package/file-storage/entity/src/lib/file-metadata.service.d.ts +15 -0
  293. package/file-storage/entity/src/lib/file-metadata.service.js +47 -0
  294. package/file-storage/entity/src/lib/file-metadata.service.js.map +1 -0
  295. package/file-storage/entity/src/lib/file-storage-engine.registry.d.ts +10 -0
  296. package/file-storage/entity/src/lib/file-storage-engine.registry.js +42 -0
  297. package/file-storage/entity/src/lib/file-storage-engine.registry.js.map +1 -0
  298. package/file-storage/entity/src/lib/file-storage-infrastructure.service.d.ts +24 -0
  299. package/file-storage/entity/src/lib/file-storage-infrastructure.service.js +145 -0
  300. package/file-storage/entity/src/lib/file-storage-infrastructure.service.js.map +1 -0
  301. package/file-storage/http/package.json +18 -0
  302. package/file-storage/http/src/index.d.ts +3 -0
  303. package/file-storage/http/src/index.js +7 -0
  304. package/file-storage/http/src/index.js.map +1 -0
  305. package/file-storage/http/src/lib/file-storage-facade.service.d.ts +37 -0
  306. package/file-storage/http/src/lib/file-storage-facade.service.js +58 -0
  307. package/file-storage/http/src/lib/file-storage-facade.service.js.map +1 -0
  308. package/file-storage/http/src/lib/file-storage-http.module.d.ts +2 -0
  309. package/file-storage/http/src/lib/file-storage-http.module.js +20 -0
  310. package/file-storage/http/src/lib/file-storage-http.module.js.map +1 -0
  311. package/file-storage/http/src/lib/file-storage.controller.d.ts +25 -0
  312. package/file-storage/http/src/lib/file-storage.controller.js +188 -0
  313. package/file-storage/http/src/lib/file-storage.controller.js.map +1 -0
  314. package/file-storage/local/package.json +16 -0
  315. package/file-storage/local/src/index.d.ts +4 -0
  316. package/file-storage/local/src/index.js +8 -0
  317. package/file-storage/local/src/index.js.map +1 -0
  318. package/file-storage/local/src/lib/filename.util.d.ts +14 -0
  319. package/file-storage/local/src/lib/filename.util.js +71 -0
  320. package/file-storage/local/src/lib/filename.util.js.map +1 -0
  321. package/file-storage/local/src/lib/local-disk-file-storage.engine.d.ts +9 -0
  322. package/file-storage/local/src/lib/local-disk-file-storage.engine.js +49 -0
  323. package/file-storage/local/src/lib/local-disk-file-storage.engine.js.map +1 -0
  324. package/file-storage/local/src/lib/local-file-storage-engine.module.d.ts +2 -0
  325. package/file-storage/local/src/lib/local-file-storage-engine.module.js +18 -0
  326. package/file-storage/local/src/lib/local-file-storage-engine.module.js.map +1 -0
  327. package/file-storage/local/src/lib/local-file-storage.config.d.ts +1 -0
  328. package/file-storage/local/src/lib/local-file-storage.config.js +10 -0
  329. package/file-storage/local/src/lib/local-file-storage.config.js.map +1 -0
  330. package/file-storage/providers/package.json +21 -0
  331. package/file-storage/providers/src/index.d.ts +5 -0
  332. package/file-storage/providers/src/index.js +8 -0
  333. package/file-storage/providers/src/index.js.map +1 -0
  334. package/file-storage/providers/src/lib/file-storage-jql-instance.resolve.d.ts +5 -0
  335. package/file-storage/providers/src/lib/file-storage-jql-instance.resolve.js +16 -0
  336. package/file-storage/providers/src/lib/file-storage-jql-instance.resolve.js.map +1 -0
  337. package/file-storage/providers/src/lib/file-storage-provider.module.d.ts +8 -0
  338. package/file-storage/providers/src/lib/file-storage-provider.module.js +70 -0
  339. package/file-storage/providers/src/lib/file-storage-provider.module.js.map +1 -0
  340. package/file-storage/providers/src/lib/file-storage-provider.resolve.d.ts +5 -0
  341. package/file-storage/providers/src/lib/file-storage-provider.resolve.js +20 -0
  342. package/file-storage/providers/src/lib/file-storage-provider.resolve.js.map +1 -0
  343. package/file-storage/providers/src/lib/file-storage-provider.types.d.ts +1 -0
  344. package/file-storage/providers/src/lib/file-storage-provider.types.js +5 -0
  345. package/file-storage/providers/src/lib/file-storage-provider.types.js.map +1 -0
  346. package/identifier/package.json +17 -0
  347. package/identifier/src/index.d.ts +5 -0
  348. package/identifier/src/index.js +9 -0
  349. package/identifier/src/index.js.map +1 -0
  350. package/identifier/src/lib/identifier-engine.service.d.ts +26 -0
  351. package/identifier/src/lib/identifier-engine.service.js +198 -0
  352. package/identifier/src/lib/identifier-engine.service.js.map +1 -0
  353. package/identifier/src/lib/identifier-rule.registry.d.ts +17 -0
  354. package/identifier/src/lib/identifier-rule.registry.js +84 -0
  355. package/identifier/src/lib/identifier-rule.registry.js.map +1 -0
  356. package/identifier/src/lib/identifier-sequence.store.d.ts +24 -0
  357. package/identifier/src/lib/identifier-sequence.store.js +40 -0
  358. package/identifier/src/lib/identifier-sequence.store.js.map +1 -0
  359. package/identifier/src/lib/identifier.module.d.ts +5 -0
  360. package/identifier/src/lib/identifier.module.js +58 -0
  361. package/identifier/src/lib/identifier.module.js.map +1 -0
  362. package/identifier/src/lib/identifier.providers.d.ts +25 -0
  363. package/identifier/src/lib/identifier.providers.js +108 -0
  364. package/identifier/src/lib/identifier.providers.js.map +1 -0
  365. package/identifier/src/lib/identifier.types.d.ts +31 -0
  366. package/identifier/src/lib/identifier.types.js +5 -0
  367. package/identifier/src/lib/identifier.types.js.map +1 -0
  368. package/identifier/src/lib/pattern-engine.d.ts +20 -0
  369. package/identifier/src/lib/pattern-engine.js +70 -0
  370. package/identifier/src/lib/pattern-engine.js.map +1 -0
  371. package/identifier/src/lib/token-registry.service.d.ts +8 -0
  372. package/identifier/src/lib/token-registry.service.js +27 -0
  373. package/identifier/src/lib/token-registry.service.js.map +1 -0
  374. package/identifier/src/lib/tokens-default.d.ts +33 -0
  375. package/identifier/src/lib/tokens-default.js +99 -0
  376. package/identifier/src/lib/tokens-default.js.map +1 -0
  377. package/identifier/src/lib/tokens.types.d.ts +54 -0
  378. package/identifier/src/lib/tokens.types.js +8 -0
  379. package/identifier/src/lib/tokens.types.js.map +1 -0
  380. package/identifier/src/lib/utils.d.ts +2 -0
  381. package/identifier/src/lib/utils.js +17 -0
  382. package/identifier/src/lib/utils.js.map +1 -0
  383. package/jql/abstract/package.json +14 -0
  384. package/jql/abstract/src/index.d.ts +26 -0
  385. package/jql/abstract/src/index.js +30 -0
  386. package/jql/abstract/src/index.js.map +1 -0
  387. package/jql/abstract/src/lib/entity-schema/entity-schema-naming.util.d.ts +6 -0
  388. package/jql/abstract/src/lib/entity-schema/entity-schema-naming.util.js +31 -0
  389. package/jql/abstract/src/lib/entity-schema/entity-schema-naming.util.js.map +1 -0
  390. package/jql/abstract/src/lib/entity-schema/entity-storage-source.util.d.ts +2 -0
  391. package/jql/abstract/src/lib/entity-schema/entity-storage-source.util.js +26 -0
  392. package/jql/abstract/src/lib/entity-schema/entity-storage-source.util.js.map +1 -0
  393. package/jql/abstract/src/lib/entity-schema/jql-entity-schema-not-found.error.d.ts +3 -0
  394. package/jql/abstract/src/lib/entity-schema/jql-entity-schema-not-found.error.js +13 -0
  395. package/jql/abstract/src/lib/entity-schema/jql-entity-schema-not-found.error.js.map +1 -0
  396. package/jql/abstract/src/lib/entity-schema/jql-entity-schema.types.d.ts +35 -0
  397. package/jql/abstract/src/lib/entity-schema/jql-entity-schema.types.js +5 -0
  398. package/jql/abstract/src/lib/entity-schema/jql-entity-schema.types.js.map +1 -0
  399. package/jql/abstract/src/lib/entity-store/category-hierarchy-filter.util.d.ts +37 -0
  400. package/jql/abstract/src/lib/entity-store/category-hierarchy-filter.util.js +138 -0
  401. package/jql/abstract/src/lib/entity-store/category-hierarchy-filter.util.js.map +1 -0
  402. package/jql/abstract/src/lib/entity-store/entity-fulltext-search-paths.util.d.ts +25 -0
  403. package/jql/abstract/src/lib/entity-store/entity-fulltext-search-paths.util.js +128 -0
  404. package/jql/abstract/src/lib/entity-store/entity-fulltext-search-paths.util.js.map +1 -0
  405. package/jql/abstract/src/lib/entity-store/entity-fulltext-search.util.d.ts +44 -0
  406. package/jql/abstract/src/lib/entity-store/entity-fulltext-search.util.js +193 -0
  407. package/jql/abstract/src/lib/entity-store/entity-fulltext-search.util.js.map +1 -0
  408. package/jql/abstract/src/lib/entity-store/entity-store-aggregate.util.d.ts +6 -0
  409. package/jql/abstract/src/lib/entity-store/entity-store-aggregate.util.js +45 -0
  410. package/jql/abstract/src/lib/entity-store/entity-store-aggregate.util.js.map +1 -0
  411. package/jql/abstract/src/lib/entity-store/entity-store-backend.interface.d.ts +16 -0
  412. package/jql/abstract/src/lib/entity-store/entity-store-backend.interface.js +4 -0
  413. package/jql/abstract/src/lib/entity-store/entity-store-backend.interface.js.map +1 -0
  414. package/jql/abstract/src/lib/entity-store/entity-store-initial.types.d.ts +6 -0
  415. package/jql/abstract/src/lib/entity-store/entity-store-initial.types.js +5 -0
  416. package/jql/abstract/src/lib/entity-store/entity-store-initial.types.js.map +1 -0
  417. package/jql/abstract/src/lib/entity-store/entity-store-request.util.d.ts +18 -0
  418. package/jql/abstract/src/lib/entity-store/entity-store-request.util.js +144 -0
  419. package/jql/abstract/src/lib/entity-store/entity-store-request.util.js.map +1 -0
  420. package/jql/abstract/src/lib/entity-store/entity-store.service.d.ts +34 -0
  421. package/jql/abstract/src/lib/entity-store/entity-store.service.js +181 -0
  422. package/jql/abstract/src/lib/entity-store/entity-store.service.js.map +1 -0
  423. package/jql/abstract/src/lib/entity-store/entity-store.tokens.d.ts +6 -0
  424. package/jql/abstract/src/lib/entity-store/entity-store.tokens.js +12 -0
  425. package/jql/abstract/src/lib/entity-store/entity-store.tokens.js.map +1 -0
  426. package/jql/abstract/src/lib/entity-store/entity-store.types.d.ts +20 -0
  427. package/jql/abstract/src/lib/entity-store/entity-store.types.js +5 -0
  428. package/jql/abstract/src/lib/entity-store/entity-store.types.js.map +1 -0
  429. package/jql/abstract/src/lib/entity-store/entity-visibility-filter.util.d.ts +22 -0
  430. package/jql/abstract/src/lib/entity-store/entity-visibility-filter.util.js +99 -0
  431. package/jql/abstract/src/lib/entity-store/entity-visibility-filter.util.js.map +1 -0
  432. package/jql/abstract/src/lib/entity-store/json-store-record-id.util.d.ts +2 -0
  433. package/jql/abstract/src/lib/entity-store/json-store-record-id.util.js +23 -0
  434. package/jql/abstract/src/lib/entity-store/json-store-record-id.util.js.map +1 -0
  435. package/jql/abstract/src/lib/jql-engine.base.d.ts +43 -0
  436. package/jql/abstract/src/lib/jql-engine.base.js +79 -0
  437. package/jql/abstract/src/lib/jql-engine.base.js.map +1 -0
  438. package/jql/abstract/src/lib/jql-engine.interface.d.ts +20 -0
  439. package/jql/abstract/src/lib/jql-engine.interface.js +4 -0
  440. package/jql/abstract/src/lib/jql-engine.interface.js.map +1 -0
  441. package/jql/abstract/src/lib/jql-filter.util.d.ts +5 -0
  442. package/jql/abstract/src/lib/jql-filter.util.js +37 -0
  443. package/jql/abstract/src/lib/jql-filter.util.js.map +1 -0
  444. package/jql/abstract/src/lib/jql-operator.util.d.ts +3 -0
  445. package/jql/abstract/src/lib/jql-operator.util.js +39 -0
  446. package/jql/abstract/src/lib/jql-operator.util.js.map +1 -0
  447. package/jql/abstract/src/lib/jql-source-registry.d.ts +10 -0
  448. package/jql/abstract/src/lib/jql-source-registry.js +41 -0
  449. package/jql/abstract/src/lib/jql-source-registry.js.map +1 -0
  450. package/jql/abstract/src/lib/jql-source.types.d.ts +35 -0
  451. package/jql/abstract/src/lib/jql-source.types.js +5 -0
  452. package/jql/abstract/src/lib/jql-source.types.js.map +1 -0
  453. package/jql/abstract/src/lib/jql.tokens.d.ts +10 -0
  454. package/jql/abstract/src/lib/jql.tokens.js +22 -0
  455. package/jql/abstract/src/lib/jql.tokens.js.map +1 -0
  456. package/jql/abstract/src/lib/jql.types.d.ts +64 -0
  457. package/jql/abstract/src/lib/jql.types.js +11 -0
  458. package/jql/abstract/src/lib/jql.types.js.map +1 -0
  459. package/jql/abstract/src/lib/odata/odata-query.parser.d.ts +15 -0
  460. package/jql/abstract/src/lib/odata/odata-query.parser.js +318 -0
  461. package/jql/abstract/src/lib/odata/odata-query.parser.js.map +1 -0
  462. package/jql/abstract/src/lib/odata/odata-query.types.d.ts +21 -0
  463. package/jql/abstract/src/lib/odata/odata-query.types.js +4 -0
  464. package/jql/abstract/src/lib/odata/odata-query.types.js.map +1 -0
  465. package/jql/json/package.json +15 -0
  466. package/jql/json/src/index.d.ts +4 -0
  467. package/jql/json/src/index.js +8 -0
  468. package/jql/json/src/index.js.map +1 -0
  469. package/jql/json/src/lib/jql-json.config.d.ts +6 -0
  470. package/jql/json/src/lib/jql-json.config.js +20 -0
  471. package/jql/json/src/lib/jql-json.config.js.map +1 -0
  472. package/jql/json/src/lib/jql-json.engine.d.ts +22 -0
  473. package/jql/json/src/lib/jql-json.engine.js +187 -0
  474. package/jql/json/src/lib/jql-json.engine.js.map +1 -0
  475. package/jql/json/src/lib/jql-json.filter.d.ts +2 -0
  476. package/jql/json/src/lib/jql-json.filter.js +175 -0
  477. package/jql/json/src/lib/jql-json.filter.js.map +1 -0
  478. package/jql/json/src/lib/jql-json.module.d.ts +6 -0
  479. package/jql/json/src/lib/jql-json.module.js +49 -0
  480. package/jql/json/src/lib/jql-json.module.js.map +1 -0
  481. package/jql/mongodb/package.json +17 -0
  482. package/jql/mongodb/src/index.d.ts +5 -0
  483. package/jql/mongodb/src/index.js +9 -0
  484. package/jql/mongodb/src/index.js.map +1 -0
  485. package/jql/mongodb/src/lib/compile/filter-compiler.d.ts +3 -0
  486. package/jql/mongodb/src/lib/compile/filter-compiler.js +70 -0
  487. package/jql/mongodb/src/lib/compile/filter-compiler.js.map +1 -0
  488. package/jql/mongodb/src/lib/compile/sort-builder.d.ts +3 -0
  489. package/jql/mongodb/src/lib/compile/sort-builder.js +16 -0
  490. package/jql/mongodb/src/lib/compile/sort-builder.js.map +1 -0
  491. package/jql/mongodb/src/lib/document-mapper.d.ts +3 -0
  492. package/jql/mongodb/src/lib/document-mapper.js +14 -0
  493. package/jql/mongodb/src/lib/document-mapper.js.map +1 -0
  494. package/jql/mongodb/src/lib/jql-mongodb.config.d.ts +5 -0
  495. package/jql/mongodb/src/lib/jql-mongodb.config.js +10 -0
  496. package/jql/mongodb/src/lib/jql-mongodb.config.js.map +1 -0
  497. package/jql/mongodb/src/lib/jql-mongodb.engine.d.ts +33 -0
  498. package/jql/mongodb/src/lib/jql-mongodb.engine.js +259 -0
  499. package/jql/mongodb/src/lib/jql-mongodb.engine.js.map +1 -0
  500. package/jql/mongodb/src/lib/jql-mongodb.module.d.ts +7 -0
  501. package/jql/mongodb/src/lib/jql-mongodb.module.js +58 -0
  502. package/jql/mongodb/src/lib/jql-mongodb.module.js.map +1 -0
  503. package/jql/mongodb/src/lib/jql-mongodb.tokens.d.ts +1 -0
  504. package/jql/mongodb/src/lib/jql-mongodb.tokens.js +7 -0
  505. package/jql/mongodb/src/lib/jql-mongodb.tokens.js.map +1 -0
  506. package/jql/postgres/package.json +17 -0
  507. package/jql/postgres/src/index.d.ts +5 -0
  508. package/jql/postgres/src/index.js +9 -0
  509. package/jql/postgres/src/index.js.map +1 -0
  510. package/jql/postgres/src/lib/compile/aggregate-builder.d.ts +5 -0
  511. package/jql/postgres/src/lib/compile/aggregate-builder.js +48 -0
  512. package/jql/postgres/src/lib/compile/aggregate-builder.js.map +1 -0
  513. package/jql/postgres/src/lib/compile/field-resolver.d.ts +4 -0
  514. package/jql/postgres/src/lib/compile/field-resolver.js +66 -0
  515. package/jql/postgres/src/lib/compile/field-resolver.js.map +1 -0
  516. package/jql/postgres/src/lib/compile/filter-compiler.d.ts +7 -0
  517. package/jql/postgres/src/lib/compile/filter-compiler.js +129 -0
  518. package/jql/postgres/src/lib/compile/filter-compiler.js.map +1 -0
  519. package/jql/postgres/src/lib/compile/pg-placeholders.util.d.ts +4 -0
  520. package/jql/postgres/src/lib/compile/pg-placeholders.util.js +16 -0
  521. package/jql/postgres/src/lib/compile/pg-placeholders.util.js.map +1 -0
  522. package/jql/postgres/src/lib/compile/query-builder.d.ts +7 -0
  523. package/jql/postgres/src/lib/compile/query-builder.js +58 -0
  524. package/jql/postgres/src/lib/compile/query-builder.js.map +1 -0
  525. package/jql/postgres/src/lib/compile/sql-where.types.d.ts +8 -0
  526. package/jql/postgres/src/lib/compile/sql-where.types.js +5 -0
  527. package/jql/postgres/src/lib/compile/sql-where.types.js.map +1 -0
  528. package/jql/postgres/src/lib/document-mapper.d.ts +2 -0
  529. package/jql/postgres/src/lib/document-mapper.js +21 -0
  530. package/jql/postgres/src/lib/document-mapper.js.map +1 -0
  531. package/jql/postgres/src/lib/jql-postgres.config.d.ts +5 -0
  532. package/jql/postgres/src/lib/jql-postgres.config.js +10 -0
  533. package/jql/postgres/src/lib/jql-postgres.config.js.map +1 -0
  534. package/jql/postgres/src/lib/jql-postgres.engine.d.ts +32 -0
  535. package/jql/postgres/src/lib/jql-postgres.engine.js +286 -0
  536. package/jql/postgres/src/lib/jql-postgres.engine.js.map +1 -0
  537. package/jql/postgres/src/lib/jql-postgres.module.d.ts +7 -0
  538. package/jql/postgres/src/lib/jql-postgres.module.js +61 -0
  539. package/jql/postgres/src/lib/jql-postgres.module.js.map +1 -0
  540. package/jql/postgres/src/lib/jql-postgres.tokens.d.ts +1 -0
  541. package/jql/postgres/src/lib/jql-postgres.tokens.js +7 -0
  542. package/jql/postgres/src/lib/jql-postgres.tokens.js.map +1 -0
  543. package/jql/postgres/src/lib/postgres-connection.util.d.ts +5 -0
  544. package/jql/postgres/src/lib/postgres-connection.util.js +18 -0
  545. package/jql/postgres/src/lib/postgres-connection.util.js.map +1 -0
  546. package/jql/postgres/src/lib/structured-document-mapper.d.ts +6 -0
  547. package/jql/postgres/src/lib/structured-document-mapper.js +84 -0
  548. package/jql/postgres/src/lib/structured-document-mapper.js.map +1 -0
  549. package/jql/providers/package.json +20 -0
  550. package/jql/providers/src/index.d.ts +8 -0
  551. package/jql/providers/src/index.js +11 -0
  552. package/jql/providers/src/index.js.map +1 -0
  553. package/jql/providers/src/lib/entity-storage-instance.resolve.d.ts +5 -0
  554. package/jql/providers/src/lib/entity-storage-instance.resolve.js +16 -0
  555. package/jql/providers/src/lib/entity-storage-instance.resolve.js.map +1 -0
  556. package/jql/providers/src/lib/jql-entity-store.config.d.ts +6 -0
  557. package/jql/providers/src/lib/jql-entity-store.config.js +17 -0
  558. package/jql/providers/src/lib/jql-entity-store.config.js.map +1 -0
  559. package/jql/providers/src/lib/jql-instance-db.resolve.d.ts +6 -0
  560. package/jql/providers/src/lib/jql-instance-db.resolve.js +21 -0
  561. package/jql/providers/src/lib/jql-instance-db.resolve.js.map +1 -0
  562. package/jql/providers/src/lib/jql-instance.types.d.ts +12 -0
  563. package/jql/providers/src/lib/jql-instance.types.js +5 -0
  564. package/jql/providers/src/lib/jql-instance.types.js.map +1 -0
  565. package/jql/providers/src/lib/jql-provider.module.d.ts +8 -0
  566. package/jql/providers/src/lib/jql-provider.module.js +54 -0
  567. package/jql/providers/src/lib/jql-provider.module.js.map +1 -0
  568. package/jql/providers/src/lib/jql-provider.resolve.d.ts +5 -0
  569. package/jql/providers/src/lib/jql-provider.resolve.js +26 -0
  570. package/jql/providers/src/lib/jql-provider.resolve.js.map +1 -0
  571. package/jql/providers/src/lib/jql-provider.types.d.ts +1 -0
  572. package/jql/providers/src/lib/jql-provider.types.js +5 -0
  573. package/jql/providers/src/lib/jql-provider.types.js.map +1 -0
  574. package/jql/providers/src/lib/jql.module.d.ts +6 -0
  575. package/jql/providers/src/lib/jql.module.js +134 -0
  576. package/jql/providers/src/lib/jql.module.js.map +1 -0
  577. package/jql/schema/package.json +18 -0
  578. package/jql/schema/src/index.d.ts +9 -0
  579. package/jql/schema/src/index.js +13 -0
  580. package/jql/schema/src/index.js.map +1 -0
  581. package/jql/schema/src/lib/domain-data-type.mapper.d.ts +6 -0
  582. package/jql/schema/src/lib/domain-data-type.mapper.js +54 -0
  583. package/jql/schema/src/lib/domain-data-type.mapper.js.map +1 -0
  584. package/jql/schema/src/lib/entity-schema-builder.d.ts +14 -0
  585. package/jql/schema/src/lib/entity-schema-builder.js +147 -0
  586. package/jql/schema/src/lib/entity-schema-builder.js.map +1 -0
  587. package/jql/schema/src/lib/entity-schema-jql-source.factory.d.ts +5 -0
  588. package/jql/schema/src/lib/entity-schema-jql-source.factory.js +75 -0
  589. package/jql/schema/src/lib/entity-schema-jql-source.factory.js.map +1 -0
  590. package/jql/schema/src/lib/jql-auto-migrator.d.ts +17 -0
  591. package/jql/schema/src/lib/jql-auto-migrator.js +106 -0
  592. package/jql/schema/src/lib/jql-auto-migrator.js.map +1 -0
  593. package/jql/schema/src/lib/jql-schema-history.hydrator.d.ts +4 -0
  594. package/jql/schema/src/lib/jql-schema-history.hydrator.js +113 -0
  595. package/jql/schema/src/lib/jql-schema-history.hydrator.js.map +1 -0
  596. package/jql/schema/src/lib/jql-schema-registry.service.d.ts +8 -0
  597. package/jql/schema/src/lib/jql-schema-registry.service.js +29 -0
  598. package/jql/schema/src/lib/jql-schema-registry.service.js.map +1 -0
  599. package/jql/schema/src/lib/jql-schema.controller.d.ts +14 -0
  600. package/jql/schema/src/lib/jql-schema.controller.js +28 -0
  601. package/jql/schema/src/lib/jql-schema.controller.js.map +1 -0
  602. package/jql/schema/src/lib/jql-schema.module.d.ts +4 -0
  603. package/jql/schema/src/lib/jql-schema.module.js +35 -0
  604. package/jql/schema/src/lib/jql-schema.module.js.map +1 -0
  605. package/jql/schema/src/lib/jql-schema.service.d.ts +30 -0
  606. package/jql/schema/src/lib/jql-schema.service.js +121 -0
  607. package/jql/schema/src/lib/jql-schema.service.js.map +1 -0
  608. package/jql/seed/package.json +18 -0
  609. package/jql/seed/src/index.d.ts +13 -0
  610. package/jql/seed/src/index.js +17 -0
  611. package/jql/seed/src/index.js.map +1 -0
  612. package/jql/seed/src/lib/entity-data-seed.provider.d.ts +14 -0
  613. package/jql/seed/src/lib/entity-data-seed.provider.js +45 -0
  614. package/jql/seed/src/lib/entity-data-seed.provider.js.map +1 -0
  615. package/jql/seed/src/lib/entity-seed-storage.adapter.d.ts +3 -0
  616. package/jql/seed/src/lib/entity-seed-storage.adapter.js +25 -0
  617. package/jql/seed/src/lib/entity-seed-storage.adapter.js.map +1 -0
  618. package/jql/seed/src/lib/jql-auto-seed.resolve.d.ts +4 -0
  619. package/jql/seed/src/lib/jql-auto-seed.resolve.js +13 -0
  620. package/jql/seed/src/lib/jql-auto-seed.resolve.js.map +1 -0
  621. package/jql/seed/src/lib/jql-auto-seed.service.d.ts +8 -0
  622. package/jql/seed/src/lib/jql-auto-seed.service.js +29 -0
  623. package/jql/seed/src/lib/jql-auto-seed.service.js.map +1 -0
  624. package/jql/seed/src/lib/jql-engine-registry.service.d.ts +7 -0
  625. package/jql/seed/src/lib/jql-engine-registry.service.js +31 -0
  626. package/jql/seed/src/lib/jql-engine-registry.service.js.map +1 -0
  627. package/jql/seed/src/lib/jql-multi-seed-runner.service.d.ts +11 -0
  628. package/jql/seed/src/lib/jql-multi-seed-runner.service.js +56 -0
  629. package/jql/seed/src/lib/jql-multi-seed-runner.service.js.map +1 -0
  630. package/jql/seed/src/lib/jql-seed-phase.resolve.d.ts +10 -0
  631. package/jql/seed/src/lib/jql-seed-phase.resolve.js +36 -0
  632. package/jql/seed/src/lib/jql-seed-phase.resolve.js.map +1 -0
  633. package/jql/seed/src/lib/jql-seed-provider.interface.d.ts +10 -0
  634. package/jql/seed/src/lib/jql-seed-provider.interface.js +4 -0
  635. package/jql/seed/src/lib/jql-seed-provider.interface.js.map +1 -0
  636. package/jql/seed/src/lib/jql-seed-runner.service.d.ts +19 -0
  637. package/jql/seed/src/lib/jql-seed-runner.service.js +50 -0
  638. package/jql/seed/src/lib/jql-seed-runner.service.js.map +1 -0
  639. package/jql/seed/src/lib/jql-seed-target.types.d.ts +28 -0
  640. package/jql/seed/src/lib/jql-seed-target.types.js +4 -0
  641. package/jql/seed/src/lib/jql-seed-target.types.js.map +1 -0
  642. package/jql/seed/src/lib/jql-seed.module.d.ts +14 -0
  643. package/jql/seed/src/lib/jql-seed.module.js +68 -0
  644. package/jql/seed/src/lib/jql-seed.module.js.map +1 -0
  645. package/jql/seed/src/lib/jql-seed.tokens.d.ts +5 -0
  646. package/jql/seed/src/lib/jql-seed.tokens.js +11 -0
  647. package/jql/seed/src/lib/jql-seed.tokens.js.map +1 -0
  648. package/jql/seed/src/lib/jql-store-seed.writer.d.ts +11 -0
  649. package/jql/seed/src/lib/jql-store-seed.writer.js +55 -0
  650. package/jql/seed/src/lib/jql-store-seed.writer.js.map +1 -0
  651. package/jql/sqlite/package.json +17 -0
  652. package/jql/sqlite/src/index.d.ts +3 -0
  653. package/jql/sqlite/src/index.js +7 -0
  654. package/jql/sqlite/src/index.js.map +1 -0
  655. package/jql/sqlite/src/lib/jql-sqlite.config.d.ts +6 -0
  656. package/jql/sqlite/src/lib/jql-sqlite.config.js +18 -0
  657. package/jql/sqlite/src/lib/jql-sqlite.config.js.map +1 -0
  658. package/jql/sqlite/src/lib/jql-sqlite.engine.d.ts +29 -0
  659. package/jql/sqlite/src/lib/jql-sqlite.engine.js +237 -0
  660. package/jql/sqlite/src/lib/jql-sqlite.engine.js.map +1 -0
  661. package/jql/sqlite/src/lib/jql-sqlite.module.d.ts +7 -0
  662. package/jql/sqlite/src/lib/jql-sqlite.module.js +51 -0
  663. package/jql/sqlite/src/lib/jql-sqlite.module.js.map +1 -0
  664. package/package.json +108 -0
  665. package/report/package.json +17 -0
  666. package/report/src/index.d.ts +8 -0
  667. package/report/src/index.js +12 -0
  668. package/report/src/index.js.map +1 -0
  669. package/report/src/lib/report-definition.registry.d.ts +20 -0
  670. package/report/src/lib/report-definition.registry.js +134 -0
  671. package/report/src/lib/report-definition.registry.js.map +1 -0
  672. package/report/src/lib/report-execute.service.d.ts +14 -0
  673. package/report/src/lib/report-execute.service.js +115 -0
  674. package/report/src/lib/report-execute.service.js.map +1 -0
  675. package/report/src/lib/report-query.registry.d.ts +19 -0
  676. package/report/src/lib/report-query.registry.js +73 -0
  677. package/report/src/lib/report-query.registry.js.map +1 -0
  678. package/report/src/lib/report-result-normalizer.d.ts +6 -0
  679. package/report/src/lib/report-result-normalizer.js +108 -0
  680. package/report/src/lib/report-result-normalizer.js.map +1 -0
  681. package/report/src/lib/report-summary.util.d.ts +9 -0
  682. package/report/src/lib/report-summary.util.js +56 -0
  683. package/report/src/lib/report-summary.util.js.map +1 -0
  684. package/report/src/lib/report.decorators.d.ts +6 -0
  685. package/report/src/lib/report.decorators.js +15 -0
  686. package/report/src/lib/report.decorators.js.map +1 -0
  687. package/report/src/lib/report.module.d.ts +2 -0
  688. package/report/src/lib/report.module.js +32 -0
  689. package/report/src/lib/report.module.js.map +1 -0
  690. package/report/src/lib/report.types.d.ts +74 -0
  691. package/report/src/lib/report.types.js +10 -0
  692. package/report/src/lib/report.types.js.map +1 -0
  693. package/report/src/lib/report.util.d.ts +1 -0
  694. package/report/src/lib/report.util.js +19 -0
  695. package/report/src/lib/report.util.js.map +1 -0
  696. package/security/package.json +17 -0
  697. package/security/src/index.d.ts +13 -0
  698. package/security/src/index.js +17 -0
  699. package/security/src/index.js.map +1 -0
  700. package/security/src/lib/auth/auth.controller.d.ts +10 -0
  701. package/security/src/lib/auth/auth.controller.js +117 -0
  702. package/security/src/lib/auth/auth.controller.js.map +1 -0
  703. package/security/src/lib/auth/auth.service.d.ts +22 -0
  704. package/security/src/lib/auth/auth.service.js +238 -0
  705. package/security/src/lib/auth/auth.service.js.map +1 -0
  706. package/security/src/lib/auth/auth.types.d.ts +69 -0
  707. package/security/src/lib/auth/auth.types.js +5 -0
  708. package/security/src/lib/auth/auth.types.js.map +1 -0
  709. package/security/src/lib/auth/jwt-auth.guard.d.ts +14 -0
  710. package/security/src/lib/auth/jwt-auth.guard.js +68 -0
  711. package/security/src/lib/auth/jwt-auth.guard.js.map +1 -0
  712. package/security/src/lib/auth/public.decorator.d.ts +3 -0
  713. package/security/src/lib/auth/public.decorator.js +11 -0
  714. package/security/src/lib/auth/public.decorator.js.map +1 -0
  715. package/security/src/lib/authorization/platform-root-user.util.d.ts +18 -0
  716. package/security/src/lib/authorization/platform-root-user.util.js +51 -0
  717. package/security/src/lib/authorization/platform-root-user.util.js.map +1 -0
  718. package/security/src/lib/entity-storage/policy-enforce.middleware.d.ts +26 -0
  719. package/security/src/lib/entity-storage/policy-enforce.middleware.js +207 -0
  720. package/security/src/lib/entity-storage/policy-enforce.middleware.js.map +1 -0
  721. package/security/src/lib/entity-storage/policy-expression-evaluator.util.d.ts +7 -0
  722. package/security/src/lib/entity-storage/policy-expression-evaluator.util.js +70 -0
  723. package/security/src/lib/entity-storage/policy-expression-evaluator.util.js.map +1 -0
  724. package/security/src/lib/entity-storage/policy-field.util.d.ts +3 -0
  725. package/security/src/lib/entity-storage/policy-field.util.js +95 -0
  726. package/security/src/lib/entity-storage/policy-field.util.js.map +1 -0
  727. package/security/src/lib/entity-storage/visibility-filter.middleware.d.ts +29 -0
  728. package/security/src/lib/entity-storage/visibility-filter.middleware.js +84 -0
  729. package/security/src/lib/entity-storage/visibility-filter.middleware.js.map +1 -0
  730. package/security/src/lib/security.module.d.ts +8 -0
  731. package/security/src/lib/security.module.js +65 -0
  732. package/security/src/lib/security.module.js.map +1 -0
  733. package/security/src/lib/session/abp.controller.d.ts +9 -0
  734. package/security/src/lib/session/abp.controller.js +38 -0
  735. package/security/src/lib/session/abp.controller.js.map +1 -0
  736. package/security/src/lib/session/applications.controller.d.ts +9 -0
  737. package/security/src/lib/session/applications.controller.js +38 -0
  738. package/security/src/lib/session/applications.controller.js.map +1 -0
  739. package/security/src/lib/session/backend-session.service.d.ts +21 -0
  740. package/security/src/lib/session/backend-session.service.js +51 -0
  741. package/security/src/lib/session/backend-session.service.js.map +1 -0
  742. package/security/src/lib/session/backend-session.types.d.ts +7 -0
  743. package/security/src/lib/session/backend-session.types.js +5 -0
  744. package/security/src/lib/session/backend-session.types.js.map +1 -0
  745. package/security/src/lib/session/current-session.decorator.d.ts +2 -0
  746. package/security/src/lib/session/current-session.decorator.js +12 -0
  747. package/security/src/lib/session/current-session.decorator.js.map +1 -0
  748. package/security/src/lib/session/optional-jwt-session.middleware.d.ts +22 -0
  749. package/security/src/lib/session/optional-jwt-session.middleware.js +59 -0
  750. package/security/src/lib/session/optional-jwt-session.middleware.js.map +1 -0
  751. package/security/src/lib/session/session-context.service.d.ts +21 -0
  752. package/security/src/lib/session/session-context.service.js +204 -0
  753. package/security/src/lib/session/session-context.service.js.map +1 -0
  754. package/security/src/lib/session/session-context.types.d.ts +31 -0
  755. package/security/src/lib/session/session-context.types.js +5 -0
  756. package/security/src/lib/session/session-context.types.js.map +1 -0
  757. package/security/src/lib/session/tenants.controller.d.ts +9 -0
  758. package/security/src/lib/session/tenants.controller.js +38 -0
  759. package/security/src/lib/session/tenants.controller.js.map +1 -0
  760. package/swagger/package.json +18 -0
  761. package/swagger/src/index.d.ts +6 -0
  762. package/swagger/src/index.js +10 -0
  763. package/swagger/src/index.js.map +1 -0
  764. package/swagger/src/lib/entity-storage-swagger.module.d.ts +2 -0
  765. package/swagger/src/lib/entity-storage-swagger.module.js +18 -0
  766. package/swagger/src/lib/entity-storage-swagger.module.js.map +1 -0
  767. package/swagger/src/lib/entity-storage-swagger.service.d.ts +11 -0
  768. package/swagger/src/lib/entity-storage-swagger.service.js +189 -0
  769. package/swagger/src/lib/entity-storage-swagger.service.js.map +1 -0
  770. package/swagger/src/lib/swagger.helpers.d.ts +3 -0
  771. package/swagger/src/lib/swagger.helpers.js +14 -0
  772. package/swagger/src/lib/swagger.helpers.js.map +1 -0
  773. package/swagger/src/lib/swagger.setup.d.ts +11 -0
  774. package/swagger/src/lib/swagger.setup.js +77 -0
  775. package/swagger/src/lib/swagger.setup.js.map +1 -0
  776. package/swagger/src/lib/swagger.tokens.d.ts +1 -0
  777. package/swagger/src/lib/swagger.tokens.js +7 -0
  778. package/swagger/src/lib/swagger.tokens.js.map +1 -0
  779. package/swagger/src/lib/swagger.types.d.ts +29 -0
  780. package/swagger/src/lib/swagger.types.js +5 -0
  781. package/swagger/src/lib/swagger.types.js.map +1 -0
  782. package/swagger/src/lib/utils/openapi-schema.util.d.ts +4 -0
  783. package/swagger/src/lib/utils/openapi-schema.util.js +64 -0
  784. package/swagger/src/lib/utils/openapi-schema.util.js.map +1 -0
  785. package/workflow/package.json +20 -0
  786. package/workflow/src/index.d.ts +7 -0
  787. package/workflow/src/index.js +11 -0
  788. package/workflow/src/index.js.map +1 -0
  789. package/workflow/src/lib/activities/handlers/assign-to-manager.activity.d.ts +9 -0
  790. package/workflow/src/lib/activities/handlers/assign-to-manager.activity.js +164 -0
  791. package/workflow/src/lib/activities/handlers/assign-to-manager.activity.js.map +1 -0
  792. package/workflow/src/lib/activities/handlers/built-in.activities.d.ts +13 -0
  793. package/workflow/src/lib/activities/handlers/built-in.activities.js +166 -0
  794. package/workflow/src/lib/activities/handlers/built-in.activities.js.map +1 -0
  795. package/workflow/src/lib/activities/handlers/check-permission.activity.d.ts +8 -0
  796. package/workflow/src/lib/activities/handlers/check-permission.activity.js +36 -0
  797. package/workflow/src/lib/activities/handlers/check-permission.activity.js.map +1 -0
  798. package/workflow/src/lib/activities/handlers/distribution-record.activity.d.ts +5 -0
  799. package/workflow/src/lib/activities/handlers/distribution-record.activity.js +65 -0
  800. package/workflow/src/lib/activities/handlers/distribution-record.activity.js.map +1 -0
  801. package/workflow/src/lib/activities/handlers/entity-create.activity.d.ts +5 -0
  802. package/workflow/src/lib/activities/handlers/entity-create.activity.js +55 -0
  803. package/workflow/src/lib/activities/handlers/entity-create.activity.js.map +1 -0
  804. package/workflow/src/lib/activities/handlers/entity-delete.activity.d.ts +5 -0
  805. package/workflow/src/lib/activities/handlers/entity-delete.activity.js +48 -0
  806. package/workflow/src/lib/activities/handlers/entity-delete.activity.js.map +1 -0
  807. package/workflow/src/lib/activities/handlers/entity-read.activity.d.ts +5 -0
  808. package/workflow/src/lib/activities/handlers/entity-read.activity.js +54 -0
  809. package/workflow/src/lib/activities/handlers/entity-read.activity.js.map +1 -0
  810. package/workflow/src/lib/activities/handlers/entity-update.activity.d.ts +5 -0
  811. package/workflow/src/lib/activities/handlers/entity-update.activity.js +55 -0
  812. package/workflow/src/lib/activities/handlers/entity-update.activity.js.map +1 -0
  813. package/workflow/src/lib/activities/handlers/get-current-session-user.activity.d.ts +5 -0
  814. package/workflow/src/lib/activities/handlers/get-current-session-user.activity.js +24 -0
  815. package/workflow/src/lib/activities/handlers/get-current-session-user.activity.js.map +1 -0
  816. package/workflow/src/lib/activities/handlers/get-current-user-manager.activity.d.ts +5 -0
  817. package/workflow/src/lib/activities/handlers/get-current-user-manager.activity.js +50 -0
  818. package/workflow/src/lib/activities/handlers/get-current-user-manager.activity.js.map +1 -0
  819. package/workflow/src/lib/activities/handlers/if.activity.d.ts +5 -0
  820. package/workflow/src/lib/activities/handlers/if.activity.js +25 -0
  821. package/workflow/src/lib/activities/handlers/if.activity.js.map +1 -0
  822. package/workflow/src/lib/activities/handlers/index.d.ts +11 -0
  823. package/workflow/src/lib/activities/handlers/index.js +15 -0
  824. package/workflow/src/lib/activities/handlers/index.js.map +1 -0
  825. package/workflow/src/lib/activities/index.d.ts +7 -0
  826. package/workflow/src/lib/activities/index.js +11 -0
  827. package/workflow/src/lib/activities/index.js.map +1 -0
  828. package/workflow/src/lib/activities/workflow-activity-execution.types.d.ts +17 -0
  829. package/workflow/src/lib/activities/workflow-activity-execution.types.js +4 -0
  830. package/workflow/src/lib/activities/workflow-activity-execution.types.js.map +1 -0
  831. package/workflow/src/lib/activities/workflow-activity.constants.d.ts +4 -0
  832. package/workflow/src/lib/activities/workflow-activity.constants.js +10 -0
  833. package/workflow/src/lib/activities/workflow-activity.constants.js.map +1 -0
  834. package/workflow/src/lib/activities/workflow-activity.registry.d.ts +15 -0
  835. package/workflow/src/lib/activities/workflow-activity.registry.js +78 -0
  836. package/workflow/src/lib/activities/workflow-activity.registry.js.map +1 -0
  837. package/workflow/src/lib/activities/workflow-activity.utils.d.ts +24 -0
  838. package/workflow/src/lib/activities/workflow-activity.utils.js +108 -0
  839. package/workflow/src/lib/activities/workflow-activity.utils.js.map +1 -0
  840. package/workflow/src/lib/activities/workflow-permission.service.d.ts +21 -0
  841. package/workflow/src/lib/activities/workflow-permission.service.js +99 -0
  842. package/workflow/src/lib/activities/workflow-permission.service.js.map +1 -0
  843. package/workflow/src/lib/activities/workflow-request-session.adapter.d.ts +9 -0
  844. package/workflow/src/lib/activities/workflow-request-session.adapter.js +29 -0
  845. package/workflow/src/lib/activities/workflow-request-session.adapter.js.map +1 -0
  846. package/workflow/src/lib/activity/activity.types.d.ts +130 -0
  847. package/workflow/src/lib/activity/activity.types.js +8 -0
  848. package/workflow/src/lib/activity/activity.types.js.map +1 -0
  849. package/workflow/src/lib/authorization/platform-root-user.util.d.ts +1 -0
  850. package/workflow/src/lib/authorization/platform-root-user.util.js +16 -0
  851. package/workflow/src/lib/authorization/platform-root-user.util.js.map +1 -0
  852. package/workflow/src/lib/jobs/workflow-job-dispatcher.service.d.ts +20 -0
  853. package/workflow/src/lib/jobs/workflow-job-dispatcher.service.js +59 -0
  854. package/workflow/src/lib/jobs/workflow-job-dispatcher.service.js.map +1 -0
  855. package/workflow/src/lib/jobs/workflow-jobs.constants.d.ts +2 -0
  856. package/workflow/src/lib/jobs/workflow-jobs.constants.js +8 -0
  857. package/workflow/src/lib/jobs/workflow-jobs.constants.js.map +1 -0
  858. package/workflow/src/lib/jobs/workflow-jobs.module.d.ts +9 -0
  859. package/workflow/src/lib/jobs/workflow-jobs.module.js +53 -0
  860. package/workflow/src/lib/jobs/workflow-jobs.module.js.map +1 -0
  861. package/workflow/src/lib/jobs/workflow-maintenance.scheduler.d.ts +10 -0
  862. package/workflow/src/lib/jobs/workflow-maintenance.scheduler.js +43 -0
  863. package/workflow/src/lib/jobs/workflow-maintenance.scheduler.js.map +1 -0
  864. package/workflow/src/lib/jobs/workflow-redis.config.d.ts +6 -0
  865. package/workflow/src/lib/jobs/workflow-redis.config.js +18 -0
  866. package/workflow/src/lib/jobs/workflow-redis.config.js.map +1 -0
  867. package/workflow/src/lib/jobs/workflow-start-job.types.d.ts +6 -0
  868. package/workflow/src/lib/jobs/workflow-start-job.types.js +4 -0
  869. package/workflow/src/lib/jobs/workflow-start-job.types.js.map +1 -0
  870. package/workflow/src/lib/jobs/workflow-start.processor.d.ts +10 -0
  871. package/workflow/src/lib/jobs/workflow-start.processor.js +31 -0
  872. package/workflow/src/lib/jobs/workflow-start.processor.js.map +1 -0
  873. package/workflow/src/lib/middlewares/automation-command.middleware.d.ts +13 -0
  874. package/workflow/src/lib/middlewares/automation-command.middleware.js +38 -0
  875. package/workflow/src/lib/middlewares/automation-command.middleware.js.map +1 -0
  876. package/workflow/src/lib/middlewares/document-workflow-trigger.middleware.d.ts +17 -0
  877. package/workflow/src/lib/middlewares/document-workflow-trigger.middleware.js +104 -0
  878. package/workflow/src/lib/middlewares/document-workflow-trigger.middleware.js.map +1 -0
  879. package/workflow/src/lib/middlewares/workflow-trigger-guard.d.ts +2 -0
  880. package/workflow/src/lib/middlewares/workflow-trigger-guard.js +16 -0
  881. package/workflow/src/lib/middlewares/workflow-trigger-guard.js.map +1 -0
  882. package/workflow/src/lib/middlewares/workflow-trigger.middleware.d.ts +18 -0
  883. package/workflow/src/lib/middlewares/workflow-trigger.middleware.js +190 -0
  884. package/workflow/src/lib/middlewares/workflow-trigger.middleware.js.map +1 -0
  885. package/workflow/src/lib/runtime/entity-workflow-info.sync.d.ts +14 -0
  886. package/workflow/src/lib/runtime/entity-workflow-info.sync.js +43 -0
  887. package/workflow/src/lib/runtime/entity-workflow-info.sync.js.map +1 -0
  888. package/workflow/src/lib/runtime/jql-workflow-execution-store.service.d.ts +27 -0
  889. package/workflow/src/lib/runtime/jql-workflow-execution-store.service.js +212 -0
  890. package/workflow/src/lib/runtime/jql-workflow-execution-store.service.js.map +1 -0
  891. package/workflow/src/lib/runtime/platform-core.types.d.ts +18 -0
  892. package/workflow/src/lib/runtime/platform-core.types.js +5 -0
  893. package/workflow/src/lib/runtime/platform-core.types.js.map +1 -0
  894. package/workflow/src/lib/runtime/record-workflow-info.util.d.ts +12 -0
  895. package/workflow/src/lib/runtime/record-workflow-info.util.js +14 -0
  896. package/workflow/src/lib/runtime/record-workflow-info.util.js.map +1 -0
  897. package/workflow/src/lib/runtime/workflow-activity-definition.service.d.ts +8 -0
  898. package/workflow/src/lib/runtime/workflow-activity-definition.service.js +45 -0
  899. package/workflow/src/lib/runtime/workflow-activity-definition.service.js.map +1 -0
  900. package/workflow/src/lib/runtime/workflow-definition.types.d.ts +164 -0
  901. package/workflow/src/lib/runtime/workflow-definition.types.js +4 -0
  902. package/workflow/src/lib/runtime/workflow-definition.types.js.map +1 -0
  903. package/workflow/src/lib/runtime/workflow-engine.errors.d.ts +28 -0
  904. package/workflow/src/lib/runtime/workflow-engine.errors.js +51 -0
  905. package/workflow/src/lib/runtime/workflow-engine.errors.js.map +1 -0
  906. package/workflow/src/lib/runtime/workflow-engine.service.d.ts +373 -0
  907. package/workflow/src/lib/runtime/workflow-engine.service.js +2922 -0
  908. package/workflow/src/lib/runtime/workflow-engine.service.js.map +1 -0
  909. package/workflow/src/lib/runtime/workflow-execution-store.service.d.ts +35 -0
  910. package/workflow/src/lib/runtime/workflow-execution-store.service.js +57 -0
  911. package/workflow/src/lib/runtime/workflow-execution-store.service.js.map +1 -0
  912. package/workflow/src/lib/runtime/workflow-expression-evaluator.service.d.ts +7 -0
  913. package/workflow/src/lib/runtime/workflow-expression-evaluator.service.js +80 -0
  914. package/workflow/src/lib/runtime/workflow-expression-evaluator.service.js.map +1 -0
  915. package/workflow/src/lib/runtime/workflow-expression-scope.service.d.ts +101 -0
  916. package/workflow/src/lib/runtime/workflow-expression-scope.service.js +214 -0
  917. package/workflow/src/lib/runtime/workflow-expression-scope.service.js.map +1 -0
  918. package/workflow/src/lib/runtime/workflow-instance.types.d.ts +374 -0
  919. package/workflow/src/lib/runtime/workflow-instance.types.js +8 -0
  920. package/workflow/src/lib/runtime/workflow-instance.types.js.map +1 -0
  921. package/workflow/src/lib/runtime/workflow-management.const.d.ts +6 -0
  922. package/workflow/src/lib/runtime/workflow-management.const.js +12 -0
  923. package/workflow/src/lib/runtime/workflow-management.const.js.map +1 -0
  924. package/workflow/src/lib/runtime/workflow-runtime.types.d.ts +263 -0
  925. package/workflow/src/lib/runtime/workflow-runtime.types.js +15 -0
  926. package/workflow/src/lib/runtime/workflow-runtime.types.js.map +1 -0
  927. package/workflow/src/lib/utils/multilanguage.util.d.ts +2 -0
  928. package/workflow/src/lib/utils/multilanguage.util.js +21 -0
  929. package/workflow/src/lib/utils/multilanguage.util.js.map +1 -0
  930. package/workflow/src/lib/utils/uuid.util.d.ts +1 -0
  931. package/workflow/src/lib/utils/uuid.util.js +10 -0
  932. package/workflow/src/lib/utils/uuid.util.js.map +1 -0
  933. package/workflow/src/lib/workflow.module.d.ts +2 -0
  934. package/workflow/src/lib/workflow.module.js +92 -0
  935. package/workflow/src/lib/workflow.module.js.map +1 -0
@@ -0,0 +1,2922 @@
1
+ "use strict";
2
+ var BackendWorkflowEngineService_1;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.BackendWorkflowEngineService = void 0;
5
+ const tslib_1 = require("tslib");
6
+ const common_1 = require("@nestjs/common");
7
+ const core_1 = require("@acorex-platform/framework-server/core");
8
+ const workflow_request_session_adapter_1 = require("../activities/workflow-request-session.adapter");
9
+ const multilanguage_util_1 = require("../utils/multilanguage.util");
10
+ const uuid_util_1 = require("../utils/uuid.util");
11
+ const workflow_management_const_1 = require("./workflow-management.const");
12
+ const workflow_engine_errors_1 = require("./workflow-engine.errors");
13
+ const workflow_activity_definition_service_1 = require("./workflow-activity-definition.service");
14
+ const workflow_activity_registry_1 = require("../activities/workflow-activity.registry");
15
+ const workflow_expression_evaluator_service_1 = require("./workflow-expression-evaluator.service");
16
+ const workflow_expression_scope_service_1 = require("./workflow-expression-scope.service");
17
+ const workflow_execution_store_service_1 = require("./workflow-execution-store.service");
18
+ const entity_workflow_info_sync_1 = require("./entity-workflow-info.sync");
19
+ /** Task context key for composed human-task titles (workflow-management). */
20
+ const AXP_WORKFLOW_TASK_CONTEXT_TITLE_PARTS_KEY = '_taskTitleParts';
21
+ /**
22
+ * Backend workflow runtime engine (ported from mock connectivity).
23
+ * Persists instances/bookmarks via {@link WorkflowExecutionStoreService}.
24
+ */
25
+ let BackendWorkflowEngineService = BackendWorkflowEngineService_1 = class BackendWorkflowEngineService {
26
+ //#region ---- Services & Dependencies ----
27
+ constructor(store, entityStorageService, activityDefinitionService, expressionScopeService, expressionEvaluator, sessionService, activityRegistry) {
28
+ this.store = store;
29
+ this.entityStorageService = entityStorageService;
30
+ this.activityDefinitionService = activityDefinitionService;
31
+ this.expressionScopeService = expressionScopeService;
32
+ this.expressionEvaluator = expressionEvaluator;
33
+ this.sessionService = sessionService;
34
+ this.activityRegistry = activityRegistry;
35
+ //#endregion
36
+ //#region ---- Task Token Management ----
37
+ /**
38
+ * Secure task token storage.
39
+ * Key: token (UUID)
40
+ * Value: { instanceId, activityId, expiresAt }
41
+ */
42
+ this.taskTokens = new Map();
43
+ /**
44
+ * Token expiration time: 30 minutes.
45
+ * Tasks in task board (human-task) may wait days; resume is allowed via bookmark fallback when token is expired.
46
+ */
47
+ this.TOKEN_EXPIRATION_MS = 30 * 60 * 1000;
48
+ //#region ---- Execution Mode Detection ----
49
+ /**
50
+ * Cache for activity definitions to avoid repeated queries.
51
+ */
52
+ this.activityDefinitionCache = new Map();
53
+ /**
54
+ * Cache TTL: 5 minutes
55
+ */
56
+ this.CACHE_TTL_MS = 5 * 60 * 1000;
57
+ }
58
+ /** Minimal session user shape used by workflow runtime. */
59
+ getSessionUser() {
60
+ const userId = this.sessionService?.userId;
61
+ if (!userId) {
62
+ return null;
63
+ }
64
+ return { id: userId, title: userId, name: userId };
65
+ }
66
+ //#endregion
67
+ //#region ---- Definition Loading ----
68
+ /**
69
+ * Load workflow definition by name from entity storage.
70
+ */
71
+ async getDefinition(workflowId) {
72
+ console.log(`[BackendWorkflowRuntime] 🔍 Loading workflow definition: ${workflowId}`);
73
+ // Query entity storage by name field (not id)
74
+ console.log(`[BackendWorkflowRuntime] 🔄 Fallback: Querying entity storage by name field: ${workflowId}`);
75
+ try {
76
+ const result = await this.entityStorageService.query('WorkflowManagement.WorkflowDefinition', {
77
+ skip: 0,
78
+ take: 1,
79
+ filter: {
80
+ field: 'name',
81
+ operator: { type: 'equal' },
82
+ value: workflowId,
83
+ },
84
+ });
85
+ if (result.items && result.items.length > 0) {
86
+ const entity = result.items[0];
87
+ console.log(`[BackendWorkflowRuntime] ✅ Found definition via entity storage: ${workflowId}`);
88
+ return entity;
89
+ }
90
+ }
91
+ catch (error) {
92
+ console.error(`[BackendWorkflowRuntime] ❌ Error querying entity storage:`, error);
93
+ }
94
+ console.error(`[BackendWorkflowRuntime] ❌ Workflow definition not found: ${workflowId}`);
95
+ return null;
96
+ }
97
+ /**
98
+ * Generate secure, non-guessable task token (UUID).
99
+ */
100
+ generateTaskToken(instanceId, activityId) {
101
+ const token = (0, uuid_util_1.generateUuid)();
102
+ const expiresAt = new Date(Date.now() + this.TOKEN_EXPIRATION_MS);
103
+ this.taskTokens.set(token, {
104
+ instanceId,
105
+ activityId,
106
+ expiresAt,
107
+ });
108
+ // Cleanup expired tokens periodically (lightweight)
109
+ this.cleanupExpiredTokens();
110
+ console.log(`[BackendWorkflowEngineService] 🔐 Generated task token for ${instanceId}:${activityId}`);
111
+ return token;
112
+ }
113
+ /**
114
+ * Validate task token.
115
+ * Returns true if token exists, not expired, and matches instanceId + activityId.
116
+ */
117
+ validateTaskToken(token, instanceId, activityId) {
118
+ const tokenInfo = this.taskTokens.get(token);
119
+ if (!tokenInfo) {
120
+ console.warn(`[BackendWorkflowEngineService] ❌ Task token not found: ${token}`);
121
+ return false;
122
+ }
123
+ if (tokenInfo.expiresAt < new Date()) {
124
+ console.warn(`[BackendWorkflowEngineService] ❌ Task token expired: ${token}`);
125
+ this.taskTokens.delete(token);
126
+ return false;
127
+ }
128
+ if (tokenInfo.instanceId !== instanceId || tokenInfo.activityId !== activityId) {
129
+ console.warn(`[BackendWorkflowEngineService] ❌ Task token mismatch: expected ${instanceId}:${activityId}, got ${tokenInfo.instanceId}:${tokenInfo.activityId}`);
130
+ return false;
131
+ }
132
+ return true;
133
+ }
134
+ /**
135
+ * Allow resume when token is missing/expired but instance is suspended and has an active bookmark for this step.
136
+ * Used for task board tasks that may wait days (token is in-memory and expires after 30 min).
137
+ */
138
+ async canResumeByBookmark(instanceId, stepId) {
139
+ const instance = await this.getInstance(instanceId);
140
+ if (!instance || instance.subStatus !== 'Suspended') {
141
+ return false;
142
+ }
143
+ const bookmarks = await this.getActiveBookmarks(instanceId);
144
+ return bookmarks.some((b) => b.activityId === stepId);
145
+ }
146
+ /**
147
+ * Remove task token after completion to prevent replay.
148
+ */
149
+ removeTaskToken(token) {
150
+ this.taskTokens.delete(token);
151
+ console.log(`[BackendWorkflowEngineService] 🗑️ Removed task token: ${token}`);
152
+ }
153
+ /**
154
+ * Cleanup expired tokens (lightweight).
155
+ */
156
+ cleanupExpiredTokens() {
157
+ const now = new Date();
158
+ let cleaned = 0;
159
+ for (const [token, info] of this.taskTokens.entries()) {
160
+ if (info.expiresAt < now) {
161
+ this.taskTokens.delete(token);
162
+ cleaned++;
163
+ }
164
+ }
165
+ if (cleaned > 0) {
166
+ console.log(`[BackendWorkflowEngineService] 🧹 Cleaned up ${cleaned} expired task tokens`);
167
+ }
168
+ }
169
+ //#endregion
170
+ /**
171
+ * Start a new workflow instance.
172
+ * Creates a workflow instance and stores it in IndexedDB.
173
+ */
174
+ async start(request) {
175
+ console.log(`[BackendWorkflowEngineService] 🚀 Starting workflow: ${request.workflowId}`);
176
+ // Load workflow definition using definition loader (queries by name field)
177
+ // This ensures consistency with Workflow Management UI which also uses name field
178
+ const workflow = await this.getDefinition(request.workflowId);
179
+ if (!workflow) {
180
+ console.error(`[BackendWorkflowEngineService] ❌ Workflow definition not found: ${request.workflowId}`);
181
+ throw new Error(`Workflow definition not found: ${request.workflowId}`);
182
+ }
183
+ // Validate workflow structure
184
+ const graph = workflow.graph;
185
+ if (!graph) {
186
+ throw new Error(`Workflow definition has no graph: ${request.workflowId}`);
187
+ }
188
+ const activities = graph.activities || [];
189
+ const connections = graph.connections || [];
190
+ if (activities.length === 0) {
191
+ throw new Error(`Workflow definition has no activities: ${request.workflowId}`);
192
+ }
193
+ // Validate startActivityId exists
194
+ if (graph.startActivityId) {
195
+ const startActivity = activities.find((a) => a.id === graph.startActivityId);
196
+ if (!startActivity) {
197
+ throw new Error(`Start activity '${graph.startActivityId}' not found in workflow: ${request.workflowId}`);
198
+ }
199
+ }
200
+ // Validate connections are structurally valid (no circular references in simple check)
201
+ const activityIds = new Set(activities.map((a) => a.id));
202
+ for (const conn of connections) {
203
+ if (!activityIds.has(conn.source.activtyName) || !activityIds.has(conn.target.activtyName)) {
204
+ console.warn(`[BackendWorkflowEngineService] ⚠️ Connection references non-existent activity: ${conn.source.activtyName} -> ${conn.target.activtyName}`);
205
+ }
206
+ }
207
+ const instanceId = (0, uuid_util_1.generateUuid)();
208
+ const now = new Date().toISOString();
209
+ // Build connection map: target -> source[]
210
+ const incomingConnections = new Map();
211
+ connections.forEach((conn) => {
212
+ const targetId = conn.target.activtyName;
213
+ if (!incomingConnections.has(targetId)) {
214
+ incomingConnections.set(targetId, []);
215
+ }
216
+ incomingConnections.get(targetId).push(conn.source.activtyName);
217
+ });
218
+ // Find root activity (use startActivityId or activity with no incoming connections, or first activity)
219
+ let firstActivity = null;
220
+ if (graph.startActivityId) {
221
+ firstActivity = activities.find((a) => a.id === graph.startActivityId) || null;
222
+ }
223
+ if (!firstActivity) {
224
+ for (const activity of activities) {
225
+ if (!incomingConnections.has(activity.id)) {
226
+ firstActivity = activity;
227
+ break;
228
+ }
229
+ }
230
+ }
231
+ // If no root found, use first activity
232
+ if (!firstActivity && activities.length > 0) {
233
+ firstActivity = activities[0];
234
+ }
235
+ const firstStepId = firstActivity?.id || 'root';
236
+ // Extract correlationId from input if provided (remove it from input to avoid pollution)
237
+ const correlationId = request.input?.['correlationId'] || null;
238
+ const entityRefId = request.input?.['refId'] || null;
239
+ const entityRefType = request.input?.['refType'] || null;
240
+ const workflowInput = { ...request.input };
241
+ if (correlationId && workflowInput['correlationId']) {
242
+ delete workflowInput['correlationId'];
243
+ }
244
+ // Remove refId and refType from workflow input (they're stored in instance metadata)
245
+ if (entityRefId && workflowInput['refId']) {
246
+ delete workflowInput['refId'];
247
+ }
248
+ if (entityRefType && workflowInput['refType']) {
249
+ delete workflowInput['refType'];
250
+ }
251
+ // Create workflow state (totalSteps for overview progress display)
252
+ const totalSteps = activities.length;
253
+ const workflowState = {
254
+ id: `state-${instanceId}`,
255
+ definitionId: workflow.name, // Use name as definitionId (backward compatibility)
256
+ //definitionVersion: workflow.version,
257
+ definitionVersion: 1,
258
+ correlationId,
259
+ status: 'Running',
260
+ subStatus: 'Executing',
261
+ bookmarks: [],
262
+ incidents: [],
263
+ fault: null,
264
+ completionCallbacks: [],
265
+ activityExecutionContexts: firstActivity
266
+ ? [
267
+ {
268
+ id: `ctx-${firstStepId}`,
269
+ parentContextId: null,
270
+ scheduledActivityNodeId: firstStepId,
271
+ ownerActivityNodeId: null,
272
+ properties: {},
273
+ activityState: null,
274
+ dynamicVariables: [],
275
+ status: 'Running',
276
+ isExecuting: false,
277
+ faultCount: 0,
278
+ startedAt: now,
279
+ completedAt: null,
280
+ tag: null,
281
+ },
282
+ ]
283
+ : [],
284
+ input: { ...workflowInput, _workflowInstanceId: instanceId },
285
+ output: {},
286
+ properties: {},
287
+ createdAt: now,
288
+ updatedAt: now,
289
+ finishedAt: null,
290
+ totalSteps,
291
+ };
292
+ // Create workflow instance
293
+ const instance = {
294
+ $schema: 'https://elsaworkflows.io/schemas/workflow-instance/v3.0.0/schema.json',
295
+ id: instanceId,
296
+ definitionId: workflow.name, // Use name as definitionId (backward compatibility)
297
+ //definitionVersionId: workflow.id,
298
+ //version: workflow.version,
299
+ version: 1,
300
+ definitionVersionId: '1',
301
+ parentWorkflowInstanceId: null,
302
+ workflowState,
303
+ status: 'Running',
304
+ subStatus: 'Executing',
305
+ correlationId,
306
+ name: (0, multilanguage_util_1.resolveMultiLanguageString)(workflow.title) || workflow.name || null,
307
+ incidentCount: 0,
308
+ createdAt: now,
309
+ updatedAt: now,
310
+ finishedAt: null,
311
+ // Store entity reference for work item creation
312
+ entityRefId: entityRefId || null,
313
+ entityRefType: entityRefType || null,
314
+ };
315
+ await this.store.addInstance(instance);
316
+ console.log(`[BackendWorkflowEngineService] 💾 Stored workflow instance:`, {
317
+ id: instance.id,
318
+ definitionId: instance.definitionId,
319
+ name: instance.name,
320
+ correlationId: instance.correlationId,
321
+ entityRefId: instance.entityRefId,
322
+ entityRefType: instance.entityRefType,
323
+ status: instance.status,
324
+ subStatus: instance.subStatus,
325
+ });
326
+ // 🎯 Also store in entity service for entity-based access
327
+ await this.saveInstanceToEntityService(instance);
328
+ // Convert to instance state for response (async - needs bookmark lookup)
329
+ let state = await this.instanceToInstanceState(instance);
330
+ // 🎯 KEY LOGIC: Execute all backend activities until we reach a frontend activity
331
+ let currentActivity = firstActivity;
332
+ let executionCount = 0;
333
+ const maxExecutions = 500; // Prevent infinite loops
334
+ // Only last activity output is kept; each step overwrites it. Expression scope uses outputs = lastActivityOutput.
335
+ let lastActivityOutput = state.lastActivityOutput;
336
+ while (currentActivity && executionCount < maxExecutions) {
337
+ executionCount++;
338
+ const activityType = currentActivity.name;
339
+ if (request.workflowId === 'documentReview') {
340
+ console.log('[WFT-ENG] documentReview step', executionCount, 'activityId=', currentActivity.id, 'type=', activityType);
341
+ }
342
+ // Determine execution mode (async)
343
+ const executionMode = await this.determineExecutionMode(activityType, currentActivity);
344
+ // Get activity definition to retrieve taskType (taskType === 'human-task' → suspend for cartable)
345
+ const activityDef = await this.activityDefinitionService.getActivityByName(activityType);
346
+ let taskType = currentActivity.metadata?.['taskType'] ?? activityDef?.taskType ?? 'ui-activity';
347
+ // Defensive: human-task and cartable must suspend for task board
348
+ if (this.isTaskBoardSuspendGraphActivity(activityType)) {
349
+ if (activityDef?.taskType === 'human-task') {
350
+ taskType = 'human-task';
351
+ }
352
+ if (executionMode === 'backend') {
353
+ console.warn(`[BackendWorkflowEngineService] ⚠️ ${activityType} had executionMode=backend (definition or cache). Forcing frontend so workflow suspends at this step.`, {
354
+ activityId: currentActivity.id,
355
+ definitionExecutionMode: activityDef?.executionMode,
356
+ definitionTaskType: activityDef?.taskType,
357
+ });
358
+ }
359
+ }
360
+ const effectiveExecutionMode = taskType === 'human-task' && executionMode === 'backend'
361
+ ? 'frontend'
362
+ : this.isTaskBoardSuspendGraphActivity(activityType) &&
363
+ (activityDef?.taskType === 'human-task' || taskType === 'human-task')
364
+ ? executionMode === 'backend'
365
+ ? 'frontend'
366
+ : executionMode
367
+ : executionMode;
368
+ // If frontend activity → stop and return as pendingTask
369
+ if (effectiveExecutionMode === 'frontend' || effectiveExecutionMode === 'both') {
370
+ const pendingTask = await this.createTaskFromActivity(currentActivity, state);
371
+ // Use local taskType (may be forced to human-task for workflow-activity:human-task) so bookmark and UI see correct type
372
+ const resolvedTaskTypeForBookmark = taskType === 'human-task' || pendingTask.taskType === 'human-task' ? 'human-task' : pendingTask.taskType;
373
+ // Extract assignment and task metadata from activity inputs (for human-task activities)
374
+ let bookmarkPayload = {
375
+ activityType,
376
+ activityName: currentActivity.name,
377
+ taskToken: pendingTask.taskToken, // Store taskToken for resume
378
+ taskType: resolvedTaskTypeForBookmark,
379
+ };
380
+ // For human-task activities, extract assignment and task metadata from inputs
381
+ if (resolvedTaskTypeForBookmark === 'human-task' && pendingTask.input) {
382
+ const inputs = pendingTask.input;
383
+ // Assignment metadata (normalize to array so task board filter works; expression may return single id)
384
+ bookmarkPayload['assignedUserIds'] = this.normalizeUserIds(inputs['assignedUserIds']);
385
+ bookmarkPayload['candidateUserIds'] = this.normalizeUserIds(inputs['candidateUserIds']);
386
+ bookmarkPayload['candidateRoleIds'] = this.normalizeUserIds(inputs['candidateRoleIds']);
387
+ // Task metadata
388
+ bookmarkPayload['title'] = this.resolveHumanTaskBookmarkTitle(inputs, activityDef, currentActivity);
389
+ bookmarkPayload['description'] = inputs['description'] || null;
390
+ bookmarkPayload['priority'] = inputs['priority'] || 'Normal';
391
+ bookmarkPayload['dueDate'] = inputs['dueDate'] || null;
392
+ // UI configuration
393
+ bookmarkPayload['layout'] = inputs['layout'] || null;
394
+ bookmarkPayload['actions'] = inputs['actions'] || null;
395
+ bookmarkPayload['context'] = inputs['context'] || {};
396
+ }
397
+ if (activityType === workflow_management_const_1.WorkflowManagementRootConfig.activities.cartable) {
398
+ bookmarkPayload['assignedUserIds'] = [];
399
+ }
400
+ if (resolvedTaskTypeForBookmark === 'human-task') {
401
+ const htInputs = pendingTask.input;
402
+ this.logHumanTaskBookmarkAssignmentTrace({
403
+ phase: 'engine-start',
404
+ instanceId,
405
+ workflowDefinitionName: workflow.name,
406
+ activityId: currentActivity.id,
407
+ activityType,
408
+ rawAssignedUserIds: htInputs?.['assignedUserIds'],
409
+ normalizedAssignedUserIds: bookmarkPayload['assignedUserIds'],
410
+ variables: state.variables,
411
+ });
412
+ }
413
+ const bookmarkId = await this.createBookmark(instanceId, currentActivity.id, 'user-task', bookmarkPayload);
414
+ const isTaskBoardSuspend = this.isTaskBoardSuspendGraphActivity(activityType);
415
+ if (isTaskBoardSuspend) {
416
+ console.log('[WFT-ENG] task-board bookmark created instanceId=', instanceId, 'activityId=', currentActivity.id, 'bookmarkId=', bookmarkId, 'type=', activityType);
417
+ }
418
+ const newStatus = isTaskBoardSuspend ? 'suspended' : 'running';
419
+ state = {
420
+ ...state,
421
+ lastActivityOutput,
422
+ status: newStatus,
423
+ currentStepId: currentActivity.id,
424
+ };
425
+ await this.updateInstanceFromState(instanceId, state);
426
+ return {
427
+ instanceId: instanceId,
428
+ state,
429
+ pendingTask,
430
+ lastActivityOutput,
431
+ };
432
+ }
433
+ // Backend activity → execute it
434
+ const executionResult = await this.executeBackendActivityLocally(currentActivity, state, lastActivityOutput);
435
+ lastActivityOutput = executionResult.output;
436
+ // set-variable writes workflow variables directly into output map (no outputToVariables).
437
+ const isSetVariableRun = currentActivity.name === 'workflow-activity:set-variable';
438
+ const variableUpdates = isSetVariableRun
439
+ ? executionResult.output
440
+ : this.getVariableUpdatesFromOutput(workflow, currentActivity.id, executionResult.output);
441
+ const outcome = Object.keys(executionResult.outcomes)[0] || 'Done';
442
+ const sessionUser = this.getSessionUser();
443
+ const backendStepAudit = {
444
+ [`${currentActivity.id}_outcome`]: outcome,
445
+ [`${currentActivity.id}_activityOutput`]: executionResult.output,
446
+ };
447
+ if (sessionUser?.id) {
448
+ backendStepAudit[`${currentActivity.id}_completedByUserId`] = sessionUser.id;
449
+ backendStepAudit[`${currentActivity.id}_completedByLabel`] =
450
+ sessionUser.title || sessionUser.name || sessionUser.id;
451
+ }
452
+ else {
453
+ backendStepAudit[`${currentActivity.id}_completedByLabel`] = 'System';
454
+ }
455
+ state = {
456
+ ...state,
457
+ variables: {
458
+ ...state.variables,
459
+ ...variableUpdates,
460
+ ...backendStepAudit,
461
+ },
462
+ lastActivityOutput,
463
+ currentStepId: currentActivity.id,
464
+ lastUpdated: new Date(),
465
+ };
466
+ await this.updateInstanceFromState(instanceId, state);
467
+ // Find next activity based on outcome
468
+ const nextConnection = this.findWorkflowConnection(connections, currentActivity.id, outcome);
469
+ if (!nextConnection) {
470
+ // No next activity → workflow completed
471
+ state = {
472
+ ...state,
473
+ status: 'completed',
474
+ currentStepId: undefined,
475
+ output: state.variables,
476
+ };
477
+ await this.updateInstanceFromState(instanceId, state);
478
+ return {
479
+ instanceId: instanceId,
480
+ state,
481
+ pendingTask: null,
482
+ lastActivityOutput,
483
+ };
484
+ }
485
+ // Find next activity
486
+ const nextActivity = this.findActivityInGraph(graph, nextConnection.target.activtyName);
487
+ if (!nextActivity) {
488
+ console.error(`[BackendWorkflowEngineService] ❌ Next activity '${nextConnection.target.activtyName}' not found in graph`);
489
+ state = {
490
+ ...state,
491
+ status: 'error',
492
+ currentStepId: undefined,
493
+ };
494
+ await this.updateInstanceFromState(instanceId, state);
495
+ throw new Error(`Next activity '${nextConnection.target.activtyName}' not found in workflow graph`);
496
+ }
497
+ currentActivity = nextActivity;
498
+ }
499
+ // If we exit loop due to max executions, mark as error
500
+ if (executionCount >= maxExecutions) {
501
+ console.error(`[BackendWorkflowEngineService] ❌ Maximum execution count (${maxExecutions}) reached - possible infinite loop`);
502
+ state = {
503
+ ...state,
504
+ status: 'error',
505
+ currentStepId: undefined,
506
+ };
507
+ await this.updateInstanceFromState(instanceId, state);
508
+ throw new Error(`Workflow execution exceeded maximum steps (${maxExecutions}) - possible infinite loop`);
509
+ }
510
+ // If we exit loop without frontend activity, workflow is complete
511
+ state = {
512
+ ...state,
513
+ status: 'completed',
514
+ currentStepId: undefined,
515
+ output: state.variables,
516
+ lastActivityOutput,
517
+ };
518
+ await this.updateInstanceFromState(instanceId, state);
519
+ return {
520
+ instanceId: instanceId,
521
+ state,
522
+ pendingTask: null,
523
+ lastActivityOutput,
524
+ };
525
+ }
526
+ /**
527
+ * Terminates a non-finished workflow instance (e.g. superseded lifecycle run).
528
+ */
529
+ async cancelInstance(instanceId, reason) {
530
+ const instance = await this.getInstance(instanceId);
531
+ if (!instance || instance.status === 'Finished') {
532
+ return;
533
+ }
534
+ const now = new Date().toISOString();
535
+ instance.status = 'Finished';
536
+ instance.subStatus = 'Cancelled';
537
+ instance.updatedAt = now;
538
+ instance.finishedAt = now;
539
+ instance.workflowState.status = 'Finished';
540
+ instance.workflowState.subStatus = 'Cancelled';
541
+ instance.workflowState.updatedAt = now;
542
+ instance.workflowState.finishedAt = now;
543
+ if (reason) {
544
+ instance.workflowState.properties = {
545
+ ...(instance.workflowState.properties ?? {}),
546
+ cancelReason: reason,
547
+ };
548
+ }
549
+ await this.store.updateInstance(instance);
550
+ await this.updateInstanceInEntityService(instance);
551
+ console.log(`[BackendWorkflowEngineService] 🛑 Cancelled workflow instance: ${instanceId}`, { reason });
552
+ }
553
+ /**
554
+ * Find activity in Graph by ID.
555
+ */
556
+ findActivityInGraph(graph, activityId) {
557
+ const activities = graph.activities || [];
558
+ return activities.find((a) => a.id === activityId) || null;
559
+ }
560
+ /**
561
+ * Resolve allowed outcomes for the current activity from the workflow definition.
562
+ * - First: use outgoing connection ports from the workflow graph (so workflow-defined ports like 'Submitted'/'Cancelled' are accepted).
563
+ * - For human-task: parse activity instance inputs.actions (prefix/suffix) and use action names as outcomes.
564
+ * - Otherwise: use activity definition outcomes or ['Done'].
565
+ */
566
+ async getActivityAllowedOutcomes(workflow, stepId) {
567
+ const activityInstance = this.findActivityInGraph(workflow.graph, stepId);
568
+ if (!activityInstance)
569
+ return [BackendWorkflowEngineService_1.DEFAULT_UNMATCHED_OUTCOME];
570
+ // Prefer outcomes from workflow graph: outgoing connection ports for this step (e.g. leaveRequestForm → Submitted, Cancelled)
571
+ const connections = workflow.graph?.connections ?? [];
572
+ const outgoingPorts = connections
573
+ .filter((c) => c.source?.activtyName === stepId)
574
+ .map((c) => c.source?.port ?? BackendWorkflowEngineService_1.DEFAULT_UNMATCHED_OUTCOME);
575
+ const uniquePorts = this.normalizeAllowedOutcomeList(outgoingPorts);
576
+ if (uniquePorts.length > 0)
577
+ return uniquePorts;
578
+ const activityDef = await this.activityDefinitionService.getActivityByName(activityInstance.name);
579
+ const taskType = activityDef?.taskType ?? 'ui-activity';
580
+ // Resolve outcomes from instance inputs.actions (human-task, show-layout-popup, etc.)
581
+ if (activityInstance.inputs?.['actions']) {
582
+ const actions = activityInstance.inputs['actions'];
583
+ const names = [];
584
+ try {
585
+ const parsed = typeof actions === 'string' ? JSON.parse(actions) : actions;
586
+ const prefix = parsed?.prefix ?? [];
587
+ const suffix = parsed?.suffix ?? [];
588
+ for (const item of [...prefix, ...suffix]) {
589
+ const name = item?.command?.name ?? item?.name;
590
+ if (name && typeof name === 'string' && !names.includes(name))
591
+ names.push(name);
592
+ }
593
+ }
594
+ catch {
595
+ // ignore parse error
596
+ }
597
+ if (names.length > 0)
598
+ return names;
599
+ }
600
+ const staticOutcomes = activityDef?.outcomes;
601
+ if (Array.isArray(staticOutcomes) && staticOutcomes.length > 0) {
602
+ const normalized = this.normalizeAllowedOutcomeList(staticOutcomes);
603
+ if (normalized.length > 0) {
604
+ return normalized;
605
+ }
606
+ }
607
+ return [BackendWorkflowEngineService_1.DEFAULT_UNMATCHED_OUTCOME];
608
+ }
609
+ /**
610
+ * Coerces workflow outcome/port values (string or legacy object shapes) to a plain label.
611
+ */
612
+ resolveOutcomeLabel(value) {
613
+ if (value == null || value === '') {
614
+ return null;
615
+ }
616
+ if (typeof value === 'string') {
617
+ const trimmed = value.trim();
618
+ return trimmed.length > 0 ? trimmed : null;
619
+ }
620
+ if (typeof value === 'object') {
621
+ const record = value;
622
+ for (const key of ['name', 'value', 'outcome', 'port', 'id']) {
623
+ const resolved = this.resolveOutcomeLabel(record[key]);
624
+ if (resolved) {
625
+ return resolved;
626
+ }
627
+ }
628
+ }
629
+ return null;
630
+ }
631
+ normalizeAllowedOutcomeList(values) {
632
+ const names = [];
633
+ for (const value of values) {
634
+ const label = this.resolveOutcomeLabel(value);
635
+ if (label && !names.includes(label)) {
636
+ names.push(label);
637
+ }
638
+ }
639
+ return names;
640
+ }
641
+ /**
642
+ * Normalize outcome: if it is in the allowed list, return as-is; otherwise use standard fallback and log.
643
+ */
644
+ normalizeOutcome(requestedOutcome, allowedOutcomes, stepId) {
645
+ const allowed = this.normalizeAllowedOutcomeList(allowedOutcomes);
646
+ const requested = this.resolveOutcomeLabel(requestedOutcome) ?? BackendWorkflowEngineService_1.DEFAULT_UNMATCHED_OUTCOME;
647
+ if (allowed.includes(requested)) {
648
+ return requested;
649
+ }
650
+ const caseInsensitive = allowed.find((allowedOutcome) => allowedOutcome.toLowerCase() === requested.toLowerCase());
651
+ if (caseInsensitive) {
652
+ return caseInsensitive;
653
+ }
654
+ console.warn(`[BackendWorkflowEngineService] ⚠️ Outcome "${requested}" not in allowed list [${allowed.join(', ')}] for step ${stepId}. Using "${BackendWorkflowEngineService_1.DEFAULT_UNMATCHED_OUTCOME}".`);
655
+ return BackendWorkflowEngineService_1.DEFAULT_UNMATCHED_OUTCOME;
656
+ }
657
+ /**
658
+ * Maps mistaken `Done` outcomes from `create-entity-form` when `persistInWorkflow` is true
659
+ * but command metadata was lost on the client (payload still contains `output.result`).
660
+ */
661
+ coerceCreateEntityFormOutcome(activity, requestedOutcome, output) {
662
+ if (!activity || activity.name !== 'workflow-activity:create-entity-form') {
663
+ return requestedOutcome;
664
+ }
665
+ if (requestedOutcome === 'Submitted' || requestedOutcome === 'Cancelled') {
666
+ return requestedOutcome;
667
+ }
668
+ const persistFlag = activity.inputs?.['persistInWorkflow'];
669
+ const persistInWorkflow = persistFlag === true || persistFlag === 'true';
670
+ if (!persistInWorkflow) {
671
+ return requestedOutcome;
672
+ }
673
+ if (requestedOutcome === 'Done' && this.extractPersistedEntityFormResult(output)) {
674
+ return 'Submitted';
675
+ }
676
+ return requestedOutcome;
677
+ }
678
+ findWorkflowConnection(connections, sourceStepId, outcome) {
679
+ const normalizedOutcome = this.resolveOutcomeLabel(outcome) ?? BackendWorkflowEngineService_1.DEFAULT_UNMATCHED_OUTCOME;
680
+ return connections.find((conn) => {
681
+ if (conn.source.activtyName !== sourceStepId) {
682
+ return false;
683
+ }
684
+ const port = this.resolveOutcomeLabel(conn.source.port);
685
+ if (!port) {
686
+ return normalizedOutcome === 'Done';
687
+ }
688
+ return port === normalizedOutcome || port.toLowerCase() === normalizedOutcome.toLowerCase();
689
+ });
690
+ }
691
+ /**
692
+ * Normalize value to a plain object for use as scope.outputs.
693
+ * Used when building expression scope so that outputs.* (e.g. outputs.result, outputs.action) is available.
694
+ */
695
+ ensureOutputsForScope(value) {
696
+ if (value == null)
697
+ return {};
698
+ if (typeof value === 'object' && !Array.isArray(value))
699
+ return { ...value };
700
+ return { value };
701
+ }
702
+ /**
703
+ * Extracts persisted create-entity-form payload (`data.result`) from a frontend step output.
704
+ */
705
+ extractPersistedEntityFormResult(output) {
706
+ const result = output['result'];
707
+ if (result && typeof result === 'object' && !Array.isArray(result)) {
708
+ return result;
709
+ }
710
+ return null;
711
+ }
712
+ /**
713
+ * Coerces date-like workflow values to a {@link Date} (local calendar date when input is `yyyy-mm-dd`).
714
+ */
715
+ coerceWorkflowDateValue(value) {
716
+ if (value == null) {
717
+ return null;
718
+ }
719
+ if (value instanceof Date) {
720
+ return Number.isNaN(value.getTime()) ? null : value;
721
+ }
722
+ if (typeof value === 'string') {
723
+ const trimmed = value.trim();
724
+ const dateOnlyMatch = /^(\d{4})-(\d{2})-(\d{2})/.exec(trimmed);
725
+ if (dateOnlyMatch) {
726
+ const year = Number(dateOnlyMatch[1]);
727
+ const month = Number(dateOnlyMatch[2]);
728
+ const day = Number(dateOnlyMatch[3]);
729
+ const local = new Date(year, month - 1, day);
730
+ return Number.isNaN(local.getTime()) ? null : local;
731
+ }
732
+ const parsed = new Date(trimmed);
733
+ return Number.isNaN(parsed.getTime()) ? null : parsed;
734
+ }
735
+ return null;
736
+ }
737
+ /**
738
+ * Promotes `create-entity-form` submit payload (`output.result`) onto workflow variables
739
+ * so downstream steps and human tasks see form values (e.g. effectiveDate), not start inputs.
740
+ */
741
+ buildPersistedEntityFormVariablePromotions(output, activityName, outcome) {
742
+ if (activityName !== 'workflow-activity:create-entity-form' || outcome !== 'Submitted') {
743
+ return {};
744
+ }
745
+ const form = this.extractPersistedEntityFormResult(output);
746
+ if (!form) {
747
+ return {};
748
+ }
749
+ const promoted = {};
750
+ for (const [key, value] of Object.entries(form)) {
751
+ if (value == null || key === 'id') {
752
+ continue;
753
+ }
754
+ if (key === 'effectiveDate') {
755
+ const coerced = this.coerceWorkflowDateValue(value);
756
+ if (coerced) {
757
+ promoted[key] = coerced;
758
+ }
759
+ continue;
760
+ }
761
+ if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
762
+ promoted[key] = value;
763
+ }
764
+ }
765
+ return promoted;
766
+ }
767
+ /**
768
+ * Resume a suspended workflow instance.
769
+ *
770
+ * After frontend completes its task:
771
+ * 1. Validates taskToken (secure, non-guessable)
772
+ * 2. Verifies resumed activity matches currentStepId/bookmark
773
+ * 3. Marks related bookmark as consumed
774
+ * 4. Applies frontend outputs into workflow state
775
+ * 5. Traverses to next activity based on outcomes
776
+ * 6. Executes ALL backend activities until hitting frontend activity or completion
777
+ * 7. Returns either pendingTask (with new secure token) or completed status
778
+ */
779
+ async resume(request) {
780
+ console.log(`[BackendWorkflowEngineService] 🔄 Resuming workflow: ${request.instanceId}`, {
781
+ stepId: request.stepId,
782
+ outcome: request.outcome,
783
+ });
784
+ // Get current state
785
+ let state = await this.getState({
786
+ instanceId: request.instanceId,
787
+ });
788
+ if (!state) {
789
+ throw new Error(`Workflow instance not found: ${request.instanceId}`);
790
+ }
791
+ if (state.status !== 'suspended') {
792
+ throw new Error(`Cannot resume workflow with status: ${state.status}. Expected: suspended`);
793
+ }
794
+ // Validate task token (secure validation). If token missing/expired, allow resume when instance is suspended and bookmark for this step exists (task board tasks may wait days).
795
+ const tokenValid = request.taskToken && this.validateTaskToken(request.taskToken, request.instanceId, request.stepId);
796
+ if (!tokenValid) {
797
+ const allowedByBookmark = await this.canResumeByBookmark(request.instanceId, request.stepId);
798
+ if (!allowedByBookmark) {
799
+ throw new Error(request.taskToken ? 'Invalid or expired task token' : 'Missing taskToken for resume operation');
800
+ }
801
+ console.log(`[BackendWorkflowEngineService] ✅ Resume allowed by bookmark (token expired/missing): ${request.instanceId}:${request.stepId}`);
802
+ }
803
+ // Verify stepId matches current step
804
+ if (state.currentStepId !== request.stepId) {
805
+ throw new Error(`Step mismatch: expected '${state.currentStepId}', got '${request.stepId}'`);
806
+ }
807
+ // Enforce claim / assignee for task-board bookmarks
808
+ const resumeBookmarks = await this.store.getBookmarksByInstanceAndActivity(request.instanceId, request.stepId, true);
809
+ const resumePayloadSource = resumeBookmarks[0];
810
+ const resumePayload = resumePayloadSource
811
+ ? this.parseBookmarkPayloadJson(resumePayloadSource.payloadJson)
812
+ : null;
813
+ if (resumePayload) {
814
+ const payloadActivityType = String(resumePayload['activityType'] ?? '');
815
+ const assigned = this.normalizeUserIds(resumePayload['assignedUserIds']) ?? [];
816
+ const candidates = this.normalizeUserIds(resumePayload['candidateUserIds']) ?? [];
817
+ const isCartablePayload = payloadActivityType === workflow_management_const_1.WorkflowManagementRootConfig.activities.cartable;
818
+ const isPooledHumanPayload = payloadActivityType === workflow_management_const_1.WorkflowManagementRootConfig.activities.humanTask &&
819
+ assigned.length === 0 &&
820
+ candidates.length > 0;
821
+ if (isCartablePayload || isPooledHumanPayload) {
822
+ if (assigned.length === 0) {
823
+ throw new workflow_engine_errors_1.AXPWorkflowEngineError('Claim the task before completing it', workflow_engine_errors_1.AXP_WORKFLOW_ERROR_CODES.CLAIM_REQUIRED);
824
+ }
825
+ }
826
+ if (assigned.length > 0) {
827
+ const uid = this.getSessionUser()?.id;
828
+ if (uid && !assigned.includes(String(uid))) {
829
+ throw new workflow_engine_errors_1.AXPWorkflowEngineError('Only the assigned user can complete this task', workflow_engine_errors_1.AXP_WORKFLOW_ERROR_CODES.TASK_NOT_ASSIGNEE, { assignedUserIds: assigned });
830
+ }
831
+ }
832
+ }
833
+ // Mark bookmark as consumed
834
+ await this.consumeBookmark(request.instanceId, request.stepId);
835
+ // Remove task token after validation (prevent replay); no-op if token was already expired/missing
836
+ if (request.taskToken) {
837
+ this.removeTaskToken(request.taskToken);
838
+ }
839
+ // Load workflow definition using definition loader (queries by name field)
840
+ const workflow = await this.getDefinition(state.workflowId);
841
+ if (!workflow) {
842
+ console.error(`[BackendWorkflowRuntime] ❌ Workflow definition not found: ${state.workflowId}`);
843
+ throw new Error(`Workflow definition not found: ${state.workflowId}`);
844
+ }
845
+ const connections = workflow.graph.connections || [];
846
+ // Resolve allowed outcomes from workflow definition (e.g. human-task from instance inputs.actions)
847
+ const allowedOutcomes = await this.getActivityAllowedOutcomes(workflow, request.stepId);
848
+ const outcome = this.normalizeOutcome(request.outcome ?? 'Done', allowedOutcomes, request.stepId);
849
+ // Apply frontend output: last activity output for expressions (outputs.*); outcome/output/completer go into variables for audit UI
850
+ const userInput = request.userInput || {};
851
+ const lastActivityOutput = userInput;
852
+ const variableUpdatesResume = this.getVariableUpdatesFromOutput(workflow, request.stepId, userInput);
853
+ const sessionUser = this.getSessionUser();
854
+ const completerId = sessionUser?.id;
855
+ const completerLabel = sessionUser?.title ?? sessionUser?.name ?? completerId;
856
+ const resumeVariablePatch = {
857
+ ...variableUpdatesResume,
858
+ [`${request.stepId}_outcome`]: outcome,
859
+ [`${request.stepId}_activityOutput`]: userInput,
860
+ };
861
+ if (completerId) {
862
+ resumeVariablePatch[`${request.stepId}_completedByUserId`] = completerId;
863
+ }
864
+ if (completerLabel) {
865
+ resumeVariablePatch[`${request.stepId}_completedByLabel`] = completerLabel;
866
+ }
867
+ else {
868
+ resumeVariablePatch[`${request.stepId}_completedByLabel`] = completerId ? String(completerId) : 'System';
869
+ }
870
+ state = {
871
+ ...state,
872
+ variables: {
873
+ ...state.variables,
874
+ ...resumeVariablePatch,
875
+ },
876
+ lastActivityOutput,
877
+ lastUpdated: new Date(),
878
+ };
879
+ // Find next activity based on outcome from frontend (use normalized outcome)
880
+ const nextConnection = this.findWorkflowConnection(connections, request.stepId, outcome);
881
+ if (!nextConnection) {
882
+ // No next activity → workflow completed
883
+ console.log('[AXCWorkflowExecutionService] ✅ No next activity found - workflow completed');
884
+ state = {
885
+ ...state,
886
+ status: 'completed',
887
+ currentStepId: undefined,
888
+ output: state.variables,
889
+ lastActivityOutput,
890
+ };
891
+ console.log('[AXCWorkflowExecutionService] 📝 Updating instance to completed state');
892
+ await this.updateInstanceFromState(request.instanceId, state);
893
+ return {
894
+ output: { outcome, userInput: request.userInput },
895
+ outcomes: { [outcome]: true },
896
+ nextTask: null,
897
+ state,
898
+ };
899
+ }
900
+ // 🎯 KEY LOGIC: Execute all backend activities until we reach next frontend activity
901
+ let currentActivity = this.findActivityInGraph(workflow.graph, nextConnection.target.activtyName);
902
+ let lastActivityOutputResume = lastActivityOutput;
903
+ let executionCount = 0;
904
+ const maxExecutions = 500;
905
+ if (!currentActivity) {
906
+ console.error(`[BackendWorkflowEngineService] ❌ Next activity '${nextConnection.target.activtyName}' not found in graph`);
907
+ state = {
908
+ ...state,
909
+ status: 'error',
910
+ currentStepId: undefined,
911
+ };
912
+ await this.updateInstanceFromState(request.instanceId, state);
913
+ throw new Error(`Next activity '${nextConnection.target.activtyName}' not found in workflow graph`);
914
+ }
915
+ while (currentActivity && executionCount < maxExecutions) {
916
+ executionCount++;
917
+ // Map activity name (registry key) to activity type
918
+ const activityType = currentActivity.name;
919
+ // Determine execution mode (async)
920
+ const executionMode = await this.determineExecutionMode(activityType, currentActivity);
921
+ // Get activity definition to retrieve taskType (taskType === 'human-task' → suspend for cartable)
922
+ const activityDef = await this.activityDefinitionService.getActivityByName(activityType);
923
+ let taskType = currentActivity.metadata?.['taskType'] ?? activityDef?.taskType ?? 'ui-activity';
924
+ // Defensive: human-task and cartable must suspend (same as run())
925
+ if (this.isTaskBoardSuspendGraphActivity(activityType)) {
926
+ if (activityDef?.taskType === 'human-task')
927
+ taskType = 'human-task';
928
+ }
929
+ const effectiveExecutionModeResume = taskType === 'human-task' && executionMode === 'backend'
930
+ ? 'frontend'
931
+ : this.isTaskBoardSuspendGraphActivity(activityType) &&
932
+ (activityDef?.taskType === 'human-task' || taskType === 'human-task')
933
+ ? executionMode === 'backend'
934
+ ? 'frontend'
935
+ : executionMode
936
+ : executionMode;
937
+ // If frontend activity → stop and return as pendingTask
938
+ if (effectiveExecutionModeResume === 'frontend' || effectiveExecutionModeResume === 'both') {
939
+ const pendingTask = await this.createTaskFromActivity(currentActivity, state);
940
+ // Extract assignment and task metadata from activity inputs (for human-task activities)
941
+ const resolvedTaskType = taskType === 'human-task' || pendingTask.taskType === 'human-task' ? 'human-task' : pendingTask.taskType;
942
+ let bookmarkPayload = {
943
+ activityType,
944
+ activityName: currentActivity.name,
945
+ taskToken: pendingTask.taskToken, // Store taskToken for resume
946
+ taskType: resolvedTaskType, // Add taskType to payload
947
+ };
948
+ // For human-task activities, extract assignment and task metadata from inputs
949
+ if (resolvedTaskType === 'human-task' && pendingTask.input) {
950
+ const inputs = pendingTask.input;
951
+ // Assignment metadata (normalize to array; expression may return single id e.g. {{ variables.managerId }})
952
+ bookmarkPayload['assignedUserIds'] = this.normalizeUserIds(inputs['assignedUserIds']);
953
+ bookmarkPayload['candidateUserIds'] = this.normalizeUserIds(inputs['candidateUserIds']);
954
+ bookmarkPayload['candidateRoleIds'] = this.normalizeUserIds(inputs['candidateRoleIds']);
955
+ // Task metadata
956
+ bookmarkPayload['title'] = this.resolveHumanTaskBookmarkTitle(inputs, activityDef, currentActivity);
957
+ bookmarkPayload['description'] = inputs['description'] || null;
958
+ bookmarkPayload['priority'] = inputs['priority'] || 'Normal';
959
+ bookmarkPayload['dueDate'] = inputs['dueDate'] || null;
960
+ // UI configuration
961
+ bookmarkPayload['layout'] = inputs['layout'] || null;
962
+ bookmarkPayload['actions'] = inputs['actions'] || null;
963
+ bookmarkPayload['context'] = inputs['context'] || {};
964
+ }
965
+ if (activityType === workflow_management_const_1.WorkflowManagementRootConfig.activities.cartable) {
966
+ bookmarkPayload['assignedUserIds'] = [];
967
+ }
968
+ if (resolvedTaskType === 'human-task') {
969
+ const htInputs = pendingTask.input;
970
+ this.logHumanTaskBookmarkAssignmentTrace({
971
+ phase: 'engine-resume',
972
+ instanceId: request.instanceId,
973
+ workflowDefinitionName: workflow.name,
974
+ activityId: currentActivity.id,
975
+ activityType,
976
+ rawAssignedUserIds: htInputs?.['assignedUserIds'],
977
+ normalizedAssignedUserIds: bookmarkPayload['assignedUserIds'],
978
+ variables: state.variables,
979
+ });
980
+ }
981
+ // Create bookmark for frontend activity
982
+ // Store all metadata in bookmark payload (replaces Work Item)
983
+ await this.createBookmark(request.instanceId, currentActivity.id, 'user-task', bookmarkPayload);
984
+ // Note: Work Item creation removed - all metadata stored in bookmark payload
985
+ // Set status: task-board activities → suspended, else running (form/popup)
986
+ const isTaskBoardSuspendResume = this.isTaskBoardSuspendGraphActivity(activityType);
987
+ state = {
988
+ ...state,
989
+ lastActivityOutput: lastActivityOutputResume,
990
+ status: isTaskBoardSuspendResume ? 'suspended' : 'running',
991
+ currentStepId: currentActivity.id,
992
+ };
993
+ await this.updateInstanceFromState(request.instanceId, state);
994
+ console.log(`[BackendWorkflowEngineService] ✅ Workflow suspended at frontend activity: ${activityType} (taskType: ${taskType}, status: ${state.status})`);
995
+ return {
996
+ output: { outcome, userInput: request.userInput },
997
+ outcomes: { [outcome]: true },
998
+ nextTask: pendingTask,
999
+ state,
1000
+ };
1001
+ }
1002
+ // Backend activity → execute it
1003
+ console.log(`[BackendWorkflowEngineService] ⚙️ Executing backend activity '${currentActivity.name || currentActivity.id}' (${activityType})`);
1004
+ const executionResult = await this.executeBackendActivityLocally(currentActivity, state, lastActivityOutputResume);
1005
+ lastActivityOutputResume = executionResult.output;
1006
+ const isSetVariable = currentActivity.name === 'workflow-activity:set-variable';
1007
+ const variableUpdatesResumeLoop = isSetVariable
1008
+ ? executionResult.output
1009
+ : this.getVariableUpdatesFromOutput(workflow, currentActivity.id, executionResult.output);
1010
+ const backendOutcome = Object.keys(executionResult.outcomes)[0] || 'Done';
1011
+ const sessionUserResume = this.getSessionUser();
1012
+ const backendAuditResume = {
1013
+ [`${currentActivity.id}_outcome`]: backendOutcome,
1014
+ [`${currentActivity.id}_activityOutput`]: executionResult.output,
1015
+ };
1016
+ if (sessionUserResume?.id) {
1017
+ backendAuditResume[`${currentActivity.id}_completedByUserId`] = sessionUserResume.id;
1018
+ backendAuditResume[`${currentActivity.id}_completedByLabel`] =
1019
+ sessionUserResume.title || sessionUserResume.name || sessionUserResume.id;
1020
+ }
1021
+ else {
1022
+ backendAuditResume[`${currentActivity.id}_completedByLabel`] = 'System';
1023
+ }
1024
+ state = {
1025
+ ...state,
1026
+ variables: {
1027
+ ...state.variables,
1028
+ ...(typeof variableUpdatesResumeLoop === 'object' && variableUpdatesResumeLoop !== null
1029
+ ? variableUpdatesResumeLoop
1030
+ : {}),
1031
+ ...backendAuditResume,
1032
+ },
1033
+ lastActivityOutput: lastActivityOutputResume,
1034
+ currentStepId: currentActivity.id,
1035
+ lastUpdated: new Date(),
1036
+ };
1037
+ await this.updateInstanceFromState(request.instanceId, state);
1038
+ // Find next activity based on outcome (backend execution result)
1039
+ const nextConn = this.findWorkflowConnection(connections, currentActivity.id, backendOutcome);
1040
+ if (!nextConn) {
1041
+ // No next activity → workflow completed
1042
+ state = {
1043
+ ...state,
1044
+ status: 'completed',
1045
+ currentStepId: undefined,
1046
+ output: state.variables,
1047
+ lastActivityOutput: lastActivityOutputResume,
1048
+ };
1049
+ await this.updateInstanceFromState(request.instanceId, state);
1050
+ return {
1051
+ output: state.variables,
1052
+ outcomes: { Done: true },
1053
+ nextTask: null,
1054
+ state,
1055
+ };
1056
+ }
1057
+ // Find next activity
1058
+ const nextActivity = this.findActivityInGraph(workflow.graph, nextConn.target.activtyName);
1059
+ if (!nextActivity) {
1060
+ console.error(`[BackendWorkflowEngineService] ❌ Next activity '${nextConn.target.activtyName}' not found in graph`);
1061
+ state = {
1062
+ ...state,
1063
+ status: 'error',
1064
+ currentStepId: undefined,
1065
+ };
1066
+ await this.updateInstanceFromState(request.instanceId, state);
1067
+ throw new Error(`Next activity '${nextConn.target.activtyName}' not found in workflow graph`);
1068
+ }
1069
+ currentActivity = nextActivity;
1070
+ }
1071
+ // If we exit loop due to max executions, mark as error
1072
+ if (executionCount >= maxExecutions) {
1073
+ console.error(`[BackendWorkflowEngineService] ❌ Maximum execution count (${maxExecutions}) reached - possible infinite loop`);
1074
+ state = {
1075
+ ...state,
1076
+ status: 'error',
1077
+ currentStepId: undefined,
1078
+ };
1079
+ await this.updateInstanceFromState(request.instanceId, state);
1080
+ throw new Error(`Workflow execution exceeded maximum steps (${maxExecutions}) - possible infinite loop`);
1081
+ }
1082
+ // If we exit loop, workflow is complete
1083
+ state = {
1084
+ ...state,
1085
+ status: 'completed',
1086
+ currentStepId: undefined,
1087
+ output: state.variables,
1088
+ lastActivityOutput: lastActivityOutputResume,
1089
+ };
1090
+ await this.updateInstanceFromState(request.instanceId, state);
1091
+ return {
1092
+ output: state.variables,
1093
+ outcomes: { Done: true },
1094
+ nextTask: null,
1095
+ state,
1096
+ };
1097
+ }
1098
+ /**
1099
+ * Get current workflow execution state.
1100
+ */
1101
+ async getState(request) {
1102
+ // Get instance from IndexedDB
1103
+ const instance = await this.getInstance(request.instanceId);
1104
+ if (!instance) {
1105
+ throw new Error(`Workflow instance not found: ${request.instanceId}`);
1106
+ }
1107
+ // Convert instance to state (async - needs bookmark lookup)
1108
+ return await this.instanceToInstanceState(instance);
1109
+ }
1110
+ /**
1111
+ * Restores a suspended task-board step when the user declines a pre-interactive continuation prompt.
1112
+ * Re-opens the human-task bookmark on the task board and removes the aborted inline step bookmark.
1113
+ */
1114
+ async revertResumeAfterDeclinedInteractiveContinuation(request) {
1115
+ try {
1116
+ const instance = await this.getInstance(request.instanceId);
1117
+ if (!instance) {
1118
+ return { success: false, error: `Workflow instance not found: ${request.instanceId}` };
1119
+ }
1120
+ if (request.abortedStepId) {
1121
+ const abortedBookmarks = await this.store.getBookmarksByInstanceAndActivity(request.instanceId, request.abortedStepId, false);
1122
+ for (const bookmark of abortedBookmarks) {
1123
+ if (!bookmark.isConsumed) {
1124
+ bookmark.isConsumed = true;
1125
+ await this.store.updateBookmark(bookmark);
1126
+ }
1127
+ }
1128
+ }
1129
+ const suspendedBookmarks = await this.store.getBookmarksByInstanceAndActivity(request.instanceId, request.suspendedStepId, false);
1130
+ let restoredBookmark = (request.bookmarkId
1131
+ ? suspendedBookmarks.find((bookmark) => bookmark.id === request.bookmarkId)
1132
+ : null) ?? suspendedBookmarks[0];
1133
+ if (!restoredBookmark) {
1134
+ return { success: false, error: 'Suspended step bookmark not found' };
1135
+ }
1136
+ const payload = this.parseBookmarkPayloadJson(restoredBookmark.payloadJson) ?? {};
1137
+ const taskToken = this.generateTaskToken(request.instanceId, request.suspendedStepId);
1138
+ payload['taskToken'] = taskToken;
1139
+ restoredBookmark.payloadJson = JSON.stringify(payload);
1140
+ restoredBookmark.isConsumed = false;
1141
+ await this.store.updateBookmark(restoredBookmark);
1142
+ const state = await this.getState({ instanceId: request.instanceId });
1143
+ const revertedState = {
1144
+ ...state,
1145
+ status: 'suspended',
1146
+ currentStepId: request.suspendedStepId,
1147
+ lastUpdated: new Date(),
1148
+ };
1149
+ await this.updateInstanceFromState(request.instanceId, revertedState);
1150
+ return {
1151
+ success: true,
1152
+ state: revertedState,
1153
+ };
1154
+ }
1155
+ catch (error) {
1156
+ const message = error instanceof Error ? error.message : 'Failed to revert workflow resume';
1157
+ return { success: false, error: message };
1158
+ }
1159
+ }
1160
+ /**
1161
+ * Claim a pooled task (cartable or human-task with candidates only): assign current user without resuming.
1162
+ */
1163
+ async claimTask(request) {
1164
+ const rawUserId = this.getSessionUser()?.id;
1165
+ if (rawUserId === undefined || rawUserId === null || rawUserId === '') {
1166
+ return { success: false, error: 'You must be signed in to claim a task' };
1167
+ }
1168
+ const uid = String(rawUserId);
1169
+ const dexieInstance = await this.getInstance(request.instanceId).catch(() => null);
1170
+ if (!dexieInstance) {
1171
+ return this.claimTaskOnWorkflowInstanceEntity(request, uid);
1172
+ }
1173
+ const state = await this.getState({ instanceId: request.instanceId }).catch(() => null);
1174
+ if (!state || state.status !== 'suspended') {
1175
+ return { success: false, error: 'Workflow instance is not suspended or was not found' };
1176
+ }
1177
+ if (state.currentStepId && state.currentStepId !== request.stepId) {
1178
+ return { success: false, error: 'Step does not match the current suspended step' };
1179
+ }
1180
+ const bookmarks = await this.getActiveBookmarks(request.instanceId);
1181
+ const bookmark = bookmarks.find((b) => b.id === request.bookmarkId && b.activityId === request.stepId);
1182
+ if (!bookmark) {
1183
+ return { success: false, error: 'Bookmark not found or already completed' };
1184
+ }
1185
+ const payload = this.parseBookmarkPayloadJson(bookmark.payloadJson);
1186
+ if (!payload) {
1187
+ return { success: false, error: 'Invalid bookmark payload' };
1188
+ }
1189
+ const activityType = String(payload['activityType'] ?? '');
1190
+ const assigned = this.normalizeUserIds(payload['assignedUserIds']) ?? [];
1191
+ const candidates = this.normalizeUserIds(payload['candidateUserIds']) ?? [];
1192
+ if (assigned.length > 0) {
1193
+ return { success: false, error: 'This task is already claimed' };
1194
+ }
1195
+ const isCartable = activityType === workflow_management_const_1.WorkflowManagementRootConfig.activities.cartable;
1196
+ const isPooledHuman = activityType === workflow_management_const_1.WorkflowManagementRootConfig.activities.humanTask && candidates.length > 0;
1197
+ if (!isCartable && !isPooledHuman) {
1198
+ return { success: false, error: 'This task cannot be claimed' };
1199
+ }
1200
+ if (isCartable && candidates.length === 0) {
1201
+ return { success: false, error: 'Cartable task has no candidate users' };
1202
+ }
1203
+ const candidateSet = new Set(candidates.map((c) => String(c)));
1204
+ if (!candidateSet.has(uid)) {
1205
+ return { success: false, error: 'You are not in the candidate list for this task' };
1206
+ }
1207
+ payload['assignedUserIds'] = [uid];
1208
+ payload['candidateUserIds'] = [];
1209
+ bookmark.payloadJson = JSON.stringify(payload);
1210
+ await this.store.updateBookmark(bookmark);
1211
+ const instance = await this.getInstance(request.instanceId);
1212
+ if (instance) {
1213
+ await this.updateInstanceInEntityService(instance);
1214
+ }
1215
+ return { success: true };
1216
+ }
1217
+ /**
1218
+ * Claim when execution state lives only on `WorkflowManagement.WorkflowInstance` (seeded / entity-only rows).
1219
+ */
1220
+ async claimTaskOnWorkflowInstanceEntity(request, uid) {
1221
+ const entityName = 'WorkflowManagement.WorkflowInstance';
1222
+ let row;
1223
+ try {
1224
+ row = (await this.entityStorageService.getOne(entityName, request.instanceId));
1225
+ }
1226
+ catch {
1227
+ return { success: false, error: 'Workflow instance is not suspended or was not found' };
1228
+ }
1229
+ const subStatus = String(row['subStatus'] ?? '');
1230
+ if (subStatus !== 'Suspended') {
1231
+ return { success: false, error: 'Workflow instance is not suspended or was not found' };
1232
+ }
1233
+ const wi = row['workflowInstance'];
1234
+ const bookmarksUnknown = wi?.['bookmarks'];
1235
+ const bookmarks = Array.isArray(bookmarksUnknown) ? [...bookmarksUnknown] : [];
1236
+ const idx = bookmarks.findIndex((b) => {
1237
+ if (typeof b !== 'object' || b === null) {
1238
+ return false;
1239
+ }
1240
+ const br = b;
1241
+ return br['id'] === request.bookmarkId && br['activityId'] === request.stepId;
1242
+ });
1243
+ if (idx < 0) {
1244
+ return { success: false, error: 'Bookmark not found or already completed' };
1245
+ }
1246
+ const bookmarkRow = bookmarks[idx];
1247
+ const payloadJson = typeof bookmarkRow['payloadJson'] === 'string' ? bookmarkRow['payloadJson'] : null;
1248
+ let payload = payloadJson ? this.parseBookmarkPayloadJson(payloadJson) : null;
1249
+ if (!payload && bookmarkRow['payload'] && typeof bookmarkRow['payload'] === 'object') {
1250
+ payload = { ...bookmarkRow['payload'] };
1251
+ }
1252
+ if (!payload) {
1253
+ return { success: false, error: 'Invalid bookmark payload' };
1254
+ }
1255
+ const activityType = String(payload['activityType'] ?? '');
1256
+ const assigned = this.normalizeUserIds(payload['assignedUserIds']) ?? [];
1257
+ const candidates = this.normalizeUserIds(payload['candidateUserIds']) ?? [];
1258
+ if (assigned.length > 0) {
1259
+ return { success: false, error: 'This task is already claimed' };
1260
+ }
1261
+ const isCartable = activityType === workflow_management_const_1.WorkflowManagementRootConfig.activities.cartable;
1262
+ const isPooledHuman = activityType === workflow_management_const_1.WorkflowManagementRootConfig.activities.humanTask && candidates.length > 0;
1263
+ if (!isCartable && !isPooledHuman) {
1264
+ return { success: false, error: 'This task cannot be claimed' };
1265
+ }
1266
+ if (isCartable && candidates.length === 0) {
1267
+ return { success: false, error: 'Cartable task has no candidate users' };
1268
+ }
1269
+ const candidateSet = new Set(candidates.map((c) => String(c)));
1270
+ if (!candidateSet.has(uid)) {
1271
+ return { success: false, error: 'You are not in the candidate list for this task' };
1272
+ }
1273
+ payload['assignedUserIds'] = [uid];
1274
+ payload['candidateUserIds'] = [];
1275
+ const nextPayloadJson = JSON.stringify(payload);
1276
+ const nextBookmark = {
1277
+ ...bookmarkRow,
1278
+ payload,
1279
+ payloadJson: nextPayloadJson,
1280
+ };
1281
+ const nextBookmarks = [...bookmarks];
1282
+ nextBookmarks[idx] = nextBookmark;
1283
+ if (!wi) {
1284
+ return { success: false, error: 'Workflow instance is not suspended or was not found' };
1285
+ }
1286
+ const nextWi = {
1287
+ ...wi,
1288
+ bookmarks: nextBookmarks,
1289
+ };
1290
+ try {
1291
+ await this.entityStorageService.updateOne(entityName, request.instanceId, {
1292
+ workflowInstance: nextWi,
1293
+ updatedAt: new Date().toISOString(),
1294
+ });
1295
+ }
1296
+ catch (error) {
1297
+ console.warn('[BackendWorkflowEngineService] claimTask entity update failed', error);
1298
+ return { success: false, error: 'Failed to persist claim' };
1299
+ }
1300
+ return { success: true };
1301
+ }
1302
+ /**
1303
+ * Reassign a human-task bookmark to the current user (permission-gated; does not resume).
1304
+ */
1305
+ async reassignTaskToSelf(request) {
1306
+ const rawUserId = this.getSessionUser()?.id;
1307
+ if (rawUserId === undefined || rawUserId === null || rawUserId === '') {
1308
+ return { success: false, error: 'You must be signed in to reassign a task' };
1309
+ }
1310
+ const uid = String(rawUserId);
1311
+ if (!this.canReassignTaskToSelf()) {
1312
+ return {
1313
+ success: false,
1314
+ error: 'You do not have permission to reassign this task to yourself',
1315
+ errorCode: workflow_engine_errors_1.AXP_WORKFLOW_ERROR_CODES.REASSIGN_NOT_ALLOWED,
1316
+ };
1317
+ }
1318
+ const dexieInstance = await this.getInstance(request.instanceId).catch(() => null);
1319
+ if (!dexieInstance) {
1320
+ return this.reassignTaskOnWorkflowInstanceEntity(request, uid);
1321
+ }
1322
+ const state = await this.getState({ instanceId: request.instanceId }).catch(() => null);
1323
+ if (!state || state.status !== 'suspended') {
1324
+ return { success: false, error: 'Workflow instance is not suspended or was not found' };
1325
+ }
1326
+ if (state.currentStepId && state.currentStepId !== request.stepId) {
1327
+ return { success: false, error: 'Step does not match the current suspended step' };
1328
+ }
1329
+ const bookmarks = await this.getActiveBookmarks(request.instanceId);
1330
+ const bookmark = bookmarks.find((b) => b.id === request.bookmarkId && b.activityId === request.stepId);
1331
+ if (!bookmark) {
1332
+ return { success: false, error: 'Bookmark not found or already completed' };
1333
+ }
1334
+ const payload = this.parseBookmarkPayloadJson(bookmark.payloadJson);
1335
+ if (!payload) {
1336
+ return { success: false, error: 'Invalid bookmark payload' };
1337
+ }
1338
+ const validation = this.validateHumanTaskReassignPayload(payload, uid);
1339
+ if (validation.ok === false) {
1340
+ return {
1341
+ success: false,
1342
+ error: validation.error,
1343
+ errorCode: validation.errorCode,
1344
+ };
1345
+ }
1346
+ const previousAssigned = validation.previousAssigned ?? [];
1347
+ payload['assignedUserIds'] = [uid];
1348
+ bookmark.payloadJson = JSON.stringify(payload);
1349
+ await this.store.updateBookmark(bookmark);
1350
+ const auditPatch = this.buildReassignAuditVariablePatch(request.stepId, previousAssigned, uid, state.variables);
1351
+ const nextState = {
1352
+ ...state,
1353
+ variables: {
1354
+ ...(state.variables || {}),
1355
+ ...auditPatch,
1356
+ },
1357
+ lastUpdated: new Date(),
1358
+ };
1359
+ await this.updateInstanceFromState(request.instanceId, nextState);
1360
+ const instance = await this.getInstance(request.instanceId);
1361
+ if (instance) {
1362
+ await this.updateInstanceInEntityService(instance);
1363
+ }
1364
+ return { success: true };
1365
+ }
1366
+ /**
1367
+ * Reassign when execution state lives only on `WorkflowManagement.WorkflowInstance` (entity-only rows).
1368
+ */
1369
+ async reassignTaskOnWorkflowInstanceEntity(request, uid) {
1370
+ const entityName = 'WorkflowManagement.WorkflowInstance';
1371
+ let row;
1372
+ try {
1373
+ row = (await this.entityStorageService.getOne(entityName, request.instanceId));
1374
+ }
1375
+ catch {
1376
+ return { success: false, error: 'Workflow instance is not suspended or was not found' };
1377
+ }
1378
+ const subStatus = String(row['subStatus'] ?? '');
1379
+ if (subStatus !== 'Suspended') {
1380
+ return { success: false, error: 'Workflow instance is not suspended or was not found' };
1381
+ }
1382
+ const wi = row['workflowInstance'];
1383
+ const bookmarksUnknown = wi?.['bookmarks'];
1384
+ const bookmarks = Array.isArray(bookmarksUnknown) ? [...bookmarksUnknown] : [];
1385
+ const idx = bookmarks.findIndex((b) => {
1386
+ if (typeof b !== 'object' || b === null) {
1387
+ return false;
1388
+ }
1389
+ const br = b;
1390
+ return br['id'] === request.bookmarkId && br['activityId'] === request.stepId;
1391
+ });
1392
+ if (idx < 0) {
1393
+ return { success: false, error: 'Bookmark not found or already completed' };
1394
+ }
1395
+ const bookmarkRow = bookmarks[idx];
1396
+ const payloadJson = typeof bookmarkRow['payloadJson'] === 'string' ? bookmarkRow['payloadJson'] : null;
1397
+ let payload = payloadJson ? this.parseBookmarkPayloadJson(payloadJson) : null;
1398
+ if (!payload && bookmarkRow['payload'] && typeof bookmarkRow['payload'] === 'object') {
1399
+ payload = { ...bookmarkRow['payload'] };
1400
+ }
1401
+ if (!payload) {
1402
+ return { success: false, error: 'Invalid bookmark payload' };
1403
+ }
1404
+ const validation = this.validateHumanTaskReassignPayload(payload, uid);
1405
+ if (validation.ok === false) {
1406
+ return {
1407
+ success: false,
1408
+ error: validation.error,
1409
+ errorCode: validation.errorCode,
1410
+ };
1411
+ }
1412
+ const previousAssigned = validation.previousAssigned ?? [];
1413
+ payload['assignedUserIds'] = [uid];
1414
+ const nextPayloadJson = JSON.stringify(payload);
1415
+ const nextBookmark = {
1416
+ ...bookmarkRow,
1417
+ payload,
1418
+ payloadJson: nextPayloadJson,
1419
+ };
1420
+ const nextBookmarks = [...bookmarks];
1421
+ nextBookmarks[idx] = nextBookmark;
1422
+ if (!wi) {
1423
+ return { success: false, error: 'Workflow instance is not suspended or was not found' };
1424
+ }
1425
+ const workflowState = wi['workflowState'] ?? {};
1426
+ const existingProperties = workflowState['properties'] ?? {};
1427
+ const auditPatch = this.buildReassignAuditVariablePatch(request.stepId, previousAssigned, uid, existingProperties);
1428
+ const properties = {
1429
+ ...existingProperties,
1430
+ ...auditPatch,
1431
+ };
1432
+ const nextWi = {
1433
+ ...wi,
1434
+ bookmarks: nextBookmarks,
1435
+ workflowState: {
1436
+ ...workflowState,
1437
+ properties,
1438
+ },
1439
+ };
1440
+ try {
1441
+ await this.entityStorageService.updateOne(entityName, request.instanceId, {
1442
+ workflowInstance: nextWi,
1443
+ updatedAt: new Date().toISOString(),
1444
+ });
1445
+ }
1446
+ catch (error) {
1447
+ console.warn('[BackendWorkflowEngineService] reassignTaskToSelf entity update failed', error);
1448
+ return { success: false, error: 'Failed to persist reassignment' };
1449
+ }
1450
+ return { success: true };
1451
+ }
1452
+ canReassignTaskToSelf() {
1453
+ return !!this.getSessionUser()?.id;
1454
+ }
1455
+ validateHumanTaskReassignPayload(payload, uid) {
1456
+ const activityType = String(payload['activityType'] ?? '');
1457
+ if (activityType !== workflow_management_const_1.WorkflowManagementRootConfig.activities.humanTask) {
1458
+ return { ok: false, error: 'Only human tasks can be reassigned to yourself' };
1459
+ }
1460
+ const assigned = this.normalizeUserIds(payload['assignedUserIds']) ?? [];
1461
+ if (assigned.length === 0) {
1462
+ return { ok: false, error: 'This task has no assignee to reassign from' };
1463
+ }
1464
+ if (assigned.includes(uid)) {
1465
+ return { ok: false, error: 'You are already assigned to this task' };
1466
+ }
1467
+ // TODO(workflow): Require current user to be in candidateUserIds (or role candidates) before self-reassign.
1468
+ // Permission alone is sufficient for now; tighten assignee pool validation in a follow-up.
1469
+ return { ok: true, previousAssigned: assigned };
1470
+ }
1471
+ buildReassignAuditVariablePatch(stepId, fromUserIds, toUserId, existingVariables) {
1472
+ const at = new Date().toISOString();
1473
+ const entry = {
1474
+ stepId,
1475
+ fromUserIds,
1476
+ toUserId,
1477
+ at,
1478
+ };
1479
+ const priorHistory = existingVariables?.['taskReassignHistory'];
1480
+ const history = Array.isArray(priorHistory) ? [...priorHistory, entry] : [entry];
1481
+ return {
1482
+ [`${stepId}_reassignedToSelf`]: entry,
1483
+ taskReassignHistory: history,
1484
+ };
1485
+ }
1486
+ //#region ---- Task-Based Helper Methods ----
1487
+ /**
1488
+ * Activities that suspend for the task board (inbox), same completion path as human-task.
1489
+ */
1490
+ isTaskBoardSuspendGraphActivity(activityType) {
1491
+ return activityType === workflow_management_const_1.WorkflowManagementRootConfig.activities.humanTask || activityType === workflow_management_const_1.WorkflowManagementRootConfig.activities.cartable;
1492
+ }
1493
+ /**
1494
+ * Determine execution mode for an activity (async).
1495
+ *
1496
+ * Priority (highest to lowest):
1497
+ * 1. Activity instance's executionMode (from AXPActivity in workflow definition)
1498
+ * 2. ActivityDefinition's executionMode (from ActivityDefinitionService)
1499
+ * 3. Default: 'frontend'
1500
+ *
1501
+ * @param activityType - Activity type (e.g., 'workflow-activity:show-toast')
1502
+ * @param activity - Activity from workflow definition (AXPActivity)
1503
+ * @returns Promise of execution mode: 'frontend', 'backend', or 'both'
1504
+ */
1505
+ async determineExecutionMode(activityType, activity) {
1506
+ // 1. Check if executionMode is explicitly set in activity instance (highest priority)
1507
+ if (activity?.metadata && activity.metadata['executionMode']) {
1508
+ if (activityType === workflow_management_const_1.WorkflowManagementRootConfig.activities.humanTask) {
1509
+ console.log(`[BackendWorkflowEngineService] determineExecutionMode(${activityType}): from instance metadata →`, activity.metadata['executionMode']);
1510
+ }
1511
+ return activity.metadata['executionMode'];
1512
+ }
1513
+ // 2. Check cache
1514
+ const cached = this.activityDefinitionCache.get(activityType);
1515
+ if (cached && Date.now() - cached.cachedAt.getTime() < this.CACHE_TTL_MS) {
1516
+ if (activityType === workflow_management_const_1.WorkflowManagementRootConfig.activities.humanTask) {
1517
+ console.log(`[BackendWorkflowEngineService] determineExecutionMode(${activityType}): from cache →`, cached.executionMode);
1518
+ }
1519
+ return cached.executionMode;
1520
+ }
1521
+ // 3. Query ActivityDefinitionService
1522
+ try {
1523
+ const activityDef = await this.activityDefinitionService.getActivityByName(activityType);
1524
+ if (activityType === workflow_management_const_1.WorkflowManagementRootConfig.activities.humanTask) {
1525
+ console.log(`[BackendWorkflowEngineService] determineExecutionMode(${activityType}): from definition →`, {
1526
+ definitionFound: !!activityDef,
1527
+ executionMode: activityDef?.executionMode,
1528
+ taskType: activityDef?.taskType,
1529
+ });
1530
+ }
1531
+ if (activityDef?.executionMode) {
1532
+ this.activityDefinitionCache.set(activityType, {
1533
+ executionMode: activityDef.executionMode,
1534
+ cachedAt: new Date(),
1535
+ });
1536
+ return activityDef.executionMode;
1537
+ }
1538
+ }
1539
+ catch (error) {
1540
+ console.warn(`[BackendWorkflowEngineService] ⚠️ Could not get activity definition for ${activityType}:`, error);
1541
+ }
1542
+ // 4. Default to frontend
1543
+ const defaultMode = 'frontend';
1544
+ if (activityType === workflow_management_const_1.WorkflowManagementRootConfig.activities.humanTask) {
1545
+ console.log(`[BackendWorkflowEngineService] determineExecutionMode(${activityType}): using default →`, defaultMode);
1546
+ }
1547
+ this.activityDefinitionCache.set(activityType, {
1548
+ executionMode: defaultMode,
1549
+ cachedAt: new Date(),
1550
+ });
1551
+ return defaultMode;
1552
+ }
1553
+ //#endregion
1554
+ /**
1555
+ * Create a task from a workflow activity.
1556
+ * Inspired by Temporal's Activity Task and Elsa's Bookmark pattern.
1557
+ * Uses same expression scope (inputs, variables, outputs, context.eval) as backend execution.
1558
+ */
1559
+ async createTaskFromActivity(activity, state) {
1560
+ const rawInputs = activity.inputs || {};
1561
+ const scope = this.expressionScopeService.buildScopeFromState(state, this.ensureOutputsForScope(state.lastActivityOutput));
1562
+ const properties = await this.expressionEvaluator.evaluate(rawInputs, scope);
1563
+ if (rawInputs['persistInWorkflow'] !== undefined && properties['persistInWorkflow'] === undefined) {
1564
+ properties['persistInWorkflow'] = await this.expressionEvaluator.evaluate(rawInputs['persistInWorkflow'], scope);
1565
+ }
1566
+ // Activity name is the registry key (e.g., 'workflow-activity:show-toast')
1567
+ const activityType = activity.name;
1568
+ // Get executionMode from activity descriptor (async)
1569
+ const executionMode = await this.determineExecutionMode(activityType, activity);
1570
+ // Get activity definition for title and taskType (taskType === 'human-task' → suspend for cartable)
1571
+ const activityDef = await this.activityDefinitionService.getActivityByName(activityType);
1572
+ const taskType = activity.metadata?.['taskType'] ?? activityDef?.taskType ?? 'ui-activity';
1573
+ return {
1574
+ taskToken: this.generateTaskToken(state.instanceId, activity.id),
1575
+ activityId: activity.id,
1576
+ activityType,
1577
+ activityName: (0, multilanguage_util_1.resolveMultiLanguageString)(activityDef?.title) || activity.name || undefined,
1578
+ executionMode,
1579
+ taskType: taskType,
1580
+ input: executionMode === 'frontend' || executionMode === 'both' ? properties : undefined,
1581
+ config: executionMode === 'frontend' || executionMode === 'both' ? properties : undefined,
1582
+ continuation: activityDef?.workflowContinuation,
1583
+ };
1584
+ }
1585
+ /**
1586
+ * Build variables table for entity: only variables defined in workflow definition (name, title, value).
1587
+ */
1588
+ computeWorkflowVariablesTable(instance, definition) {
1589
+ const vars = instance.workflowState?.properties ?? {};
1590
+ const out = instance.workflowState?.output ?? {};
1591
+ const getValue = (key) => vars[key] ?? out[key];
1592
+ const formatValue = (v) => {
1593
+ if (v === null || v === undefined)
1594
+ return '';
1595
+ if (typeof v === 'object')
1596
+ return JSON.stringify(v);
1597
+ return String(v);
1598
+ };
1599
+ const defVars = definition?.variables ?? [];
1600
+ return defVars.map((v) => ({
1601
+ name: v.name,
1602
+ title: (0, multilanguage_util_1.resolveMultiLanguageString)(v.title, 'en-US') || v.name,
1603
+ value: formatValue(getValue(v.name)),
1604
+ }));
1605
+ }
1606
+ /**
1607
+ * Compute overview display fields for entity model (statusDisplay, step progress, etc.).
1608
+ */
1609
+ computeOverviewDisplayFields(instance, definition) {
1610
+ const workflowTitle = instance.name || instance.definitionId || instance.id;
1611
+ const statusDisplay = this.getWorkflowStatusDisplay(instance.status, instance.subStatus);
1612
+ const contexts = instance.workflowState?.activityExecutionContexts ?? [];
1613
+ const graph = definition?.graph;
1614
+ const allActivities = graph?.activities ?? [];
1615
+ const allConnections = graph?.connections ?? [];
1616
+ // Fallback to previous linear logic when definition graph is unavailable.
1617
+ if (!graph || allActivities.length === 0) {
1618
+ const completedCount = contexts.filter((ctx) => ctx.status === 'Completed').length;
1619
+ const hasRunning = contexts.some((ctx) => ctx.status === 'Running');
1620
+ const currentStepIndex = hasRunning ? completedCount + 1 : completedCount;
1621
+ const totalSteps = instance.workflowState?.totalSteps ?? (contexts.length > 0 ? contexts.length : 0);
1622
+ const progressPercentage = totalSteps > 0 ? Math.min(100, Math.round((currentStepIndex / totalSteps) * 100)) : 0;
1623
+ return { workflowTitle, statusDisplay, currentStepIndex, totalSteps, progressPercentage };
1624
+ }
1625
+ const completedSet = new Set(contexts
1626
+ .filter((ctx) => ctx.status === 'Completed')
1627
+ .map((ctx) => ctx.scheduledActivityNodeId)
1628
+ .filter((id) => !!id));
1629
+ const runningSet = new Set(contexts
1630
+ .filter((ctx) => ctx.status === 'Running')
1631
+ .map((ctx) => ctx.scheduledActivityNodeId)
1632
+ .filter((id) => !!id));
1633
+ const visitedSet = new Set([...completedSet, ...runningSet]);
1634
+ const currentStepId = Array.from(runningSet)[0] ?? undefined;
1635
+ // Extract chosen outcomes from workflow state (written as `${stepId}_outcome`).
1636
+ const outcomeByStep = new Map();
1637
+ const stateProperties = instance.workflowState?.properties ?? {};
1638
+ for (const [key, value] of Object.entries(stateProperties)) {
1639
+ if (!key.endsWith('_outcome') || typeof value !== 'string') {
1640
+ continue;
1641
+ }
1642
+ const stepId = key.slice(0, -'_outcome'.length);
1643
+ if (stepId) {
1644
+ outcomeByStep.set(stepId, value);
1645
+ }
1646
+ }
1647
+ // Build incoming map to infer start step when startActivityId is not set.
1648
+ const incomingMap = new Map();
1649
+ for (const connection of allConnections) {
1650
+ const targetId = connection.target.activtyName;
1651
+ incomingMap.set(targetId, (incomingMap.get(targetId) ?? 0) + 1);
1652
+ }
1653
+ let startStepId = graph.startActivityId;
1654
+ if (!startStepId) {
1655
+ const root = allActivities.find((activity) => (incomingMap.get(activity.id) ?? 0) === 0);
1656
+ startStepId = root?.id ?? allActivities[0]?.id;
1657
+ }
1658
+ // Resolve the "active path" by following decided outcomes and preferring visited targets.
1659
+ const resolveNextStepId = (stepId) => {
1660
+ const outgoing = allConnections.filter((connection) => connection.source.activtyName === stepId);
1661
+ if (outgoing.length === 0) {
1662
+ return null;
1663
+ }
1664
+ const chosenOutcome = outcomeByStep.get(stepId);
1665
+ if (chosenOutcome) {
1666
+ const exact = outgoing.find((connection) => connection.source.port === chosenOutcome);
1667
+ if (exact) {
1668
+ return exact.target.activtyName;
1669
+ }
1670
+ }
1671
+ if (currentStepId) {
1672
+ const toCurrent = outgoing.find((connection) => connection.target.activtyName === currentStepId);
1673
+ if (toCurrent) {
1674
+ return toCurrent.target.activtyName;
1675
+ }
1676
+ }
1677
+ const toVisited = outgoing.find((connection) => visitedSet.has(connection.target.activtyName));
1678
+ if (toVisited) {
1679
+ return toVisited.target.activtyName;
1680
+ }
1681
+ const donePort = outgoing.find((connection) => connection.source.port === 'Done');
1682
+ if (donePort) {
1683
+ return donePort.target.activtyName;
1684
+ }
1685
+ return outgoing[0]?.target.activtyName ?? null;
1686
+ };
1687
+ const path = [];
1688
+ const seen = new Set();
1689
+ const maxDepth = Math.max(1, allActivities.length * 3);
1690
+ let cursor = startStepId;
1691
+ while (cursor && !seen.has(cursor) && path.length < maxDepth) {
1692
+ path.push(cursor);
1693
+ seen.add(cursor);
1694
+ if (currentStepId && cursor === currentStepId) {
1695
+ break;
1696
+ }
1697
+ cursor = resolveNextStepId(cursor);
1698
+ }
1699
+ if (currentStepId && !path.includes(currentStepId)) {
1700
+ path.push(currentStepId);
1701
+ }
1702
+ const totalSteps = path.length > 0 ? path.length : allActivities.length;
1703
+ const completedCount = path.filter((stepId) => completedSet.has(stepId)).length;
1704
+ const hasRunning = !!currentStepId && path.includes(currentStepId);
1705
+ const currentStepIndex = Math.min(totalSteps, hasRunning ? completedCount + 1 : completedCount);
1706
+ const progressPercentage = instance.status === 'Finished'
1707
+ ? 100
1708
+ : totalSteps > 0
1709
+ ? Math.min(100, Math.round((currentStepIndex / totalSteps) * 100))
1710
+ : 0;
1711
+ return { workflowTitle, statusDisplay, currentStepIndex, totalSteps, progressPercentage };
1712
+ }
1713
+ /**
1714
+ * Compute runtime details for task board style overview fields.
1715
+ */
1716
+ computeRuntimeDetails(instance, definition, activeBookmarks) {
1717
+ const currentStepId = this.resolveCurrentStepId(instance, activeBookmarks);
1718
+ if (!definition?.graph || !currentStepId) {
1719
+ return {
1720
+ currentActivityTitle: 'N/A',
1721
+ nextActivityTitle: instance.status === 'Finished' ? 'Completed' : 'N/A',
1722
+ };
1723
+ }
1724
+ const graph = definition.graph;
1725
+ const currentActivity = this.findActivityInGraph(graph, currentStepId);
1726
+ const primaryBookmark = activeBookmarks.find((bookmark) => bookmark.activityId === currentStepId) ?? activeBookmarks[0] ?? null;
1727
+ const bookmarkPayload = this.parseBookmarkPayloadJson(primaryBookmark?.payloadJson);
1728
+ const currentActivityTitle = this.resolveActivityTitle(currentActivity, bookmarkPayload, currentStepId);
1729
+ const nextActivityTitle = this.resolveNextActivityTitle(graph, currentStepId, instance, definition);
1730
+ return {
1731
+ currentActivityTitle,
1732
+ nextActivityTitle,
1733
+ };
1734
+ }
1735
+ /**
1736
+ * Human-task / cartable bookmark types that surface on the task board.
1737
+ */
1738
+ isTaskBoardHumanBookmarkPayload(payload) {
1739
+ if (!payload) {
1740
+ return false;
1741
+ }
1742
+ const t = payload['activityType'];
1743
+ return t === workflow_management_const_1.WorkflowManagementRootConfig.activities.humanTask || t === workflow_management_const_1.WorkflowManagementRootConfig.activities.cartable;
1744
+ }
1745
+ /**
1746
+ * Primary user id for assignee column: suspended task-board bookmark (assigned, then candidate users),
1747
+ * otherwise last completed step with a persisted user id.
1748
+ */
1749
+ resolvePrimaryAssignUserId(instance, activeBookmarks) {
1750
+ const suspended = instance.subStatus === 'Suspended';
1751
+ if (suspended && activeBookmarks.length > 0) {
1752
+ const sorted = [...activeBookmarks].sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
1753
+ for (const bm of sorted) {
1754
+ const payload = this.parseBookmarkPayloadJson(bm.payloadJson);
1755
+ if (!this.isTaskBoardHumanBookmarkPayload(payload)) {
1756
+ continue;
1757
+ }
1758
+ const assigned = this.normalizeUserIds(payload?.['assignedUserIds']) ?? [];
1759
+ if (assigned.length > 0) {
1760
+ return assigned[0];
1761
+ }
1762
+ const candidates = this.normalizeUserIds(payload?.['candidateUserIds']) ?? [];
1763
+ if (candidates.length > 0) {
1764
+ return candidates[0];
1765
+ }
1766
+ }
1767
+ }
1768
+ return this.resolveLastPerformerUserId(instance);
1769
+ }
1770
+ /**
1771
+ * Last completed activity's `completedByUserId` from workflow state properties.
1772
+ */
1773
+ resolveLastPerformerUserId(instance) {
1774
+ const props = (instance.workflowState?.properties ?? {});
1775
+ const contexts = [...(instance.workflowState?.activityExecutionContexts ?? [])];
1776
+ contexts.sort((a, b) => new Date(a.startedAt).getTime() - new Date(b.startedAt).getTime());
1777
+ let lastId;
1778
+ for (const ctx of contexts) {
1779
+ const completed = ctx.status === 'Completed' || (ctx.completedAt != null && String(ctx.completedAt).trim().length > 0);
1780
+ if (!completed) {
1781
+ continue;
1782
+ }
1783
+ const nodeId = ctx.scheduledActivityNodeId;
1784
+ const uid = props[`${nodeId}_completedByUserId`];
1785
+ if (uid != null && String(uid).trim() !== '') {
1786
+ lastId = String(uid).trim();
1787
+ }
1788
+ }
1789
+ return lastId;
1790
+ }
1791
+ /**
1792
+ * Lookup user row for WorkflowInstance list/detail lookup column.
1793
+ */
1794
+ async resolveAssignUserLookupFields(userId) {
1795
+ if (!userId) {
1796
+ return {};
1797
+ }
1798
+ const entityName = 'SecurityManagement.User';
1799
+ try {
1800
+ const row = await this.entityStorageService.getOne(entityName, userId);
1801
+ const displayName = row && typeof row === 'object' && row !== null && 'displayName' in row
1802
+ ? String(row.displayName ?? '').trim()
1803
+ : '';
1804
+ const label = displayName.length > 0 ? displayName : userId;
1805
+ return {
1806
+ assignUser: { id: userId },
1807
+ assignUserRef: { id: userId, displayName: label },
1808
+ };
1809
+ }
1810
+ catch {
1811
+ return {
1812
+ assignUser: { id: userId },
1813
+ assignUserRef: { id: userId, displayName: userId },
1814
+ };
1815
+ }
1816
+ }
1817
+ /**
1818
+ * Resolve current step from active bookmark first, then running context.
1819
+ */
1820
+ resolveCurrentStepId(instance, activeBookmarks) {
1821
+ if (activeBookmarks.length > 0) {
1822
+ const latestBookmark = [...activeBookmarks].sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())[0];
1823
+ return latestBookmark.activityId ?? null;
1824
+ }
1825
+ const contexts = instance.workflowState?.activityExecutionContexts ?? [];
1826
+ const runningContext = contexts.find((ctx) => ctx.status === 'Running' && !ctx.completedAt);
1827
+ return runningContext?.scheduledActivityNodeId ?? null;
1828
+ }
1829
+ /**
1830
+ * Resolve friendly activity title using payload/title inputs and fallback label.
1831
+ */
1832
+ resolveActivityTitle(activity, bookmarkPayload, fallbackId) {
1833
+ const payloadTitle = bookmarkPayload?.['title'];
1834
+ if (typeof payloadTitle === 'string' && payloadTitle.trim().length > 0) {
1835
+ return payloadTitle.trim();
1836
+ }
1837
+ const inputTitle = activity?.inputs?.['title'];
1838
+ if (typeof inputTitle === 'string' && inputTitle.trim().length > 0) {
1839
+ return inputTitle.trim();
1840
+ }
1841
+ return this.formatReadableLabel(activity?.id ?? fallbackId);
1842
+ }
1843
+ /**
1844
+ * Resolve next activity title from workflow graph and known outcome.
1845
+ */
1846
+ resolveNextActivityTitle(graph, currentStepId, instance, definition) {
1847
+ const outgoing = (graph.connections ?? []).filter((connection) => connection.source.activtyName === currentStepId);
1848
+ if (outgoing.length === 0) {
1849
+ return instance.status === 'Finished' ? 'Completed' : 'N/A';
1850
+ }
1851
+ const currentOutcomeKey = `${currentStepId}_outcome`;
1852
+ const currentOutcome = instance.workflowState?.properties?.[currentOutcomeKey];
1853
+ if (typeof currentOutcome === 'string' && currentOutcome.length > 0) {
1854
+ const matched = outgoing.find((connection) => connection.source.port === currentOutcome);
1855
+ if (matched) {
1856
+ const target = this.findActivityInGraph(graph, matched.target.activtyName);
1857
+ return this.resolveActivityTitle(target, null, matched.target.activtyName);
1858
+ }
1859
+ }
1860
+ if (outgoing.length === 1) {
1861
+ const target = this.findActivityInGraph(graph, outgoing[0].target.activtyName);
1862
+ return this.resolveActivityTitle(target, null, outgoing[0].target.activtyName);
1863
+ }
1864
+ const nextOptions = outgoing.map((connection) => {
1865
+ const target = this.findActivityInGraph(graph, connection.target.activtyName);
1866
+ const targetTitle = this.resolveActivityTitle(target, null, connection.target.activtyName);
1867
+ const port = connection.source.port || 'Done';
1868
+ return `${port}: ${targetTitle}`;
1869
+ });
1870
+ return nextOptions.join(' | ');
1871
+ }
1872
+ /**
1873
+ * Parse bookmark payload safely.
1874
+ */
1875
+ parseBookmarkPayloadJson(payloadJson) {
1876
+ if (!payloadJson) {
1877
+ return null;
1878
+ }
1879
+ try {
1880
+ const parsed = JSON.parse(payloadJson);
1881
+ return parsed && typeof parsed === 'object' ? parsed : null;
1882
+ }
1883
+ catch {
1884
+ return null;
1885
+ }
1886
+ }
1887
+ /**
1888
+ * Convert technical identifier to readable title-case label.
1889
+ */
1890
+ formatReadableLabel(value) {
1891
+ return value
1892
+ .replace(/^workflow-activity:/, '')
1893
+ .replace(/([a-z])([A-Z])/g, '$1 $2')
1894
+ .replace(/[-_]/g, ' ')
1895
+ .split(' ')
1896
+ .filter((token) => token.length > 0)
1897
+ .map((token) => token.charAt(0).toUpperCase() + token.slice(1))
1898
+ .join(' ');
1899
+ }
1900
+ /**
1901
+ * Build a user-friendly task board status from workflow status and sub-status.
1902
+ * Returns plain English labels instead of translation keys.
1903
+ */
1904
+ getWorkflowStatusDisplay(status, subStatus) {
1905
+ const normalizedStatus = (status ?? '').toString().trim().toLowerCase();
1906
+ const normalizedSubStatus = (subStatus ?? '').toString().trim().toLowerCase();
1907
+ const stateKey = `${normalizedStatus}:${normalizedSubStatus}`;
1908
+ const combinedLabels = {
1909
+ 'running:executing': 'In Progress',
1910
+ 'running:suspended': 'Pending User Action',
1911
+ 'running:idle': 'Waiting',
1912
+ running: 'In Progress',
1913
+ 'finished:finished': 'Completed',
1914
+ 'finished:faulted': 'Failed',
1915
+ 'finished:cancelled': 'Cancelled',
1916
+ finished: 'Completed',
1917
+ };
1918
+ const exactMatch = combinedLabels[stateKey];
1919
+ if (exactMatch) {
1920
+ return exactMatch;
1921
+ }
1922
+ const statusOnlyMatch = combinedLabels[normalizedStatus];
1923
+ if (statusOnlyMatch) {
1924
+ return statusOnlyMatch;
1925
+ }
1926
+ if (normalizedSubStatus.includes('suspend')) {
1927
+ return 'Pending User Action';
1928
+ }
1929
+ if (normalizedSubStatus.includes('fault') || normalizedSubStatus.includes('error')) {
1930
+ return 'Failed';
1931
+ }
1932
+ if (normalizedSubStatus.includes('cancel')) {
1933
+ return 'Cancelled';
1934
+ }
1935
+ if (normalizedSubStatus.includes('finish') || normalizedSubStatus.includes('complete')) {
1936
+ return 'Completed';
1937
+ }
1938
+ if (normalizedSubStatus.includes('execut')) {
1939
+ return 'In Progress';
1940
+ }
1941
+ const fallbackTokens = [status, subStatus]
1942
+ .filter((value) => typeof value === 'string' && value.trim().length > 0)
1943
+ .map((value) => value.replace(/([a-z])([A-Z])/g, '$1 $2').trim());
1944
+ return fallbackTokens.length > 0 ? fallbackTokens.join(' - ') : 'Unknown';
1945
+ }
1946
+ /**
1947
+ * Save workflow instance to entity service for entity-based access.
1948
+ */
1949
+ async saveInstanceToEntityService(instance) {
1950
+ try {
1951
+ // Get active bookmarks for this instance to include in entity model
1952
+ const activeBookmarks = await this.getActiveBookmarks(instance.id);
1953
+ // Add bookmarks to instance for entity storage access
1954
+ const instanceWithBookmarks = {
1955
+ ...instance,
1956
+ bookmarks: activeBookmarks.map((b) => ({
1957
+ id: b.id,
1958
+ activityId: b.activityId,
1959
+ activityInstanceId: b.activityId, // For compatibility
1960
+ type: b.type,
1961
+ payload: b.payloadJson ? JSON.parse(b.payloadJson) : null,
1962
+ payloadJson: b.payloadJson,
1963
+ consumed: b.isConsumed,
1964
+ isConsumed: b.isConsumed,
1965
+ createdAt: b.createdAt,
1966
+ })),
1967
+ };
1968
+ const definition = await this.getDefinition(instance.definitionId);
1969
+ const overview = this.computeOverviewDisplayFields(instance, definition);
1970
+ const runtimeDetails = this.computeRuntimeDetails(instance, definition, activeBookmarks);
1971
+ const workflowVariablesTable = this.computeWorkflowVariablesTable(instance, definition);
1972
+ const assignUserFields = await this.resolveAssignUserLookupFields(this.resolvePrimaryAssignUserId(instance, activeBookmarks));
1973
+ const entityModel = {
1974
+ id: instance.id,
1975
+ definitionId: instance.definitionId,
1976
+ definitionVersionId: instance.definitionVersionId,
1977
+ version: instance.version,
1978
+ status: instance.status,
1979
+ subStatus: instance.subStatus,
1980
+ correlationId: instance.correlationId || undefined,
1981
+ name: instance.name || undefined,
1982
+ incidentCount: instance.incidentCount,
1983
+ parentWorkflowInstanceId: instance.parentWorkflowInstanceId || undefined,
1984
+ createdAt: instance.createdAt,
1985
+ updatedAt: instance.updatedAt,
1986
+ finishedAt: instance.finishedAt || undefined,
1987
+ workflowInstance: instanceWithBookmarks, // Include bookmarks
1988
+ workflowTitle: overview.workflowTitle,
1989
+ statusDisplay: overview.statusDisplay,
1990
+ startedAt: instance.createdAt,
1991
+ ...assignUserFields,
1992
+ currentActivityTitle: runtimeDetails.currentActivityTitle,
1993
+ nextActivityTitle: runtimeDetails.nextActivityTitle,
1994
+ currentStepIndex: overview.currentStepIndex,
1995
+ totalSteps: overview.totalSteps,
1996
+ progressPercentage: overview.progressPercentage,
1997
+ workflowVariablesTable,
1998
+ };
1999
+ const entityName = 'WorkflowManagement.WorkflowInstance';
2000
+ // Check if instance already exists
2001
+ try {
2002
+ const existing = await this.entityStorageService.getOne(entityName, entityModel.id);
2003
+ if (existing) {
2004
+ // Already exists - don't insert again, will be updated later
2005
+ console.log('[AXCWorkflowExecutionService] ℹ️ Instance already exists in entity service, will be updated later', {
2006
+ instanceId: instance.id,
2007
+ });
2008
+ return;
2009
+ }
2010
+ }
2011
+ catch (getError) {
2012
+ // Instance doesn't exist - proceed with insert
2013
+ }
2014
+ // Insert new instance
2015
+ await this.entityStorageService.insertOne(entityName, entityModel);
2016
+ console.log('[AXCWorkflowExecutionService] ✅ Inserted new instance in entity service', {
2017
+ instanceId: instance.id,
2018
+ status: instance.status,
2019
+ subStatus: instance.subStatus,
2020
+ });
2021
+ }
2022
+ catch (error) {
2023
+ console.warn('[AXCWorkflowExecutionService] Failed to save instance to entity service:', error);
2024
+ // Don't throw - IndexedDB is primary storage
2025
+ }
2026
+ }
2027
+ /**
2028
+ * Update workflow instance in entity service.
2029
+ * Uses upsert pattern: try update first, if fails then insert.
2030
+ */
2031
+ async updateInstanceInEntityService(instance) {
2032
+ try {
2033
+ // Get active bookmarks for this instance to include in entity model
2034
+ const activeBookmarks = await this.getActiveBookmarks(instance.id);
2035
+ // Add bookmarks to instance for entity storage access
2036
+ const instanceWithBookmarks = {
2037
+ ...instance,
2038
+ bookmarks: activeBookmarks.map((b) => ({
2039
+ id: b.id,
2040
+ activityId: b.activityId,
2041
+ activityInstanceId: b.activityId, // For compatibility
2042
+ type: b.type,
2043
+ payload: b.payloadJson ? JSON.parse(b.payloadJson) : null,
2044
+ payloadJson: b.payloadJson,
2045
+ consumed: b.isConsumed,
2046
+ isConsumed: b.isConsumed,
2047
+ createdAt: b.createdAt,
2048
+ })),
2049
+ };
2050
+ const definition = await this.getDefinition(instance.definitionId);
2051
+ const overview = this.computeOverviewDisplayFields(instance, definition);
2052
+ const runtimeDetails = this.computeRuntimeDetails(instance, definition, activeBookmarks);
2053
+ const workflowVariablesTable = this.computeWorkflowVariablesTable(instance, definition);
2054
+ const assignUserFields = await this.resolveAssignUserLookupFields(this.resolvePrimaryAssignUserId(instance, activeBookmarks));
2055
+ const entityModel = {
2056
+ id: instance.id,
2057
+ definitionId: instance.definitionId,
2058
+ definitionVersionId: instance.definitionVersionId,
2059
+ version: instance.version,
2060
+ status: instance.status,
2061
+ subStatus: instance.subStatus,
2062
+ correlationId: instance.correlationId || undefined,
2063
+ name: instance.name || undefined,
2064
+ incidentCount: instance.incidentCount,
2065
+ parentWorkflowInstanceId: instance.parentWorkflowInstanceId || undefined,
2066
+ createdAt: instance.createdAt,
2067
+ updatedAt: instance.updatedAt,
2068
+ finishedAt: instance.finishedAt || undefined,
2069
+ workflowInstance: instanceWithBookmarks, // Include bookmarks
2070
+ workflowTitle: overview.workflowTitle,
2071
+ statusDisplay: overview.statusDisplay,
2072
+ startedAt: instance.createdAt,
2073
+ ...assignUserFields,
2074
+ currentActivityTitle: runtimeDetails.currentActivityTitle,
2075
+ nextActivityTitle: runtimeDetails.nextActivityTitle,
2076
+ currentStepIndex: overview.currentStepIndex,
2077
+ totalSteps: overview.totalSteps,
2078
+ progressPercentage: overview.progressPercentage,
2079
+ workflowVariablesTable,
2080
+ };
2081
+ const entityName = 'WorkflowManagement.WorkflowInstance';
2082
+ // Try update first (upsert pattern)
2083
+ try {
2084
+ await this.entityStorageService.updateOne(entityName, entityModel.id, entityModel);
2085
+ console.log('[AXCWorkflowExecutionService] ✅ Updated instance in entity service', {
2086
+ instanceId: instance.id,
2087
+ status: instance.status,
2088
+ subStatus: instance.subStatus,
2089
+ });
2090
+ return; // Successfully updated, exit
2091
+ }
2092
+ catch (updateError) {
2093
+ // Update failed - instance doesn't exist, try insert
2094
+ console.log('[AXCWorkflowExecutionService] ℹ️ Update failed, trying insert', {
2095
+ instanceId: instance.id,
2096
+ error: updateError.message,
2097
+ });
2098
+ }
2099
+ // Try insert
2100
+ try {
2101
+ await this.entityStorageService.insertOne(entityName, entityModel);
2102
+ console.log('[AXCWorkflowExecutionService] ✅ Inserted instance in entity service', {
2103
+ instanceId: instance.id,
2104
+ status: instance.status,
2105
+ subStatus: instance.subStatus,
2106
+ });
2107
+ }
2108
+ catch (insertError) {
2109
+ // Insert might fail if instance was created between update and insert
2110
+ // Try update again as fallback
2111
+ try {
2112
+ await this.entityStorageService.updateOne(entityName, entityModel.id, entityModel);
2113
+ console.log('[AXCWorkflowExecutionService] ✅ Updated instance in entity service (after insert failed)', {
2114
+ instanceId: instance.id,
2115
+ status: instance.status,
2116
+ subStatus: instance.subStatus,
2117
+ });
2118
+ }
2119
+ catch (finalError) {
2120
+ console.warn('[AXCWorkflowExecutionService] Failed to upsert instance in entity service:', finalError);
2121
+ }
2122
+ }
2123
+ }
2124
+ catch (error) {
2125
+ console.warn('[AXCWorkflowExecutionService] Failed to update instance in entity service:', error);
2126
+ // Don't throw - IndexedDB is primary storage
2127
+ }
2128
+ }
2129
+ //#endregion
2130
+ //#region ---- Backend Activity Executors ----
2131
+ /**
2132
+ * Evaluates activity inputs against current workflow scope (same as backend execution).
2133
+ */
2134
+ async evaluateActivityInputs(activity, state, lastOutput) {
2135
+ const scope = this.expressionScopeService.buildScopeFromState(state, this.ensureOutputsForScope(lastOutput));
2136
+ return (await this.expressionEvaluator.evaluate(activity.inputs || {}, scope));
2137
+ }
2138
+ /**
2139
+ * After entity-create: link instance entity ref and persist {@link AXPRecordWorkflowInfo} on the row.
2140
+ */
2141
+ async linkEntityRecordAfterCreate(instanceId, activity, state, lastOutput, entityId) {
2142
+ const properties = await this.evaluateActivityInputs(activity, state, lastOutput);
2143
+ const entityType = typeof properties['entity'] === 'string' ? properties['entity'].trim() : '';
2144
+ const recordId = entityId?.trim();
2145
+ if (!entityType || !recordId) {
2146
+ return;
2147
+ }
2148
+ const instance = await this.store.getInstance(instanceId);
2149
+ const definitionId = instance?.definitionId ?? instance?.workflowState?.definitionId ?? state.workflowId ?? null;
2150
+ const correlationId = instance?.correlationId ?? instance?.workflowState?.correlationId ?? null;
2151
+ await (0, entity_workflow_info_sync_1.syncEntityRecordWorkflowInfo)(this.entityStorageService, this.store, {
2152
+ entityType,
2153
+ entityId: recordId,
2154
+ instanceId,
2155
+ definitionId: definitionId != null ? String(definitionId) : null,
2156
+ correlationId: correlationId != null ? String(correlationId) : null,
2157
+ });
2158
+ }
2159
+ /**
2160
+ * Execute backend activities locally via {@link WorkflowActivityRegistryService}.
2161
+ *
2162
+ * Uses WorkflowExpressionScopeService + WorkflowExpressionEvaluatorService for expression
2163
+ * evaluation (inputs, variables, outputs, context.eval) so backend activities get the
2164
+ * same expression handling as the platform ActivityExecutor.
2165
+ */
2166
+ async executeBackendActivityLocally(activity, state, lastOutput) {
2167
+ const rawInputs = activity.inputs || {};
2168
+ // Evaluate expressions using same scope as platform (inputs, variables, outputs = lastActivityOutput)
2169
+ const scope = this.expressionScopeService.buildScopeFromState(state, this.ensureOutputsForScope(lastOutput));
2170
+ const properties = (await this.expressionEvaluator.evaluate(rawInputs, scope));
2171
+ const activityType = activity.name;
2172
+ return this.activityRegistry.execute(activityType, properties, {
2173
+ entityStorage: this.entityStorageService,
2174
+ sessionService: this.sessionService,
2175
+ });
2176
+ }
2177
+ /**
2178
+ * Build variable updates from activity output using activity's outputToVariables (BPMN-style: activity → variable).
2179
+ * For each entry in activity.outputToVariables, sets variables[variableName] = output[outputPath].
2180
+ */
2181
+ getVariableUpdatesFromOutput(workflow, activityId, output) {
2182
+ const activity = this.findActivityInGraph(workflow.graph, activityId);
2183
+ const outputToVariables = activity?.outputToVariables;
2184
+ if (!outputToVariables || typeof outputToVariables !== 'object')
2185
+ return {};
2186
+ const updates = {};
2187
+ for (const [variableName, outputPath] of Object.entries(outputToVariables)) {
2188
+ const path = String(outputPath);
2189
+ const value = path.split('.').reduce((obj, key) => obj?.[key], output);
2190
+ if (value !== undefined)
2191
+ updates[variableName] = value;
2192
+ }
2193
+ return updates;
2194
+ }
2195
+ /**
2196
+ * Resolves human-task bookmark title from evaluated inputs, then context, then activity definition.
2197
+ */
2198
+ resolveHumanTaskBookmarkTitle(inputs, activityDef, currentActivity) {
2199
+ const rawTitle = inputs['title'];
2200
+ if (typeof rawTitle === 'string' && rawTitle.trim().length > 0) {
2201
+ return rawTitle.trim();
2202
+ }
2203
+ const ctx = inputs['context'];
2204
+ if (ctx != null && typeof ctx === 'object') {
2205
+ const composed = this.composeHumanTaskTitleFromContext(ctx);
2206
+ if (composed) {
2207
+ return composed;
2208
+ }
2209
+ }
2210
+ const activityTitle = activityDef?.title;
2211
+ const resolvedActivityTitle = activityTitle != null ? (0, multilanguage_util_1.resolveMultiLanguageString)(activityTitle) : '';
2212
+ return resolvedActivityTitle || currentActivity.name || 'Workflow Task';
2213
+ }
2214
+ /**
2215
+ * Builds title from `context._taskTitleParts` when activity title input did not resolve.
2216
+ */
2217
+ composeHumanTaskTitleFromContext(context) {
2218
+ const parts = context[AXP_WORKFLOW_TASK_CONTEXT_TITLE_PARTS_KEY];
2219
+ if (!Array.isArray(parts)) {
2220
+ return '';
2221
+ }
2222
+ return parts
2223
+ .map((part) => this.humanTaskContextLabel(part))
2224
+ .filter((segment) => segment.length > 0)
2225
+ .join(' — ');
2226
+ }
2227
+ humanTaskContextLabel(value) {
2228
+ if (value == null) {
2229
+ return '';
2230
+ }
2231
+ if (typeof value === 'string') {
2232
+ return value.trim();
2233
+ }
2234
+ if (typeof value === 'object') {
2235
+ return (0, multilanguage_util_1.resolveMultiLanguageString)(value)?.trim() ?? '';
2236
+ }
2237
+ return String(value).trim();
2238
+ }
2239
+ /**
2240
+ * Normalize user/role id field to array for bookmark payload (task board expects array).
2241
+ * Expression may evaluate to single string (e.g. {{ variables.managerId }}) or already array.
2242
+ */
2243
+ normalizeUserIds(value) {
2244
+ if (value == null)
2245
+ return null;
2246
+ const raw = Array.isArray(value) ? value : [value];
2247
+ const trimmed = raw.map((id) => String(id).trim()).filter((id) => id.length > 0);
2248
+ return trimmed.length > 0 ? trimmed : null;
2249
+ }
2250
+ /**
2251
+ * Diagnostic logging for human-task bookmark assignment (task board assignee).
2252
+ * Filter the browser console by `[WFM-LifecycleTaskTrace]`.
2253
+ */
2254
+ logHumanTaskBookmarkAssignmentTrace(info) {
2255
+ const v = info.variables ?? {};
2256
+ console.log('[WFM-LifecycleTaskTrace] human-task bookmark', {
2257
+ phase: info.phase,
2258
+ instanceId: info.instanceId,
2259
+ workflowDefinitionName: info.workflowDefinitionName,
2260
+ activityId: info.activityId,
2261
+ activityType: info.activityType,
2262
+ sessionUserId: this.getSessionUser()?.id ?? null,
2263
+ rawAssignedUserIds: info.rawAssignedUserIds,
2264
+ rawAssignedUserIdsType: typeof info.rawAssignedUserIds,
2265
+ normalizedAssignedUserIds: info.normalizedAssignedUserIds,
2266
+ lifecycleVariableSlice: {
2267
+ employeeId: v['employeeId'],
2268
+ assigneeUserId: v['assigneeUserId'],
2269
+ managerUserId: v['managerUserId'],
2270
+ initiatorUserId: v['initiatorUserId'],
2271
+ targetEmployeeStatusId: v['targetEmployeeStatusId'],
2272
+ questionnaireId: v['questionnaireId'],
2273
+ },
2274
+ });
2275
+ }
2276
+ //#endregion
2277
+ //#region ---- Bookmark Management ----
2278
+ /**
2279
+ * Create a bookmark for a workflow instance.
2280
+ * Aligns with ERD: BOOKMARK table structure.
2281
+ *
2282
+ * @param instanceId - Workflow instance ID
2283
+ * @param activityId - Activity ID where bookmark is created
2284
+ * @param type - Bookmark type (e.g., 'user-task', 'event', 'timer')
2285
+ * @param payload - Bookmark payload data
2286
+ * @returns Bookmark ID
2287
+ */
2288
+ async createBookmark(instanceId, activityId, type, payload) {
2289
+ const bookmarkId = (0, uuid_util_1.generateUuid)();
2290
+ const hash = (0, uuid_util_1.generateUuid)(); // Simple hash for now
2291
+ const now = new Date().toISOString();
2292
+ const bookmark = {
2293
+ id: bookmarkId,
2294
+ instanceId,
2295
+ activityId,
2296
+ type,
2297
+ hash,
2298
+ payloadJson: JSON.stringify(payload),
2299
+ isConsumed: false,
2300
+ createdAt: now,
2301
+ };
2302
+ await this.store.addBookmark(bookmark);
2303
+ console.log(`[BackendWorkflowEngineService] 📌 Created bookmark: ${bookmarkId} for activity ${activityId}`);
2304
+ return bookmarkId;
2305
+ }
2306
+ /**
2307
+ * Consume (mark as consumed) a bookmark for a workflow instance.
2308
+ *
2309
+ * @param instanceId - Workflow instance ID
2310
+ * @param activityId - Activity ID of the bookmark to consume
2311
+ */
2312
+ async consumeBookmark(instanceId, activityId) {
2313
+ const bookmarks = await this.store.getBookmarksByInstanceAndActivity(instanceId, activityId, true);
2314
+ for (const bookmark of bookmarks) {
2315
+ bookmark.isConsumed = true;
2316
+ await this.store.updateBookmark(bookmark);
2317
+ console.log(`[BackendWorkflowEngineService] ✅ Consumed bookmark: ${bookmark.id} for activity ${activityId}`);
2318
+ }
2319
+ }
2320
+ /**
2321
+ * Get active bookmarks for a workflow instance.
2322
+ *
2323
+ * @param instanceId - Workflow instance ID
2324
+ * @returns Array of active (non-consumed) bookmarks
2325
+ */
2326
+ async getActiveBookmarks(instanceId) {
2327
+ return this.store.getActiveBookmarks(instanceId);
2328
+ }
2329
+ //#endregion
2330
+ //#region ---- Instance Management ----
2331
+ /**
2332
+ * Convert workflow instance to instance state.
2333
+ *
2334
+ * Aligns with ERD structure:
2335
+ * - WORKFLOW_INSTANCE: header fields (status, subStatus, timestamps)
2336
+ * - WORKFLOW_INSTANCE_STATE: heavy state (input, output, properties, stateJson)
2337
+ * - BOOKMARK: separate table (used to derive currentStepId)
2338
+ */
2339
+ async instanceToInstanceState(instance) {
2340
+ const state = instance.workflowState;
2341
+ // Derive currentStepId from active bookmarks (preferred) or execution contexts
2342
+ let currentStepId;
2343
+ // Try to get from active bookmarks first
2344
+ const activeBookmarks = await this.getActiveBookmarks(instance.id);
2345
+ if (activeBookmarks.length > 0) {
2346
+ // Use the most recent bookmark's activityId
2347
+ const latestBookmark = activeBookmarks.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())[0];
2348
+ currentStepId = latestBookmark.activityId;
2349
+ }
2350
+ else {
2351
+ // Fallback to execution contexts
2352
+ const currentContext = state.activityExecutionContexts.find((ctx) => ctx.status === 'Running' && !ctx.completedAt);
2353
+ currentStepId = currentContext?.scheduledActivityNodeId;
2354
+ }
2355
+ // Map status from instance header fields (ERD: WORKFLOW_INSTANCE.status/subStatus)
2356
+ let status = 'running';
2357
+ if (instance.status === 'Finished') {
2358
+ if (instance.subStatus === 'Faulted') {
2359
+ status = 'error';
2360
+ }
2361
+ else {
2362
+ status = 'completed';
2363
+ }
2364
+ }
2365
+ else if (instance.subStatus === 'Suspended') {
2366
+ status = 'suspended';
2367
+ }
2368
+ // Extract state from workflowState (ERD: WORKFLOW_INSTANCE_STATE). Only last activity output is loaded.
2369
+ const properties = (state.properties || {});
2370
+ const { __lastActivityOutput, ...variables } = properties;
2371
+ const lastActivityOutput = __lastActivityOutput;
2372
+ const input = state.input || {};
2373
+ const output = state.output || {};
2374
+ // Normalize dates (instance.updatedAt is always string in AXPWorkflowInstance)
2375
+ const lastUpdated = instance.updatedAt ? new Date(instance.updatedAt) : new Date();
2376
+ return {
2377
+ instanceId: instance.id,
2378
+ workflowId: instance.definitionId,
2379
+ status,
2380
+ currentStepId,
2381
+ variables,
2382
+ lastActivityOutput,
2383
+ input,
2384
+ output,
2385
+ lastUpdated,
2386
+ };
2387
+ }
2388
+ /**
2389
+ * Update instance state in instance and save to IndexedDB.
2390
+ *
2391
+ * Aligns with ERD structure:
2392
+ * - WORKFLOW_INSTANCE: header fields (status, subStatus, timestamps, correlationId)
2393
+ * - WORKFLOW_INSTANCE_STATE: heavy state (input, output, properties, stateJson)
2394
+ *
2395
+ * Handles status transitions correctly:
2396
+ * - running → suspended (when frontend activity encountered)
2397
+ * - suspended → running → completed (when workflow finishes)
2398
+ * - any → error (on errors)
2399
+ */
2400
+ async updateInstanceFromState(instanceId, instanceState) {
2401
+ const instance = await this.getInstance(instanceId);
2402
+ if (!instance) {
2403
+ throw new Error(`Workflow instance not found: ${instanceId}`);
2404
+ }
2405
+ // Update instance from state
2406
+ const now = new Date().toISOString();
2407
+ // Map state status to instance status (ERD: WORKFLOW_INSTANCE.status/subStatus)
2408
+ let status = 'Running';
2409
+ let subStatus = 'Executing';
2410
+ // Handle status transitions
2411
+ if (instanceState.status === 'completed') {
2412
+ console.log('[BackendWorkflowEngineService] ✅ Marking workflow as Finished');
2413
+ status = 'Finished';
2414
+ subStatus = 'Finished';
2415
+ instance.finishedAt = now;
2416
+ }
2417
+ else if (instanceState.status === 'error') {
2418
+ status = 'Finished';
2419
+ subStatus = 'Faulted';
2420
+ instance.finishedAt = now;
2421
+ }
2422
+ else if (instanceState.status === 'suspended') {
2423
+ subStatus = 'Suspended';
2424
+ }
2425
+ else if (instanceState.status === 'running') {
2426
+ subStatus = 'Executing';
2427
+ }
2428
+ // Update WORKFLOW_INSTANCE header fields (ERD)
2429
+ instance.status = status;
2430
+ instance.subStatus = subStatus;
2431
+ instance.updatedAt = now;
2432
+ // Update WORKFLOW_INSTANCE_STATE heavy state (ERD). Only last activity output is persisted; exposed as scope.outputs.
2433
+ instance.workflowState.status = status;
2434
+ instance.workflowState.subStatus = subStatus;
2435
+ instance.workflowState.input = instanceState.input || {};
2436
+ instance.workflowState.output = instanceState.output || {};
2437
+ instance.workflowState.properties = {
2438
+ ...(instanceState.variables || {}),
2439
+ __lastActivityOutput: instanceState.lastActivityOutput ?? null,
2440
+ };
2441
+ instance.workflowState.updatedAt = now;
2442
+ if (instanceState.status === 'completed' || instanceState.status === 'error') {
2443
+ instance.workflowState.finishedAt = now;
2444
+ }
2445
+ // Update activity execution context if currentStepId changed
2446
+ if (instanceState.currentStepId) {
2447
+ // Mark previous contexts as completed
2448
+ instance.workflowState.activityExecutionContexts.forEach((ctx) => {
2449
+ if (ctx.status === 'Running' && ctx.scheduledActivityNodeId !== instanceState.currentStepId) {
2450
+ ctx.status = 'Completed';
2451
+ ctx.completedAt = now;
2452
+ ctx.isExecuting = false;
2453
+ }
2454
+ });
2455
+ // Find or create context for current step
2456
+ let existingContext = instance.workflowState.activityExecutionContexts.find((ctx) => ctx.scheduledActivityNodeId === instanceState.currentStepId && ctx.status === 'Running');
2457
+ if (!existingContext) {
2458
+ // Add new context
2459
+ existingContext = {
2460
+ id: `ctx-${instanceState.currentStepId}`,
2461
+ parentContextId: null,
2462
+ scheduledActivityNodeId: instanceState.currentStepId,
2463
+ ownerActivityNodeId: null,
2464
+ properties: {},
2465
+ activityState: null,
2466
+ dynamicVariables: [],
2467
+ status: 'Running',
2468
+ isExecuting: false,
2469
+ faultCount: 0,
2470
+ startedAt: now,
2471
+ completedAt: null,
2472
+ tag: null,
2473
+ };
2474
+ instance.workflowState.activityExecutionContexts.push(existingContext);
2475
+ }
2476
+ }
2477
+ else {
2478
+ // No current step - mark all contexts as completed
2479
+ instance.workflowState.activityExecutionContexts.forEach((ctx) => {
2480
+ if (ctx.status === 'Running') {
2481
+ ctx.status = 'Completed';
2482
+ ctx.completedAt = now;
2483
+ ctx.isExecuting = false;
2484
+ }
2485
+ });
2486
+ }
2487
+ // Save to IndexedDB
2488
+ await this.updateInstance(instance);
2489
+ // 🎯 Also update in entity service
2490
+ await this.updateInstanceInEntityService(instance);
2491
+ return instance;
2492
+ }
2493
+ /**
2494
+ * Get workflow instance from IndexedDB.
2495
+ */
2496
+ async getInstance(instanceId) {
2497
+ return this.store.getInstance(instanceId);
2498
+ }
2499
+ /**
2500
+ * Update workflow instance in store.
2501
+ */
2502
+ async updateInstance(instance) {
2503
+ instance.updatedAt = new Date().toISOString();
2504
+ await this.store.updateInstance(instance);
2505
+ }
2506
+ /**
2507
+ * Complete a frontend activity and continue workflow execution.
2508
+ *
2509
+ * This method is called when a frontend activity (ui-activity) completes execution.
2510
+ * It applies the frontend output to workflow state, finds the next activity based on outcome,
2511
+ * and executes all backend activities until reaching the next frontend activity or completion.
2512
+ *
2513
+ * Flow:
2514
+ * 1. Apply frontend output to workflow state
2515
+ * 2. Find next activity based on outcome from connections
2516
+ * 3. Execute ALL backend activities until hitting frontend activity or completion
2517
+ * 4. Return either nextTask (with new secure token) or completed status
2518
+ *
2519
+ * @param request - Front activity completion request with instanceId, activityNode, output, and outcome
2520
+ * @returns Response with nextTask (if frontend activity) or completion status
2521
+ */
2522
+ async frontActivtyComplete(request) {
2523
+ try {
2524
+ // Get current workflow instance state
2525
+ let state = await this.getState({ instanceId: request.instanceId });
2526
+ if (!state) {
2527
+ console.error('[BackendWorkflowEngineService] ❌ Workflow instance not found:', request.instanceId);
2528
+ throw new Error(`Workflow instance not found: ${request.instanceId}`);
2529
+ }
2530
+ // Check if workflow is suspended
2531
+ // If suspended, check if the activity being completed is a ui-activity (not human-task)
2532
+ // If it's a ui-activity, we can continue execution (workflow manager is handling it)
2533
+ // If it's a human-task, use resume() instead
2534
+ if (state.status === 'suspended') {
2535
+ // Find the activity being completed to check its taskType
2536
+ const workflow = await this.getDefinition(state.workflowId);
2537
+ if (!workflow) {
2538
+ console.error('[BackendWorkflowEngineService] ❌ Workflow definition not found:', state.workflowId);
2539
+ throw new Error(`Workflow definition not found: ${state.workflowId}`);
2540
+ }
2541
+ const activity = this.findActivityInGraph(workflow.graph, request.activityNode);
2542
+ if (activity) {
2543
+ const activityType = activity.name;
2544
+ const activityDef = await this.activityDefinitionService.getActivityByName(activityType);
2545
+ const taskType = activityDef?.taskType || 'ui-activity';
2546
+ // If it's a ui-activity, allow continuation (workflow manager is handling it)
2547
+ if (taskType === 'ui-activity') {
2548
+ // Change status to running to allow continuation
2549
+ state = {
2550
+ ...state,
2551
+ status: 'running',
2552
+ };
2553
+ }
2554
+ else {
2555
+ // It's a human-task, must use resume()
2556
+ console.warn('[BackendWorkflowEngineService] ⚠️ Workflow is suspended. Use resume() method instead.');
2557
+ throw new Error('Workflow is suspended. Use resume() method for suspended workflows.');
2558
+ }
2559
+ }
2560
+ else {
2561
+ // Activity not found, but allow continuation (might be edge case)
2562
+ state = {
2563
+ ...state,
2564
+ status: 'running',
2565
+ };
2566
+ }
2567
+ }
2568
+ // Load workflow definition
2569
+ const workflow = await this.getDefinition(state.workflowId);
2570
+ if (!workflow) {
2571
+ console.error('[BackendWorkflowEngineService] ❌ Workflow definition not found:', state.workflowId);
2572
+ throw new Error(`Workflow definition not found: ${state.workflowId}`);
2573
+ }
2574
+ const connections = workflow.graph.connections || [];
2575
+ // Consume bookmark for the activity being completed so only the next step has an active bookmark
2576
+ await this.consumeBookmark(request.instanceId, request.activityNode);
2577
+ const output = (request.output || {});
2578
+ const completedActivity = this.findActivityInGraph(workflow.graph, request.activityNode);
2579
+ // Resolve allowed outcomes from workflow definition and normalize outcome
2580
+ const allowedOutcomes = await this.getActivityAllowedOutcomes(workflow, request.activityNode);
2581
+ const coercedOutcome = this.coerceCreateEntityFormOutcome(completedActivity, request.outcome ?? 'Done', output);
2582
+ const outcome = this.normalizeOutcome(coercedOutcome, allowedOutcomes, request.activityNode);
2583
+ // Apply frontend output: only last activity output is kept (overwritten each step)
2584
+ let lastActivityOutput = output;
2585
+ // Apply outputToVariables for the completed frontend activity (e.g. leaveRequestForm → leaveRequestId: 'id')
2586
+ const variableUpdatesFromOutput = this.getVariableUpdatesFromOutput(workflow, request.activityNode, output);
2587
+ const formResultPromotions = this.buildPersistedEntityFormVariablePromotions(output, completedActivity?.name, outcome);
2588
+ const sessionUserFrontComplete = this.getSessionUser();
2589
+ const frontCompleteAudit = {
2590
+ [`${request.activityNode}_outcome`]: outcome,
2591
+ [`${request.activityNode}_activityOutput`]: output,
2592
+ };
2593
+ if (sessionUserFrontComplete?.id) {
2594
+ frontCompleteAudit[`${request.activityNode}_completedByUserId`] = sessionUserFrontComplete.id;
2595
+ frontCompleteAudit[`${request.activityNode}_completedByLabel`] =
2596
+ sessionUserFrontComplete.title || sessionUserFrontComplete.name || sessionUserFrontComplete.id;
2597
+ }
2598
+ else {
2599
+ frontCompleteAudit[`${request.activityNode}_completedByLabel`] = 'System';
2600
+ }
2601
+ state = {
2602
+ ...state,
2603
+ variables: {
2604
+ ...state.variables,
2605
+ ...output, // Merge frontend output into variables
2606
+ ...formResultPromotions, // Promote capture-form fields (e.g. effectiveDate) onto variables
2607
+ ...variableUpdatesFromOutput, // Map output paths to variable names (e.g. id → leaveRequestId)
2608
+ ...frontCompleteAudit,
2609
+ },
2610
+ lastActivityOutput,
2611
+ lastUpdated: new Date(),
2612
+ };
2613
+ // Find next activity based on outcome from frontend (use normalized outcome)
2614
+ const nextConnection = this.findWorkflowConnection(connections, request.activityNode, outcome);
2615
+ if (!nextConnection) {
2616
+ // No next activity → workflow completed
2617
+ state = {
2618
+ ...state,
2619
+ status: 'completed',
2620
+ currentStepId: undefined,
2621
+ output: state.variables,
2622
+ };
2623
+ await this.updateInstanceFromState(request.instanceId, state);
2624
+ return {
2625
+ output: { outcome, userInput: request.output },
2626
+ outcomes: { [outcome]: true },
2627
+ nextTask: null,
2628
+ state,
2629
+ };
2630
+ }
2631
+ // 🎯 KEY LOGIC: Execute all backend activities until we reach next frontend activity
2632
+ let currentActivity = this.findActivityInGraph(workflow.graph, nextConnection.target.activtyName);
2633
+ let executionCount = 0;
2634
+ const maxExecutions = 500;
2635
+ if (!currentActivity) {
2636
+ console.error(`[BackendWorkflowEngineService] ❌ Next activity '${nextConnection.target.activtyName}' not found in graph`);
2637
+ state = {
2638
+ ...state,
2639
+ status: 'error',
2640
+ currentStepId: undefined,
2641
+ };
2642
+ await this.updateInstanceFromState(request.instanceId, state);
2643
+ throw new Error(`Next activity '${nextConnection.target.activtyName}' not found in workflow graph`);
2644
+ }
2645
+ // Only lastActivityOutput is persisted; used as scope.outputs for expressions.
2646
+ while (currentActivity && executionCount < maxExecutions) {
2647
+ executionCount++;
2648
+ // Map activity name (registry key) to activity type
2649
+ const activityType = currentActivity.name;
2650
+ // Determine execution mode (async)
2651
+ const executionMode = await this.determineExecutionMode(activityType, currentActivity);
2652
+ // Get activity definition to retrieve taskType (taskType === 'human-task' → suspend for cartable)
2653
+ const activityDef = await this.activityDefinitionService.getActivityByName(activityType);
2654
+ let taskTypeComplete = currentActivity.metadata?.['taskType'] ?? activityDef?.taskType ?? 'ui-activity';
2655
+ // Defensive: human-task and cartable must suspend (same as run())
2656
+ if (this.isTaskBoardSuspendGraphActivity(activityType)) {
2657
+ if (activityDef?.taskType === 'human-task')
2658
+ taskTypeComplete = 'human-task';
2659
+ }
2660
+ const effectiveExecutionModeComplete = taskTypeComplete === 'human-task' && executionMode === 'backend'
2661
+ ? 'frontend'
2662
+ : this.isTaskBoardSuspendGraphActivity(activityType) &&
2663
+ (activityDef?.taskType === 'human-task' || taskTypeComplete === 'human-task')
2664
+ ? executionMode === 'backend'
2665
+ ? 'frontend'
2666
+ : executionMode
2667
+ : executionMode;
2668
+ // If frontend activity → stop and return as nextTask
2669
+ if (effectiveExecutionModeComplete === 'frontend' || effectiveExecutionModeComplete === 'both') {
2670
+ const pendingTask = await this.createTaskFromActivity(currentActivity, state);
2671
+ const resolvedTaskTypeComplete = taskTypeComplete === 'human-task' || pendingTask.taskType === 'human-task'
2672
+ ? 'human-task'
2673
+ : pendingTask.taskType;
2674
+ // Extract assignment and task metadata from activity inputs (for human-task activities)
2675
+ let bookmarkPayload = {
2676
+ activityType,
2677
+ activityName: currentActivity.name,
2678
+ taskToken: pendingTask.taskToken, // Store taskToken for resume
2679
+ taskType: resolvedTaskTypeComplete,
2680
+ };
2681
+ // For human-task activities, extract assignment and task metadata from inputs
2682
+ if (resolvedTaskTypeComplete === 'human-task' && pendingTask.input) {
2683
+ const inputs = pendingTask.input;
2684
+ // Assignment metadata (normalize to array; expression may return single id)
2685
+ bookmarkPayload['assignedUserIds'] = this.normalizeUserIds(inputs['assignedUserIds']);
2686
+ bookmarkPayload['candidateUserIds'] = this.normalizeUserIds(inputs['candidateUserIds']);
2687
+ bookmarkPayload['candidateRoleIds'] = this.normalizeUserIds(inputs['candidateRoleIds']);
2688
+ // Task metadata
2689
+ bookmarkPayload['title'] = this.resolveHumanTaskBookmarkTitle(inputs, activityDef, currentActivity);
2690
+ bookmarkPayload['description'] = inputs['description'] || null;
2691
+ bookmarkPayload['priority'] = inputs['priority'] || 'Normal';
2692
+ bookmarkPayload['dueDate'] = inputs['dueDate'] || null;
2693
+ // UI configuration
2694
+ bookmarkPayload['layout'] = inputs['layout'] || null;
2695
+ bookmarkPayload['actions'] = inputs['actions'] || null;
2696
+ bookmarkPayload['context'] = inputs['context'] || {};
2697
+ }
2698
+ if (activityType === workflow_management_const_1.WorkflowManagementRootConfig.activities.cartable) {
2699
+ bookmarkPayload['assignedUserIds'] = [];
2700
+ }
2701
+ if (resolvedTaskTypeComplete === 'human-task') {
2702
+ const htInputs = pendingTask.input;
2703
+ this.logHumanTaskBookmarkAssignmentTrace({
2704
+ phase: 'engine-frontActivityComplete',
2705
+ instanceId: request.instanceId,
2706
+ workflowDefinitionName: workflow.name,
2707
+ activityId: currentActivity.id,
2708
+ activityType,
2709
+ rawAssignedUserIds: htInputs?.['assignedUserIds'],
2710
+ normalizedAssignedUserIds: bookmarkPayload['assignedUserIds'],
2711
+ variables: state.variables,
2712
+ });
2713
+ }
2714
+ // Create bookmark for frontend activity
2715
+ // Store all metadata in bookmark payload (replaces Work Item)
2716
+ const bookmarkId = await this.createBookmark(request.instanceId, currentActivity.id, 'user-task', bookmarkPayload);
2717
+ // Update state: task-board activities → suspended, else running (form/popup)
2718
+ const isHumanTaskComplete = this.isTaskBoardSuspendGraphActivity(activityType);
2719
+ state = {
2720
+ ...state,
2721
+ lastActivityOutput,
2722
+ status: isHumanTaskComplete ? 'suspended' : 'running',
2723
+ currentStepId: currentActivity.id,
2724
+ };
2725
+ await this.updateInstanceFromState(request.instanceId, state);
2726
+ return {
2727
+ output: { outcome, userInput: request.output },
2728
+ outcomes: { [outcome]: true },
2729
+ nextTask: pendingTask,
2730
+ state,
2731
+ };
2732
+ }
2733
+ // Backend activity → execute it
2734
+ const executionResult = await this.executeBackendActivityLocally(currentActivity, state, lastActivityOutput);
2735
+ lastActivityOutput = executionResult.output;
2736
+ // set-variable activity writes variables directly in output; it has no outputToVariables
2737
+ const isSetVariableComplete = currentActivity.name === 'workflow-activity:set-variable';
2738
+ const variableUpdatesComplete = isSetVariableComplete
2739
+ ? executionResult.output
2740
+ : this.getVariableUpdatesFromOutput(workflow, currentActivity.id, executionResult.output);
2741
+ const backendOutcome = Object.keys(executionResult.outcomes)[0] || 'Done';
2742
+ const sessionUserComplete = this.getSessionUser();
2743
+ const backendAuditComplete = {
2744
+ [`${currentActivity.id}_outcome`]: backendOutcome,
2745
+ [`${currentActivity.id}_activityOutput`]: executionResult.output,
2746
+ };
2747
+ if (sessionUserComplete?.id) {
2748
+ backendAuditComplete[`${currentActivity.id}_completedByUserId`] = sessionUserComplete.id;
2749
+ backendAuditComplete[`${currentActivity.id}_completedByLabel`] =
2750
+ sessionUserComplete.title || sessionUserComplete.name || sessionUserComplete.id;
2751
+ }
2752
+ else {
2753
+ backendAuditComplete[`${currentActivity.id}_completedByLabel`] = 'System';
2754
+ }
2755
+ state = {
2756
+ ...state,
2757
+ variables: {
2758
+ ...state.variables,
2759
+ ...(typeof variableUpdatesComplete === 'object' && variableUpdatesComplete !== null
2760
+ ? variableUpdatesComplete
2761
+ : {}),
2762
+ ...backendAuditComplete,
2763
+ },
2764
+ lastActivityOutput,
2765
+ currentStepId: currentActivity.id,
2766
+ lastUpdated: new Date(),
2767
+ };
2768
+ await this.updateInstanceFromState(request.instanceId, state);
2769
+ // Find next activity based on outcome (backend execution result)
2770
+ const nextConn = this.findWorkflowConnection(connections, currentActivity.id, backendOutcome);
2771
+ if (!nextConn) {
2772
+ // No next activity → workflow completed
2773
+ state = {
2774
+ ...state,
2775
+ status: 'completed',
2776
+ currentStepId: undefined,
2777
+ output: state.variables,
2778
+ lastActivityOutput,
2779
+ };
2780
+ await this.updateInstanceFromState(request.instanceId, state);
2781
+ return {
2782
+ output: state.variables,
2783
+ outcomes: { Done: true },
2784
+ nextTask: null,
2785
+ state,
2786
+ };
2787
+ }
2788
+ // Find next activity
2789
+ const nextActivity = this.findActivityInGraph(workflow.graph, nextConn.target.activtyName);
2790
+ if (!nextActivity) {
2791
+ console.error(`[BackendWorkflowEngineService] ❌ Next activity '${nextConn.target.activtyName}' not found in graph`);
2792
+ state = {
2793
+ ...state,
2794
+ status: 'error',
2795
+ currentStepId: undefined,
2796
+ };
2797
+ await this.updateInstanceFromState(request.instanceId, state);
2798
+ throw new Error(`Next activity '${nextConn.target.activtyName}' not found in workflow graph`);
2799
+ }
2800
+ currentActivity = nextActivity;
2801
+ }
2802
+ // If we exit loop due to max executions, mark as error
2803
+ if (executionCount >= maxExecutions) {
2804
+ console.error(`[BackendWorkflowEngineService] ❌ Maximum execution count (${maxExecutions}) reached - possible infinite loop`);
2805
+ state = {
2806
+ ...state,
2807
+ status: 'error',
2808
+ currentStepId: undefined,
2809
+ };
2810
+ await this.updateInstanceFromState(request.instanceId, state);
2811
+ throw new Error(`Workflow execution exceeded maximum steps (${maxExecutions}) - possible infinite loop`);
2812
+ }
2813
+ // If we exit loop, workflow is complete
2814
+ state = {
2815
+ ...state,
2816
+ status: 'completed',
2817
+ currentStepId: undefined,
2818
+ output: state.variables,
2819
+ lastActivityOutput,
2820
+ };
2821
+ await this.updateInstanceFromState(request.instanceId, state);
2822
+ return {
2823
+ output: state.variables,
2824
+ outcomes: { Done: true },
2825
+ nextTask: null,
2826
+ state,
2827
+ };
2828
+ }
2829
+ catch (error) {
2830
+ console.error('[BackendWorkflowEngineService] ❌ Error completing front activity:', error);
2831
+ throw error; // Re-throw to let caller handle
2832
+ }
2833
+ }
2834
+ //#endregion
2835
+ //#region ---- Stale suspension cleanup (app startup) ----
2836
+ /**
2837
+ * Cleans up stale UI activities (form/popup) when user refreshed without submitting.
2838
+ * - Suspended instances with non-human-task bookmark → resume with outcome 'cancel'.
2839
+ * - Running instances with non-human-task bookmark (e.g. rejectionReasonDialog) → frontActivtyComplete with outcome 'cancel'.
2840
+ * So e.g. leave request: manager clicks Reject, dialog opens, user refreshes → dialog is "cancelled" and workflow goes back to managerConfirm (task board).
2841
+ */
2842
+ async resumeStaleNonHumanTaskSuspensions() {
2843
+ // 1) Suspended instances: non-human-task bookmark → resume with cancel
2844
+ const suspended = await this.store.getInstancesBySubStatus('Suspended');
2845
+ for (const instance of suspended) {
2846
+ try {
2847
+ const bookmarks = await this.getActiveBookmarks(instance.id);
2848
+ for (const b of bookmarks) {
2849
+ const payload = this.parseBookmarkPayload(b);
2850
+ if (payload?.activityType === workflow_management_const_1.WorkflowManagementRootConfig.activities.humanTask ||
2851
+ payload?.activityType === workflow_management_const_1.WorkflowManagementRootConfig.activities.cartable) {
2852
+ continue;
2853
+ }
2854
+ const taskToken = payload?.taskToken;
2855
+ if (!taskToken)
2856
+ continue;
2857
+ await this.resume({
2858
+ instanceId: instance.id,
2859
+ stepId: b.activityId,
2860
+ outcome: 'cancel',
2861
+ taskToken,
2862
+ userInput: {},
2863
+ });
2864
+ console.log(`[BackendWorkflowEngineService] 🧹 Resumed stale non-human-task suspension: ${instance.id} activity ${b.activityId} with outcome cancel`);
2865
+ break;
2866
+ }
2867
+ }
2868
+ catch (err) {
2869
+ console.warn(`[BackendWorkflowEngineService] ⚠️ Failed to resume stale suspension for instance ${instance.id}:`, err);
2870
+ }
2871
+ }
2872
+ // 2) Running instances: non-human-task bookmark (e.g. show-layout-popup) → complete with cancel so flow returns to previous step (e.g. task board)
2873
+ const running = await this.store.getInstancesBySubStatus('Executing');
2874
+ for (const instance of running) {
2875
+ try {
2876
+ const bookmarks = await this.getActiveBookmarks(instance.id);
2877
+ for (const b of bookmarks) {
2878
+ const payload = this.parseBookmarkPayload(b);
2879
+ if (payload?.activityType === workflow_management_const_1.WorkflowManagementRootConfig.activities.humanTask ||
2880
+ payload?.activityType === workflow_management_const_1.WorkflowManagementRootConfig.activities.cartable) {
2881
+ continue;
2882
+ }
2883
+ await this.frontActivtyComplete({
2884
+ instanceId: instance.id,
2885
+ activityNode: b.activityId,
2886
+ output: {},
2887
+ outcome: 'cancel',
2888
+ });
2889
+ console.log(`[BackendWorkflowEngineService] 🧹 Completed stale non-human-task (running): ${instance.id} activity ${b.activityId} with outcome cancel`);
2890
+ break;
2891
+ }
2892
+ }
2893
+ catch (err) {
2894
+ console.warn(`[BackendWorkflowEngineService] ⚠️ Failed to complete stale running activity for instance ${instance.id}:`, err);
2895
+ }
2896
+ }
2897
+ }
2898
+ parseBookmarkPayload(b) {
2899
+ try {
2900
+ return b.payloadJson ? JSON.parse(b.payloadJson) : null;
2901
+ }
2902
+ catch {
2903
+ return null;
2904
+ }
2905
+ }
2906
+ };
2907
+ exports.BackendWorkflowEngineService = BackendWorkflowEngineService;
2908
+ /**
2909
+ * Default outcome used when the requested outcome is not in the allowed list (standard scenario).
2910
+ */
2911
+ BackendWorkflowEngineService.DEFAULT_UNMATCHED_OUTCOME = 'Done';
2912
+ exports.BackendWorkflowEngineService = BackendWorkflowEngineService = BackendWorkflowEngineService_1 = tslib_1.__decorate([
2913
+ (0, common_1.Injectable)(),
2914
+ tslib_1.__metadata("design:paramtypes", [workflow_execution_store_service_1.WorkflowExecutionStoreService,
2915
+ core_1.EntityStorageMiddlewareService,
2916
+ workflow_activity_definition_service_1.WorkflowActivityDefinitionService,
2917
+ workflow_expression_scope_service_1.WorkflowExpressionScopeService,
2918
+ workflow_expression_evaluator_service_1.WorkflowExpressionEvaluatorService,
2919
+ workflow_request_session_adapter_1.WorkflowRequestSessionAdapter,
2920
+ workflow_activity_registry_1.WorkflowActivityRegistryService])
2921
+ ], BackendWorkflowEngineService);
2922
+ //# sourceMappingURL=workflow-engine.service.js.map