procesio-cli 0.1.1__py3-none-any.whl

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 (647) hide show
  1. procesio_cli/__init__.py +18 -0
  2. procesio_cli/_cli.py +71 -0
  3. procesio_cli/agents/__init__.py +0 -0
  4. procesio_cli/agents/_lib/__init__.py +0 -0
  5. procesio_cli/agents/_lib/actiondef.py +24 -0
  6. procesio_cli/agents/_lib/errors.py +40 -0
  7. procesio_cli/agents/_lib/reversibility.py +236 -0
  8. procesio_cli/agents/_lib/toolrunner.py +141 -0
  9. procesio_cli/agents/connector-builder/CONNECTOR-BUILDER-PLAYBOOK.md +62 -0
  10. procesio_cli/agents/connector-builder/CONNECTOR-BUILDER-PROCESIO-INTEROP.md +76 -0
  11. procesio_cli/agents/connector-builder/CONNECTOR-BUILDER-TROUBLESHOOTING.md +60 -0
  12. procesio_cli/agents/connector-builder/README.md +51 -0
  13. procesio_cli/agents/connector-builder/agent.yaml +61 -0
  14. procesio_cli/agents/connector-builder/context.py +19 -0
  15. procesio_cli/agents/connector-builder/handlers/__init__.py +1 -0
  16. procesio_cli/agents/connector-builder/handlers/checklist.py +71 -0
  17. procesio_cli/agents/connector-builder/handlers/guidance.py +37 -0
  18. procesio_cli/agents/connector-builder/handlers/nextstep.py +221 -0
  19. procesio_cli/agents/connector-builder/handlers/status.py +35 -0
  20. procesio_cli/agents/connector-builder/knowledge.py +47 -0
  21. procesio_cli/agents/connector-builder/main.py +93 -0
  22. procesio_cli/agents/connector-builder/tests/conftest.py +95 -0
  23. procesio_cli/agents/connector-builder/tests/test_cba_agent.py +148 -0
  24. procesio_cli/agents/orchestrator/__init__.py +0 -0
  25. procesio_cli/agents/orchestrator/bootstraplib.py +166 -0
  26. procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/00-INDEX.md +60 -0
  27. procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/01-PROCESSES.md +230 -0
  28. procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/02-FORMS.md +287 -0
  29. procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/03-INTEGRATIONS.md +384 -0
  30. procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/04-DATABASE.md +293 -0
  31. procesio_cli/agents/procesio/PROCESIO-API-RELIABILITY-DOCTRINE.md +113 -0
  32. procesio_cli/agents/procesio/PROCESIO-BEST-PRACTICES.md +316 -0
  33. procesio_cli/agents/procesio/PROCESIO-BUILD-AND-TEST-PLAYBOOK.md +217 -0
  34. procesio_cli/agents/procesio/PROCESIO-DATASTORE.md +72 -0
  35. procesio_cli/agents/procesio/PROCESIO-ENVIRONMENTS.md +62 -0
  36. procesio_cli/agents/procesio/PROCESIO-SCHEDULING.md +47 -0
  37. procesio_cli/agents/procesio/PROCESIO-VISUAL-ORGANIZATION.md +175 -0
  38. procesio_cli/agents/procesio/README.md +97 -0
  39. procesio_cli/agents/procesio/__init__.py +0 -0
  40. procesio_cli/agents/procesio/agent.yaml +73 -0
  41. procesio_cli/agents/procesio/audit.py +226 -0
  42. procesio_cli/agents/procesio/checklist.py +135 -0
  43. procesio_cli/agents/procesio/context.py +19 -0
  44. procesio_cli/agents/procesio/handlers/__init__.py +0 -0
  45. procesio_cli/agents/procesio/handlers/audit.py +39 -0
  46. procesio_cli/agents/procesio/handlers/checklist.py +34 -0
  47. procesio_cli/agents/procesio/handlers/guidance.py +36 -0
  48. procesio_cli/agents/procesio/handlers/status.py +33 -0
  49. procesio_cli/agents/procesio/handlers/verify.py +39 -0
  50. procesio_cli/agents/procesio/knowledge.py +115 -0
  51. procesio_cli/agents/procesio/main.py +89 -0
  52. procesio_cli/agents/procesio/tests/__init__.py +0 -0
  53. procesio_cli/agents/procesio/tests/conftest.py +62 -0
  54. procesio_cli/agents/procesio/tests/test_audit.py +91 -0
  55. procesio_cli/agents/procesio/tests/test_checklist.py +28 -0
  56. procesio_cli/agents/procesio/tests/test_guidance.py +78 -0
  57. procesio_cli/agents/procesio/tests/test_manifest_sync.py +48 -0
  58. procesio_cli/agents/procesio/tests/test_verify.py +134 -0
  59. procesio_cli/agents/procesio/tests/test_workspace_scope.py +97 -0
  60. procesio_cli/agents/procesio/verifylib.py +222 -0
  61. procesio_cli/dashboard/README.md +117 -0
  62. procesio_cli/dashboard/__init__.py +18 -0
  63. procesio_cli/dashboard/serve.py +98 -0
  64. procesio_cli/dashboard/server/__init__.py +1 -0
  65. procesio_cli/dashboard/server/config_schemas.py +92 -0
  66. procesio_cli/dashboard/server/google.py +103 -0
  67. procesio_cli/dashboard/server/handler.py +160 -0
  68. procesio_cli/dashboard/server/inventory.py +213 -0
  69. procesio_cli/dashboard/server/jobs.py +118 -0
  70. procesio_cli/dashboard/server/llmtest.py +181 -0
  71. procesio_cli/dashboard/server/procesio_env.py +94 -0
  72. procesio_cli/dashboard/server/routes.py +74 -0
  73. procesio_cli/dashboard/server/runner.py +150 -0
  74. procesio_cli/dashboard/server/security.py +29 -0
  75. procesio_cli/dashboard/server/setup.py +211 -0
  76. procesio_cli/dashboard/server/validate.py +152 -0
  77. procesio_cli/dashboard/tests/conftest.py +16 -0
  78. procesio_cli/dashboard/tests/test_dashboard.py +225 -0
  79. procesio_cli/dashboard/tests/test_procesio_env.py +159 -0
  80. procesio_cli/dashboard/web/actions.js +274 -0
  81. procesio_cli/dashboard/web/api.js +79 -0
  82. procesio_cli/dashboard/web/app.js +385 -0
  83. procesio_cli/dashboard/web/copilot.js +72 -0
  84. procesio_cli/dashboard/web/google.js +121 -0
  85. procesio_cli/dashboard/web/index.html +67 -0
  86. procesio_cli/dashboard/web/procesio_env.js +187 -0
  87. procesio_cli/dashboard/web/styles.css +207 -0
  88. procesio_cli/registry.py +370 -0
  89. procesio_cli/scripts/build-router.py +249 -0
  90. procesio_cli/scripts/build-tool-skill.py +202 -0
  91. procesio_cli/scripts/check-requirements.py +131 -0
  92. procesio_cli/scripts/check-skill-governance.py +174 -0
  93. procesio_cli/scripts/evaluate-skill-routing.py +217 -0
  94. procesio_cli/scripts/evaluate-skills.py +316 -0
  95. procesio_cli/scripts/get-skill.py +122 -0
  96. procesio_cli/scripts/list-skills.py +68 -0
  97. procesio_cli/scripts/list-tools.py +73 -0
  98. procesio_cli/scripts/run-agent.py +59 -0
  99. procesio_cli/scripts/run-tool.py +123 -0
  100. procesio_cli/scripts/secret_scan.py +584 -0
  101. procesio_cli/scripts/set-credential.py +126 -0
  102. procesio_cli/scripts/validate-skills.py +530 -0
  103. procesio_cli/skills/PORTFOLIO.md +134 -0
  104. procesio_cli/skills/__init__.py +6 -0
  105. procesio_cli/skills/agent-skill-engineer/SKILL.md +226 -0
  106. procesio_cli/skills/agent-skill-engineer/evals/evals.json +422 -0
  107. procesio_cli/skills/agent-skill-engineer/references/authoring-standard.md +178 -0
  108. procesio_cli/skills/agent-skill-engineer/references/decision-framework.md +107 -0
  109. procesio_cli/skills/agent-skill-engineer/references/domain-evidence-protocol.md +248 -0
  110. procesio_cli/skills/agent-skill-engineer/references/evaluation-standard.md +191 -0
  111. procesio_cli/skills/agent-skill-engineer/references/expert-lenses.md +167 -0
  112. procesio_cli/skills/agent-skill-engineer/references/field-gate-standard.md +231 -0
  113. procesio_cli/skills/agent-skill-engineer/references/optimization-protocol.md +233 -0
  114. procesio_cli/skills/agent-skill-engineer/references/optimizer-contract.md +268 -0
  115. procesio_cli/skills/agent-skill-engineer/references/portability-standard.md +99 -0
  116. procesio_cli/skills/agent-skill-engineer/references/research-basis.md +128 -0
  117. procesio_cli/skills/agent-skill-engineer/references/review-standard.md +143 -0
  118. procesio_cli/skills/agent-skill-engineer/scripts/audit_skill.py +959 -0
  119. procesio_cli/skills/agent-skill-engineer/scripts/optimize_skill.py +891 -0
  120. procesio_cli/skills/agent-skill-engineer/scripts/scaffold_skill.py +397 -0
  121. procesio_cli/skills/evals/baseline-catalog.json +14 -0
  122. procesio_cli/skills/evals/baseline-routing-v2.json +38 -0
  123. procesio_cli/skills/evals/baseline.json +37 -0
  124. procesio_cli/skills/evals/behavioral.json +367 -0
  125. procesio_cli/skills/evals/field-boundary-development-v1.json +126 -0
  126. procesio_cli/skills/evals/field-closeout-correction-development-v1.json +23 -0
  127. procesio_cli/skills/evals/field-closeout-development-v1.json +89 -0
  128. procesio_cli/skills/evals/portfolio-pressure-training-v1.json +83 -0
  129. procesio_cli/skills/evals/routing.json +363 -0
  130. procesio_cli/skills/evals/validation-baseline.json +4 -0
  131. procesio_cli/skills/procesio-cli/SKILL.md +134 -0
  132. procesio_cli/skills/procesio-cli/evals/evals.json +111 -0
  133. procesio_cli/skills/procesio-cli/evals/workflows.json +16 -0
  134. procesio_cli/skills/procesio-cli/references/connector-lifecycle.md +47 -0
  135. procesio_cli/skills/procesio-cli/references/credentials-admin.md +113 -0
  136. procesio_cli/skills/procesio-cli/references/data-verification.md +71 -0
  137. procesio_cli/skills/procesio-cli/references/documents-files.md +44 -0
  138. procesio_cli/skills/procesio-cli/references/form-e2e.md +57 -0
  139. procesio_cli/skills/procesio-cli/references/operation-contract.md +138 -0
  140. procesio_cli/skills/procesio-cli/references/process-debugging.md +65 -0
  141. procesio_cli/skills/procesio-cli/references/process-lifecycle.md +88 -0
  142. procesio_cli/skills/procesio-cli/references/schedules-webhooks.md +58 -0
  143. procesio_cli/skills/procesio-cli/references/transport-environments.md +53 -0
  144. procesio_cli/skills/procesio-cli-maintainer/SKILL.md +84 -0
  145. procesio_cli/skills/procesio-cli-maintainer/evals/evals.json +116 -0
  146. procesio_cli/skills/procesio-cli-maintainer/references/change-contract.md +34 -0
  147. procesio_cli/skills/procesio-cli-maintainer/references/mcp-compatibility.md +13 -0
  148. procesio_cli/skills/procesio-cli-maintainer/references/skill-authoring.md +51 -0
  149. procesio_cli/skills/procesio-platform-advisor/SKILL.md +82 -0
  150. procesio_cli/skills/procesio-platform-advisor/evals/evals.json +116 -0
  151. procesio_cli/skills/procesio-platform-advisor/references/capability-map.md +22 -0
  152. procesio_cli/skills/procesio-platform-advisor/references/fit-framework.md +35 -0
  153. procesio_cli/skills/procesio-platform-advisor/references/freshness-policy.md +25 -0
  154. procesio_cli/skills/procesio-platform-advisor/references/sizing-method.md +70 -0
  155. procesio_cli/skills/procesio-platform-advisor/scripts/estimate_capacity.py +99 -0
  156. procesio_cli/skills/procesio-setup/SKILL.md +180 -0
  157. procesio_cli/skills/sql-server-optimizer/SKILL.md +86 -0
  158. procesio_cli/skills/sql-server-optimizer/evals/evals.json +116 -0
  159. procesio_cli/skills/sql-server-optimizer/references/db-context.md +44 -0
  160. procesio_cli/skills/sql-server-optimizer/references/generic-mode.md +32 -0
  161. procesio_cli/skills/sql-server-optimizer/references/procesio-mode.md +40 -0
  162. procesio_cli/skills/sql-server-optimizer/references/sql-rules.md +43 -0
  163. procesio_cli/skills/sql-server-optimizer/scripts/export-indexes.sql +178 -0
  164. procesio_cli/skills/sql-server-optimizer/scripts/export-procs-and-functions.sql +118 -0
  165. procesio_cli/skills/sql-server-optimizer/scripts/export-tables.sql +367 -0
  166. procesio_cli/skills/tests/__init__.py +0 -0
  167. procesio_cli/skills/tests/test_agent_skill_engineer.py +240 -0
  168. procesio_cli/skills/tests/test_auth_failure_stop.py +25 -0
  169. procesio_cli/skills/tests/test_capacity_estimator.py +85 -0
  170. procesio_cli/skills/tests/test_field_boundary_learning.py +100 -0
  171. procesio_cli/skills/tests/test_field_closeout_learning.py +123 -0
  172. procesio_cli/skills/tests/test_field_gate_standard.py +76 -0
  173. procesio_cli/skills/tests/test_operational_playbooks.py +51 -0
  174. procesio_cli/skills/tests/test_portfolio_pressure_training.py +35 -0
  175. procesio_cli/skills/tests/test_process_lifecycle_single_run.py +25 -0
  176. procesio_cli/skills/tests/test_skill_evaluator.py +67 -0
  177. procesio_cli/skills/tests/test_skill_optimizer.py +473 -0
  178. procesio_cli/skills/tests/test_skill_portfolio_review.py +70 -0
  179. procesio_cli/skills/tests/test_skill_release_binding.py +204 -0
  180. procesio_cli/skills/tests/test_skill_routing.py +74 -0
  181. procesio_cli/skills/tests/test_skill_scaffold_v2.py +116 -0
  182. procesio_cli/skills/tests/test_validate_skills.py +115 -0
  183. procesio_cli/tools/__init__.py +0 -0
  184. procesio_cli/tools/_lib/README.md +119 -0
  185. procesio_cli/tools/_lib/__init__.py +0 -0
  186. procesio_cli/tools/_lib/accounting.py +120 -0
  187. procesio_cli/tools/_lib/contacts.py +544 -0
  188. procesio_cli/tools/_lib/creds.py +83 -0
  189. procesio_cli/tools/_lib/creds_backends.py +578 -0
  190. procesio_cli/tools/_lib/dbprofiles.py +147 -0
  191. procesio_cli/tools/_lib/dbquery.py +286 -0
  192. procesio_cli/tools/_lib/dbschema.py +225 -0
  193. procesio_cli/tools/_lib/io.py +54 -0
  194. procesio_cli/tools/_lib/manifest.py +297 -0
  195. procesio_cli/tools/_lib/skill_release.py +127 -0
  196. procesio_cli/tools/_lib/skill_resources.py +118 -0
  197. procesio_cli/tools/_lib/userdata.py +228 -0
  198. procesio_cli/tools/_lib/webserialize/__init__.py +16 -0
  199. procesio_cli/tools/_lib/webserialize/admin.py +61 -0
  200. procesio_cli/tools/_lib/webserialize/client.py +264 -0
  201. procesio_cli/tools/_lib/webserialize/config.py +96 -0
  202. procesio_cli/tools/_lib/webserialize/errors.py +27 -0
  203. procesio_cli/tools/_lib/webserialize/framing.py +45 -0
  204. procesio_cli/tools/_lib/webserialize/registry.py +47 -0
  205. procesio_cli/tools/_lib/webserialize/runtime.py +61 -0
  206. procesio_cli/tools/_lib/webserialize/server.py +510 -0
  207. procesio_cli/tools/_lib/websession.py +194 -0
  208. procesio_cli/tools/connector-builder/CONNECTOR-BUILDER-API-NOTES.md +91 -0
  209. procesio_cli/tools/connector-builder/README.md +101 -0
  210. procesio_cli/tools/connector-builder/SKILL.md +248 -0
  211. procesio_cli/tools/connector-builder/__init__.py +7 -0
  212. procesio_cli/tools/connector-builder/actiondef.py +24 -0
  213. procesio_cli/tools/connector-builder/client.py +251 -0
  214. procesio_cli/tools/connector-builder/errors.py +44 -0
  215. procesio_cli/tools/connector-builder/gen_manifest.py +142 -0
  216. procesio_cli/tools/connector-builder/handlers/__init__.py +1 -0
  217. procesio_cli/tools/connector-builder/handlers/admin.py +182 -0
  218. procesio_cli/tools/connector-builder/handlers/auth.py +74 -0
  219. procesio_cli/tools/connector-builder/handlers/builds.py +396 -0
  220. procesio_cli/tools/connector-builder/handlers/common.py +104 -0
  221. procesio_cli/tools/connector-builder/handlers/files.py +111 -0
  222. procesio_cli/tools/connector-builder/handlers/raw.py +38 -0
  223. procesio_cli/tools/connector-builder/handlers/telemetry.py +39 -0
  224. procesio_cli/tools/connector-builder/main.py +94 -0
  225. procesio_cli/tools/connector-builder/tests/conftest.py +146 -0
  226. procesio_cli/tools/connector-builder/tests/test_cb_client.py +86 -0
  227. procesio_cli/tools/connector-builder/tests/test_cb_dispatch.py +105 -0
  228. procesio_cli/tools/connector-builder/tests/test_cb_manifest_sync.py +76 -0
  229. procesio_cli/tools/connector-builder/tests/test_cb_wait.py +123 -0
  230. procesio_cli/tools/connector-builder/tool.yaml +671 -0
  231. procesio_cli/tools/framework-map/.gitattributes +2 -0
  232. procesio_cli/tools/framework-map/README.md +98 -0
  233. procesio_cli/tools/framework-map/SKILL.md +30 -0
  234. procesio_cli/tools/framework-map/app.js +188 -0
  235. procesio_cli/tools/framework-map/fm_builder.py +476 -0
  236. procesio_cli/tools/framework-map/fm_catalog.py +19 -0
  237. procesio_cli/tools/framework-map/fm_ro_catalog.py +94 -0
  238. procesio_cli/tools/framework-map/fm_strings.py +101 -0
  239. procesio_cli/tools/framework-map/main.py +95 -0
  240. procesio_cli/tools/framework-map/styles.css +214 -0
  241. procesio_cli/tools/framework-map/tests/conftest.py +33 -0
  242. procesio_cli/tools/framework-map/tests/test_fm_build.py +126 -0
  243. procesio_cli/tools/framework-map/tests/test_fm_manifest_sync.py +63 -0
  244. procesio_cli/tools/framework-map/tests/test_fm_store_tree.py +75 -0
  245. procesio_cli/tools/framework-map/tool.yaml +61 -0
  246. procesio_cli/tools/mysql/MOVED-TO-CENTRAL.md +29 -0
  247. procesio_cli/tools/mysql/README.md +196 -0
  248. procesio_cli/tools/mysql/SKILL.md +37 -0
  249. procesio_cli/tools/mysql/__init__.py +0 -0
  250. procesio_cli/tools/mysql/connection.py +191 -0
  251. procesio_cli/tools/mysql/main.py +487 -0
  252. procesio_cli/tools/mysql/profiles.template.json +1 -0
  253. procesio_cli/tools/mysql/schema.py +434 -0
  254. procesio_cli/tools/mysql/tests/__init__.py +0 -0
  255. procesio_cli/tools/mysql/tests/conftest.py +21 -0
  256. procesio_cli/tools/mysql/tests/test_manifest_sync.py +68 -0
  257. procesio_cli/tools/mysql/tests/test_mysql.py +201 -0
  258. procesio_cli/tools/mysql/tests/test_mysql_schema.py +337 -0
  259. procesio_cli/tools/mysql/tool.yaml +112 -0
  260. procesio_cli/tools/procesio/DTO-SUBTOOLS-NOTE.md +360 -0
  261. procesio_cli/tools/procesio/FORM-DEV-GUIDE/00-INDEX.md +67 -0
  262. procesio_cli/tools/procesio/FORM-DEV-GUIDE/01-ANATOMY.md +209 -0
  263. procesio_cli/tools/procesio/FORM-DEV-GUIDE/02-CODE-INJECTION.md +309 -0
  264. procesio_cli/tools/procesio/FORM-DEV-GUIDE/03-DOM-CONTRACT.md +370 -0
  265. procesio_cli/tools/procesio/FORM-DEV-GUIDE/04-INTERACTION-RECIPES.md +600 -0
  266. procesio_cli/tools/procesio/FORM-DEV-GUIDE/05-STEPPER-AND-MOTION.md +426 -0
  267. procesio_cli/tools/procesio/FORM-DEV-GUIDE/06-PROCESS-INTEGRATION.md +347 -0
  268. procesio_cli/tools/procesio/FORM-DEV-GUIDE/07-DEPLOY-WORKFLOW.md +294 -0
  269. procesio_cli/tools/procesio/FORM-DEV-GUIDE/08-PITFALLS.md +569 -0
  270. procesio_cli/tools/procesio/FORM-DEV-GUIDE/09-NAVIGATION-AND-HOSTING.md +308 -0
  271. procesio_cli/tools/procesio/PHASE4-E2E-NOTES.md +594 -0
  272. procesio_cli/tools/procesio/PROCESIO-API-CORRECTIONS.md +295 -0
  273. procesio_cli/tools/procesio/PROCESIO-API-NOTES.md +6976 -0
  274. procesio_cli/tools/procesio/PROCESIO-AUTH-NOTES.md +226 -0
  275. procesio_cli/tools/procesio/PROCESIO-CARD-BUILD-NOTES.md +183 -0
  276. procesio_cli/tools/procesio/PROCESIO-CONNECTORS-NOTES.md +141 -0
  277. procesio_cli/tools/procesio/PROCESIO-CUSTOM-ACTION-NOTES.md +179 -0
  278. procesio_cli/tools/procesio/PROCESIO-DOCS-FIX-REPORT.md +123 -0
  279. procesio_cli/tools/procesio/PROCESIO-ENVIRONMENTS-NOTES.md +94 -0
  280. procesio_cli/tools/procesio/PROCESIO-FE-VALIDATION-NOTES.md +107 -0
  281. procesio_cli/tools/procesio/PROCESIO-FOREACH-NOTES.md +199 -0
  282. procesio_cli/tools/procesio/PROCESIO-FORM-API-HANG-NOTE.md +101 -0
  283. procesio_cli/tools/procesio/PROCESIO-FORM-SUBMISSION-NOTES.md +172 -0
  284. procesio_cli/tools/procesio/PROCESIO-HTML-TO-DOCX-NOTES.md +110 -0
  285. procesio_cli/tools/procesio/PROCESIO-INSTANCE-HISTORY-NOTES.md +242 -0
  286. procesio_cli/tools/procesio/PROCESIO-METERING-NOTES.md +201 -0
  287. procesio_cli/tools/procesio/PROCESIO-NODE-CODE-NOTES.md +279 -0
  288. procesio_cli/tools/procesio/PROCESIO-NODE-MODULE-WHITELIST.md +113 -0
  289. procesio_cli/tools/procesio/PROCESIO-PYTHON-ACTION-NOTES.md +165 -0
  290. procesio_cli/tools/procesio/PROCESIO-QUERY-STORE-NOTES.md +826 -0
  291. procesio_cli/tools/procesio/PROCESIO-RECONCILIATION-PATTERNS.md +104 -0
  292. procesio_cli/tools/procesio/PROCESIO-RESOURCE-MODEL-NOTES.md +1100 -0
  293. procesio_cli/tools/procesio/PROCESIO-SEND-EMAIL-CRED-OPTIONALITY.md +45 -0
  294. procesio_cli/tools/procesio/PROCESIO-SEND-EMAIL-NOTES.md +252 -0
  295. procesio_cli/tools/procesio/PROCESIO-SQL-ACTIONS-NOTES.md +284 -0
  296. procesio_cli/tools/procesio/PROCESIO-USAGE-GUIDE.md +219 -0
  297. procesio_cli/tools/procesio/README.md +341 -0
  298. procesio_cli/tools/procesio/SCHEDULE-INPUT-SECURITY-NOTES.md +63 -0
  299. procesio_cli/tools/procesio/SKILL.md +694 -0
  300. procesio_cli/tools/procesio/__init__.py +1 -0
  301. procesio_cli/tools/procesio/actiondef.py +27 -0
  302. procesio_cli/tools/procesio/assets/html2docx/html2docx.js +2155 -0
  303. procesio_cli/tools/procesio/auth.py +354 -0
  304. procesio_cli/tools/procesio/autogen.py +121 -0
  305. procesio_cli/tools/procesio/client.py +355 -0
  306. procesio_cli/tools/procesio/config.py +96 -0
  307. procesio_cli/tools/procesio/data/endpoints.json +2901 -0
  308. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/01-authentication.md +180 -0
  309. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/02-conventions.md +116 -0
  310. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/ANONYMOUS-SURFACE.md +51 -0
  311. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/README.md +104 -0
  312. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/SYMBOL-INDEX.md +444 -0
  313. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/03-auth-users-workspaces.md +731 -0
  314. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/04-processes.md +913 -0
  315. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/05-actions.md +605 -0
  316. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/06-files.md +237 -0
  317. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/07-forms-documents.md +985 -0
  318. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/08-credentials.md +532 -0
  319. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/09-datastore-datatypes.md +830 -0
  320. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/10-custom-urls.md +319 -0
  321. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/11-subscriptions-resources-analytics.md +455 -0
  322. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/12-webhooks-notifications-misc.md +519 -0
  323. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/13-realtime-signalr.md +153 -0
  324. procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/99-internal-and-other-services.md +52 -0
  325. procesio_cli/tools/procesio/docs_info/FormBuilder mock.ts +5725 -0
  326. procesio_cli/tools/procesio/docs_info/Procesio Platform Actions.json +30219 -0
  327. procesio_cli/tools/procesio/docs_info/form-config-enums.ts +92 -0
  328. procesio_cli/tools/procesio/docs_info/form-theme.ts +1603 -0
  329. procesio_cli/tools/procesio/docs_info/process-validation-reference-1.md +2739 -0
  330. procesio_cli/tools/procesio/dto/__init__.py +13 -0
  331. procesio_cli/tools/procesio/dto/credential/builder.py +179 -0
  332. procesio_cli/tools/procesio/dto/credential/config.schema.json +19 -0
  333. procesio_cli/tools/procesio/dto/credential/description.md +193 -0
  334. procesio_cli/tools/procesio/dto/credential/fixtures/rest.config.json +11 -0
  335. procesio_cli/tools/procesio/dto/credential/fixtures/rest.dto.json +28 -0
  336. procesio_cli/tools/procesio/dto/credential/fixtures/rest.template.json +44 -0
  337. procesio_cli/tools/procesio/dto/credential/template.dto.json +16 -0
  338. procesio_cli/tools/procesio/dto/data/_refresh.py +147 -0
  339. procesio_cli/tools/procesio/dto/data/action_catalog.json +30825 -0
  340. procesio_cli/tools/procesio/dto/data/action_families.json +55 -0
  341. procesio_cli/tools/procesio/dto/data/platform_types.json +182 -0
  342. procesio_cli/tools/procesio/dto/datatype/builder.py +223 -0
  343. procesio_cli/tools/procesio/dto/datatype/config.schema.json +47 -0
  344. procesio_cli/tools/procesio/dto/datatype/description.md +85 -0
  345. procesio_cli/tools/procesio/dto/datatype/fixtures/customer.config.json +41 -0
  346. procesio_cli/tools/procesio/dto/datatype/fixtures/customer.dto.json +164 -0
  347. procesio_cli/tools/procesio/dto/datatype/template.dto.json +37 -0
  348. procesio_cli/tools/procesio/dto/document/builder.py +193 -0
  349. procesio_cli/tools/procesio/dto/document/config.schema.json +33 -0
  350. procesio_cli/tools/procesio/dto/document/description.md +124 -0
  351. procesio_cli/tools/procesio/dto/document/fixtures/invoice.config.json +16 -0
  352. procesio_cli/tools/procesio/dto/document/fixtures/invoice.dto.json +32 -0
  353. procesio_cli/tools/procesio/dto/document/template.dto.json +14 -0
  354. procesio_cli/tools/procesio/dto/form/FORM-STYLING-NOTES.md +142 -0
  355. procesio_cli/tools/procesio/dto/form/GOLDEN-DRIFT-NOTES.md +72 -0
  356. procesio_cli/tools/procesio/dto/form/RUN-PROCESS-RESULT-NOTES.md +80 -0
  357. procesio_cli/tools/procesio/dto/form/addelement.py +277 -0
  358. procesio_cli/tools/procesio/dto/form/builder.py +1009 -0
  359. procesio_cli/tools/procesio/dto/form/capture_goldens.py +106 -0
  360. procesio_cli/tools/procesio/dto/form/code_cipher.py +67 -0
  361. procesio_cli/tools/procesio/dto/form/config.schema.json +76 -0
  362. procesio_cli/tools/procesio/dto/form/data_shell.json +1 -0
  363. procesio_cli/tools/procesio/dto/form/description.md +346 -0
  364. procesio_cli/tools/procesio/dto/form/elements/approval.json +259 -0
  365. procesio_cli/tools/procesio/dto/form/elements/assignee.json +137 -0
  366. procesio_cli/tools/procesio/dto/form/elements/button.json +125 -0
  367. procesio_cli/tools/procesio/dto/form/elements/chart.json +341 -0
  368. procesio_cli/tools/procesio/dto/form/elements/chat.json +199 -0
  369. procesio_cli/tools/procesio/dto/form/elements/checkbox.json +153 -0
  370. procesio_cli/tools/procesio/dto/form/elements/column.json +77 -0
  371. procesio_cli/tools/procesio/dto/form/elements/columns.json +78 -0
  372. procesio_cli/tools/procesio/dto/form/elements/datetime-input.json +304 -0
  373. procesio_cli/tools/procesio/dto/form/elements/divider.json +54 -0
  374. procesio_cli/tools/procesio/dto/form/elements/dropdown.json +130 -0
  375. procesio_cli/tools/procesio/dto/form/elements/dynamic-table-row.json +253 -0
  376. procesio_cli/tools/procesio/dto/form/elements/file-upload.json +196 -0
  377. procesio_cli/tools/procesio/dto/form/elements/file-viewer.json +169 -0
  378. procesio_cli/tools/procesio/dto/form/elements/heading.json +79 -0
  379. procesio_cli/tools/procesio/dto/form/elements/icon.json +107 -0
  380. procesio_cli/tools/procesio/dto/form/elements/image.json +174 -0
  381. procesio_cli/tools/procesio/dto/form/elements/input.json +206 -0
  382. procesio_cli/tools/procesio/dto/form/elements/list.json +202 -0
  383. procesio_cli/tools/procesio/dto/form/elements/number-input.json +202 -0
  384. procesio_cli/tools/procesio/dto/form/elements/paragraph.json +79 -0
  385. procesio_cli/tools/procesio/dto/form/elements/radiobox.json +174 -0
  386. procesio_cli/tools/procesio/dto/form/elements/section.json +114 -0
  387. procesio_cli/tools/procesio/dto/form/elements/select.json +217 -0
  388. procesio_cli/tools/procesio/dto/form/elements/side-panel.json +146 -0
  389. procesio_cli/tools/procesio/dto/form/elements/signature-pad.json +141 -0
  390. procesio_cli/tools/procesio/dto/form/elements/static-table-row.json +84 -0
  391. procesio_cli/tools/procesio/dto/form/elements/step.json +105 -0
  392. procesio_cli/tools/procesio/dto/form/elements/stepper.json +126 -0
  393. procesio_cli/tools/procesio/dto/form/elements/tab.json +77 -0
  394. procesio_cli/tools/procesio/dto/form/elements/table.json +279 -0
  395. procesio_cli/tools/procesio/dto/form/elements/tabs.json +114 -0
  396. procesio_cli/tools/procesio/dto/form/elements/textarea.json +213 -0
  397. procesio_cli/tools/procesio/dto/form/enum_map.json +68 -0
  398. procesio_cli/tools/procesio/dto/form/fieldpath.py +284 -0
  399. procesio_cli/tools/procesio/dto/form/fixtures/reg.config.json +32 -0
  400. procesio_cli/tools/procesio/dto/form/fixtures/reg.elements.json +638 -0
  401. procesio_cli/tools/procesio/dto/form/sync_from_mock.py +386 -0
  402. procesio_cli/tools/procesio/dto/framework.py +125 -0
  403. procesio_cli/tools/procesio/dto/process/builder.py +1991 -0
  404. procesio_cli/tools/procesio/dto/process/config.schema.json +159 -0
  405. procesio_cli/tools/procesio/dto/process/description.md +218 -0
  406. procesio_cli/tools/procesio/dto/process/fixtures/greet.config.json +32 -0
  407. procesio_cli/tools/procesio/dto/process/fixtures/greet.dto.json +317 -0
  408. procesio_cli/tools/procesio/dto/process/naming.py +305 -0
  409. procesio_cli/tools/procesio/dto/process/normalize.py +74 -0
  410. procesio_cli/tools/procesio/dto/process/template.dto.json +32 -0
  411. procesio_cli/tools/procesio/dto/refdata.py +87 -0
  412. procesio_cli/tools/procesio/dto/registry.py +27 -0
  413. procesio_cli/tools/procesio/dto/webhook/builder.py +142 -0
  414. procesio_cli/tools/procesio/dto/webhook/config.schema.json +25 -0
  415. procesio_cli/tools/procesio/dto/webhook/description.md +92 -0
  416. procesio_cli/tools/procesio/dto/webhook/fixtures/order.config.json +10 -0
  417. procesio_cli/tools/procesio/dto/webhook/fixtures/order.dto.json +25 -0
  418. procesio_cli/tools/procesio/dto/webhook/template.dto.json +14 -0
  419. procesio_cli/tools/procesio/environments.py +264 -0
  420. procesio_cli/tools/procesio/errors.py +166 -0
  421. procesio_cli/tools/procesio/flowmodel/README.md +37 -0
  422. procesio_cli/tools/procesio/flowmodel/__init__.py +14 -0
  423. procesio_cli/tools/procesio/flowmodel/digest.py +223 -0
  424. procesio_cli/tools/procesio/flowmodel/families.py +34 -0
  425. procesio_cli/tools/procesio/flowmodel/fevalidation.py +1098 -0
  426. procesio_cli/tools/procesio/flowmodel/formdigest.py +232 -0
  427. procesio_cli/tools/procesio/flowmodel/inspect.py +78 -0
  428. procesio_cli/tools/procesio/flowmodel/model.py +82 -0
  429. procesio_cli/tools/procesio/flowmodel/nodeparam.py +871 -0
  430. procesio_cli/tools/procesio/flowmodel/reader.py +191 -0
  431. procesio_cli/tools/procesio/flowmodel/sqlparam.py +410 -0
  432. procesio_cli/tools/procesio/form_code_keys.py +50 -0
  433. procesio_cli/tools/procesio/formlint.py +292 -0
  434. procesio_cli/tools/procesio/gen_manifest.py +118 -0
  435. procesio_cli/tools/procesio/handlers/__init__.py +1 -0
  436. procesio_cli/tools/procesio/handlers/auth_actions.py +103 -0
  437. procesio_cli/tools/procesio/handlers/catalog.py +147 -0
  438. procesio_cli/tools/procesio/handlers/common.py +90 -0
  439. procesio_cli/tools/procesio/handlers/customaction_ops.py +146 -0
  440. procesio_cli/tools/procesio/handlers/datastore_ops.py +482 -0
  441. procesio_cli/tools/procesio/handlers/datatype_ops.py +275 -0
  442. procesio_cli/tools/procesio/handlers/dto_actions.py +258 -0
  443. procesio_cli/tools/procesio/handlers/environment_admin.py +146 -0
  444. procesio_cli/tools/procesio/handlers/fevalidate.py +236 -0
  445. procesio_cli/tools/procesio/handlers/files.py +141 -0
  446. procesio_cli/tools/procesio/handlers/flowgraph.py +229 -0
  447. procesio_cli/tools/procesio/handlers/flowlint.py +269 -0
  448. procesio_cli/tools/procesio/handlers/form_chains.py +336 -0
  449. procesio_cli/tools/procesio/handlers/form_code.py +277 -0
  450. procesio_cli/tools/procesio/handlers/form_element.py +199 -0
  451. procesio_cli/tools/procesio/handlers/form_events.py +441 -0
  452. procesio_cli/tools/procesio/handlers/form_update.py +270 -0
  453. procesio_cli/tools/procesio/handlers/formprocess.py +211 -0
  454. procesio_cli/tools/procesio/handlers/generic.py +135 -0
  455. procesio_cli/tools/procesio/handlers/layout.py +137 -0
  456. procesio_cli/tools/procesio/handlers/nodeparams.py +1018 -0
  457. procesio_cli/tools/procesio/handlers/process_layout.py +189 -0
  458. procesio_cli/tools/procesio/handlers/process_naming.py +213 -0
  459. procesio_cli/tools/procesio/handlers/processes.py +416 -0
  460. procesio_cli/tools/procesio/handlers/profile_admin.py +184 -0
  461. procesio_cli/tools/procesio/handlers/resource_ops.py +447 -0
  462. procesio_cli/tools/procesio/handlers/schedules.py +320 -0
  463. procesio_cli/tools/procesio/handlers/sqlactions.py +232 -0
  464. procesio_cli/tools/procesio/handlers/transport.py +463 -0
  465. procesio_cli/tools/procesio/handlers/usageguide.py +222 -0
  466. procesio_cli/tools/procesio/layout/README.md +196 -0
  467. procesio_cli/tools/procesio/layout/__init__.py +11 -0
  468. procesio_cli/tools/procesio/layout/adapter.py +736 -0
  469. procesio_cli/tools/procesio/layout/cycles.py +186 -0
  470. procesio_cli/tools/procesio/layout/dispatch.py +39 -0
  471. procesio_cli/tools/procesio/layout/elk/elk_runner.mjs +50 -0
  472. procesio_cli/tools/procesio/layout/elk/package-lock.json +21 -0
  473. procesio_cli/tools/procesio/layout/elk/package.json +11 -0
  474. procesio_cli/tools/procesio/layout/elk_engine.py +568 -0
  475. procesio_cli/tools/procesio/layout/engine.py +1311 -0
  476. procesio_cli/tools/procesio/layout/report.py +187 -0
  477. procesio_cli/tools/procesio/main.py +179 -0
  478. procesio_cli/tools/procesio/profiles.py +193 -0
  479. procesio_cli/tools/procesio/reliability.py +193 -0
  480. procesio_cli/tools/procesio/sqlformat.py +167 -0
  481. procesio_cli/tools/procesio/swagger.py +51 -0
  482. procesio_cli/tools/procesio/tests/__init__.py +0 -0
  483. procesio_cli/tools/procesio/tests/conftest.py +129 -0
  484. procesio_cli/tools/procesio/tests/test_auth.py +200 -0
  485. procesio_cli/tools/procesio/tests/test_autogen.py +78 -0
  486. procesio_cli/tools/procesio/tests/test_builder_attrpath_sqlbind.py +180 -0
  487. procesio_cli/tools/procesio/tests/test_builder_custom_action_catalog.py +72 -0
  488. procesio_cli/tools/procesio/tests/test_client.py +114 -0
  489. procesio_cli/tools/procesio/tests/test_client_reliability.py +139 -0
  490. procesio_cli/tools/procesio/tests/test_customaction.py +103 -0
  491. procesio_cli/tools/procesio/tests/test_customaction_test.py +80 -0
  492. procesio_cli/tools/procesio/tests/test_cycles.py +69 -0
  493. procesio_cli/tools/procesio/tests/test_datastore.py +378 -0
  494. procesio_cli/tools/procesio/tests/test_datastore_node.py +94 -0
  495. procesio_cli/tools/procesio/tests/test_dispatch.py +170 -0
  496. procesio_cli/tools/procesio/tests/test_document_page_size.py +19 -0
  497. procesio_cli/tools/procesio/tests/test_dto.py +734 -0
  498. procesio_cli/tools/procesio/tests/test_edit_dryrun_preview.py +96 -0
  499. procesio_cli/tools/procesio/tests/test_elk_layout.py +221 -0
  500. procesio_cli/tools/procesio/tests/test_environments.py +214 -0
  501. procesio_cli/tools/procesio/tests/test_fevalidate_gate.py +104 -0
  502. procesio_cli/tools/procesio/tests/test_fevalidation.py +317 -0
  503. procesio_cli/tools/procesio/tests/test_fieldpath_variables.py +87 -0
  504. procesio_cli/tools/procesio/tests/test_files.py +72 -0
  505. procesio_cli/tools/procesio/tests/test_flow_digest.py +202 -0
  506. procesio_cli/tools/procesio/tests/test_flowlint.py +114 -0
  507. procesio_cli/tools/procesio/tests/test_flowmodel.py +158 -0
  508. procesio_cli/tools/procesio/tests/test_form_add_element.py +256 -0
  509. procesio_cli/tools/procesio/tests/test_form_approval_gaps.py +319 -0
  510. procesio_cli/tools/procesio/tests/test_form_auto_names.py +60 -0
  511. procesio_cli/tools/procesio/tests/test_form_chains.py +217 -0
  512. procesio_cli/tools/procesio/tests/test_form_code_actions.py +188 -0
  513. procesio_cli/tools/procesio/tests/test_form_code_keys.py +92 -0
  514. procesio_cli/tools/procesio/tests/test_form_code_style.py +178 -0
  515. procesio_cli/tools/procesio/tests/test_form_delete_element.py +99 -0
  516. procesio_cli/tools/procesio/tests/test_form_element_config.py +141 -0
  517. procesio_cli/tools/procesio/tests/test_form_event_maps.py +135 -0
  518. procesio_cli/tools/procesio/tests/test_form_event_ops.py +376 -0
  519. procesio_cli/tools/procesio/tests/test_form_event_replace.py +86 -0
  520. procesio_cli/tools/procesio/tests/test_form_events.py +92 -0
  521. procesio_cli/tools/procesio/tests/test_form_parity.py +171 -0
  522. procesio_cli/tools/procesio/tests/test_form_select_source.py +74 -0
  523. procesio_cli/tools/procesio/tests/test_form_sync.py +35 -0
  524. procesio_cli/tools/procesio/tests/test_form_update.py +133 -0
  525. procesio_cli/tools/procesio/tests/test_formlint.py +155 -0
  526. procesio_cli/tools/procesio/tests/test_formlint_css_scope.py +38 -0
  527. procesio_cli/tools/procesio/tests/test_formlint_field_names.py +83 -0
  528. procesio_cli/tools/procesio/tests/test_guards.py +110 -0
  529. procesio_cli/tools/procesio/tests/test_hidden_setting_types.py +39 -0
  530. procesio_cli/tools/procesio/tests/test_html2docx_asset.py +132 -0
  531. procesio_cli/tools/procesio/tests/test_key_handle_terminology.py +45 -0
  532. procesio_cli/tools/procesio/tests/test_layout.py +574 -0
  533. procesio_cli/tools/procesio/tests/test_layout_report.py +88 -0
  534. procesio_cli/tools/procesio/tests/test_manifest_sync.py +68 -0
  535. procesio_cli/tools/procesio/tests/test_nodedelete.py +151 -0
  536. procesio_cli/tools/procesio/tests/test_nodeparam.py +826 -0
  537. procesio_cli/tools/procesio/tests/test_normalize.py +70 -0
  538. procesio_cli/tools/procesio/tests/test_payload_docs.py +86 -0
  539. procesio_cli/tools/procesio/tests/test_process_action_naming.py +170 -0
  540. procesio_cli/tools/procesio/tests/test_process_call_api_seed.py +46 -0
  541. procesio_cli/tools/procesio/tests/test_process_ext.py +373 -0
  542. procesio_cli/tools/procesio/tests/test_process_invariants.py +183 -0
  543. procesio_cli/tools/procesio/tests/test_process_layout.py +117 -0
  544. procesio_cli/tools/procesio/tests/test_process_naming.py +188 -0
  545. procesio_cli/tools/procesio/tests/test_process_query_store.py +172 -0
  546. procesio_cli/tools/procesio/tests/test_processinfo_variable.py +56 -0
  547. procesio_cli/tools/procesio/tests/test_profiles.py +127 -0
  548. procesio_cli/tools/procesio/tests/test_put_projects.py +41 -0
  549. procesio_cli/tools/procesio/tests/test_reliability.py +107 -0
  550. procesio_cli/tools/procesio/tests/test_removal_gate.py +95 -0
  551. procesio_cli/tools/procesio/tests/test_resource_ops.py +173 -0
  552. procesio_cli/tools/procesio/tests/test_save_validity.py +207 -0
  553. procesio_cli/tools/procesio/tests/test_schedule_cron_shape.py +111 -0
  554. procesio_cli/tools/procesio/tests/test_schedules.py +309 -0
  555. procesio_cli/tools/procesio/tests/test_sqlconvert.py +234 -0
  556. procesio_cli/tools/procesio/tests/test_sqlformat.py +83 -0
  557. procesio_cli/tools/procesio/tests/test_sqlparam.py +187 -0
  558. procesio_cli/tools/procesio/tests/test_superseded_actions.py +54 -0
  559. procesio_cli/tools/procesio/tests/test_surgical_concurrency.py +156 -0
  560. procesio_cli/tools/procesio/tests/test_tier4.py +123 -0
  561. procesio_cli/tools/procesio/tests/test_transport.py +147 -0
  562. procesio_cli/tools/procesio/tests/test_transport_data_stores.py +168 -0
  563. procesio_cli/tools/procesio/tests/test_transport_mapper_repair.py +150 -0
  564. procesio_cli/tools/procesio/tests/test_transport_webhook_strip.py +253 -0
  565. procesio_cli/tools/procesio/tests/test_usage_guide.py +96 -0
  566. procesio_cli/tools/procesio/tool.yaml +12486 -0
  567. procesio_cli/tools/sqlserver/MOVED-TO-CENTRAL.md +29 -0
  568. procesio_cli/tools/sqlserver/README.md +192 -0
  569. procesio_cli/tools/sqlserver/SKILL.md +37 -0
  570. procesio_cli/tools/sqlserver/SQLSERVER-SCHEMA-NOTES.md +284 -0
  571. procesio_cli/tools/sqlserver/__init__.py +0 -0
  572. procesio_cli/tools/sqlserver/connection.py +242 -0
  573. procesio_cli/tools/sqlserver/main.py +521 -0
  574. procesio_cli/tools/sqlserver/profiles.template.json +1 -0
  575. procesio_cli/tools/sqlserver/schema.py +600 -0
  576. procesio_cli/tools/sqlserver/tests/__init__.py +0 -0
  577. procesio_cli/tools/sqlserver/tests/conftest.py +21 -0
  578. procesio_cli/tools/sqlserver/tests/test_connection.py +75 -0
  579. procesio_cli/tools/sqlserver/tests/test_dbprofiles.py +92 -0
  580. procesio_cli/tools/sqlserver/tests/test_dbquery.py +220 -0
  581. procesio_cli/tools/sqlserver/tests/test_manifest_sync.py +68 -0
  582. procesio_cli/tools/sqlserver/tests/test_sqlserver.py +326 -0
  583. procesio_cli/tools/sqlserver/tests/test_sqlserver_schema.py +488 -0
  584. procesio_cli/tools/sqlserver/tool.yaml +123 -0
  585. procesio_cli/tools/web/README.md +381 -0
  586. procesio_cli/tools/web/SKILL.md +37 -0
  587. procesio_cli/tools/web/WEB-AUTOMATION-NOTES.md +277 -0
  588. procesio_cli/tools/web/__init__.py +21 -0
  589. procesio_cli/tools/web/actiondef.py +24 -0
  590. procesio_cli/tools/web/api.py +444 -0
  591. procesio_cli/tools/web/brokered.py +107 -0
  592. procesio_cli/tools/web/driver.py +839 -0
  593. procesio_cli/tools/web/drivercontract.py +44 -0
  594. procesio_cli/tools/web/errors.py +54 -0
  595. procesio_cli/tools/web/handlers/__init__.py +1 -0
  596. procesio_cli/tools/web/handlers/archive.py +367 -0
  597. procesio_cli/tools/web/handlers/browse.py +182 -0
  598. procesio_cli/tools/web/handlers/contacts.py +74 -0
  599. procesio_cli/tools/web/handlers/sessmgmt.py +120 -0
  600. procesio_cli/tools/web/main.py +128 -0
  601. procesio_cli/tools/web/sessions.py +253 -0
  602. procesio_cli/tools/web/steps.py +162 -0
  603. procesio_cli/tools/web/tests/__init__.py +0 -0
  604. procesio_cli/tools/web/tests/conftest.py +197 -0
  605. procesio_cli/tools/web/tests/test_api.py +330 -0
  606. procesio_cli/tools/web/tests/test_archive.py +190 -0
  607. procesio_cli/tools/web/tests/test_brokered.py +138 -0
  608. procesio_cli/tools/web/tests/test_dispatch.py +132 -0
  609. procesio_cli/tools/web/tests/test_errors.py +60 -0
  610. procesio_cli/tools/web/tests/test_manifest_sync.py +76 -0
  611. procesio_cli/tools/web/tests/test_page_contacts.py +68 -0
  612. procesio_cli/tools/web/tests/test_sessions.py +145 -0
  613. procesio_cli/tools/web/tests/test_steps.py +210 -0
  614. procesio_cli/tools/web/tool.yaml +184 -0
  615. procesio_cli/tools/xlsx/README.md +34 -0
  616. procesio_cli/tools/xlsx/SKILL.md +28 -0
  617. procesio_cli/tools/xlsx/__init__.py +0 -0
  618. procesio_cli/tools/xlsx/main.py +129 -0
  619. procesio_cli/tools/xlsx/reader.py +91 -0
  620. procesio_cli/tools/xlsx/tests/__init__.py +0 -0
  621. procesio_cli/tools/xlsx/tests/conftest.py +39 -0
  622. procesio_cli/tools/xlsx/tests/test_xlsx.py +103 -0
  623. procesio_cli/tools/xlsx/tool.yaml +30 -0
  624. procesio_cli/webplatform/aat_mcp/AAT-MCP-NOTES.md +244 -0
  625. procesio_cli/webplatform/aat_mcp/README.md +78 -0
  626. procesio_cli/webplatform/aat_mcp/bridge.py +705 -0
  627. procesio_cli/webplatform/aat_mcp/chat_server.py +194 -0
  628. procesio_cli/webplatform/aat_mcp/chat_surface.snapshot.json +668 -0
  629. procesio_cli/webplatform/aat_mcp/chat_surface.yaml +372 -0
  630. procesio_cli/webplatform/aat_mcp/gate.py +68 -0
  631. procesio_cli/webplatform/aat_mcp/http_server.py +139 -0
  632. procesio_cli/webplatform/aat_mcp/protocol.py +175 -0
  633. procesio_cli/webplatform/aat_mcp/server.py +306 -0
  634. procesio_cli/webplatform/aat_mcp/tests/conftest.py +8 -0
  635. procesio_cli/webplatform/aat_mcp/tests/test_aat_mcp.py +255 -0
  636. procesio_cli/webplatform/aat_mcp/tests/test_chat_surface.py +247 -0
  637. procesio_cli/webplatform/aat_mcp/tests/test_discovery.py +489 -0
  638. procesio_cli/webplatform/aat_mcp/tests/test_multiuser.py +86 -0
  639. procesio_cli/webplatform/aat_mcp/tests/test_progressive_discovery.py +89 -0
  640. procesio_cli/webplatform/aat_mcp/tests/test_protocol.py +180 -0
  641. procesio_cli/webplatform/aat_mcp/tests/test_skill_discovery.py +23 -0
  642. procesio_cli-0.1.1.dist-info/METADATA +467 -0
  643. procesio_cli-0.1.1.dist-info/RECORD +647 -0
  644. procesio_cli-0.1.1.dist-info/WHEEL +4 -0
  645. procesio_cli-0.1.1.dist-info/entry_points.txt +7 -0
  646. procesio_cli-0.1.1.dist-info/licenses/LICENSE +201 -0
  647. procesio_cli-0.1.1.dist-info/licenses/NOTICE +5 -0
@@ -0,0 +1,2739 @@
1
+ # Process Validation — Collected Code Pieces
2
+
3
+ All the code involved in validating a process in the Process Designer, gathered
4
+ into one place for reference. Nothing below is new code — it is copied verbatim
5
+ from the source files (paths noted in each section).
6
+
7
+ > **Reading this file cold?** Start with "Conceptual model" and the "Glossary of
8
+ > external helpers" below — they give you the domain model and explain every
9
+ > function/type the validation code calls but does not define. Then the call-flow
10
+ > diagram and the code sections will make sense on their own.
11
+
12
+ ## What "validating a process" means
13
+
14
+ A **process** (a.k.a. flow) is a visual graph the user builds on a canvas: **nodes**
15
+ (actions) connected by **lines** (transitions). Each node carries **settings** — the
16
+ configured inputs for that action (e.g. a URL, a data mapping, a delay value).
17
+
18
+ Validation answers one question: *"Is this process complete and internally consistent
19
+ enough to run?"* It never mutates the process — it only **collects a list of warnings**
20
+ (`WarningI[]`). An empty list means valid. The UI later marks the offending nodes with
21
+ an error icon and lists the messages. Validation runs over the whole flow (on save /
22
+ before run) via `getFlowErrors()`.
23
+
24
+ There are two independent layers:
25
+
26
+ 1. **Graph-level checks** (structure of the whole flow): is there exactly one Start and
27
+ at least one Stop? Is every node connected? Do subprocess references resolve and map
28
+ their required variables? Are variable names unique?
29
+ 2. **Field-level checks** (per setting inside each node): required fields filled, values
30
+ match the expected data type, no leftover template placeholders, numeric values in
31
+ range. These are dispatched per setting **type** to a dedicated validator class.
32
+
33
+ ## Conceptual model — the data shapes
34
+
35
+ The validators walk this structure. Only the fields validation touches are shown.
36
+
37
+ ```ts
38
+ // A node = one action box on the canvas
39
+ interface Node {
40
+ id: string; // unique instance id (used as actionId in warnings)
41
+ templateId: string; // which ACTION this is (Start/Stop/CallApi/Decisional/…) — see §6.1
42
+ name: string; // user-facing label; "" is invalid
43
+ type: string; // canvas shape, e.g. "diamond" for decisional
44
+ configuration: SettingTab[]; // tabs, each holding settings[] (the inputs to validate)
45
+ lineArray: Line[]; // transitions attached to this node (connectivity)
46
+ parentId?: string; // set when the node lives inside a container (e.g. ForEach body)
47
+ }
48
+
49
+ // A transition between two nodes
50
+ interface Line {
51
+ nodeStart: Node;
52
+ nodeEnd: Node;
53
+ portData: any; // portData.isDefault === "error" marks the Error output path
54
+ }
55
+
56
+ // One configured input on a node. `value`'s shape depends on `type`.
57
+ interface Setting {
58
+ id: string; // identifies WHICH setting (see §6.2)
59
+ label: string; // shown in the warning badge
60
+ type: SettingType; // selects the validator class (see ControlValidatorFactory)
61
+ value: any; // string | number | array | object, depending on type
62
+ dataTypeId: string; // expected data type GUID (see §6.3)
63
+ isList: boolean; // expects a list vs a scalar
64
+ isRequired?: boolean;
65
+ limits?: { min: number; max: number };
66
+ }
67
+ ```
68
+
69
+ Key idea for **field validation**: `checkFieldValidation` iterates every
70
+ `node.configuration[].settings[]`. For each setting it asks
71
+ `ControlValidatorFactory.getValidator(setting.type)` for the right validator, then runs
72
+ four independent hooks and concatenates whatever warnings they return:
73
+
74
+ - `doRequiredCheck` — is a required value missing/empty?
75
+ - `doDataTypeCheck` — does the value's data type match `setting.dataTypeId`/`isList`?
76
+ - `doPlaceholdersCheck` — are there unresolved template placeholders left in the value?
77
+ - `doValueCheck` — is the raw value well-formed for its primitive type (number/int)?
78
+
79
+ A validator that doesn't care about a given hook returns `[]`. `DefaultControlValidator`
80
+ is the fallback for simple settings; the other classes handle complex composite settings
81
+ (API payloads, mappings, decisional conditions, delays, …).
82
+
83
+ ## Glossary of external helpers (called but defined elsewhere)
84
+
85
+ The validation code leans on these. Knowing what they return is enough to follow the logic:
86
+
87
+ | Symbol | Where | What it does |
88
+ |---|---|---|
89
+ | `WarningI` | Validation.ts | The warning object every check produces: `{ text, badges, key, actionId? }`. `text` = message, `badges` = breadcrumb chips (action + field), `actionId` = node to highlight. |
90
+ | `AbstractControlValidator.getBadges(node, suffix?)` | AbstractControlValidator.ts | Builds the badge array: resolves the action's display name from the store, appends the node's custom name (if different) and an optional ` - <field>` suffix. |
91
+ | `createGuid()` | utils/type/guid | Random id; used only as a React-style `key` for each warning. Not domain data. |
92
+ | `getValueDataTypes(value)` → `{ scalar: DataModel[], list: DataModel[] }` | Values/ValueDataTypesHelper | Parses a setting's raw string value, finds any **variable references** (GUIDs) inside it, and returns the data types those variables resolve to — split into scalar vs list. Empty arrays = a plain constant with no variables. This is the input to `SettingValidation.validateDataType`. |
93
+ | `SettingValidation.validateDataType(types, setting, excluded?)` | SettingValidation.ts (§3) | Returns `true` if the value's actual types (`getValueDataTypes` output) are assignable to what the setting expects (`dataTypeId`, `isList`). Rules: OBJECT accepts anything; STRING accepts any primitive; JSON/OBJECT accept custom models; otherwise ids must match. `excluded` forbids specific type ids (e.g. File). |
94
+ | `hasVariable(value)` | Variables/Utils | `true` if the string contains a variable reference (a GUID). Used to **skip** literal-value checks when the value is a variable (its concrete value is unknown at design time). |
95
+ | `isPrimitive`, `isCustomTypeAllowed`, `Primitives`, `NonPrimitives` | utils/dataTypeMapper (§6.3) | Data-type GUID helpers/enums. `isCustomTypeAllowed` = the id is JSON or OBJECT. |
96
+ | `isValidNumber` / `isValidInteger` | utils/type/* | Primitive value-format checks used by `doValueCheck`. |
97
+ | `FormBuilder`, `Validators` | utils/ReactiveForm | A tiny reactive-forms lib. Decisional validators build a throwaway form (one control per condition field with `Validators.required` etc.), call `form.validate()`, and read `form.hasErrors`. It's just a declarative way to check "are all these condition fields filled?". |
98
+ | `store.getters.*` | Vuex store | Read-only lookups: `getActionNameById`, `getConditionOperandByName`, `dataTypes` (all `DataModel`s), `processes.variables` (the flow's variables). |
99
+ | `OrchestrationService.loadFlow(id)` | services/crud/Orchestration.service | Async: fetches a **subprocess** flow by id, so `checkSubprocess` can confirm it's valid and inspect its input/output variables. |
100
+ | template-id / setting-id constants | actionHelper.ts, Utils/Settings.ts (§6.1–6.2) | Opaque GUIDs identifying specific action types and specific settings. Values in §6. |
101
+
102
+ ## Overview / call flow
103
+
104
+ The entry point is `Designer.component.vue → getFlowErrors()`, which orchestrates
105
+ every check via the static `FlowValidation` class. Field-level validation fans out
106
+ through `ControlValidatorFactory`, which returns the right `AbstractControlValidator`
107
+ subclass per setting type.
108
+
109
+ ```
110
+ Designer.getFlowErrors()
111
+ └─ FlowValidation (Validation.ts)
112
+ ├─ noUnconnectedNodes() graph connectivity
113
+ ├─ checkFieldValidation() per-setting → ControlValidatorFactory.getValidator()
114
+ │ └─ <Validator>.doRequiredCheck / doDataTypeCheck / doPlaceholdersCheck / doValueCheck
115
+ │ └─ SettingValidation.validateDataType()
116
+ ├─ checkNodeNameValidation() node names non-empty
117
+ ├─ checkPointsValidation() exactly 1 start, ≥1 stop
118
+ ├─ checkLimits() numeric min/max
119
+ ├─ checkSubprocess() subprocess validity + mappings (async)
120
+ └─ checkVariables() unique names, primitive-name rules
121
+ ```
122
+
123
+ Files consolidated here:
124
+
125
+ - `src/modules/ProcessDesigner/components/Designer/Designer.component.vue` (invocation)
126
+ - `src/modules/ProcessDesigner/Validation/Validation.ts`
127
+ - `src/modules/ProcessDesigner/Validation/SettingValidation.ts`
128
+ - `src/modules/ProcessDesigner/Validation/ControlValidators/*`
129
+ - `src/modules/ProcessDesigner/components/Controls/DecisionalManager/card/DecisionalCard.validation.ts`
130
+
131
+ ---
132
+
133
+ ## 1. Invocation — Designer.component.vue › getFlowErrors()
134
+
135
+ `src/modules/ProcessDesigner/components/Designer/Designer.component.vue`
136
+
137
+ ```ts
138
+ async getFlowErrors() {
139
+ const errors: WarningI[] = [];
140
+
141
+ const nodes: Node[] = this.app.getNodes().filter((node: Node) => {
142
+ const actionData = this.actionDataPerId[node.id];
143
+ return !actionData?.isDisabled;
144
+ });
145
+
146
+ this.syncDecisionCasesWithLines(nodes);
147
+
148
+ // missing transition between 2 actions - an action is not connected to any action
149
+ // no stop node for a branch
150
+ const unconnectedErrors = FlowValidation.noUnconnectedNodes(nodes);
151
+
152
+ errors.push(...unconnectedErrors);
153
+
154
+ // incomplete actions settings - mandatory input missing for an action
155
+ // invalid input on actions - data mismatch error
156
+ const requiredErrors = FlowValidation.checkFieldValidation(
157
+ nodes,
158
+ this.$store.getters.dataTypes,
159
+ this.$store.state.processes.variables
160
+ );
161
+
162
+ errors.push(...requiredErrors);
163
+
164
+ const nameErrors = FlowValidation.checkNodeNameValidation(nodes);
165
+
166
+ errors.push(...nameErrors);
167
+
168
+ const correctPointsErrors = FlowValidation.checkPointsValidation(nodes);
169
+
170
+ errors.push(...correctPointsErrors);
171
+
172
+ const limitsErrors = FlowValidation.checkLimits(nodes);
173
+
174
+ errors.push(...limitsErrors);
175
+
176
+ const subprocessErros = await FlowValidation.checkSubprocess(nodes);
177
+
178
+ errors.push(
179
+ ...subprocessErros,
180
+ ...FlowValidation.checkVariables(this.variables)
181
+ );
182
+
183
+ return errors;
184
+ }
185
+ ```
186
+
187
+ ---
188
+
189
+ ## 2. FlowValidation — Validation.ts
190
+
191
+ `src/modules/ProcessDesigner/Validation/Validation.ts`
192
+
193
+ `FlowValidation` is a static class; each method takes the flow's nodes (and sometimes
194
+ data types / variables) and returns `WarningI[]`. What each method enforces:
195
+
196
+ - **`noUnconnectedNodes`** — every node is wired up. Start/Stop need ≥1 line; a normal
197
+ node with only one line that goes to Stop, or none, is incomplete; it must ultimately
198
+ reach a Stop. Error-path lines (`portData.isDefault === "error"`) are excluded so an
199
+ action isn't considered "connected" by its error path alone. Decisional nodes need an
200
+ entry line; ForEach needs its inner Start connected.
201
+ - **`checkFieldValidation`** — the field-level layer: dispatches every setting to its
202
+ validator (see §4) and runs the four hooks. Skips array-expansion for decisional/AI
203
+ cases (validated as a whole setting).
204
+ - **`checkNodeNameValidation`** — no node may have an empty name.
205
+ - **`checkPointsValidation`** — exactly one Start action and at least one Stop action.
206
+ - **`checkLimits`** — numeric settings with `limits` must be a number within `[min,max]`.
207
+ - **`checkSubprocess`** *(async)* — for Call/Trigger Subprocess nodes: loads the referenced
208
+ flow, requires it to be valid, requires all its **required input variables** to be mapped,
209
+ and checks that mapped variable references actually exist in the subprocess.
210
+ - **`checkVariables`** — flow variable names are unique and don't collide with a primitive
211
+ type name unless they are that type.
212
+ - `checkDecisional` is a stub (kept for reference; currently a no-op).
213
+
214
+ ```ts
215
+ import {
216
+ Line,
217
+ Node,
218
+ ProcessInputOuputSetting,
219
+ Setting,
220
+ SettingType,
221
+ } from "@/modules/ProcessDesigner/components/PropertiesPanel/PropertiesPanel.model";
222
+ import OrchestrationService, {
223
+ VariableType,
224
+ Variable,
225
+ } from "@/services/crud/Orchestration.service";
226
+ import { ProcessVariable } from "@/services/processvariables/ProcessVariables.model";
227
+ import { createGuid } from "@/utils/type/guid";
228
+ import mapguid from "@/utils/mapGUIDtoType";
229
+ import { typeArray } from "@/utils/mapGUIDtoType";
230
+
231
+ import { ControlValidatorFactory } from "./ControlValidators/ControlValidatorFactory";
232
+ import {
233
+ DECISIONAL_CASE_SETTING,
234
+ SUBPROCESS_SELECT_SETTING,
235
+ SUBPROCESS_SIDE_PANEL_SETTING,
236
+ TRIGGER_SUBPROCESS_SELECT_SETTING,
237
+ TRIGGER_SUBPROCESS_SIDE_PANEL_SETTING,
238
+ } from "../components/PropertiesPanel/Utils/Settings";
239
+ import {
240
+ FOREACH_TEMPLATE_ID,
241
+ START_ACTION_TEMPLATE_ID,
242
+ CALL_SUBPROCESS_TEMPLATE_ID,
243
+ DECISIONAL_TEMPLATE_ID,
244
+ AI_DECISIONAL_TEMPLATE_ID,
245
+ STOP_ACTION_TEMPLATE_ID,
246
+ TRIGGER_SUBPROCESS_TEMPLATE_ID,
247
+ } from "@/utils/actionHelper";
248
+ import { DataModel } from "@/services/datamodel/DataModel.model";
249
+ import { AbstractControlValidator } from "./ControlValidators/AbstractControlValidator";
250
+
251
+ export interface WarningI {
252
+ text: string;
253
+ badges: string[];
254
+ key: string;
255
+ actionId?: string;
256
+ }
257
+ export class FlowValidation {
258
+ static noUnconnectedNodes(actions: Node[]): WarningI[] {
259
+ const unconnectedNodesMessage =
260
+ "Please make sure that all actions are connected.";
261
+
262
+ const missingEndNode =
263
+ "Process definition incomplete. Please make sure the action is connected to Stop action.";
264
+ const missingEndNodeExceptErrorPath =
265
+ "Process definition incomplete. Please make sure the action has any connection besides Error path connection.";
266
+
267
+ const filterErrorPortLines = (nodeId: string, lines: Line[]) =>
268
+ (Array.isArray(lines) ? lines : []).filter(
269
+ (line) =>
270
+ line.nodeEnd.id === nodeId || line.portData?.isDefault !== "error",
271
+ );
272
+
273
+ const errors = actions.reduce((acc: WarningI[], value) => {
274
+ const originalLines = [...value.lineArray];
275
+ const lines = filterErrorPortLines(value.id, originalLines);
276
+
277
+ // check start stop
278
+ if (
279
+ value.templateId === START_ACTION_TEMPLATE_ID ||
280
+ value.templateId === STOP_ACTION_TEMPLATE_ID
281
+ ) {
282
+ if (!lines.length) {
283
+ acc.push({
284
+ text: unconnectedNodesMessage,
285
+ badges: AbstractControlValidator.getBadges(value),
286
+ key: createGuid(),
287
+ actionId: value.id,
288
+ });
289
+ }
290
+ } else {
291
+ if (!lines.length) {
292
+ acc.push({
293
+ text: unconnectedNodesMessage,
294
+ badges: AbstractControlValidator.getBadges(value),
295
+ key: createGuid(),
296
+ actionId: value.id,
297
+ });
298
+ } else if (lines.length === 1) {
299
+ if (
300
+ lines[0].nodeStart.templateId === STOP_ACTION_TEMPLATE_ID ||
301
+ lines[0].nodeEnd.templateId === STOP_ACTION_TEMPLATE_ID
302
+ ) {
303
+ acc.push({
304
+ text: unconnectedNodesMessage,
305
+ badges: AbstractControlValidator.getBadges(value),
306
+ key: createGuid(),
307
+ actionId: value.id,
308
+ });
309
+ } else {
310
+ if (!value.parentId) {
311
+ let text = missingEndNode;
312
+ if (lines.length !== originalLines.length) {
313
+ text = missingEndNodeExceptErrorPath;
314
+ }
315
+
316
+ acc.push({
317
+ text,
318
+ badges: AbstractControlValidator.getBadges(value),
319
+ key: createGuid(),
320
+ actionId: value.id,
321
+ });
322
+ }
323
+ }
324
+ } else if (
325
+ [DECISIONAL_TEMPLATE_ID, AI_DECISIONAL_TEMPLATE_ID].includes(
326
+ value.templateId,
327
+ ) &&
328
+ lines.length >= 2
329
+ ) {
330
+ // check if conditional has entry node
331
+ let isValid = false;
332
+
333
+ lines.forEach((line) => {
334
+ if (line.nodeEnd.id === value.id) {
335
+ isValid = true;
336
+ }
337
+ });
338
+
339
+ if (!isValid) {
340
+ acc.push({
341
+ text: unconnectedNodesMessage,
342
+ badges: AbstractControlValidator.getBadges(value),
343
+ key: createGuid(),
344
+ actionId: value.id,
345
+ });
346
+ }
347
+ } else if (value.templateId === FOREACH_TEMPLATE_ID) {
348
+ const foreachStart = (value as any).children.find(
349
+ (c: Node) => c?.templateId === START_ACTION_TEMPLATE_ID,
350
+ );
351
+ if (foreachStart && !foreachStart.lineArray.length) {
352
+ acc.push({
353
+ text: unconnectedNodesMessage,
354
+ badges: AbstractControlValidator.getBadges(value),
355
+ key: createGuid(),
356
+ actionId: value.id,
357
+ });
358
+ }
359
+ }
360
+ }
361
+
362
+ return acc;
363
+ }, []);
364
+
365
+ return errors;
366
+ }
367
+
368
+ static checkFieldValidation(
369
+ actions: Node[],
370
+ dataType: DataModel[],
371
+ processVariables: ProcessVariable[],
372
+ ): WarningI[] {
373
+ const errors: WarningI[] = [];
374
+
375
+ actions.forEach((node) => {
376
+ node.configuration.forEach((config) => {
377
+ config.settings.forEach((setting) => {
378
+ const settingValues =
379
+ Array.isArray(setting.value) &&
380
+ setting.id !== DECISIONAL_CASE_SETTING && // this is an exception for the decision case validation
381
+ setting.type !== SettingType.AI_DECISIONAL_CASE // AI Decisional cases are validated as a whole setting
382
+ ? setting.value
383
+ : [setting];
384
+
385
+ settingValues.forEach((val) => {
386
+ const validator = ControlValidatorFactory.getValidator(val.type);
387
+ errors.push(
388
+ ...[
389
+ ...validator.doRequiredCheck(node, val),
390
+ ...validator.doDataTypeCheck(
391
+ node,
392
+ val,
393
+ dataType,
394
+ processVariables,
395
+ ),
396
+ ...validator.doPlaceholdersCheck(node, val),
397
+ ...validator.doValueCheck(node, val),
398
+ ],
399
+ );
400
+ });
401
+ });
402
+ });
403
+ });
404
+
405
+ return errors;
406
+ }
407
+
408
+ static checkNodeNameValidation(actions: Node[]): WarningI[] {
409
+ const errors: WarningI[] = [];
410
+
411
+ actions.forEach((node) => {
412
+ if (node.name == "") {
413
+ errors.push({
414
+ text: "Please make sure that all actions have a name.",
415
+ badges: AbstractControlValidator.getBadges(node, " - node name"),
416
+ key: createGuid(),
417
+ actionId: node.id,
418
+ });
419
+ }
420
+ });
421
+
422
+ return errors;
423
+ }
424
+
425
+ static checkDecisional(actions: Node[]): WarningI[] {
426
+ const errors: WarningI[] = [];
427
+
428
+ actions.forEach((node) => {
429
+ if (node.type === "diamond") {
430
+ node.configuration.forEach((config) => {
431
+ config.settings.forEach((setting) => {
432
+ if (setting.value) {
433
+ //TODO: call new validation error
434
+ }
435
+ });
436
+ });
437
+ }
438
+ });
439
+
440
+ return errors;
441
+ }
442
+
443
+ static checkLimits(actions: Node[]): WarningI[] {
444
+ const errors: WarningI[] = [];
445
+ actions.forEach((node) => {
446
+ node.configuration.forEach((config) => {
447
+ config.settings.forEach((setting) => {
448
+ const settings = Array.isArray(setting.value)
449
+ ? setting.value
450
+ : [setting];
451
+
452
+ settings.forEach((setting) => {
453
+ if (
454
+ setting.limits &&
455
+ (setting.value < setting.limits.min ||
456
+ setting.value > setting.limits.max)
457
+ ) {
458
+ if (isNaN(setting.value)) {
459
+ errors.push({
460
+ text: `Please make sure that the value is a number.`,
461
+ badges: AbstractControlValidator.getBadges(
462
+ node,
463
+ ` - ${setting.label}`,
464
+ ),
465
+ key: createGuid(),
466
+ actionId: node.id,
467
+ });
468
+ }
469
+ errors.push({
470
+ text: `Please make sure that the value is between ${setting.limits.min} and ${setting.limits.max}.`,
471
+ badges: AbstractControlValidator.getBadges(
472
+ node,
473
+ ` - ${setting.label}`,
474
+ ),
475
+ key: createGuid(),
476
+ actionId: node.id,
477
+ });
478
+ }
479
+ });
480
+ });
481
+ });
482
+ });
483
+
484
+ return errors;
485
+ }
486
+
487
+ static checkPointsValidation(actions: Node[]): WarningI[] {
488
+ const missingStartError =
489
+ "Please make sure that the process have 1 start action";
490
+
491
+ const missingStopError =
492
+ "Please make sure that the process have at least 1 stop action";
493
+ const errors: WarningI[] = [];
494
+
495
+ const startNode = actions.filter(
496
+ (node) => node.templateId === "c0e32108-6e3e-4ab8-96bd-cd61be6edb33",
497
+ );
498
+
499
+ const endNodes = actions.filter(
500
+ (node) => node.templateId === "c0e32108-6e3e-4ab8-96bd-cd61be6edb34",
501
+ );
502
+
503
+ if (startNode.length !== 1) {
504
+ errors.push({
505
+ text: missingStartError,
506
+ badges: ["Start"],
507
+ key: createGuid(),
508
+ });
509
+ }
510
+
511
+ if (endNodes.length < 1) {
512
+ errors.push({
513
+ text: missingStopError,
514
+ badges: ["Stop"],
515
+ key: createGuid(),
516
+ });
517
+ }
518
+
519
+ return errors;
520
+ }
521
+
522
+ static async checkSubprocess(actions: Node[]): Promise<WarningI[]> {
523
+ const errors: WarningI[] = [];
524
+
525
+ for (let index = 0; index < actions.length; index++) {
526
+ const action = actions[index];
527
+
528
+ if (
529
+ ![CALL_SUBPROCESS_TEMPLATE_ID, TRIGGER_SUBPROCESS_TEMPLATE_ID].includes(
530
+ action.templateId,
531
+ )
532
+ ) {
533
+ continue;
534
+ }
535
+
536
+ const subprocessNode: Node | undefined = action;
537
+
538
+ /** id of select component */
539
+ const selectSubprocess: Setting | undefined =
540
+ action.configuration[0].settings.find((setting) =>
541
+ [
542
+ SUBPROCESS_SELECT_SETTING,
543
+ TRIGGER_SUBPROCESS_SELECT_SETTING,
544
+ ].includes(setting.id),
545
+ );
546
+
547
+ const subprocessValue = action.configuration[0].settings.find((setting) =>
548
+ [
549
+ SUBPROCESS_SIDE_PANEL_SETTING,
550
+ TRIGGER_SUBPROCESS_SIDE_PANEL_SETTING,
551
+ ].includes(setting.id),
552
+ )?.value;
553
+
554
+ /** id of the sidepanel holding the input and output variables */
555
+ const subprocessInput: ProcessInputOuputSetting | undefined =
556
+ subprocessValue?.length && subprocessValue[0];
557
+ const subprocessOutput: ProcessInputOuputSetting | undefined =
558
+ subprocessValue?.length && subprocessValue[1];
559
+
560
+ if (selectSubprocess?.value) {
561
+ const response = await OrchestrationService.loadFlow(
562
+ selectSubprocess.value,
563
+ );
564
+
565
+ if (response.content) {
566
+ const inputVariables: Variable[] = [];
567
+ const outputVariables: Variable[] = [];
568
+
569
+ const process = response.content.flow;
570
+
571
+ if (process && !process.isValid) {
572
+ errors.push({
573
+ text: "Subprocess should be valid.",
574
+ badges: subprocessNode
575
+ ? AbstractControlValidator.getBadges(subprocessNode)
576
+ : [],
577
+ key: createGuid(),
578
+ actionId: subprocessNode?.id,
579
+ });
580
+ }
581
+
582
+ process?.variables?.forEach((variable) => {
583
+ if (variable.type === VariableType.INPUT) {
584
+ inputVariables.push(variable);
585
+ }
586
+
587
+ if (variable.type === VariableType.OUTPUT) {
588
+ outputVariables.push(variable);
589
+ }
590
+ });
591
+
592
+ inputVariables
593
+ .filter((variable) => variable.isRequired)
594
+ .forEach((requiredInputVariable) => {
595
+ const inputs = subprocessInput?.value || [];
596
+ const mapIndex = inputs.findIndex(
597
+ (input) =>
598
+ input.subprocess === requiredInputVariable.id &&
599
+ !!input.process,
600
+ );
601
+
602
+ if (mapIndex === -1) {
603
+ errors.push({
604
+ text: `Mapping of required subprocess variable (<b>${requiredInputVariable.name}</b>) is missing.`,
605
+ badges: subprocessNode
606
+ ? AbstractControlValidator.getBadges(subprocessNode)
607
+ : [],
608
+ key: createGuid(),
609
+ actionId: subprocessNode?.id,
610
+ });
611
+ }
612
+ });
613
+
614
+ const variableRegex =
615
+ /([0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\.[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12})*)\b(?!\.)/g;
616
+
617
+ (subprocessInput?.value || [])?.forEach((input) => {
618
+ const variables = input.subprocess.match(new RegExp(variableRegex));
619
+
620
+ if (variables) {
621
+ variables.forEach((matchedVariable) => {
622
+ const guidArray = matchedVariable.split(".");
623
+
624
+ const isValid =
625
+ inputVariables
626
+ .map((variable) => variable.id)
627
+ .indexOf(guidArray[0]) >= 0;
628
+
629
+ if (!isValid) {
630
+ errors.push({
631
+ text: `Check data mapping.`,
632
+ badges: subprocessNode
633
+ ? AbstractControlValidator.getBadges(subprocessNode)
634
+ : [],
635
+ key: createGuid(),
636
+ actionId: subprocessNode?.id,
637
+ });
638
+ }
639
+ });
640
+ }
641
+ });
642
+
643
+ if (Array.isArray(subprocessOutput?.value)) {
644
+ (subprocessOutput?.value || []).forEach((input) => {
645
+ const variables = input.subprocess.match(
646
+ new RegExp(variableRegex),
647
+ );
648
+
649
+ if (variables) {
650
+ variables.forEach((matchedVariable) => {
651
+ const guidArray = matchedVariable.split(".");
652
+
653
+ const isValid =
654
+ outputVariables
655
+ .map((variable) => variable.id)
656
+ .indexOf(guidArray[0]) >= 0;
657
+
658
+ if (!isValid) {
659
+ errors.push({
660
+ text: `Check data mapping.`,
661
+ badges: subprocessNode
662
+ ? AbstractControlValidator.getBadges(subprocessNode)
663
+ : [],
664
+ key: createGuid(),
665
+ actionId: subprocessNode?.id,
666
+ });
667
+ }
668
+ });
669
+ }
670
+ });
671
+ }
672
+ }
673
+ }
674
+ }
675
+
676
+ return errors;
677
+ }
678
+
679
+ static checkVariables(variables: Variable[]): WarningI[] {
680
+ const errors: WarningI[] = [];
681
+
682
+ // store already found duplicates to do not show same message few times
683
+ const duplicates: string[] = [];
684
+
685
+ variables.forEach((variable: Variable) => {
686
+ const sameNameVariableIndex = variables.findIndex(
687
+ (v) => v.name === variable.name && v.id !== variable.id,
688
+ );
689
+ if (
690
+ sameNameVariableIndex !== -1 &&
691
+ duplicates.indexOf(variable.name) === -1
692
+ ) {
693
+ errors.push({
694
+ text: "Variable name should be unique.",
695
+ badges: [`Variable: ${variable.name}`],
696
+ key: createGuid(),
697
+ });
698
+ duplicates.push(variable.name);
699
+ }
700
+
701
+ const typeName = mapguid(variable);
702
+
703
+ typeArray.forEach((option: string) => {
704
+ if (variable.name.toLowerCase() == option) {
705
+ if (typeName != "custom") {
706
+ if (typeName != variable.name.toLowerCase()) {
707
+ errors.push({
708
+ text: `Cannot name variables as Primitives with a different type.`,
709
+ badges: [`Variable: ${variable.name}`],
710
+ key: createGuid(),
711
+ });
712
+ }
713
+ }
714
+ }
715
+ });
716
+ });
717
+
718
+ return errors;
719
+ }
720
+ }
721
+ ```
722
+
723
+ ---
724
+
725
+ ## 3. SettingValidation — data-type matching
726
+
727
+ `src/modules/ProcessDesigner/Validation/SettingValidation.ts`
728
+
729
+ ```ts
730
+ import { ValueDataTypes } from "@/modules/ProcessDesigner/Values/ValueDataTypesHelper";
731
+ import {
732
+ isCustomTypeAllowed,
733
+ isPrimitive,
734
+ NonPrimitives,
735
+ Primitives,
736
+ } from "@/utils/dataTypeMapper";
737
+ import { Setting } from "@/modules/ProcessDesigner/components/PropertiesPanel/PropertiesPanel.model";
738
+ import { DataModel } from "@/services/datamodel/DataModel.model";
739
+
740
+ export class SettingValidation {
741
+ static validateDataType(
742
+ { scalar: scalarDataTypes, list: listDataTypes }: ValueDataTypes,
743
+ setting: Setting,
744
+ excludedDataTypesId: string[] = []
745
+ ): boolean {
746
+ if (scalarDataTypes.length === 0 && listDataTypes.length === 0) {
747
+ return true;
748
+ }
749
+
750
+ // check for list type
751
+ if (
752
+ (setting.isList &&
753
+ (scalarDataTypes.length !== 0 || listDataTypes.length !== 1)) ||
754
+ (!setting.isList &&
755
+ (scalarDataTypes.length === 0 || listDataTypes.length !== 0))
756
+ ) {
757
+ return false;
758
+ }
759
+
760
+ const settingDataTypeId = setting.dataTypeId;
761
+
762
+ const validTypeFlags = [...scalarDataTypes, ...listDataTypes]
763
+ .filter((dataType) => !!dataType)
764
+ .reduce((flags: boolean[], dataType: DataModel) => {
765
+ let flag = false;
766
+
767
+ if (excludedDataTypesId.includes(dataType.id)) {
768
+ flag = false;
769
+ }
770
+ // Object data type means any type is allowed
771
+ else if (settingDataTypeId === NonPrimitives.OBJECT) {
772
+ flag = true;
773
+ } else if (isPrimitive(dataType.id)) {
774
+ flag =
775
+ settingDataTypeId === Primitives.STRING
776
+ ? true
777
+ : dataType.id === settingDataTypeId;
778
+ } else {
779
+ flag =
780
+ isCustomTypeAllowed(settingDataTypeId) ||
781
+ dataType.id === settingDataTypeId;
782
+ }
783
+
784
+ flags.push(flag);
785
+ return flags;
786
+ }, []);
787
+
788
+ return validTypeFlags.every((flag: boolean) => flag);
789
+ }
790
+ }
791
+ ```
792
+
793
+ ---
794
+
795
+ ## 4. ControlValidators
796
+
797
+ Each setting **type** maps to one validator class (via `ControlValidatorFactory`, §4.2).
798
+ The class implements the four hooks; anything it doesn't check returns `[]`. What each
799
+ one guards:
800
+
801
+ | Setting type (§6.4) | Validator (§) | Guards against |
802
+ |---|---|---|
803
+ | *(fallback / simple inputs)* | DefaultControlValidator (4.3) | required-but-empty; value's variable types not assignable to the field; malformed number/integer/object literals |
804
+ | `AI_DECISIONAL_CASE` | AiDecisionalCaseValidator (4.4) | any AI case missing name, condition, or target |
805
+ | `TABS_PAYLOAD` (Call API v2) | TabsPayloadControlValidator (4.5) | body/query/header row has a value but no key; body item type mismatch (form-data/urlencoded/binary) |
806
+ | `TABS_PAYLOAD_OLD` (Call API legacy) | TabsPayloadOldControlValidator (4.6) | query/header row has a value but no key |
807
+ | `PROCESS_INPUT` / `PROCESS_OUTPUT` | ProcessInputOutputValidator (4.7) | subprocess mapping row missing its subprocess side (type-check currently disabled) |
808
+ | `DECISIONAL_CASE` | ConditionalValidator (4.8) | case missing name/target/≥1 condition; left/right operand type mismatch; missing operator |
809
+ | `DATA_STORE_DECISIONAL` | DataStoreDecisionalValidator (4.9) | "Where" conditions not fully configured (extends ConditionalValidator) |
810
+ | `DELAY_DEFINITION` | DelayDefinitionValidator (4.10) | delay value missing; negative wait-for; wait-until date in the past |
811
+ | `DOCUMENT_MAPPER_BUILDER` / `DATA_STORE_MAPPER` | DocumentMapperValidator (4.11) | mapper row missing its document target (type-check currently disabled) |
812
+ | `COLUMN_DEFINITION` (Get File Data) | ColumnDefinitionControlValidator (4.12) | no rows, or a row missing column name / attribute; attribute type mismatch |
813
+ | `MAP_PARAMETERS` | MapParametersValidator (4.13) | mapping row missing destination/source |
814
+ | `MAP_PROCESS_DATA` | MapProcessDataValidator (4.14) | mapping row missing destination/source; source→destination type mismatch (File→File allowed) |
815
+
816
+ Note: several `doDataTypeCheck` bodies are intentionally disabled (return `[]` with the
817
+ old implementation left commented out) — flagged inline where that's the case.
818
+
819
+ ### 4.1 AbstractControlValidator (base class)
820
+
821
+ `src/modules/ProcessDesigner/Validation/ControlValidators/AbstractControlValidator.ts`
822
+
823
+ ```ts
824
+ import {
825
+ Node,
826
+ Setting,
827
+ } from "@/modules/ProcessDesigner/components/PropertiesPanel/PropertiesPanel.model";
828
+ import { WarningI } from "../Validation";
829
+
830
+ import { DataModel } from "@/services/datamodel/DataModel.model";
831
+ import { ProcessVariable } from "@/services/processvariables/ProcessVariables.model";
832
+ import { createGuid } from "@/utils/type/guid";
833
+ import { store } from "@/store";
834
+ export abstract class AbstractControlValidator {
835
+ // messages are customizable with the methods below
836
+ requiredCheckErrorMessage =
837
+ "Please make sure that the action is defined/configured properly.";
838
+
839
+ typeCheckErrorMessage = "Error: data type mismatch.";
840
+
841
+ placeholdersCheckErrorMessage =
842
+ "Please replace all placeholders in the template.";
843
+
844
+ setRequiredCheckErrorMessage(message: string) {
845
+ this.requiredCheckErrorMessage = message;
846
+ }
847
+
848
+ setTypeCheckErrorMessage(message: string) {
849
+ this.typeCheckErrorMessage = message;
850
+ }
851
+
852
+ // if a control should not be checked for requiring - implement the method and return an empty array
853
+ abstract doRequiredCheck(node: Node, setting: Setting): WarningI[];
854
+
855
+ // if a control should not be checked for types - implement the method and return an empty array
856
+ abstract doDataTypeCheck(
857
+ node: Node,
858
+ setting: Setting,
859
+ dataType?: DataModel[],
860
+ processVariables?: ProcessVariable[]
861
+ ): WarningI[];
862
+
863
+ doPlaceholdersCheck(node: Node, setting: Setting): WarningI[] {
864
+ const errors: WarningI[] = [];
865
+
866
+ if (setting.value) {
867
+ let value = setting.value;
868
+ if (typeof value === "object") {
869
+ value = JSON.stringify(value);
870
+ }
871
+
872
+ if (
873
+ typeof value === "string" &&
874
+ (this.hasPlaceholder(value) || value.includes("<%%>"))
875
+ )
876
+ errors.push({
877
+ text: this.placeholdersCheckErrorMessage,
878
+ badges: AbstractControlValidator.getBadges(
879
+ node,
880
+ ` - ${setting.label}`
881
+ ),
882
+ key: createGuid(),
883
+ actionId: node.id,
884
+ });
885
+ }
886
+
887
+ return errors;
888
+ }
889
+
890
+ getAllSettings(node: Node) {
891
+ const settings: Setting[] = [];
892
+
893
+ const getSettings = (setting: Setting) => {
894
+ if (typeof setting.id !== "undefined") {
895
+ settings.push(setting);
896
+ if (Array.isArray(setting.value)) {
897
+ setting.value.forEach((setting: Setting) => {
898
+ getSettings(setting);
899
+ });
900
+ }
901
+ }
902
+ };
903
+
904
+ // get settings recursively
905
+ node.configuration.forEach((config) => {
906
+ config.settings.forEach((setting: Setting) => {
907
+ getSettings(setting);
908
+ });
909
+ });
910
+
911
+ return settings;
912
+ }
913
+
914
+ hasPlaceholder(value: string) {
915
+ return new RegExp(
916
+ /([x]{8}\-[x]{4}\-[x]{4}\-[x]{4}\-[a-zA-Z]{11}(\.[x]{8}\-[x]{4}\-[x]{4}\-[x]{4}\-[a-zA-Z]{11})*)\b(?!\.)/g
917
+ ).test(value);
918
+ }
919
+
920
+ abstract doValueCheck(node: Node, setting: Setting): WarningI[];
921
+
922
+ // badge should have action type with messsage and actual node name (if it differs from action type)
923
+ // check PRC-3091 for reference
924
+ static getBadges(node: Node, additionalMesage = "") {
925
+ const actionName = store.getters.getActionNameById(node.templateId);
926
+
927
+ if (!actionName) {
928
+ return [node.name + additionalMesage];
929
+ }
930
+
931
+ const badges = [];
932
+
933
+ if (node.name && actionName.trim() !== node.name.trim()) {
934
+ badges.push(node.name);
935
+ }
936
+
937
+ badges.push(actionName + additionalMesage);
938
+
939
+ return badges;
940
+ }
941
+ }
942
+ ```
943
+
944
+ ### 4.2 ControlValidatorFactory
945
+
946
+ `src/modules/ProcessDesigner/Validation/ControlValidators/ControlValidatorFactory.ts`
947
+
948
+ ```ts
949
+ import { SettingType } from "@/modules/ProcessDesigner/components/PropertiesPanel/PropertiesPanel.model";
950
+ import { AbstractControlValidator } from "./AbstractControlValidator";
951
+ import { TabsPayloadControlValidator } from "./CallApiAction/TabsPayloadControlValidator";
952
+ import { TabsPayloadOldControlValidator } from "./CallApiAction/TabsPayloadOldControlValidator";
953
+ import { ProcessInputOutputValidator } from "./CallSubprocess/ProcessInputOutputValidator";
954
+ import { ConditionalValidator } from "./DecisionalAction/ConditionsValidator";
955
+ import { DefaultControlValidator } from "./DefaultControlValidator";
956
+ import { DelayDefinitionValidator } from "./DelayAction/DelayDefinitionValidator";
957
+ import { DocumentMapperValidator } from "./DocumentMapper/DocumentMapperValidator";
958
+ import { ColumnDefinitionControlValidator } from "./GetFileData/ColumnDefinitionControlValidator";
959
+ import { MapParametersValidator } from "./MapParameters/MapParametersValidator";
960
+ import { AiDecisionalCaseValidator } from "./AiDecisionalAction/AiDecisionalCaseValidator";
961
+ import { MapProcessDataValidator } from "./MapProcessData/MapProcessDataValidator";
962
+ import { DataStoreDecisionalValidator } from "./DataStoreDecisional/DataStoreDecisionalValidator";
963
+
964
+ export class ControlValidatorFactory {
965
+ static getValidator(settingType: SettingType): AbstractControlValidator {
966
+ switch (settingType) {
967
+ case SettingType.TABS_PAYLOAD_OLD:
968
+ return new TabsPayloadOldControlValidator();
969
+ case SettingType.TABS_PAYLOAD:
970
+ return new TabsPayloadControlValidator();
971
+ case SettingType.COLUMN_DEFINITION:
972
+ return new ColumnDefinitionControlValidator();
973
+ case SettingType.DELAY_DEFINITION:
974
+ return new DelayDefinitionValidator();
975
+ case SettingType.PROCESS_INPUT:
976
+ case SettingType.PROCESS_OUTPUT:
977
+ return new ProcessInputOutputValidator();
978
+ case SettingType.MAP_PROCESS_DATA:
979
+ return new MapProcessDataValidator();
980
+ case SettingType.MAP_PARAMETERS:
981
+ return new MapParametersValidator();
982
+ case SettingType.DECISIONAL_CASE:
983
+ return new ConditionalValidator();
984
+ case SettingType.DATA_STORE_DECISIONAL:
985
+ return new DataStoreDecisionalValidator();
986
+ case SettingType.AI_DECISIONAL_CASE:
987
+ return new AiDecisionalCaseValidator();
988
+ case SettingType.DOCUMENT_MAPPER_BUILDER:
989
+ case SettingType.DATA_STORE_MAPPER:
990
+ return new DocumentMapperValidator();
991
+ default:
992
+ return new DefaultControlValidator();
993
+ }
994
+ }
995
+ }
996
+ ```
997
+
998
+ ### 4.3 DefaultControlValidator
999
+
1000
+ `src/modules/ProcessDesigner/Validation/ControlValidators/DefaultControlValidator.ts`
1001
+
1002
+ ```ts
1003
+ import {
1004
+ Node,
1005
+ Setting,
1006
+ SettingType,
1007
+ } from "@/modules/ProcessDesigner/components/PropertiesPanel/PropertiesPanel.model";
1008
+ import { NonPrimitives, Primitives } from "@/utils/dataTypeMapper";
1009
+ import { createGuid } from "@/utils/type/guid";
1010
+ import { isValidInteger } from "@/utils/type/integer";
1011
+ import { parseJSON } from "@/utils/type/json";
1012
+ import { isValidNumber } from "@/utils/type/number";
1013
+ import { getValueDataTypes } from "../../Values/ValueDataTypesHelper";
1014
+ import { hasVariable } from "../../Variables/Utils";
1015
+ import { SettingValidation } from "../SettingValidation";
1016
+ import { WarningI } from "../Validation";
1017
+ import { AbstractControlValidator } from "./AbstractControlValidator";
1018
+
1019
+ export class DefaultControlValidator extends AbstractControlValidator {
1020
+ doRequiredCheck(node: Node, setting: Setting): WarningI[] {
1021
+ const errors = [];
1022
+ const value = setting.value;
1023
+ const isEmpty =
1024
+ value === null ||
1025
+ typeof value === "undefined" ||
1026
+ value === "" ||
1027
+ (Array.isArray(value) && value.length === 0);
1028
+
1029
+ if (setting.isRequired && isEmpty) {
1030
+ errors.push({
1031
+ text: this.requiredCheckErrorMessage,
1032
+ badges: AbstractControlValidator.getBadges(node, ` - ${setting.label}`),
1033
+ key: createGuid(),
1034
+ actionId: node.id,
1035
+ });
1036
+ }
1037
+
1038
+ return errors;
1039
+ }
1040
+
1041
+ doDataTypeCheck(node: Node, setting: Setting): WarningI[] {
1042
+ const value = setting.value || "";
1043
+
1044
+ if (typeof value !== "string") {
1045
+ return [];
1046
+ }
1047
+
1048
+ const errors = [];
1049
+ if (
1050
+ !SettingValidation.validateDataType(getValueDataTypes(value), setting)
1051
+ ) {
1052
+ errors.push({
1053
+ text: this.typeCheckErrorMessage,
1054
+ badges: AbstractControlValidator.getBadges(node, ` - ${setting.label}`),
1055
+ key: createGuid(),
1056
+ actionId: node.id,
1057
+ });
1058
+ }
1059
+
1060
+ return errors;
1061
+ }
1062
+
1063
+ doValueCheck(node: Node, setting: Setting): WarningI[] {
1064
+ const errors: WarningI[] = [];
1065
+
1066
+ if (
1067
+ setting.value === null ||
1068
+ typeof setting.value === "undefined" ||
1069
+ hasVariable(setting.value)
1070
+ ) {
1071
+ return [];
1072
+ }
1073
+
1074
+ let valuesList: any[] | string = setting.isList
1075
+ ? setting.value
1076
+ : [setting.value];
1077
+
1078
+ if (!Array.isArray(valuesList)) {
1079
+ const parsedValuesList = parseJSON(
1080
+ typeof valuesList === "string"
1081
+ ? valuesList.replace(/'/g, '"')
1082
+ : valuesList
1083
+ );
1084
+
1085
+ if (Array.isArray(parsedValuesList)) {
1086
+ valuesList = parsedValuesList;
1087
+ }
1088
+ }
1089
+
1090
+ switch (setting.dataTypeId) {
1091
+ case Primitives.FLOAT:
1092
+ case Primitives.DOUBLE:
1093
+ case Primitives.NUMBER: {
1094
+ if (
1095
+ !Array.isArray(valuesList) ||
1096
+ !valuesList.every((item) => isValidNumber(item))
1097
+ ) {
1098
+ errors.push({
1099
+ text: `Please make sure that the value is a number.`,
1100
+ badges: AbstractControlValidator.getBadges(
1101
+ node,
1102
+ ` - ${setting.label}`
1103
+ ),
1104
+ key: createGuid(),
1105
+ actionId: node.id,
1106
+ });
1107
+ }
1108
+ break;
1109
+ }
1110
+
1111
+ case Primitives.INTEGER:
1112
+ if (
1113
+ !Array.isArray(valuesList) ||
1114
+ !valuesList.every((item) => isValidInteger(item))
1115
+ ) {
1116
+ errors.push({
1117
+ text: `Please make sure that the value is an integer.`,
1118
+ badges: AbstractControlValidator.getBadges(
1119
+ node,
1120
+ ` - ${setting.label}`
1121
+ ),
1122
+ key: createGuid(),
1123
+ actionId: node.id,
1124
+ });
1125
+ }
1126
+ break;
1127
+
1128
+ case NonPrimitives.OBJECT:
1129
+ if (
1130
+ (!Array.isArray(valuesList) ||
1131
+ !valuesList.every((item) => isValidNumber(item))) &&
1132
+ setting.type == SettingType.NUMBER
1133
+ ) {
1134
+ errors.push({
1135
+ text: `Please make sure that the value is a number.`,
1136
+ badges: AbstractControlValidator.getBadges(
1137
+ node,
1138
+ ` - ${setting.label}`
1139
+ ),
1140
+ key: createGuid(),
1141
+ actionId: node.id,
1142
+ });
1143
+ }
1144
+ break;
1145
+ }
1146
+
1147
+ return errors;
1148
+ }
1149
+ }
1150
+ ```
1151
+
1152
+ ### 4.4 AiDecisionalCaseValidator
1153
+
1154
+ `src/modules/ProcessDesigner/Validation/ControlValidators/AiDecisionalAction/AiDecisionalCaseValidator.ts`
1155
+
1156
+ ```ts
1157
+ import {
1158
+ Node,
1159
+ Setting,
1160
+ } from "@/modules/ProcessDesigner/components/PropertiesPanel/PropertiesPanel.model";
1161
+ import { WarningI } from "@/modules/ProcessDesigner/Validation/Validation";
1162
+ import { AbstractControlValidator } from "../AbstractControlValidator";
1163
+ import { AiDecisionalCardValue } from "@/modules/ProcessDesigner/components/Controls/AiDecisionalManager/AiDecisional.model";
1164
+ import { createGuid } from "@/utils/type/guid";
1165
+ import { DataModel } from "@/services/datamodel/DataModel.model";
1166
+ import { ProcessVariable } from "@/services/processvariables/ProcessVariables.model";
1167
+
1168
+ const message =
1169
+ "Action definition incomplete. Please make sure all AI cases have a name, condition, and target configured.";
1170
+
1171
+ export class AiDecisionalCaseValidator extends AbstractControlValidator {
1172
+ doRequiredCheck(node: Node, setting: Setting): WarningI[] {
1173
+ const errors: WarningI[] = [];
1174
+ const value = setting.value as AiDecisionalCardValue[];
1175
+
1176
+ if (!value || !Array.isArray(value) || value.length === 0) {
1177
+ return [];
1178
+ }
1179
+
1180
+ const hasIncomplete = value.some(
1181
+ (caseItem) =>
1182
+ !caseItem.name?.trim() ||
1183
+ !caseItem.condition?.trim() ||
1184
+ !caseItem.target
1185
+ );
1186
+
1187
+ if (hasIncomplete) {
1188
+ errors.push({
1189
+ text: message,
1190
+ badges: AbstractControlValidator.getBadges(node, ` - ${setting.label}`),
1191
+ key: createGuid(),
1192
+ actionId: node.id,
1193
+ });
1194
+ }
1195
+
1196
+ return errors;
1197
+ }
1198
+
1199
+ doDataTypeCheck(
1200
+ _node: Node,
1201
+ _setting: Setting,
1202
+ _dataType?: DataModel[],
1203
+ _processVariables?: ProcessVariable[]
1204
+ ): WarningI[] {
1205
+ return [];
1206
+ }
1207
+
1208
+ doValueCheck(_node: Node, _setting: Setting): WarningI[] {
1209
+ return [];
1210
+ }
1211
+ }
1212
+ ```
1213
+
1214
+ ### 4.5 TabsPayloadControlValidator (Call API)
1215
+
1216
+ `src/modules/ProcessDesigner/Validation/ControlValidators/CallApiAction/TabsPayloadControlValidator.ts`
1217
+
1218
+ ```ts
1219
+ import {
1220
+ Node,
1221
+ RequestPayloadSetting,
1222
+ } from "@/modules/ProcessDesigner/components/PropertiesPanel/PropertiesPanel.model";
1223
+ import { getValueDataTypes } from "@/modules/ProcessDesigner/Values/ValueDataTypesHelper";
1224
+ import {
1225
+ PayloadBodyTypeLabels,
1226
+ PayloadBodyTypes,
1227
+ TabsPayloadItem,
1228
+ TabsPayloadItemType,
1229
+ } from "@/services/apiCall/tabsPayload/TabsPayload.model";
1230
+ import { NonPrimitives } from "@/utils/dataTypeMapper";
1231
+ import { createGuid } from "@/utils/type/guid";
1232
+ import cloneDeep from "lodash/cloneDeep";
1233
+ import { SettingValidation } from "../../SettingValidation";
1234
+ import { WarningI } from "../../Validation";
1235
+ import { AbstractControlValidator } from "../AbstractControlValidator";
1236
+
1237
+ export class TabsPayloadControlValidator extends AbstractControlValidator {
1238
+ doRequiredCheck(node: Node, setting: RequestPayloadSetting): WarningI[] {
1239
+ const value = setting.value;
1240
+ const activeBodyValue = value?.body.value[value?.body.type];
1241
+ const queryParams = value?.queryParams || [];
1242
+ const headers = value?.headers || [];
1243
+ const errors: WarningI[] = [];
1244
+
1245
+ if (Array.isArray(activeBodyValue)) {
1246
+ activeBodyValue.forEach((item: TabsPayloadItem, rowIndex) => {
1247
+ if (
1248
+ item.value && item.value.length > 0 &&
1249
+ (!item.key || item.key.trim().length === 0)
1250
+ ) {
1251
+ errors.push({
1252
+ text: this.requiredCheckErrorMessage,
1253
+ badges: AbstractControlValidator.getBadges(
1254
+ node,
1255
+ ` - ${setting.label} (Body: ${
1256
+ PayloadBodyTypeLabels[value.body.type]
1257
+ }, row ${rowIndex + 1})`
1258
+ ),
1259
+ key: createGuid(),
1260
+ actionId: node.id,
1261
+ });
1262
+ }
1263
+ });
1264
+ }
1265
+
1266
+ queryParams.forEach((param, rowIndex) => {
1267
+ if (
1268
+ param.value && param.value.length > 0 &&
1269
+ (!param.key || param.key.trim().length === 0)
1270
+ ) {
1271
+ errors.push({
1272
+ text: this.requiredCheckErrorMessage,
1273
+ badges: AbstractControlValidator.getBadges(
1274
+ node,
1275
+ ` - ${setting.label} (Query Params, row ${rowIndex + 1})`
1276
+ ),
1277
+ key: createGuid(),
1278
+ actionId: node.id,
1279
+ });
1280
+ }
1281
+ });
1282
+
1283
+ headers.forEach((header, rowIndex) => {
1284
+ if (
1285
+ header.value &&
1286
+ header.value.length > 0 &&
1287
+ (!header.key || header.key.trim().length === 0)
1288
+ ) {
1289
+ errors.push({
1290
+ text: this.requiredCheckErrorMessage,
1291
+ badges: AbstractControlValidator.getBadges(
1292
+ node,
1293
+ ` - ${setting.label} (Headers, row ${rowIndex + 1})`
1294
+ ),
1295
+ key: createGuid(),
1296
+ actionId: node.id,
1297
+ });
1298
+ }
1299
+ });
1300
+
1301
+ return errors;
1302
+ }
1303
+
1304
+ doDataTypeCheck(node: Node, setting: RequestPayloadSetting): WarningI[] {
1305
+ setting = cloneDeep(setting);
1306
+
1307
+ const value = setting.value;
1308
+ const activeBodyValue = value?.body.value[value?.body.type];
1309
+
1310
+ const errors: WarningI[] = [];
1311
+
1312
+ if (Array.isArray(activeBodyValue)) {
1313
+ activeBodyValue.forEach((item: TabsPayloadItem, rowIndex) => {
1314
+ const originalSettingListState = setting.isList;
1315
+ const originalSettingDataTypeId = setting.dataTypeId;
1316
+
1317
+ const inputTypes = getValueDataTypes(item.value);
1318
+
1319
+ if (value.body.type === PayloadBodyTypes.FORM_DATA) {
1320
+ if (item.type === TabsPayloadItemType.FILE) {
1321
+ setting.isList = inputTypes.list.length > 0;
1322
+ setting.dataTypeId = NonPrimitives.FILE;
1323
+ } else {
1324
+ setting.isList = inputTypes.list.length > 0;
1325
+ setting.dataTypeId = NonPrimitives.OBJECT;
1326
+ }
1327
+
1328
+ if (
1329
+ !SettingValidation.validateDataType(
1330
+ inputTypes,
1331
+ setting,
1332
+ item.type === TabsPayloadItemType.FILE ? [] : [NonPrimitives.FILE]
1333
+ )
1334
+ ) {
1335
+ errors.push({
1336
+ text: this.typeCheckErrorMessage,
1337
+ badges: AbstractControlValidator.getBadges(
1338
+ node,
1339
+ ` - ${setting.label} (Body: ${
1340
+ PayloadBodyTypeLabels[value.body.type]
1341
+ }, row ${rowIndex + 1})`
1342
+ ),
1343
+ key: createGuid(),
1344
+ actionId: node.id,
1345
+ });
1346
+ }
1347
+ } else if (value.body.type === PayloadBodyTypes.X_WWW_FORM_URLENCODED) {
1348
+ setting.isList = inputTypes.list.length > 0;
1349
+ setting.dataTypeId = NonPrimitives.OBJECT;
1350
+
1351
+ if (
1352
+ !SettingValidation.validateDataType(
1353
+ inputTypes,
1354
+ setting,
1355
+ [NonPrimitives.FILE] // file is not allowed
1356
+ )
1357
+ ) {
1358
+ errors.push({
1359
+ text: this.typeCheckErrorMessage,
1360
+ badges: AbstractControlValidator.getBadges(
1361
+ node,
1362
+ ` - ${setting.label} (Body: ${
1363
+ PayloadBodyTypeLabels[value.body.type]
1364
+ }, row ${rowIndex + 1})`
1365
+ ),
1366
+ key: createGuid(),
1367
+ actionId: node.id,
1368
+ });
1369
+ }
1370
+ }
1371
+
1372
+ // reset setting props to original state
1373
+ setting.isList = originalSettingListState;
1374
+ setting.dataTypeId = originalSettingDataTypeId;
1375
+ });
1376
+ } else if (
1377
+ typeof activeBodyValue === "string" &&
1378
+ value.body.type === PayloadBodyTypes.BINARY
1379
+ ) {
1380
+ const inputTypes = getValueDataTypes(activeBodyValue);
1381
+ if (!SettingValidation.validateDataType(inputTypes, setting)) {
1382
+ errors.push({
1383
+ text: this.typeCheckErrorMessage,
1384
+ badges: AbstractControlValidator.getBadges(
1385
+ node,
1386
+ ` - ${setting.label} (Body: ${
1387
+ PayloadBodyTypeLabels[value.body.type]
1388
+ })`
1389
+ ),
1390
+ key: createGuid(),
1391
+ actionId: node.id,
1392
+ });
1393
+ }
1394
+ }
1395
+
1396
+ return errors;
1397
+ }
1398
+
1399
+ doValueCheck(): WarningI[] {
1400
+ return [];
1401
+ //todo
1402
+ }
1403
+ }
1404
+ ```
1405
+
1406
+ ### 4.6 TabsPayloadOldControlValidator (Call API, legacy)
1407
+
1408
+ `src/modules/ProcessDesigner/Validation/ControlValidators/CallApiAction/TabsPayloadOldControlValidator.ts`
1409
+
1410
+ ```ts
1411
+ import {
1412
+ Node,
1413
+ RequestPayloadOldSetting,
1414
+ } from "@/modules/ProcessDesigner/components/PropertiesPanel/PropertiesPanel.model";
1415
+ import { createGuid } from "@/utils/type/guid";
1416
+ import { WarningI } from "../../Validation";
1417
+ import { AbstractControlValidator } from "../AbstractControlValidator";
1418
+
1419
+ export class TabsPayloadOldControlValidator extends AbstractControlValidator {
1420
+ doRequiredCheck(node: Node, setting: RequestPayloadOldSetting): WarningI[] {
1421
+ const value = setting.value;
1422
+ const queryParams = value.queryParams;
1423
+ const headers = value.headers;
1424
+ const errors: WarningI[] = [];
1425
+
1426
+ queryParams.forEach((param) => {
1427
+ if (
1428
+ param.value && param.value.length > 0 &&
1429
+ (!param.key || param.key.trim().length === 0)
1430
+ ) {
1431
+ errors.push({
1432
+ text: this.requiredCheckErrorMessage,
1433
+ badges: AbstractControlValidator.getBadges(
1434
+ node,
1435
+ ` - ${setting.label} (Query Params)`
1436
+ ),
1437
+ key: createGuid(),
1438
+ actionId: node.id,
1439
+ });
1440
+ }
1441
+ });
1442
+
1443
+ headers.forEach((header) => {
1444
+ if (
1445
+ header.value && header.value.length > 0 &&
1446
+ (!header.key || header.key.trim().length === 0)
1447
+ ) {
1448
+ errors.push({
1449
+ text: this.requiredCheckErrorMessage,
1450
+ badges: AbstractControlValidator.getBadges(
1451
+ node,
1452
+ ` - ${setting.label} (Headers)`
1453
+ ),
1454
+ key: createGuid(),
1455
+ actionId: node.id,
1456
+ });
1457
+ }
1458
+ });
1459
+
1460
+ return errors;
1461
+ }
1462
+
1463
+ doDataTypeCheck(): WarningI[] {
1464
+ return [];
1465
+ }
1466
+
1467
+ doValueCheck(): WarningI[] {
1468
+ return [];
1469
+ //todo
1470
+ }
1471
+ }
1472
+ ```
1473
+
1474
+ ### 4.7 ProcessInputOutputValidator (Call Subprocess)
1475
+
1476
+ `src/modules/ProcessDesigner/Validation/ControlValidators/CallSubprocess/ProcessInputOutputValidator.ts`
1477
+ (`doDataTypeCheck` body is a large commented-out block, omitted here — currently returns `[]`.)
1478
+
1479
+ ```ts
1480
+ import {
1481
+ Node,
1482
+ ProcessInputOuputSetting,
1483
+ } from "@/modules/ProcessDesigner/components/PropertiesPanel/PropertiesPanel.model";
1484
+ import { createGuid } from "@/utils/type/guid";
1485
+ import { WarningI } from "@/modules/ProcessDesigner/Validation/Validation";
1486
+ import { AbstractControlValidator } from "../AbstractControlValidator";
1487
+
1488
+ export class ProcessInputOutputValidator extends AbstractControlValidator {
1489
+ doRequiredCheck(node: Node, setting: ProcessInputOuputSetting): WarningI[] {
1490
+ const errors: WarningI[] = [];
1491
+
1492
+ const value = setting.value;
1493
+
1494
+ if (!value) {
1495
+ errors.push({
1496
+ text: this.requiredCheckErrorMessage,
1497
+ badges: AbstractControlValidator.getBadges(node, ` - ${setting.label}`),
1498
+ key: createGuid(),
1499
+ actionId: node.id,
1500
+ });
1501
+ }
1502
+
1503
+ if (Array.isArray(value)) {
1504
+ if (value.length === 0) {
1505
+ return [];
1506
+ }
1507
+
1508
+ value.forEach((row, rowIndex) => {
1509
+ if (!row.subprocess || row.subprocess.trim().length === 0) {
1510
+ errors.push({
1511
+ text: this.requiredCheckErrorMessage,
1512
+ badges: AbstractControlValidator.getBadges(
1513
+ node,
1514
+ ` - ${setting.label} (row ${rowIndex + 1})`
1515
+ ),
1516
+ key: createGuid(),
1517
+ actionId: node.id,
1518
+ });
1519
+ }
1520
+ });
1521
+ }
1522
+
1523
+ return errors;
1524
+ }
1525
+
1526
+ doDataTypeCheck(): WarningI[] {
1527
+ return [];
1528
+ // ... (data-type check currently commented out)
1529
+ }
1530
+
1531
+ doValueCheck(): WarningI[] {
1532
+ return [];
1533
+ //todo
1534
+ }
1535
+ }
1536
+ ```
1537
+
1538
+ ### 4.8 ConditionalValidator (Decisional cases)
1539
+
1540
+ `src/modules/ProcessDesigner/Validation/ControlValidators/DecisionalAction/ConditionsValidator.ts`
1541
+
1542
+ ```ts
1543
+ import {
1544
+ Node,
1545
+ ProcessInputOuputSetting,
1546
+ } from "@/modules/ProcessDesigner/components/PropertiesPanel/PropertiesPanel.model";
1547
+ import { createGuid } from "@/utils/type/guid";
1548
+ import { WarningI } from "@/modules/ProcessDesigner/Validation/Validation";
1549
+ import { AbstractControlValidator } from "../AbstractControlValidator";
1550
+
1551
+ import DecisionalCardValidation from "@/modules/ProcessDesigner/components/Controls/DecisionalManager/card/DecisionalCard.validation";
1552
+
1553
+ import { ProcessVariable } from "@/services/processvariables/ProcessVariables.model";
1554
+ import { Primitives } from "@/utils/dataTypeMapper";
1555
+ import { Condition } from "@/modules/ProcessDesigner/components/Controls/DecisionalManager/Decisional.model";
1556
+ import { isBoolean } from "@/utils/type/boolean";
1557
+ import { isNullOrUndefined } from "@/utils/type/nullUndefined";
1558
+ import { DataModel } from "@/services/datamodel/DataModel.model";
1559
+ import { OperatorName } from "@/services/actionlist/ActionList.service";
1560
+
1561
+ const message =
1562
+ "Action definition incomplete. Please make sure all cases are configured.";
1563
+
1564
+ export class ConditionalValidator extends AbstractControlValidator {
1565
+ typeCheckErrorMessage = "Please make sure condition's types match.";
1566
+
1567
+ doRequiredCheck(node: Node, setting: ProcessInputOuputSetting): WarningI[] {
1568
+ const errors: WarningI[] = [];
1569
+
1570
+ let hasErrors = false;
1571
+
1572
+ const value = setting.value;
1573
+
1574
+ if (!value || value.length === 0) {
1575
+ return [];
1576
+ }
1577
+
1578
+ Array.isArray(value) &&
1579
+ value.forEach((_setting: any) => {
1580
+ hasErrors = DecisionalCardValidation(_setting);
1581
+ });
1582
+
1583
+ if (hasErrors) {
1584
+ errors.push({
1585
+ text: message,
1586
+ badges: AbstractControlValidator.getBadges(node, ` - ${setting.label}`),
1587
+ key: createGuid(),
1588
+ actionId: node.id,
1589
+ });
1590
+ }
1591
+
1592
+ return errors;
1593
+ }
1594
+
1595
+ doDataTypeCheck(
1596
+ node: Node,
1597
+ setting: ProcessInputOuputSetting,
1598
+ dataType: DataModel[],
1599
+ processVariables: ProcessVariable[]
1600
+ ): WarningI[] {
1601
+ const errors: WarningI[] = [];
1602
+
1603
+ const value = setting.value;
1604
+
1605
+ if (!value || value.length === 0) {
1606
+ return [];
1607
+ }
1608
+
1609
+ const hasErrors = this.checkConditionsType(
1610
+ value[0].condition,
1611
+ dataType,
1612
+ processVariables
1613
+ );
1614
+
1615
+ if (hasErrors.hasConditionErrors) {
1616
+ errors.push({
1617
+ text: this.typeCheckErrorMessage,
1618
+ badges: AbstractControlValidator.getBadges(node, ` - ${setting.label}`),
1619
+ key: createGuid(),
1620
+ actionId: node.id,
1621
+ });
1622
+ }
1623
+
1624
+ if (hasErrors.hasOperatorErrors) {
1625
+ errors.push({
1626
+ text: "Please make sure condition's operators are set.",
1627
+ badges: AbstractControlValidator.getBadges(node, ` - ${setting.label}`),
1628
+ key: createGuid(),
1629
+ actionId: node.id,
1630
+ });
1631
+ }
1632
+
1633
+ return errors;
1634
+ }
1635
+
1636
+ getCurrentType(
1637
+ dataTypes: DataModel[],
1638
+ conditionId: string,
1639
+ pV: ProcessVariable[]
1640
+ ) {
1641
+ const attribute = (conditionId || "").split(".");
1642
+
1643
+ const firstId = attribute[0];
1644
+
1645
+ const f = pV.find((p) => {
1646
+ return firstId.includes(p.id);
1647
+ });
1648
+
1649
+ const dataType = f?.dataType;
1650
+
1651
+ const dataTypeOperator = this.findDataType(
1652
+ dataType as string,
1653
+ dataTypes,
1654
+ conditionId
1655
+ );
1656
+
1657
+ return dataTypeOperator ? dataTypeOperator : f ? f.dataType : null;
1658
+ }
1659
+
1660
+ isVariableList(varTree: string, pV: any, dataTypes: DataModel[]) {
1661
+ const varTreeAsArray = varTree.split(".");
1662
+
1663
+ const variableId = varTreeAsArray[0];
1664
+
1665
+ const variable = pV.find((val: any) => val.id === variableId);
1666
+
1667
+ if (variable) {
1668
+ if (varTreeAsArray.length === 1) {
1669
+ return variable.isList;
1670
+ }
1671
+
1672
+ let variableDataType: DataModel | undefined = dataTypes.find(
1673
+ (type: DataModel) => type.id === variable.dataType
1674
+ );
1675
+
1676
+ let attribute: any;
1677
+
1678
+ varTreeAsArray.slice(1).forEach((attrId) => {
1679
+ attribute = (variableDataType?.attributes || []).find(
1680
+ (attr) => attr.id === attrId
1681
+ );
1682
+
1683
+ variableDataType = dataTypes.find(
1684
+ (type: DataModel) => type.id === attribute?.dataTypeId
1685
+ );
1686
+ });
1687
+
1688
+ if (attribute) {
1689
+ return attribute.isList;
1690
+ }
1691
+
1692
+ return false;
1693
+ }
1694
+
1695
+ return false;
1696
+ }
1697
+
1698
+ findDataType(
1699
+ dataType: string,
1700
+ dataTypes: DataModel[],
1701
+ conditionId: string
1702
+ ): null | string {
1703
+ const attribute = (conditionId || "").split(".");
1704
+ const lastId = attribute[attribute.length - 1];
1705
+ for (let j = 0; j < dataTypes.length; j++) {
1706
+ const dt = dataTypes[j];
1707
+ if (dt.id === dataType) {
1708
+ for (let i = 0; i < (dt.attributes || []).length; i++) {
1709
+ const propList = dt.attributes[i];
1710
+
1711
+ if (lastId.includes(propList.id)) {
1712
+ return propList.dataTypeId;
1713
+ } else {
1714
+ const findDataType = this.findDataType(
1715
+ propList.dataTypeId,
1716
+ dataTypes,
1717
+ conditionId
1718
+ );
1719
+
1720
+ if (findDataType) {
1721
+ return findDataType;
1722
+ }
1723
+ }
1724
+ }
1725
+ }
1726
+ }
1727
+
1728
+ return null;
1729
+ }
1730
+
1731
+ checkConditionsType(
1732
+ conditions: Condition[],
1733
+ dataType: DataModel[],
1734
+ processVariables: ProcessVariable[]
1735
+ ): {
1736
+ hasConditionErrors: boolean;
1737
+ hasOperatorErrors: boolean;
1738
+ } {
1739
+ let hasConditionErrors = false;
1740
+ let hasOperatorErrors = false;
1741
+
1742
+ conditions.forEach((_condition: any) => {
1743
+ let leftType, rightType;
1744
+
1745
+ if (_condition.leftOperator || _condition.rightOperator) {
1746
+ if (!_condition.operator) {
1747
+ hasOperatorErrors = true;
1748
+ }
1749
+ //attribute vs atribute check
1750
+ const leftAttributeType = this.getCurrentType(
1751
+ dataType,
1752
+ _condition.leftOperator.value,
1753
+ processVariables
1754
+ );
1755
+
1756
+ const rightAttributeType = this.getCurrentType(
1757
+ dataType,
1758
+ _condition.rightOperator.value,
1759
+ processVariables
1760
+ );
1761
+
1762
+ if (leftAttributeType !== null && rightAttributeType !== null) {
1763
+ if (leftAttributeType !== rightAttributeType) {
1764
+ hasConditionErrors = true;
1765
+ }
1766
+ }
1767
+
1768
+ if (_condition.operator === OperatorName.BELONGS) {
1769
+ hasConditionErrors = !this.isVariableList(
1770
+ _condition.rightOperator.value,
1771
+ processVariables,
1772
+ dataType
1773
+ );
1774
+ }
1775
+
1776
+ //constant vs constant
1777
+ if (!leftAttributeType && !rightAttributeType) {
1778
+ const isRightValueBoolean = isBoolean(_condition.rightOperator.value);
1779
+ if (
1780
+ (isNaN(Number(_condition.rightOperator.value)) ||
1781
+ isRightValueBoolean) &&
1782
+ rightAttributeType == null
1783
+ ) {
1784
+ rightType = Primitives.STRING;
1785
+
1786
+ if (isRightValueBoolean) {
1787
+ rightType = Primitives.BOOLEAN;
1788
+
1789
+ if (
1790
+ (_condition.rightOperator.value == 0 ||
1791
+ _condition.rightOperator.value == 1) &&
1792
+ !isNaN(_condition.leftOperator.value)
1793
+ ) {
1794
+ rightType = Primitives.NUMBER;
1795
+ }
1796
+ } else if (isNullOrUndefined(_condition.rightOperator.value)) {
1797
+ rightType = null;
1798
+ }
1799
+ } else {
1800
+ rightType = Primitives.NUMBER;
1801
+ }
1802
+
1803
+ const isLeftValueBoolean = isBoolean(_condition.leftOperator.value);
1804
+
1805
+ if (
1806
+ (isNaN(Number(_condition.leftOperator.value)) ||
1807
+ isLeftValueBoolean) &&
1808
+ leftAttributeType == null
1809
+ ) {
1810
+ leftType = Primitives.STRING;
1811
+
1812
+ if (isLeftValueBoolean) {
1813
+ leftType = Primitives.BOOLEAN;
1814
+
1815
+ if (
1816
+ (_condition.leftOperator.value == 0 ||
1817
+ _condition.leftOperator.value == 1) &&
1818
+ rightType == Primitives.NUMBER
1819
+ ) {
1820
+ leftType = Primitives.NUMBER;
1821
+ }
1822
+ } else if (isNullOrUndefined(_condition.leftOperator.value)) {
1823
+ leftType = null;
1824
+ }
1825
+ } else {
1826
+ leftType = Primitives.NUMBER;
1827
+ }
1828
+
1829
+ if (leftType && rightType && leftType !== rightType) {
1830
+ hasConditionErrors = true;
1831
+ }
1832
+ }
1833
+
1834
+ // const vs attribute
1835
+ const checkOppostireAttributeType = (
1836
+ attributeType: string,
1837
+ oppositeAttributeValue: any,
1838
+ operator: OperatorName
1839
+ ) => {
1840
+ if (isNullOrUndefined(oppositeAttributeValue)) {
1841
+ return;
1842
+ }
1843
+
1844
+ switch (attributeType) {
1845
+ case Primitives.BOOLEAN: {
1846
+ if (
1847
+ [OperatorName.IS_TRUE, OperatorName.IS_FALSE].includes(operator)
1848
+ ) {
1849
+ // todo: refactor - add operators to enum
1850
+ break;
1851
+ }
1852
+ const oppositeValue =
1853
+ typeof oppositeAttributeValue === "string"
1854
+ ? oppositeAttributeValue.trim()
1855
+ : oppositeAttributeValue;
1856
+ if (!isBoolean(oppositeValue)) {
1857
+ hasConditionErrors = true;
1858
+ }
1859
+ break;
1860
+ }
1861
+ case Primitives.FLOAT:
1862
+ case Primitives.DOUBLE:
1863
+ if (isNaN(Number(oppositeAttributeValue))) {
1864
+ hasConditionErrors = true;
1865
+ }
1866
+ break;
1867
+
1868
+ case Primitives.INTEGER:
1869
+ if (!Number.isInteger(Number(oppositeAttributeValue))) {
1870
+ hasConditionErrors = true;
1871
+ }
1872
+ break;
1873
+
1874
+ case Primitives.STRING:
1875
+ break;
1876
+ }
1877
+ };
1878
+
1879
+ if (rightAttributeType && !leftAttributeType) {
1880
+ checkOppostireAttributeType(
1881
+ rightAttributeType,
1882
+ _condition.leftOperator.value,
1883
+ _condition.operator
1884
+ );
1885
+ }
1886
+
1887
+ if (leftAttributeType && !rightAttributeType) {
1888
+ checkOppostireAttributeType(
1889
+ leftAttributeType,
1890
+ _condition.rightOperator.value,
1891
+ _condition.operator
1892
+ );
1893
+ }
1894
+ } else {
1895
+ const result =
1896
+ _condition.value &&
1897
+ this.checkConditionsType(
1898
+ _condition.value,
1899
+ dataType,
1900
+ processVariables
1901
+ );
1902
+
1903
+ hasConditionErrors = result.hasConditionErrors;
1904
+ hasOperatorErrors = result.hasOperatorErrors;
1905
+ }
1906
+ });
1907
+
1908
+ return { hasConditionErrors, hasOperatorErrors };
1909
+ }
1910
+
1911
+ doValueCheck(): WarningI[] {
1912
+ return [];
1913
+ //todo
1914
+ }
1915
+ }
1916
+ ```
1917
+
1918
+ ### 4.9 DataStoreDecisionalValidator (extends ConditionalValidator)
1919
+
1920
+ `src/modules/ProcessDesigner/Validation/ControlValidators/DataStoreDecisional/DataStoreDecisionalValidator.ts`
1921
+
1922
+ ```ts
1923
+ import {
1924
+ Node,
1925
+ ProcessInputOuputSetting,
1926
+ } from "@/modules/ProcessDesigner/components/PropertiesPanel/PropertiesPanel.model";
1927
+ import { createGuid } from "@/utils/type/guid";
1928
+ import { WarningI } from "@/modules/ProcessDesigner/Validation/Validation";
1929
+ import { AbstractControlValidator } from "../AbstractControlValidator";
1930
+ import { ConditionalValidator } from "../DecisionalAction/ConditionsValidator";
1931
+ import { FormBuilder, Validators } from "@/utils/ReactiveForm";
1932
+ import {
1933
+ DataStoreDecisionalCondition,
1934
+ DataStoreDecisionalOperatorDefinition,
1935
+ DataStoreDecisionalOperatorType,
1936
+ DataStoreDecisionalRowCondition,
1937
+ isDataStoreDecisionalGroup,
1938
+ } from "@/modules/ProcessDesigner/components/Controls/DataStoreDecisional/DataStoreDecisional.model";
1939
+ import { getDataStoreDecisionalOperatorByName } from "@/modules/ProcessDesigner/components/Controls/DataStoreDecisional/dataStoreDecisionalOperators";
1940
+
1941
+ const message =
1942
+ "Action definition incomplete. Please make sure the Where conditions are configured.";
1943
+
1944
+ export class DataStoreDecisionalValidator extends ConditionalValidator {
1945
+ doRequiredCheck(node: Node, setting: ProcessInputOuputSetting): WarningI[] {
1946
+ const errors: WarningI[] = [];
1947
+
1948
+ const value = setting.value as Array<{
1949
+ condition?: DataStoreDecisionalCondition[];
1950
+ }>;
1951
+
1952
+ if (!Array.isArray(value) || value.length === 0) {
1953
+ return errors;
1954
+ }
1955
+
1956
+ const conditions: DataStoreDecisionalCondition[] =
1957
+ value[0]?.condition || [];
1958
+
1959
+ if (conditions.length === 0) {
1960
+ return errors;
1961
+ }
1962
+
1963
+ const form = new FormBuilder();
1964
+ this.buildConditionForm(conditions, form);
1965
+ form.validate();
1966
+
1967
+ if (form.hasErrors) {
1968
+ errors.push({
1969
+ text: message,
1970
+ badges: AbstractControlValidator.getBadges(
1971
+ node,
1972
+ ` - ${setting.label}`
1973
+ ),
1974
+ key: createGuid(),
1975
+ actionId: node.id,
1976
+ });
1977
+ }
1978
+
1979
+ return errors;
1980
+ }
1981
+
1982
+ private buildConditionForm(
1983
+ conditions: DataStoreDecisionalCondition[],
1984
+ form: FormBuilder,
1985
+ level = 0,
1986
+ parentIndexes: number[] = []
1987
+ ) {
1988
+ const parentLevels =
1989
+ parentIndexes.join("_") + (parentIndexes.length ? "_" : "") + level;
1990
+
1991
+ conditions.forEach((condition: DataStoreDecisionalCondition, i: number) => {
1992
+ if (isDataStoreDecisionalGroup(condition)) {
1993
+ form.control(
1994
+ "group_" + parentLevels + "_" + condition.id,
1995
+ condition.value,
1996
+ [Validators.required]
1997
+ );
1998
+ this.buildConditionForm(condition.value, form, level + 1, [
1999
+ ...parentIndexes,
2000
+ i,
2001
+ ]);
2002
+ return;
2003
+ }
2004
+
2005
+ const row: DataStoreDecisionalRowCondition = condition;
2006
+
2007
+ form.control("operator_" + parentLevels + "_" + row.id, row.operator, [
2008
+ Validators.required,
2009
+ ]);
2010
+
2011
+ form.control(
2012
+ "left_operator_" + parentLevels + "_" + row.id,
2013
+ row.leftOperator.value,
2014
+ [Validators.required]
2015
+ );
2016
+
2017
+ const operator: DataStoreDecisionalOperatorDefinition | null =
2018
+ getDataStoreDecisionalOperatorByName(row.operator);
2019
+ if (operator?.operatorType !== DataStoreDecisionalOperatorType.UNARY) {
2020
+ form.control(
2021
+ "right_operator_" + parentLevels + "_" + row.id,
2022
+ row.rightOperator?.value,
2023
+ [Validators.required]
2024
+ );
2025
+ }
2026
+ });
2027
+ }
2028
+ }
2029
+ ```
2030
+
2031
+ ### 4.10 DelayDefinitionValidator
2032
+
2033
+ `src/modules/ProcessDesigner/Validation/ControlValidators/DelayAction/DelayDefinitionValidator.ts`
2034
+
2035
+ ```ts
2036
+ import {
2037
+ DelayDefinitionSetting,
2038
+ Node,
2039
+ } from "@/modules/ProcessDesigner/components/PropertiesPanel/PropertiesPanel.model";
2040
+ import { createGuid } from "@/utils/type/guid";
2041
+ import { DelayType } from "../../../components/Controls/Delay/Delay.model";
2042
+ import { DELAY_TYPE_SETTING } from "../../../components/PropertiesPanel/Utils/Settings";
2043
+ import { WarningI } from "../../Validation";
2044
+ import { AbstractControlValidator } from "../AbstractControlValidator";
2045
+
2046
+ export class DelayDefinitionValidator extends AbstractControlValidator {
2047
+ invalidDelayValueErrorMessage = "Invalid delay value.";
2048
+
2049
+ doRequiredCheck(node: Node, setting: DelayDefinitionSetting): WarningI[] {
2050
+ const value = setting.value;
2051
+ const errors: WarningI[] = [];
2052
+
2053
+ const settings = this.getAllSettings(node);
2054
+
2055
+ const delayTypeSetting = settings.find((s) => s.id === DELAY_TYPE_SETTING);
2056
+ if (delayTypeSetting && delayTypeSetting.value) {
2057
+ const delayType = delayTypeSetting.value as DelayType;
2058
+
2059
+ if (
2060
+ !value ||
2061
+ !value.value ||
2062
+ (delayType === DelayType.WAIT_FOR && !value.interval)
2063
+ ) {
2064
+ errors.push({
2065
+ text: this.requiredCheckErrorMessage,
2066
+ badges: AbstractControlValidator.getBadges(node, ` - ${setting.label}`),
2067
+ key: createGuid(),
2068
+ actionId: node.id
2069
+ });
2070
+ }
2071
+
2072
+ if (value && value.value) {
2073
+ const delayValue = value.value;
2074
+ if (
2075
+ (delayType === DelayType.WAIT_FOR && delayValue < 0) ||
2076
+ (delayType === DelayType.WAIT_UNTIL &&
2077
+ !this.isValidDelayDate(new Date(delayValue)))
2078
+ ) {
2079
+ errors.push({
2080
+ text: this.invalidDelayValueErrorMessage,
2081
+ badges: AbstractControlValidator.getBadges(node, ` - ${setting.label}`),
2082
+ key: createGuid(),
2083
+ actionId: node.id
2084
+ });
2085
+ }
2086
+ }
2087
+ }
2088
+
2089
+ return errors;
2090
+ }
2091
+
2092
+ doDataTypeCheck(): WarningI[] {
2093
+ return [];
2094
+ }
2095
+
2096
+ isValidDelayDate(date: unknown) {
2097
+ if (!date || !(date instanceof Date)) {
2098
+ return false;
2099
+ }
2100
+
2101
+ const now = new Date();
2102
+
2103
+ date.setSeconds(0);
2104
+ now.setSeconds(0);
2105
+
2106
+ if (date.toString() === now.toString()) {
2107
+ return true;
2108
+ }
2109
+
2110
+ return date >= now;
2111
+ }
2112
+
2113
+ doValueCheck(): WarningI[] {
2114
+ return [];
2115
+ //todo
2116
+ }
2117
+ }
2118
+ ```
2119
+
2120
+ ### 4.11 DocumentMapperValidator (Document Mapper / Data Store Mapper)
2121
+
2122
+ `src/modules/ProcessDesigner/Validation/ControlValidators/DocumentMapper/DocumentMapperValidator.ts`
2123
+ (`doDataTypeCheck` is currently a commented-out block returning `[]`.)
2124
+
2125
+ ```ts
2126
+ import {
2127
+ Node,
2128
+ DocumentMapperSetting,
2129
+ } from "@/modules/ProcessDesigner/components/PropertiesPanel/PropertiesPanel.model";
2130
+ import { createGuid } from "@/utils/type/guid";
2131
+ import { WarningI } from "@/modules/ProcessDesigner/Validation/Validation";
2132
+ import { AbstractControlValidator } from "../AbstractControlValidator";
2133
+ import { store } from "@/store";
2134
+ import { DocumentMapperValue } from "@/modules/ProcessDesigner/components/Controls/DocumentMapper/DocumentMapper.model";
2135
+ import { Variable } from "@/services/crud/Orchestration.service";
2136
+ import { hasVariable } from "@/modules/ProcessDesigner/Variables/Utils";
2137
+
2138
+ export class DocumentMapperValidator extends AbstractControlValidator {
2139
+ requiredVariableCheckErrorMessage =
2140
+ "Please make sure that all document varibles are mapped.";
2141
+
2142
+ doRequiredCheck(node: Node, setting: DocumentMapperSetting): WarningI[] {
2143
+ const errors: WarningI[] = [];
2144
+
2145
+ const value = setting.value;
2146
+ if (!value || (Array.isArray(value) && value.length === 0)) {
2147
+ return errors;
2148
+ }
2149
+
2150
+ value
2151
+ .filter(
2152
+ (row) => !row.document || (row.document && hasVariable(row.document))
2153
+ )
2154
+ .forEach((row, rowIndex) => {
2155
+ if (!row.document || row.document.trim().length === 0) {
2156
+ errors.push({
2157
+ text: this.requiredCheckErrorMessage,
2158
+ badges: AbstractControlValidator.getBadges(
2159
+ node,
2160
+ ` - ${setting.label} (row ${rowIndex + 1})`
2161
+ ),
2162
+ key: createGuid(),
2163
+ actionId: node.id,
2164
+ });
2165
+ }
2166
+ });
2167
+
2168
+ return errors;
2169
+ }
2170
+
2171
+ doDataTypeCheck(): WarningI[] {
2172
+ return [];
2173
+ // ... (data-type check currently commented out)
2174
+ }
2175
+
2176
+ checkRequiredVariablesMapping(
2177
+ node: Node,
2178
+ setting: DocumentMapperSetting
2179
+ ): WarningI[] {
2180
+ const variables = store.getters.getExtraVariablesByNodeId(node.id);
2181
+ const value: DocumentMapperValue[] = setting.value;
2182
+
2183
+ const errors: WarningI[] = [];
2184
+
2185
+ variables.forEach((v: Variable) => {
2186
+ // if document variable is not mapped
2187
+ if (
2188
+ !Array.isArray(value) ||
2189
+ value.findIndex((mv) => mv.document === v.id) === -1
2190
+ ) {
2191
+ errors.push({
2192
+ text: this.requiredVariableCheckErrorMessage,
2193
+ badges: AbstractControlValidator.getBadges(
2194
+ node,
2195
+ ` - ${setting.label} (${v.name})`
2196
+ ),
2197
+ key: createGuid(),
2198
+ actionId: node.id,
2199
+ });
2200
+ }
2201
+ });
2202
+
2203
+ return errors;
2204
+ }
2205
+
2206
+ doValueCheck(): WarningI[] {
2207
+ return [];
2208
+ //todo
2209
+ }
2210
+ }
2211
+ ```
2212
+
2213
+ ### 4.12 ColumnDefinitionControlValidator (Get File Data)
2214
+
2215
+ `src/modules/ProcessDesigner/Validation/ControlValidators/GetFileData/ColumnDefinitionControlValidator.ts`
2216
+
2217
+ ```ts
2218
+ import {
2219
+ ColumnDefinitionSetting,
2220
+ Node,
2221
+ } from "@/modules/ProcessDesigner/components/PropertiesPanel/PropertiesPanel.model";
2222
+ import { createGuid } from "@/utils/type/guid";
2223
+ import { Primitives } from "@/utils/dataTypeMapper";
2224
+ import { getValueDataTypes } from "../../../Values/ValueDataTypesHelper";
2225
+ import { SettingValidation } from "../../SettingValidation";
2226
+ import { WarningI } from "../../Validation";
2227
+ import { AbstractControlValidator } from "../AbstractControlValidator";
2228
+
2229
+ export class ColumnDefinitionControlValidator extends AbstractControlValidator {
2230
+ doRequiredCheck(node: Node, setting: ColumnDefinitionSetting): WarningI[] {
2231
+ const errors: WarningI[] = [];
2232
+
2233
+ const value = setting.value;
2234
+ const rows = value ? value.rows : null;
2235
+
2236
+ if (!rows || (Array.isArray(rows) && rows.length === 0)) {
2237
+ errors.push({
2238
+ text: this.requiredCheckErrorMessage,
2239
+ badges: AbstractControlValidator.getBadges(
2240
+ node,
2241
+ ` - column definition`
2242
+ ),
2243
+ key: createGuid(),
2244
+ actionId: node.id,
2245
+ });
2246
+ return errors;
2247
+ }
2248
+
2249
+ rows.forEach((row, rowIndex) => {
2250
+ if (
2251
+ !row.columnName ||
2252
+ row.columnName.trim().length === 0 ||
2253
+ !row.attribute ||
2254
+ row.attribute.trim().length === 0
2255
+ ) {
2256
+ errors.push({
2257
+ text: this.requiredCheckErrorMessage,
2258
+ badges: AbstractControlValidator.getBadges(
2259
+ node,
2260
+ ` - ${setting.label} (row ${rowIndex + 1})`
2261
+ ),
2262
+ key: createGuid(),
2263
+ actionId: node.id,
2264
+ });
2265
+ }
2266
+ });
2267
+
2268
+ return errors;
2269
+ }
2270
+
2271
+ doDataTypeCheck(node: Node, setting: ColumnDefinitionSetting): WarningI[] {
2272
+ const errors: WarningI[] = [];
2273
+
2274
+ setting.dataTypeId = Primitives.STRING;
2275
+
2276
+ const value = setting.value;
2277
+ const rows = value ? value.rows : null;
2278
+
2279
+ if (!rows || (Array.isArray(rows) && rows.length === 0)) {
2280
+ return [];
2281
+ }
2282
+
2283
+ rows.forEach((row, rowIndex) => {
2284
+ const attributeValue = row.attribute ? row.attribute.trim() : "";
2285
+ if (
2286
+ !SettingValidation.validateDataType(
2287
+ getValueDataTypes(attributeValue),
2288
+ setting
2289
+ )
2290
+ ) {
2291
+ errors.push({
2292
+ text: this.typeCheckErrorMessage,
2293
+ badges: AbstractControlValidator.getBadges(
2294
+ node,
2295
+ ` - ${setting.label} attribute (row ${rowIndex + 1})`
2296
+ ),
2297
+ key: createGuid(),
2298
+ actionId: node.id,
2299
+ });
2300
+ }
2301
+ });
2302
+
2303
+ return errors;
2304
+ }
2305
+
2306
+ doValueCheck(): WarningI[] {
2307
+ return [];
2308
+ //todo
2309
+ }
2310
+ }
2311
+ ```
2312
+
2313
+ ### 4.13 MapParametersValidator
2314
+
2315
+ `src/modules/ProcessDesigner/Validation/ControlValidators/MapParameters/MapParametersValidator.ts`
2316
+
2317
+ ```ts
2318
+ import {
2319
+ Node,
2320
+ MapParametersSetting,
2321
+ } from "@/modules/ProcessDesigner/components/PropertiesPanel/PropertiesPanel.model";
2322
+ import { createGuid } from "@/utils/type/guid";
2323
+ import { WarningI } from "@/modules/ProcessDesigner/Validation/Validation";
2324
+ import { AbstractControlValidator } from "../AbstractControlValidator";
2325
+
2326
+ export class MapParametersValidator extends AbstractControlValidator {
2327
+ doRequiredCheck(node: Node, setting: MapParametersSetting): WarningI[] {
2328
+ const errors: WarningI[] = [];
2329
+
2330
+ const value = setting.value;
2331
+
2332
+ if (Array.isArray(value) && value.length === 0) {
2333
+ return [];
2334
+ }
2335
+
2336
+ if (!value) {
2337
+ errors.push({
2338
+ text: this.requiredCheckErrorMessage,
2339
+ badges: AbstractControlValidator.getBadges(
2340
+ node,
2341
+ ` - ${setting.label} (row 1)`
2342
+ ),
2343
+ key: createGuid(),
2344
+ actionId: node.id,
2345
+ });
2346
+
2347
+ return errors;
2348
+ }
2349
+
2350
+ value.forEach((row, rowIndex) => {
2351
+ if (!row.destination || row.source.trim().length === 0) {
2352
+ errors.push({
2353
+ text: this.requiredCheckErrorMessage,
2354
+ badges: AbstractControlValidator.getBadges(
2355
+ node,
2356
+ ` - ${setting.label} (row ${rowIndex + 1})`
2357
+ ),
2358
+ key: createGuid(),
2359
+ actionId: node.id,
2360
+ });
2361
+ }
2362
+ });
2363
+
2364
+ return errors;
2365
+ }
2366
+
2367
+ doDataTypeCheck(node: Node, setting: MapParametersSetting): WarningI[] {
2368
+ return [];
2369
+ }
2370
+
2371
+ doValueCheck(): WarningI[] {
2372
+ return [];
2373
+ //todo
2374
+ }
2375
+ }
2376
+ ```
2377
+
2378
+ ### 4.14 MapProcessDataValidator
2379
+
2380
+ `src/modules/ProcessDesigner/Validation/ControlValidators/MapProcessData/MapProcessDataValidator.ts`
2381
+
2382
+ ```ts
2383
+ import {
2384
+ Node,
2385
+ MapProcessDataSetting,
2386
+ } from "@/modules/ProcessDesigner/components/PropertiesPanel/PropertiesPanel.model";
2387
+ import { createGuid } from "@/utils/type/guid";
2388
+ import { WarningI } from "@/modules/ProcessDesigner/Validation/Validation";
2389
+ import { AbstractControlValidator } from "../AbstractControlValidator";
2390
+ import {
2391
+ isCustomTypeAllowed,
2392
+ NonPrimitives,
2393
+ Primitives,
2394
+ } from "@/utils/dataTypeMapper";
2395
+ import { SettingValidation } from "../../SettingValidation";
2396
+ import { getValueDataTypes } from "@/modules/ProcessDesigner/Values/ValueDataTypesHelper";
2397
+ import {
2398
+ DataModel,
2399
+ isCustomDataModel,
2400
+ } from "@/services/datamodel/DataModel.model";
2401
+ import cloneDeep from "lodash/cloneDeep";
2402
+
2403
+ export class MapProcessDataValidator extends AbstractControlValidator {
2404
+ doRequiredCheck(node: Node, setting: MapProcessDataSetting): WarningI[] {
2405
+ const errors: WarningI[] = [];
2406
+
2407
+ const value = setting.value;
2408
+
2409
+ if (Array.isArray(value) && value.length === 0) {
2410
+ return [];
2411
+ }
2412
+
2413
+ if (!value) {
2414
+ errors.push({
2415
+ text: this.requiredCheckErrorMessage,
2416
+ badges: AbstractControlValidator.getBadges(
2417
+ node,
2418
+ ` - ${setting.label} (row 1)`
2419
+ ),
2420
+ key: createGuid(),
2421
+ actionId: node.id,
2422
+ });
2423
+
2424
+ return errors;
2425
+ }
2426
+
2427
+ value.forEach((row, rowIndex) => {
2428
+ if (!row.destination || row.source.trim().length === 0) {
2429
+ errors.push({
2430
+ text: this.requiredCheckErrorMessage,
2431
+ badges: AbstractControlValidator.getBadges(
2432
+ node,
2433
+ ` - ${setting.label} (row ${rowIndex + 1})`
2434
+ ),
2435
+ key: createGuid(),
2436
+ actionId: node.id,
2437
+ });
2438
+ }
2439
+ });
2440
+
2441
+ return errors;
2442
+ }
2443
+
2444
+ doDataTypeCheck(node: Node, setting: MapProcessDataSetting): WarningI[] {
2445
+ setting = cloneDeep(setting);
2446
+
2447
+ const value = setting.value;
2448
+
2449
+ if (!value || value.length === 0) {
2450
+ return [];
2451
+ }
2452
+
2453
+ const errors: WarningI[] = [];
2454
+ const addTypeCheckError = (rowIndex: number) => {
2455
+ errors.push({
2456
+ text: this.typeCheckErrorMessage,
2457
+ badges: AbstractControlValidator.getBadges(
2458
+ node,
2459
+ ` - ${setting.label} (row ${rowIndex + 1})`
2460
+ ),
2461
+ key: createGuid(),
2462
+ actionId: node.id,
2463
+ });
2464
+ };
2465
+
2466
+ const originalSettingDataTypeId = setting.dataTypeId;
2467
+ const originalSettingIsListState = setting.isList;
2468
+
2469
+ value.forEach((row, rowIndex) => {
2470
+ const destinationValue = row.destination;
2471
+ const descriptionValueTypesGrouped = getValueDataTypes(destinationValue);
2472
+
2473
+ // check if source and destination variables have same type
2474
+ const checkDataTypes = (types: DataModel[], isList = false) => {
2475
+ if (types.length > 0) {
2476
+ const destinationValueType = types[0];
2477
+ // if destination is a string, make it accept ANY data type
2478
+ let dataTypeId = destinationValueType.id;
2479
+
2480
+ const sourceValueTypesGrouped = getValueDataTypes(row.source);
2481
+
2482
+ // allow map any value to string
2483
+ // allow map json to custom data model
2484
+ if (
2485
+ destinationValueType.id === Primitives.STRING ||
2486
+ (isCustomDataModel(destinationValueType) &&
2487
+ (isCustomTypeAllowed(sourceValueTypesGrouped.scalar[0]?.id) ||
2488
+ isCustomTypeAllowed(sourceValueTypesGrouped.list[0]?.id)))
2489
+ ) {
2490
+ dataTypeId = NonPrimitives.OBJECT;
2491
+ }
2492
+
2493
+ setting.dataTypeId = dataTypeId;
2494
+ setting.isList = isList;
2495
+
2496
+ // allow mapping File to File and File[] to File[]; PRC-3272
2497
+ const isMappingFileToFile =
2498
+ dataTypeId === NonPrimitives.FILE &&
2499
+ ((!isList &&
2500
+ sourceValueTypesGrouped.scalar.length === 1 &&
2501
+ sourceValueTypesGrouped.scalar[0].id === NonPrimitives.FILE) ||
2502
+ (isList &&
2503
+ sourceValueTypesGrouped.list.length === 1 &&
2504
+ sourceValueTypesGrouped.list[0].id === NonPrimitives.FILE));
2505
+
2506
+ if (
2507
+ !isMappingFileToFile &&
2508
+ !SettingValidation.validateDataType(
2509
+ sourceValueTypesGrouped,
2510
+ setting,
2511
+ // file is not allowed
2512
+ [NonPrimitives.FILE]
2513
+ )
2514
+ ) {
2515
+ addTypeCheckError(rowIndex);
2516
+ }
2517
+ }
2518
+ };
2519
+
2520
+ checkDataTypes(descriptionValueTypesGrouped.scalar);
2521
+ checkDataTypes(descriptionValueTypesGrouped.list, true);
2522
+
2523
+ // reset setting props to original state
2524
+ setting.dataTypeId = originalSettingDataTypeId;
2525
+ setting.isList = originalSettingIsListState;
2526
+ });
2527
+
2528
+ return errors;
2529
+ }
2530
+
2531
+ doValueCheck(): WarningI[] {
2532
+ return [];
2533
+ //todo
2534
+ }
2535
+ }
2536
+ ```
2537
+
2538
+ ---
2539
+
2540
+ ## 5. DecisionalCard.validation.ts (used by ConditionalValidator)
2541
+
2542
+ `src/modules/ProcessDesigner/components/Controls/DecisionalManager/card/DecisionalCard.validation.ts`
2543
+
2544
+ ```ts
2545
+ import {
2546
+ Operator,
2547
+ OperatorType,
2548
+ } from "@/services/actionlist/ActionList.service";
2549
+ import { store } from "@/store";
2550
+ import { FormBuilder, Validators } from "@/utils/ReactiveForm";
2551
+ import { Condition, RowCondition } from "../Decisional.model";
2552
+
2553
+ interface DecisionalCardValue {
2554
+ id: string;
2555
+ name: string;
2556
+ target: string;
2557
+ condition: Condition[];
2558
+ }
2559
+
2560
+ const buildForm = (
2561
+ conditions: Condition[],
2562
+ form: FormBuilder,
2563
+ level = 0,
2564
+ parentIndexes: number[] = []
2565
+ ) => {
2566
+ const parentLevels =
2567
+ parentIndexes.join("_") + (parentIndexes.length ? "_" : "") + level;
2568
+
2569
+ conditions.forEach((condition: Condition, i: number) => {
2570
+ if (!("value" in condition) || condition.value === null) {
2571
+ condition = condition as RowCondition;
2572
+
2573
+ form.control(
2574
+ "operator_" + parentLevels + "_" + condition.id,
2575
+ condition.operator,
2576
+ [Validators.required]
2577
+ );
2578
+
2579
+ form.control(
2580
+ "left_operator_" + parentLevels + "_" + condition.id,
2581
+ condition.leftOperator.value,
2582
+ [Validators.required]
2583
+ );
2584
+
2585
+ const operator: Operator | null = store.getters.getConditionOperandByName(
2586
+ condition.operator
2587
+ );
2588
+ if (operator?.operatorType !== OperatorType.UNARY) {
2589
+ form.control(
2590
+ "right_operator_" + parentLevels + "_" + condition.id,
2591
+ condition.rightOperator?.value,
2592
+ [Validators.required]
2593
+ );
2594
+ }
2595
+
2596
+ if (condition.auxOperator) {
2597
+ form.control(
2598
+ "aux_operator_" + parentLevels + "_" + condition.id,
2599
+ condition.auxOperator.value,
2600
+ []
2601
+ );
2602
+ }
2603
+ } else if (Array.isArray(condition.value)) {
2604
+ form.control(
2605
+ "group_" + parentLevels + "_" + condition.id,
2606
+ condition.value,
2607
+ [Validators.required]
2608
+ );
2609
+ return buildForm(condition.value, form, ++level, [...parentIndexes, i]);
2610
+ }
2611
+ });
2612
+ };
2613
+
2614
+ const DecisionalCardValidation = (value: DecisionalCardValue) => {
2615
+ const form = new FormBuilder();
2616
+
2617
+ form.control("name", value.name, [
2618
+ Validators.required,
2619
+ Validators.minLength(1),
2620
+ ]);
2621
+ form.control("target", value.target, [Validators.required]);
2622
+
2623
+ form.control("conditions", value.condition.length, [Validators.min(1)]);
2624
+
2625
+ buildForm(value.condition, form);
2626
+
2627
+ form.validate();
2628
+
2629
+ return form.hasErrors;
2630
+ };
2631
+
2632
+ export default DecisionalCardValidation;
2633
+ ```
2634
+
2635
+ ---
2636
+
2637
+ ## 6. Constant reference (values)
2638
+
2639
+ The validation code above references template IDs, setting IDs, data-type GUIDs,
2640
+ and enums by name. Their actual values are listed here.
2641
+
2642
+ ### 6.1 Action template IDs
2643
+
2644
+ `src/utils/actionHelper.ts`
2645
+
2646
+ ```ts
2647
+ export const START_ACTION_TEMPLATE_ID = "c0e32108-6e3e-4ab8-96bd-cd61be6edb33";
2648
+ export const STOP_ACTION_TEMPLATE_ID = "c0e32108-6e3e-4ab8-96bd-cd61be6edb34";
2649
+ export const JOIN_TEMPLATE_ID = "fb6a9d14-dd15-420d-a2b2-fc637c0c37c6";
2650
+ export const FOREACH_TEMPLATE_ID = "dbef0804-66a9-4f8f-872c-ece1b89b8fdb";
2651
+ export const CALL_SUBPROCESS_TEMPLATE_ID = "c37e56fe-d924-4604-a86f-7c93f863fcdf";
2652
+ export const TRIGGER_SUBPROCESS_TEMPLATE_ID = "615365f9-9ccb-dd46-85a6-af824b7be897";
2653
+ export const GENERATE_DOCUMENT_TEMPLATE_ID = "cdae0149-ab39-4d07-a72f-549c64cd10fe";
2654
+ export const DECISIONAL_TEMPLATE_ID = "f5dcbb04-253d-4061-99a1-9b2822c2e6d2";
2655
+ export const AI_DECISIONAL_TEMPLATE_ID = "772aac51-73f5-471d-bf9f-f5099cb30001";
2656
+ ```
2657
+
2658
+ > Note: `checkPointsValidation` in `Validation.ts` hard-codes the start/stop GUIDs
2659
+ > as string literals (`"c0e32108-...edb33"` / `"...edb34"`) instead of importing the
2660
+ > constants above — same values.
2661
+
2662
+ ### 6.2 Setting IDs
2663
+
2664
+ `src/modules/ProcessDesigner/components/PropertiesPanel/Utils/Settings.ts`
2665
+
2666
+ ```ts
2667
+ // Call Subprocess action
2668
+ export const SUBPROCESS_SELECT_SETTING = "bc93d0be-98f6-42d6-b2ac-a782eadd79bf";
2669
+ export const SUBPROCESS_SIDE_PANEL_SETTING = "5456caf0-be8e-4a04-86cb-dbae203af978";
2670
+ // Trigger Subprocess action
2671
+ export const TRIGGER_SUBPROCESS_SELECT_SETTING = "6824ee16-b6c4-a34e-bd21-f8136346af81";
2672
+ export const TRIGGER_SUBPROCESS_SIDE_PANEL_SETTING = "8540605e-2f4d-1746-9059-8bb7b944e0d3";
2673
+ // Delay action
2674
+ export const DELAY_TYPE_SETTING = "f1293589-6ede-4cc6-a04b-cc70e7084cb0";
2675
+ // Decisional
2676
+ export const DECISIONAL_CASE_SETTING = "11d4044a-8586-47f6-b3ce-1cae5da40f30";
2677
+ export const AI_DECISIONAL_CASE_SETTING = "772aac51-73f5-471d-bf9f-f5099cb30124";
2678
+ ```
2679
+
2680
+ ### 6.3 Data-type GUIDs — Primitives / NonPrimitives
2681
+
2682
+ `src/utils/dataTypeMapper.ts`
2683
+
2684
+ ```ts
2685
+ export enum Primitives {
2686
+ BOOLEAN = "0317bfee-b2f5-4bde-bfe8-121212121210",
2687
+ INTEGER = "0317bfee-b2f5-4bde-bfe8-121212121211",
2688
+ FLOAT = "0317bfee-b2f5-4bde-bfe8-121212121212",
2689
+ DOUBLE = "0317bfee-b2f5-4bde-bfe8-121212121213",
2690
+ STRING = "0317bfee-b2f5-4bde-bfe8-121212121214",
2691
+ DATE = "0317bfee-b2f5-4bde-bfe8-121212121215",
2692
+ RELATIONSHIP = "0317bfee-b2f5-4bde-bfe8-121212121216",
2693
+ TIME = "0317bfee-b2f5-4bde-bfe8-121212121217",
2694
+ DATETIME = "0317bfee-b2f5-4bde-bfe8-121212121218",
2695
+ NUMBER = "NUMBER",
2696
+ GUID = "0317bfee-b2f5-4bde-bfe8-121212121222",
2697
+ }
2698
+
2699
+ export enum NonPrimitives {
2700
+ FILE = "10c6ac59-3929-49e6-99dc-121212121219",
2701
+ JSON = "0317bfee-b2f5-4bde-bfe8-121212121220",
2702
+ OBJECT = "0317bfee-b2f5-4bde-bfe8-121212121221",
2703
+ SYSTEM_VARIABLE = "10c6ac59-3929-49e6-99dc-121212121221",
2704
+ ERROR = "10c6ac59-3929-49e6-99dc-121212121220",
2705
+ FUNCTION = "1c2fd144-836e-419a-aa25-9e624a4c7e40",
2706
+ }
2707
+
2708
+ // helpers used by SettingValidation.validateDataType
2709
+ export const isPrimitive = (dataTypeId: string) =>
2710
+ (Object.values(Primitives) as string[]).includes(dataTypeId);
2711
+
2712
+ // only JSON and OBJECT accept an arbitrary custom data model
2713
+ export const isCustomTypeAllowed = (dataTypeId: string) =>
2714
+ ([NonPrimitives.JSON, NonPrimitives.OBJECT] as string[]).includes(dataTypeId);
2715
+ ```
2716
+
2717
+ ### 6.4 SettingType values (drives ControlValidatorFactory)
2718
+
2719
+ `src/modules/ProcessDesigner/components/PropertiesPanel/PropertiesPanel.model.ts`
2720
+
2721
+ ```ts
2722
+ export enum SettingType {
2723
+ TABS_PAYLOAD_OLD = "tabs-payload", // todo: delete after tabs payload v2
2724
+ TABS_PAYLOAD = "tabs-payload-v2",
2725
+ DECISIONAL_CASE = "decisional-case",
2726
+ AI_DECISIONAL_CASE = "ai-decisional-case",
2727
+ PROCESS_INPUT = "process-inputs",
2728
+ PROCESS_OUTPUT = "process-outputs",
2729
+ COLUMN_DEFINITION = "column-definition",
2730
+ DELAY_DEFINITION = "delay-definition",
2731
+ MAP_PROCESS_DATA = "map-process-data",
2732
+ DOCUMENT_MAPPER_BUILDER = "document-mapper",
2733
+ DATA_STORE_MAPPER = "data-store-mapper",
2734
+ DATA_STORE_DECISIONAL = "data-store-decisional",
2735
+ NUMBER = "number",
2736
+ MAP_PARAMETERS = "map-parameters",
2737
+ // ...other SettingType members exist but are not referenced by the validators
2738
+ }
2739
+ ```