@shipfox/api-workflows 10.2.0 → 12.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (354) hide show
  1. package/.turbo/turbo-build.log +8 -8
  2. package/CHANGELOG.md +117 -0
  3. package/README.md +75 -0
  4. package/dist/core/agent-defaults.d.ts +2 -1
  5. package/dist/core/agent-defaults.d.ts.map +1 -1
  6. package/dist/core/agent-defaults.js.map +1 -1
  7. package/dist/core/checkout.d.ts +7 -21
  8. package/dist/core/checkout.d.ts.map +1 -1
  9. package/dist/core/checkout.js +122 -41
  10. package/dist/core/checkout.js.map +1 -1
  11. package/dist/core/entities/job-execution.d.ts +8 -0
  12. package/dist/core/entities/job-execution.d.ts.map +1 -1
  13. package/dist/core/entities/job-execution.js +13 -1
  14. package/dist/core/entities/job-execution.js.map +1 -1
  15. package/dist/core/entities/job-listener-event.d.ts +2 -0
  16. package/dist/core/entities/job-listener-event.d.ts.map +1 -1
  17. package/dist/core/entities/job-listener-event.js.map +1 -1
  18. package/dist/core/entities/step.d.ts +13 -3
  19. package/dist/core/entities/step.d.ts.map +1 -1
  20. package/dist/core/entities/step.js +6 -0
  21. package/dist/core/entities/step.js.map +1 -1
  22. package/dist/core/entities/workflow-run-attempt.d.ts +1 -0
  23. package/dist/core/entities/workflow-run-attempt.d.ts.map +1 -1
  24. package/dist/core/entities/workflow-run-attempt.js.map +1 -1
  25. package/dist/core/entities/workflow-run.d.ts +17 -0
  26. package/dist/core/entities/workflow-run.d.ts.map +1 -1
  27. package/dist/core/entities/workflow-run.js.map +1 -1
  28. package/dist/core/errors.d.ts +9 -2
  29. package/dist/core/errors.d.ts.map +1 -1
  30. package/dist/core/errors.js +10 -5
  31. package/dist/core/errors.js.map +1 -1
  32. package/dist/core/job-execution.d.ts.map +1 -1
  33. package/dist/core/job-execution.js +14 -8
  34. package/dist/core/job-execution.js.map +1 -1
  35. package/dist/core/job-transition/decide-job-activation.d.ts +1 -0
  36. package/dist/core/job-transition/decide-job-activation.d.ts.map +1 -1
  37. package/dist/core/job-transition/decide-job-activation.js +1 -0
  38. package/dist/core/job-transition/decide-job-activation.js.map +1 -1
  39. package/dist/core/job-transition/derive-job-success.d.ts +1 -0
  40. package/dist/core/job-transition/derive-job-success.d.ts.map +1 -1
  41. package/dist/core/job-transition/derive-job-success.js +5 -8
  42. package/dist/core/job-transition/derive-job-success.js.map +1 -1
  43. package/dist/core/listener-execution-materialization.d.ts +6 -3
  44. package/dist/core/listener-execution-materialization.d.ts.map +1 -1
  45. package/dist/core/listener-execution-materialization.js +44 -6
  46. package/dist/core/listener-execution-materialization.js.map +1 -1
  47. package/dist/core/resolve-trigger-reference.d.ts +11 -0
  48. package/dist/core/resolve-trigger-reference.d.ts.map +1 -0
  49. package/dist/core/resolve-trigger-reference.js +39 -0
  50. package/dist/core/resolve-trigger-reference.js.map +1 -0
  51. package/dist/core/run-workflow.d.ts +1 -0
  52. package/dist/core/run-workflow.d.ts.map +1 -1
  53. package/dist/core/run-workflow.js +1 -0
  54. package/dist/core/run-workflow.js.map +1 -1
  55. package/dist/core/step-config/agent.d.ts +1 -2
  56. package/dist/core/step-config/agent.d.ts.map +1 -1
  57. package/dist/core/step-config/agent.js +22 -7
  58. package/dist/core/step-config/agent.js.map +1 -1
  59. package/dist/core/step-config/assemble-run-context.d.ts +19 -8
  60. package/dist/core/step-config/assemble-run-context.d.ts.map +1 -1
  61. package/dist/core/step-config/assemble-run-context.js +51 -19
  62. package/dist/core/step-config/assemble-run-context.js.map +1 -1
  63. package/dist/core/step-config/complete-step-dispatch-config.d.ts.map +1 -1
  64. package/dist/core/step-config/complete-step-dispatch-config.js +72 -4
  65. package/dist/core/step-config/complete-step-dispatch-config.js.map +1 -1
  66. package/dist/core/step-config/index.d.ts +1 -0
  67. package/dist/core/step-config/index.d.ts.map +1 -1
  68. package/dist/core/step-config/index.js +1 -0
  69. package/dist/core/step-config/index.js.map +1 -1
  70. package/dist/core/step-config/materialize-job-execution-steps.d.ts +1 -1
  71. package/dist/core/step-config/materialize-job-execution-steps.d.ts.map +1 -1
  72. package/dist/core/step-config/materialize-job-execution-steps.js +49 -8
  73. package/dist/core/step-config/materialize-job-execution-steps.js.map +1 -1
  74. package/dist/core/step-config/materialize-workflow-model.d.ts +3 -3
  75. package/dist/core/step-config/materialize-workflow-model.d.ts.map +1 -1
  76. package/dist/core/step-config/materialize-workflow-model.js +9 -5
  77. package/dist/core/step-config/materialize-workflow-model.js.map +1 -1
  78. package/dist/core/step-config/resolve-job-execution-name.d.ts +3 -3
  79. package/dist/core/step-config/resolve-job-execution-name.d.ts.map +1 -1
  80. package/dist/core/step-config/resolve-job-execution-name.js +24 -13
  81. package/dist/core/step-config/resolve-job-execution-name.js.map +1 -1
  82. package/dist/core/step-config/resolve-step-config.d.ts.map +1 -1
  83. package/dist/core/step-config/resolve-step-config.js +174 -9
  84. package/dist/core/step-config/resolve-step-config.js.map +1 -1
  85. package/dist/core/step-config/resolve-workflow-run-name.d.ts +19 -0
  86. package/dist/core/step-config/resolve-workflow-run-name.d.ts.map +1 -0
  87. package/dist/core/step-config/resolve-workflow-run-name.js +73 -0
  88. package/dist/core/step-config/resolve-workflow-run-name.js.map +1 -0
  89. package/dist/core/step-transition/decide-step-transition.js.map +1 -1
  90. package/dist/core/step-transition/evaluate-gate.d.ts +2 -1
  91. package/dist/core/step-transition/evaluate-gate.d.ts.map +1 -1
  92. package/dist/core/step-transition/evaluate-gate.js +5 -3
  93. package/dist/core/step-transition/evaluate-gate.js.map +1 -1
  94. package/dist/core/workflow-run-creation.d.ts +3 -0
  95. package/dist/core/workflow-run-creation.d.ts.map +1 -1
  96. package/dist/core/workflow-run-creation.js +22 -7
  97. package/dist/core/workflow-run-creation.js.map +1 -1
  98. package/dist/db/db.d.ts +278 -10
  99. package/dist/db/db.d.ts.map +1 -1
  100. package/dist/db/db.js +2 -0
  101. package/dist/db/db.js.map +1 -1
  102. package/dist/db/index.d.ts +3 -2
  103. package/dist/db/index.d.ts.map +1 -1
  104. package/dist/db/index.js +2 -1
  105. package/dist/db/index.js.map +1 -1
  106. package/dist/db/job-listener-events.d.ts +2 -0
  107. package/dist/db/job-listener-events.d.ts.map +1 -1
  108. package/dist/db/job-listener-events.js +1 -0
  109. package/dist/db/job-listener-events.js.map +1 -1
  110. package/dist/db/job-listeners.d.ts +2 -0
  111. package/dist/db/job-listeners.d.ts.map +1 -1
  112. package/dist/db/job-listeners.js +81 -21
  113. package/dist/db/job-listeners.js.map +1 -1
  114. package/dist/db/schema/job-executions.d.ts +3 -3
  115. package/dist/db/schema/job-executions.d.ts.map +1 -1
  116. package/dist/db/schema/job-executions.js +8 -4
  117. package/dist/db/schema/job-executions.js.map +1 -1
  118. package/dist/db/schema/job-listener-events.d.ts +20 -0
  119. package/dist/db/schema/job-listener-events.d.ts.map +1 -1
  120. package/dist/db/schema/job-listener-events.js +2 -0
  121. package/dist/db/schema/job-listener-events.js.map +1 -1
  122. package/dist/db/schema/step-attempts.js +2 -2
  123. package/dist/db/schema/step-attempts.js.map +1 -1
  124. package/dist/db/schema/steps.d.ts +4 -2
  125. package/dist/db/schema/steps.d.ts.map +1 -1
  126. package/dist/db/schema/steps.js +1 -1
  127. package/dist/db/schema/steps.js.map +1 -1
  128. package/dist/db/schema/workflow-run-attempts.d.ts +21 -2
  129. package/dist/db/schema/workflow-run-attempts.d.ts.map +1 -1
  130. package/dist/db/schema/workflow-run-attempts.js +2 -0
  131. package/dist/db/schema/workflow-run-attempts.js.map +1 -1
  132. package/dist/db/schema/workflow-run-counters.d.ts +43 -0
  133. package/dist/db/schema/workflow-run-counters.d.ts.map +1 -0
  134. package/dist/db/schema/workflow-run-counters.js +10 -0
  135. package/dist/db/schema/workflow-run-counters.js.map +1 -0
  136. package/dist/db/schema/workflow-runs.d.ts +54 -1
  137. package/dist/db/schema/workflow-runs.d.ts.map +1 -1
  138. package/dist/db/schema/workflow-runs.js +10 -2
  139. package/dist/db/schema/workflow-runs.js.map +1 -1
  140. package/dist/db/workflow-runs/job-executions.d.ts.map +1 -1
  141. package/dist/db/workflow-runs/job-executions.js +35 -14
  142. package/dist/db/workflow-runs/job-executions.js.map +1 -1
  143. package/dist/db/workflow-runs/jobs.d.ts +2 -0
  144. package/dist/db/workflow-runs/jobs.d.ts.map +1 -1
  145. package/dist/db/workflow-runs/jobs.js +9 -5
  146. package/dist/db/workflow-runs/jobs.js.map +1 -1
  147. package/dist/db/workflow-runs/queries.d.ts +51 -0
  148. package/dist/db/workflow-runs/queries.d.ts.map +1 -1
  149. package/dist/db/workflow-runs/queries.js +82 -2
  150. package/dist/db/workflow-runs/queries.js.map +1 -1
  151. package/dist/db/workflow-runs/run-create.d.ts +1 -0
  152. package/dist/db/workflow-runs/run-create.d.ts.map +1 -1
  153. package/dist/db/workflow-runs/run-create.js +159 -32
  154. package/dist/db/workflow-runs/run-create.js.map +1 -1
  155. package/dist/db/workflow-runs/run-rerun.d.ts.map +1 -1
  156. package/dist/db/workflow-runs/run-rerun.js +13 -5
  157. package/dist/db/workflow-runs/run-rerun.js.map +1 -1
  158. package/dist/db/workflow-runs/shared.d.ts +1 -0
  159. package/dist/db/workflow-runs/shared.d.ts.map +1 -1
  160. package/dist/db/workflow-runs/shared.js +2 -1
  161. package/dist/db/workflow-runs/shared.js.map +1 -1
  162. package/dist/db/workflow-runs/steps.js +3 -3
  163. package/dist/db/workflow-runs/steps.js.map +1 -1
  164. package/dist/db/workflow-runs.d.ts +4 -3
  165. package/dist/db/workflow-runs.d.ts.map +1 -1
  166. package/dist/db/workflow-runs.js +3 -2
  167. package/dist/db/workflow-runs.js.map +1 -1
  168. package/dist/metrics/instance.d.ts +1 -0
  169. package/dist/metrics/instance.d.ts.map +1 -1
  170. package/dist/metrics/instance.js +9 -0
  171. package/dist/metrics/instance.js.map +1 -1
  172. package/dist/presentation/dto/checkout-token.d.ts +1 -0
  173. package/dist/presentation/dto/checkout-token.d.ts.map +1 -1
  174. package/dist/presentation/dto/checkout-token.js +1 -0
  175. package/dist/presentation/dto/checkout-token.js.map +1 -1
  176. package/dist/presentation/dto/index.d.ts +1 -1
  177. package/dist/presentation/dto/index.d.ts.map +1 -1
  178. package/dist/presentation/dto/index.js +1 -1
  179. package/dist/presentation/dto/index.js.map +1 -1
  180. package/dist/presentation/dto/step.d.ts.map +1 -1
  181. package/dist/presentation/dto/step.js +2 -2
  182. package/dist/presentation/dto/step.js.map +1 -1
  183. package/dist/presentation/dto/workflow-run.d.ts +3 -1
  184. package/dist/presentation/dto/workflow-run.d.ts.map +1 -1
  185. package/dist/presentation/dto/workflow-run.js +34 -0
  186. package/dist/presentation/dto/workflow-run.js.map +1 -1
  187. package/dist/presentation/inter-module.d.ts.map +1 -1
  188. package/dist/presentation/inter-module.js +31 -3
  189. package/dist/presentation/inter-module.js.map +1 -1
  190. package/dist/presentation/routes/checkout-token.d.ts +1 -1
  191. package/dist/presentation/routes/checkout-token.d.ts.map +1 -1
  192. package/dist/presentation/routes/checkout-token.js +32 -20
  193. package/dist/presentation/routes/checkout-token.js.map +1 -1
  194. package/dist/presentation/routes/leased-step.d.ts +2 -0
  195. package/dist/presentation/routes/leased-step.d.ts.map +1 -1
  196. package/dist/presentation/routes/leased-step.js +2 -1
  197. package/dist/presentation/routes/leased-step.js.map +1 -1
  198. package/dist/presentation/routes/list-runs.d.ts.map +1 -1
  199. package/dist/presentation/routes/list-runs.js +9 -3
  200. package/dist/presentation/routes/list-runs.js.map +1 -1
  201. package/dist/presentation/routes/project-access.d.ts +1 -0
  202. package/dist/presentation/routes/project-access.d.ts.map +1 -1
  203. package/dist/presentation/routes/report-step.d.ts.map +1 -1
  204. package/dist/presentation/routes/report-step.js +9 -2
  205. package/dist/presentation/routes/report-step.js.map +1 -1
  206. package/dist/presentation/routes/require-accessible-run.d.ts.map +1 -1
  207. package/dist/presentation/routes/require-accessible-run.js +1 -1
  208. package/dist/presentation/routes/require-accessible-run.js.map +1 -1
  209. package/dist/presentation/subscribers/on-job-steps-settled.js +1 -1
  210. package/dist/presentation/subscribers/on-job-steps-settled.js.map +1 -1
  211. package/dist/presentation/subscribers/on-runner-job-claimed.d.ts.map +1 -1
  212. package/dist/presentation/subscribers/on-runner-job-claimed.js +21 -0
  213. package/dist/presentation/subscribers/on-runner-job-claimed.js.map +1 -1
  214. package/dist/temporal/activities/index.d.ts.map +1 -1
  215. package/dist/temporal/activities/index.js +2 -1
  216. package/dist/temporal/activities/index.js.map +1 -1
  217. package/dist/temporal/activities/orchestration-activities.d.ts +1 -0
  218. package/dist/temporal/activities/orchestration-activities.d.ts.map +1 -1
  219. package/dist/temporal/activities/orchestration-activities.js.map +1 -1
  220. package/dist/temporal/constants.d.ts +1 -0
  221. package/dist/temporal/constants.d.ts.map +1 -1
  222. package/dist/temporal/constants.js +1 -0
  223. package/dist/temporal/constants.js.map +1 -1
  224. package/dist/temporal/index.d.ts +1 -1
  225. package/dist/temporal/index.d.ts.map +1 -1
  226. package/dist/temporal/index.js +1 -1
  227. package/dist/temporal/index.js.map +1 -1
  228. package/dist/temporal/workflows/index.bundle.js +82 -43
  229. package/dist/temporal/workflows/index.d.ts +1 -1
  230. package/dist/temporal/workflows/index.d.ts.map +1 -1
  231. package/dist/temporal/workflows/index.js +1 -1
  232. package/dist/temporal/workflows/index.js.map +1 -1
  233. package/dist/temporal/workflows/job-execution-orchestration.d.ts +5 -0
  234. package/dist/temporal/workflows/job-execution-orchestration.d.ts.map +1 -1
  235. package/dist/temporal/workflows/job-execution-orchestration.js +77 -43
  236. package/dist/temporal/workflows/job-execution-orchestration.js.map +1 -1
  237. package/dist/temporal/workflows/test-env.d.ts +5 -1
  238. package/dist/temporal/workflows/test-env.d.ts.map +1 -1
  239. package/dist/temporal/workflows/test-env.js +32 -11
  240. package/dist/temporal/workflows/test-env.js.map +1 -1
  241. package/dist/tsconfig.test.tsbuildinfo +1 -1
  242. package/drizzle/0000_initial.sql +14 -2
  243. package/drizzle/0001_windy_sunfire.sql +1 -0
  244. package/drizzle/meta/0000_snapshot.json +93 -1
  245. package/drizzle/meta/0001_snapshot.json +1711 -0
  246. package/drizzle/meta/_journal.json +2 -2
  247. package/package.json +21 -21
  248. package/src/core/agent-defaults.ts +2 -1
  249. package/src/core/checkout.test.ts +378 -67
  250. package/src/core/checkout.ts +142 -59
  251. package/src/core/entities/job-execution.test.ts +21 -0
  252. package/src/core/entities/job-execution.ts +24 -0
  253. package/src/core/entities/job-listener-event.ts +3 -0
  254. package/src/core/entities/step.ts +15 -3
  255. package/src/core/entities/workflow-run-attempt.ts +1 -0
  256. package/src/core/entities/workflow-run.ts +16 -0
  257. package/src/core/errors.ts +21 -7
  258. package/src/core/job-execution.ts +27 -4
  259. package/src/core/job-transition/decide-job-activation.test.ts +4 -0
  260. package/src/core/job-transition/decide-job-activation.ts +2 -0
  261. package/src/core/job-transition/derive-job-success.test.ts +12 -0
  262. package/src/core/job-transition/derive-job-success.ts +6 -9
  263. package/src/core/listener-execution-materialization.test.ts +2 -0
  264. package/src/core/listener-execution-materialization.ts +57 -11
  265. package/src/core/resolve-trigger-reference.test.ts +160 -0
  266. package/src/core/resolve-trigger-reference.ts +53 -0
  267. package/src/core/run-workflow.ts +2 -0
  268. package/src/core/step-config/agent.ts +29 -12
  269. package/src/core/step-config/assemble-run-context.test.ts +149 -6
  270. package/src/core/step-config/assemble-run-context.ts +87 -25
  271. package/src/core/step-config/complete-step-dispatch-config.test.ts +125 -2
  272. package/src/core/step-config/complete-step-dispatch-config.ts +83 -1
  273. package/src/core/step-config/index.ts +7 -0
  274. package/src/core/step-config/materialize-job-execution-steps.test.ts +250 -1
  275. package/src/core/step-config/materialize-job-execution-steps.ts +57 -10
  276. package/src/core/step-config/materialize-workflow-model.test.ts +212 -4
  277. package/src/core/step-config/materialize-workflow-model.ts +33 -28
  278. package/src/core/step-config/resolve-job-execution-name.test.ts +37 -15
  279. package/src/core/step-config/resolve-job-execution-name.ts +30 -15
  280. package/src/core/step-config/resolve-step-config.ts +175 -10
  281. package/src/core/step-config/resolve-workflow-run-name.test.ts +115 -0
  282. package/src/core/step-config/resolve-workflow-run-name.ts +108 -0
  283. package/src/core/step-transition/decide-step-transition.ts +2 -2
  284. package/src/core/step-transition/evaluate-gate.test.ts +8 -0
  285. package/src/core/step-transition/evaluate-gate.ts +8 -1
  286. package/src/core/workflow-run-creation.test.ts +7 -4
  287. package/src/core/workflow-run-creation.ts +13 -7
  288. package/src/db/db.ts +2 -0
  289. package/src/db/index.ts +6 -0
  290. package/src/db/job-listener-events.test.ts +19 -0
  291. package/src/db/job-listener-events.ts +3 -0
  292. package/src/db/job-listeners.test.ts +187 -5
  293. package/src/db/job-listeners.ts +122 -30
  294. package/src/db/schema/job-executions.ts +12 -5
  295. package/src/db/schema/job-listener-events.ts +3 -0
  296. package/src/db/schema/step-attempts.ts +2 -2
  297. package/src/db/schema/steps.ts +2 -1
  298. package/src/db/schema/workflow-run-attempts.ts +2 -0
  299. package/src/db/schema/workflow-run-counters.ts +13 -0
  300. package/src/db/schema/workflow-runs.ts +11 -2
  301. package/src/db/workflow-runs/job-executions.ts +37 -15
  302. package/src/db/workflow-runs/jobs.ts +17 -4
  303. package/src/db/workflow-runs/queries.test.ts +206 -0
  304. package/src/db/workflow-runs/queries.ts +146 -2
  305. package/src/db/workflow-runs/run-create.test.ts +606 -8
  306. package/src/db/workflow-runs/run-create.ts +185 -40
  307. package/src/db/workflow-runs/run-rerun.test.ts +61 -2
  308. package/src/db/workflow-runs/run-rerun.ts +15 -5
  309. package/src/db/workflow-runs/shared.ts +2 -0
  310. package/src/db/workflow-runs/steps.ts +3 -3
  311. package/src/db/workflow-runs.ts +7 -0
  312. package/src/metrics/instance.ts +14 -0
  313. package/src/presentation/dto/checkout-token.test.ts +19 -9
  314. package/src/presentation/dto/checkout-token.ts +2 -1
  315. package/src/presentation/dto/index.ts +1 -1
  316. package/src/presentation/dto/job.test.ts +9 -0
  317. package/src/presentation/dto/step.test.ts +12 -0
  318. package/src/presentation/dto/step.ts +5 -2
  319. package/src/presentation/dto/workflow-run.ts +44 -2
  320. package/src/presentation/inter-module.test.ts +165 -0
  321. package/src/presentation/inter-module.ts +38 -4
  322. package/src/presentation/routes/cancel-run.test.ts +1 -1
  323. package/src/presentation/routes/checkout-token.test.ts +357 -142
  324. package/src/presentation/routes/checkout-token.ts +56 -26
  325. package/src/presentation/routes/get-run-aggregates.test.ts +1 -1
  326. package/src/presentation/routes/get-run.test.ts +29 -1
  327. package/src/presentation/routes/get-step-secrets.test.ts +7 -2
  328. package/src/presentation/routes/leased-step.ts +9 -1
  329. package/src/presentation/routes/list-run-attempts.test.ts +1 -1
  330. package/src/presentation/routes/list-runs.test.ts +58 -1
  331. package/src/presentation/routes/list-runs.ts +8 -3
  332. package/src/presentation/routes/report-step.test.ts +25 -0
  333. package/src/presentation/routes/report-step.ts +10 -2
  334. package/src/presentation/routes/require-accessible-run.ts +4 -1
  335. package/src/presentation/routes/rerun-run.test.ts +1 -1
  336. package/src/presentation/subscribers/on-job-steps-settled.ts +1 -1
  337. package/src/presentation/subscribers/on-runner-job-claimed.test.ts +49 -0
  338. package/src/presentation/subscribers/on-runner-job-claimed.ts +22 -0
  339. package/src/temporal/activities/index.ts +1 -0
  340. package/src/temporal/activities/orchestration-activities.ts +1 -0
  341. package/src/temporal/constants.ts +1 -0
  342. package/src/temporal/index.ts +1 -0
  343. package/src/temporal/workflows/index.ts +1 -0
  344. package/src/temporal/workflows/job-execution-orchestration.test.ts +142 -6
  345. package/src/temporal/workflows/job-execution-orchestration.ts +99 -50
  346. package/src/temporal/workflows/run-orchestration.test.ts +1 -1
  347. package/src/temporal/workflows/test-env.ts +50 -13
  348. package/test/factories/project.ts +2 -0
  349. package/test/factories/workflow-model.ts +80 -26
  350. package/test/factories/workflow-run.ts +4 -1
  351. package/test/fixtures/agent-inter-module.ts +2 -1
  352. package/test/fixtures/job-with-steps.ts +1 -1
  353. package/tsconfig.build.tsbuildinfo +1 -1
  354. package/drizzle/0001_agent_tool_materialization.sql +0 -1
@@ -1,3 +1,4 @@
1
+ import { WORKFLOW_RUN_JOB_PREVIEW_LIMIT } from '@shipfox/api-workflows-dto';
1
2
  import { paginateTimestampIdRows, timestampIdCursorWhere } from '@shipfox/node-drizzle';
2
3
  import { and, asc, count, desc, eq, gte, lte, sql } from 'drizzle-orm';
3
4
  import { db } from '../db.js';
@@ -90,6 +91,84 @@ export async function listWorkflowRuns(params) {
90
91
  filteredTotalCount: totalCount
91
92
  };
92
93
  }
94
+ /**
95
+ * Jobs for a page of runs, keyed by run id.
96
+ *
97
+ * Issued once per page rather than once per run: the run list is the one surface that needs
98
+ * every run's jobs at once, and a per-row query would put 50 round trips behind it.
99
+ *
100
+ * Both reads are bounded by the page, not by workflow size. A workflow has no job limit and
101
+ * this list polls while runs are active, so returning every job of every row would let one
102
+ * large workflow decide how much the endpoint moves every four seconds. The preview is cut
103
+ * per run in the database, and everything past it is described by a grouped count instead.
104
+ *
105
+ * The attempt comes from the caller's own read rather than from a second look at
106
+ * `current_attempt`. Re-reading it here would let a re-run landing between the queries pair
107
+ * attempt 1's run metadata with attempt 2's jobs, and the row would report a status its strip
108
+ * contradicts.
109
+ *
110
+ * The two reads share one repeatable-read snapshot. They describe the same jobs at the same
111
+ * instant, and the strip combines them into a single glyph row, so under the default
112
+ * read-committed isolation a job settling between the statements would draw a pending glyph
113
+ * beside a summary counting it as failed. Sequential inside one transaction is the cost of
114
+ * that; at a four-second poll the extra round trip does not register.
115
+ */ export async function listWorkflowRunJobSummaries(runs) {
116
+ const summaries = new Map();
117
+ if (runs.length === 0) return summaries;
118
+ // A row-constructor IN over (run, attempt) so each pair is one lookup on the unique index
119
+ // that already covers those two columns.
120
+ const attemptPairs = sql.join(runs.map((run)=>sql`(${run.id}::uuid, ${run.currentAttempt})`), sql`, `);
121
+ const attemptFilter = sql`(${workflowRunAttempts.workflowRunId}, ${workflowRunAttempts.attempt}) in (${attemptPairs})`;
122
+ const { previewRows, countRows } = await db().transaction(async (tx)=>{
123
+ const ranked = tx.select({
124
+ workflowRunId: workflowRunAttempts.workflowRunId,
125
+ id: jobs.id,
126
+ key: jobs.key,
127
+ name: jobs.name,
128
+ status: jobs.status,
129
+ position: jobs.position,
130
+ rank: sql`row_number() over (partition by ${workflowRunAttempts.workflowRunId} order by ${jobs.position} asc, ${jobs.id} asc)`.as('rank')
131
+ }).from(jobs).innerJoin(workflowRunAttempts, eq(jobs.workflowRunAttemptId, workflowRunAttempts.id)).where(attemptFilter).as('ranked');
132
+ return {
133
+ previewRows: await tx.select({
134
+ workflowRunId: ranked.workflowRunId,
135
+ id: ranked.id,
136
+ key: ranked.key,
137
+ name: ranked.name,
138
+ status: ranked.status,
139
+ position: ranked.position
140
+ }).from(ranked).where(lte(ranked.rank, WORKFLOW_RUN_JOB_PREVIEW_LIMIT)).orderBy(asc(ranked.workflowRunId), asc(ranked.position), asc(ranked.id)),
141
+ countRows: await tx.select({
142
+ workflowRunId: workflowRunAttempts.workflowRunId,
143
+ status: jobs.status,
144
+ count: count()
145
+ }).from(jobs).innerJoin(workflowRunAttempts, eq(jobs.workflowRunAttemptId, workflowRunAttempts.id)).where(attemptFilter).groupBy(workflowRunAttempts.workflowRunId, jobs.status)
146
+ };
147
+ }, {
148
+ isolationLevel: 'repeatable read',
149
+ accessMode: 'read only'
150
+ });
151
+ for (const { workflowRunId, ...summary } of previewRows){
152
+ summaryFor(summaries, workflowRunId).preview.push(summary);
153
+ }
154
+ for (const { workflowRunId, status, count: statusCount } of countRows){
155
+ summaryFor(summaries, workflowRunId).statusCounts.push({
156
+ status,
157
+ count: statusCount
158
+ });
159
+ }
160
+ return summaries;
161
+ }
162
+ function summaryFor(summaries, workflowRunId) {
163
+ const existing = summaries.get(workflowRunId);
164
+ if (existing) return existing;
165
+ const created = {
166
+ preview: [],
167
+ statusCounts: []
168
+ };
169
+ summaries.set(workflowRunId, created);
170
+ return created;
171
+ }
93
172
  export async function listWorkflowRunsByProject(projectId) {
94
173
  const result = await listWorkflowRuns({
95
174
  projectId,
@@ -175,6 +254,7 @@ export async function getWorkflowRunDetail(workflowRunId, attempt) {
175
254
  }
176
255
  export async function getJobExecutionDetail(jobExecutionId) {
177
256
  const rows = await db().select({
257
+ job: jobs,
178
258
  jobExecution: jobExecutions,
179
259
  step: steps,
180
260
  stepAttempt: stepAttempts
@@ -182,7 +262,7 @@ export async function getJobExecutionDetail(jobExecutionId) {
182
262
  const first = rows[0];
183
263
  if (!first) return undefined;
184
264
  const detail = {
185
- ...toJobExecution(first.jobExecution),
265
+ ...toJobExecution(first.jobExecution, first.job.name ?? first.job.key),
186
266
  steps: []
187
267
  };
188
268
  const stepById = new Map();
@@ -223,7 +303,7 @@ function hydrateWorkflowRunDetail(rows, attempt, latestAttempt) {
223
303
  let jobExecution = jobExecutionById.get(row.jobExecution.id);
224
304
  if (!jobExecution) {
225
305
  jobExecution = {
226
- ...toJobExecution(row.jobExecution),
306
+ ...toJobExecution(row.jobExecution, row.job.name ?? row.job.key),
227
307
  steps: []
228
308
  };
229
309
  jobExecutionById.set(row.jobExecution.id, jobExecution);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/db/workflow-runs/queries.ts"],"sourcesContent":["import {\n paginateTimestampIdRows,\n type TimestampIdCursor,\n timestampIdCursorWhere,\n} from '@shipfox/node-drizzle';\nimport {and, asc, count, desc, eq, gte, lte, type SQL, sql} from 'drizzle-orm';\nimport type {\n JobExecutionDetail,\n StepDetail,\n WorkflowJobDetail,\n WorkflowRun,\n WorkflowRunDetail,\n WorkflowRunStatus,\n} from '#core/entities/workflow-run.js';\nimport {db} from '../db.js';\nimport {jobExecutions, toJobExecution} from '../schema/job-executions.js';\nimport {jobs, toJob} from '../schema/jobs.js';\nimport {stepAttempts, toStepAttempt} from '../schema/step-attempts.js';\nimport {steps, toStep} from '../schema/steps.js';\nimport {toWorkflowRunAttempt, workflowRunAttempts} from '../schema/workflow-run-attempts.js';\nimport {toWorkflowRun, workflowRuns} from '../schema/workflow-runs.js';\n\nexport type WorkflowRunCursor = TimestampIdCursor;\n\nexport interface WorkflowRunFilters {\n status?: WorkflowRunStatus | undefined;\n definitionId?: string | undefined;\n triggerSource?: string | undefined;\n createdFrom?: Date | undefined;\n createdTo?: Date | undefined;\n}\n\nexport interface ListWorkflowRunsParams {\n projectId: string;\n limit: number;\n cursor?: WorkflowRunCursor | undefined;\n filters?: WorkflowRunFilters | undefined;\n includeTotal?: boolean | undefined;\n}\n\nexport interface ListWorkflowRunsResult {\n runs: WorkflowRun[];\n nextCursor: WorkflowRunCursor | null;\n filteredTotalCount: number | null;\n}\n\nexport interface WorkflowRunAggregates {\n status: Array<{value: WorkflowRunStatus; count: number}>;\n triggerSource: Array<{value: string; count: number}>;\n workflow: Array<{value: string; count: number}>;\n}\n\nexport interface WorkflowJobExecutionDepth {\n runningRuns: number;\n runningJobExecutions: number;\n}\n\nexport interface WorkflowJobExecutionDepthParams {\n workspaceId?: string;\n}\n\nexport async function getWorkflowRunById(id: string): Promise<WorkflowRun | undefined> {\n const rows = await db().select().from(workflowRuns).where(eq(workflowRuns.id, id)).limit(1);\n const row = rows[0];\n if (!row) return undefined;\n return toWorkflowRun(row);\n}\n\nexport async function getWorkflowRunByAttemptId(\n workflowRunAttemptId: string,\n): Promise<WorkflowRun | undefined> {\n const rows = await db()\n .select({run: workflowRuns})\n .from(workflowRunAttempts)\n .innerJoin(workflowRuns, eq(workflowRunAttempts.workflowRunId, workflowRuns.id))\n .where(eq(workflowRunAttempts.id, workflowRunAttemptId))\n .limit(1);\n const row = rows[0];\n return row ? toWorkflowRun(row.run) : undefined;\n}\n\nexport async function getWorkflowRunAttemptById(workflowRunAttemptId: string) {\n const rows = await db()\n .select()\n .from(workflowRunAttempts)\n .where(eq(workflowRunAttempts.id, workflowRunAttemptId))\n .limit(1);\n const row = rows[0];\n return row ? toWorkflowRunAttempt(row) : undefined;\n}\n\nexport async function listRunAttempts(params: {workflowRunId: string; projectId: string}) {\n return (\n await db()\n .select({\n attempt: workflowRunAttempts,\n })\n .from(workflowRunAttempts)\n .innerJoin(workflowRuns, eq(workflowRunAttempts.workflowRunId, workflowRuns.id))\n .where(\n and(\n eq(workflowRunAttempts.workflowRunId, params.workflowRunId),\n eq(workflowRuns.projectId, params.projectId),\n ),\n )\n .orderBy(asc(workflowRunAttempts.attempt))\n ).map((row) => toWorkflowRunAttempt(row.attempt));\n}\n\nexport async function getLatestAttempt(params: {\n workflowRunId: string;\n projectId: string;\n}): Promise<number> {\n const [row] = await db()\n .select({value: sql<number>`coalesce(max(${workflowRunAttempts.attempt}), 1)`})\n .from(workflowRunAttempts)\n .innerJoin(workflowRuns, eq(workflowRunAttempts.workflowRunId, workflowRuns.id))\n .where(\n and(\n eq(workflowRunAttempts.workflowRunId, params.workflowRunId),\n eq(workflowRuns.projectId, params.projectId),\n ),\n )\n .limit(1);\n\n return Number(row?.value ?? 1);\n}\n\nexport function buildWorkflowRunListConditions(params: {\n projectId: string;\n filters?: WorkflowRunFilters | undefined;\n cursor?: WorkflowRunCursor | undefined;\n omit?: 'status' | 'definitionId' | 'triggerSource' | undefined;\n}): SQL[] {\n const filters = params.filters;\n const conditions: SQL[] = [eq(workflowRuns.projectId, params.projectId)];\n const cursorCondition = timestampIdCursorWhere({\n timestampColumn: workflowRuns.createdAt,\n idColumn: workflowRuns.id,\n cursor: params.cursor,\n });\n if (cursorCondition) conditions.push(cursorCondition);\n if (filters?.status && params.omit !== 'status') {\n conditions.push(eq(workflowRuns.status, filters.status));\n }\n if (filters?.definitionId && params.omit !== 'definitionId') {\n conditions.push(eq(workflowRuns.definitionId, filters.definitionId));\n }\n if (filters?.triggerSource && params.omit !== 'triggerSource') {\n conditions.push(eq(workflowRuns.triggerSource, filters.triggerSource));\n }\n if (filters?.createdFrom) {\n conditions.push(gte(workflowRuns.createdAt, filters.createdFrom));\n }\n if (filters?.createdTo) {\n conditions.push(lte(workflowRuns.createdAt, filters.createdTo));\n }\n return conditions;\n}\n\nexport async function listWorkflowRuns(\n params: ListWorkflowRunsParams,\n): Promise<ListWorkflowRunsResult> {\n const conditions = buildWorkflowRunListConditions(params);\n const rows = await db()\n .select()\n .from(workflowRuns)\n .where(and(...conditions))\n .orderBy(desc(workflowRuns.createdAt), desc(workflowRuns.id))\n .limit(params.limit + 1);\n\n let totalCount: number | null = null;\n if (params.includeTotal) {\n const [{value} = {value: 0}] = await db()\n .select({value: count()})\n .from(workflowRuns)\n .where(\n and(\n ...buildWorkflowRunListConditions({projectId: params.projectId, filters: params.filters}),\n ),\n );\n totalCount = value;\n }\n\n const page = paginateTimestampIdRows({rows, limit: params.limit, timestampKey: 'createdAt'});\n\n return {\n runs: page.pageRows.map(toWorkflowRun),\n nextCursor: page.nextCursor,\n filteredTotalCount: totalCount,\n };\n}\n\nexport async function listWorkflowRunsByProject(projectId: string): Promise<WorkflowRun[]> {\n const result = await listWorkflowRuns({projectId, limit: 100});\n return result.runs;\n}\n\nexport async function getWorkflowRunAggregates(params: {\n projectId: string;\n filters?: WorkflowRunFilters | undefined;\n}): Promise<WorkflowRunAggregates> {\n const [statusRows, triggerRows, workflowRows] = await Promise.all([\n db()\n .select({value: workflowRuns.status, count: count()})\n .from(workflowRuns)\n .where(\n and(\n ...buildWorkflowRunListConditions({\n projectId: params.projectId,\n filters: params.filters,\n omit: 'status',\n }),\n ),\n )\n .groupBy(workflowRuns.status),\n db()\n .select({value: workflowRuns.triggerSource, count: count()})\n .from(workflowRuns)\n .where(\n and(\n ...buildWorkflowRunListConditions({\n projectId: params.projectId,\n filters: params.filters,\n omit: 'triggerSource',\n }),\n ),\n )\n .groupBy(workflowRuns.triggerSource),\n db()\n .select({value: workflowRuns.definitionId, count: count()})\n .from(workflowRuns)\n .where(\n and(\n ...buildWorkflowRunListConditions({\n projectId: params.projectId,\n filters: params.filters,\n omit: 'definitionId',\n }),\n ),\n )\n .groupBy(workflowRuns.definitionId),\n ]);\n\n return {\n status: statusRows,\n triggerSource: triggerRows,\n workflow: workflowRows,\n };\n}\n\nexport async function getWorkflowJobExecutionDepth(\n params: WorkflowJobExecutionDepthParams = {},\n): Promise<WorkflowJobExecutionDepth> {\n const runConditions = [eq(workflowRuns.status, 'running')];\n const jobConditions = [eq(jobExecutions.status, 'running')];\n if (params.workspaceId) {\n runConditions.push(eq(workflowRuns.workspaceId, params.workspaceId));\n jobConditions.push(eq(workflowRuns.workspaceId, params.workspaceId));\n }\n\n const [runRows, jobRows] = await Promise.all([\n db()\n .select({value: count()})\n .from(workflowRuns)\n .where(and(...runConditions)),\n db()\n .select({value: count()})\n .from(jobExecutions)\n .innerJoin(jobs, eq(jobExecutions.jobId, jobs.id))\n .innerJoin(workflowRunAttempts, eq(jobs.workflowRunAttemptId, workflowRunAttempts.id))\n .innerJoin(workflowRuns, eq(workflowRunAttempts.workflowRunId, workflowRuns.id))\n .where(and(...jobConditions)),\n ]);\n\n return {\n runningRuns: runRows[0]?.value ?? 0,\n runningJobExecutions: jobRows[0]?.value ?? 0,\n };\n}\n\nexport async function getWorkflowRunDetail(\n workflowRunId: string,\n attempt?: number | undefined,\n): Promise<WorkflowRunDetail | undefined> {\n const [target] = await db()\n .select({run: workflowRuns, attempt: workflowRunAttempts})\n .from(workflowRuns)\n .innerJoin(\n workflowRunAttempts,\n and(\n eq(workflowRunAttempts.workflowRunId, workflowRuns.id),\n eq(workflowRunAttempts.attempt, attempt ?? workflowRuns.currentAttempt),\n ),\n )\n .where(eq(workflowRuns.id, workflowRunId))\n .limit(1);\n if (!target) return undefined;\n\n const latestAttempt = await getLatestAttempt({\n workflowRunId: target.run.id,\n projectId: target.run.projectId,\n });\n\n const rows = await db()\n .select({\n run: workflowRuns,\n job: jobs,\n jobExecution: jobExecutions,\n step: steps,\n stepAttempt: stepAttempts,\n })\n .from(workflowRuns)\n .innerJoin(workflowRunAttempts, eq(workflowRunAttempts.id, target.attempt.id))\n .leftJoin(jobs, eq(jobs.workflowRunAttemptId, workflowRunAttempts.id))\n .leftJoin(jobExecutions, eq(jobExecutions.jobId, jobs.id))\n .leftJoin(steps, eq(steps.jobExecutionId, jobExecutions.id))\n .leftJoin(stepAttempts, eq(stepAttempts.stepId, steps.id))\n .where(eq(workflowRuns.id, workflowRunId))\n .orderBy(\n asc(jobs.position),\n asc(jobs.id),\n asc(jobExecutions.sequence),\n asc(jobExecutions.id),\n asc(steps.position),\n asc(steps.id),\n asc(stepAttempts.executionOrder),\n asc(stepAttempts.id),\n );\n\n return hydrateWorkflowRunDetail(rows, target.attempt, latestAttempt);\n}\n\nexport async function getJobExecutionDetail(\n jobExecutionId: string,\n): Promise<JobExecutionDetail | undefined> {\n const rows = await db()\n .select({\n jobExecution: jobExecutions,\n step: steps,\n stepAttempt: stepAttempts,\n })\n .from(jobExecutions)\n .innerJoin(jobs, eq(jobExecutions.jobId, jobs.id))\n .innerJoin(workflowRunAttempts, eq(jobs.workflowRunAttemptId, workflowRunAttempts.id))\n .innerJoin(workflowRuns, eq(workflowRunAttempts.workflowRunId, workflowRuns.id))\n .leftJoin(steps, eq(steps.jobExecutionId, jobExecutions.id))\n .leftJoin(stepAttempts, eq(stepAttempts.stepId, steps.id))\n .where(eq(jobExecutions.id, jobExecutionId))\n .orderBy(\n asc(steps.position),\n asc(steps.id),\n asc(stepAttempts.executionOrder),\n asc(stepAttempts.id),\n );\n\n const first = rows[0];\n if (!first) return undefined;\n\n const detail: JobExecutionDetail = {...toJobExecution(first.jobExecution), steps: []};\n const stepById = new Map<string, StepDetail>();\n for (const row of rows) {\n if (row.step) {\n const step = getOrCreateStepDetail(stepById, detail.steps, row.step);\n if (row.stepAttempt) {\n step.attempts.push(toStepAttempt(row.stepAttempt));\n }\n }\n }\n\n return detail;\n}\n\nfunction hydrateWorkflowRunDetail(\n rows: {\n run: typeof workflowRuns.$inferSelect;\n job: typeof jobs.$inferSelect | null;\n jobExecution: typeof jobExecutions.$inferSelect | null;\n step: typeof steps.$inferSelect | null;\n stepAttempt: typeof stepAttempts.$inferSelect | null;\n }[],\n attempt: typeof workflowRunAttempts.$inferSelect,\n latestAttempt: number,\n): WorkflowRunDetail | undefined {\n const first = rows[0];\n if (!first) return undefined;\n\n const detail: WorkflowRunDetail = {\n ...toWorkflowRun(first.run),\n runAttempt: toWorkflowRunAttempt(attempt),\n latestAttempt,\n jobs: [],\n };\n const jobById = new Map<string, WorkflowJobDetail>();\n const jobExecutionById = new Map<string, JobExecutionDetail>();\n const stepById = new Map<string, StepDetail>();\n\n for (const row of rows) {\n if (!row.job) continue;\n let job = jobById.get(row.job.id);\n if (!job) {\n job = {...toJob(row.job), jobExecutions: []};\n jobById.set(row.job.id, job);\n detail.jobs.push(job);\n }\n\n if (!row.jobExecution) continue;\n let jobExecution = jobExecutionById.get(row.jobExecution.id);\n if (!jobExecution) {\n jobExecution = {...toJobExecution(row.jobExecution), steps: []};\n jobExecutionById.set(row.jobExecution.id, jobExecution);\n job.jobExecutions.push(jobExecution);\n }\n\n if (!row.step) continue;\n const step = getOrCreateStepDetail(stepById, jobExecution.steps, row.step);\n if (row.stepAttempt) {\n step.attempts.push(toStepAttempt(row.stepAttempt));\n }\n }\n\n return detail;\n}\n\nfunction getOrCreateStepDetail(\n stepById: Map<string, StepDetail>,\n target: StepDetail[],\n row: typeof steps.$inferSelect,\n): StepDetail {\n let step = stepById.get(row.id);\n if (!step) {\n step = {...toStep(row), attempts: []};\n stepById.set(row.id, step);\n target.push(step);\n }\n return step;\n}\n"],"names":["paginateTimestampIdRows","timestampIdCursorWhere","and","asc","count","desc","eq","gte","lte","sql","db","jobExecutions","toJobExecution","jobs","toJob","stepAttempts","toStepAttempt","steps","toStep","toWorkflowRunAttempt","workflowRunAttempts","toWorkflowRun","workflowRuns","getWorkflowRunById","id","rows","select","from","where","limit","row","undefined","getWorkflowRunByAttemptId","workflowRunAttemptId","run","innerJoin","workflowRunId","getWorkflowRunAttemptById","listRunAttempts","params","attempt","projectId","orderBy","map","getLatestAttempt","value","Number","buildWorkflowRunListConditions","filters","conditions","cursorCondition","timestampColumn","createdAt","idColumn","cursor","push","status","omit","definitionId","triggerSource","createdFrom","createdTo","listWorkflowRuns","totalCount","includeTotal","page","timestampKey","runs","pageRows","nextCursor","filteredTotalCount","listWorkflowRunsByProject","result","getWorkflowRunAggregates","statusRows","triggerRows","workflowRows","Promise","all","groupBy","workflow","getWorkflowJobExecutionDepth","runConditions","jobConditions","workspaceId","runRows","jobRows","jobId","runningRuns","runningJobExecutions","getWorkflowRunDetail","target","currentAttempt","latestAttempt","job","jobExecution","step","stepAttempt","leftJoin","jobExecutionId","stepId","position","sequence","executionOrder","hydrateWorkflowRunDetail","getJobExecutionDetail","first","detail","stepById","Map","getOrCreateStepDetail","attempts","runAttempt","jobById","jobExecutionById","get","set"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/db/workflow-runs/queries.ts"],"sourcesContent":["import {WORKFLOW_RUN_JOB_PREVIEW_LIMIT} from '@shipfox/api-workflows-dto';\nimport {\n paginateTimestampIdRows,\n type TimestampIdCursor,\n timestampIdCursorWhere,\n} from '@shipfox/node-drizzle';\nimport {and, asc, count, desc, eq, gte, lte, type SQL, sql} from 'drizzle-orm';\nimport type {JobStatus} from '#core/entities/job.js';\nimport type {\n JobExecutionDetail,\n StepDetail,\n WorkflowJobDetail,\n WorkflowRun,\n WorkflowRunDetail,\n WorkflowRunStatus,\n} from '#core/entities/workflow-run.js';\nimport {db} from '../db.js';\nimport {jobExecutions, toJobExecution} from '../schema/job-executions.js';\nimport {jobs, toJob} from '../schema/jobs.js';\nimport {stepAttempts, toStepAttempt} from '../schema/step-attempts.js';\nimport {steps, toStep} from '../schema/steps.js';\nimport {toWorkflowRunAttempt, workflowRunAttempts} from '../schema/workflow-run-attempts.js';\nimport {toWorkflowRun, workflowRuns} from '../schema/workflow-runs.js';\n\nexport type WorkflowRunCursor = TimestampIdCursor;\n\nexport interface WorkflowRunFilters {\n status?: WorkflowRunStatus | undefined;\n definitionId?: string | undefined;\n triggerSource?: string | undefined;\n createdFrom?: Date | undefined;\n createdTo?: Date | undefined;\n}\n\nexport interface ListWorkflowRunsParams {\n projectId: string;\n limit: number;\n cursor?: WorkflowRunCursor | undefined;\n filters?: WorkflowRunFilters | undefined;\n includeTotal?: boolean | undefined;\n}\n\nexport interface ListWorkflowRunsResult {\n runs: WorkflowRun[];\n nextCursor: WorkflowRunCursor | null;\n filteredTotalCount: number | null;\n}\n\n/** A run-list job glyph: enough to draw and label it, none of its steps. */\nexport interface WorkflowRunJobSummary {\n id: string;\n key: string;\n name: string | null;\n status: JobStatus;\n position: number;\n}\n\nexport interface WorkflowRunAggregates {\n status: Array<{value: WorkflowRunStatus; count: number}>;\n triggerSource: Array<{value: string; count: number}>;\n workflow: Array<{value: string; count: number}>;\n}\n\nexport interface WorkflowJobExecutionDepth {\n runningRuns: number;\n runningJobExecutions: number;\n}\n\nexport interface WorkflowJobExecutionDepthParams {\n workspaceId?: string;\n}\n\nexport async function getWorkflowRunById(id: string): Promise<WorkflowRun | undefined> {\n const rows = await db().select().from(workflowRuns).where(eq(workflowRuns.id, id)).limit(1);\n const row = rows[0];\n if (!row) return undefined;\n return toWorkflowRun(row);\n}\n\nexport async function getWorkflowRunByAttemptId(\n workflowRunAttemptId: string,\n): Promise<WorkflowRun | undefined> {\n const rows = await db()\n .select({run: workflowRuns})\n .from(workflowRunAttempts)\n .innerJoin(workflowRuns, eq(workflowRunAttempts.workflowRunId, workflowRuns.id))\n .where(eq(workflowRunAttempts.id, workflowRunAttemptId))\n .limit(1);\n const row = rows[0];\n return row ? toWorkflowRun(row.run) : undefined;\n}\n\nexport async function getWorkflowRunAttemptById(workflowRunAttemptId: string) {\n const rows = await db()\n .select()\n .from(workflowRunAttempts)\n .where(eq(workflowRunAttempts.id, workflowRunAttemptId))\n .limit(1);\n const row = rows[0];\n return row ? toWorkflowRunAttempt(row) : undefined;\n}\n\nexport async function listRunAttempts(params: {workflowRunId: string; projectId: string}) {\n return (\n await db()\n .select({\n attempt: workflowRunAttempts,\n })\n .from(workflowRunAttempts)\n .innerJoin(workflowRuns, eq(workflowRunAttempts.workflowRunId, workflowRuns.id))\n .where(\n and(\n eq(workflowRunAttempts.workflowRunId, params.workflowRunId),\n eq(workflowRuns.projectId, params.projectId),\n ),\n )\n .orderBy(asc(workflowRunAttempts.attempt))\n ).map((row) => toWorkflowRunAttempt(row.attempt));\n}\n\nexport async function getLatestAttempt(params: {\n workflowRunId: string;\n projectId: string;\n}): Promise<number> {\n const [row] = await db()\n .select({value: sql<number>`coalesce(max(${workflowRunAttempts.attempt}), 1)`})\n .from(workflowRunAttempts)\n .innerJoin(workflowRuns, eq(workflowRunAttempts.workflowRunId, workflowRuns.id))\n .where(\n and(\n eq(workflowRunAttempts.workflowRunId, params.workflowRunId),\n eq(workflowRuns.projectId, params.projectId),\n ),\n )\n .limit(1);\n\n return Number(row?.value ?? 1);\n}\n\nexport function buildWorkflowRunListConditions(params: {\n projectId: string;\n filters?: WorkflowRunFilters | undefined;\n cursor?: WorkflowRunCursor | undefined;\n omit?: 'status' | 'definitionId' | 'triggerSource' | undefined;\n}): SQL[] {\n const filters = params.filters;\n const conditions: SQL[] = [eq(workflowRuns.projectId, params.projectId)];\n const cursorCondition = timestampIdCursorWhere({\n timestampColumn: workflowRuns.createdAt,\n idColumn: workflowRuns.id,\n cursor: params.cursor,\n });\n if (cursorCondition) conditions.push(cursorCondition);\n if (filters?.status && params.omit !== 'status') {\n conditions.push(eq(workflowRuns.status, filters.status));\n }\n if (filters?.definitionId && params.omit !== 'definitionId') {\n conditions.push(eq(workflowRuns.definitionId, filters.definitionId));\n }\n if (filters?.triggerSource && params.omit !== 'triggerSource') {\n conditions.push(eq(workflowRuns.triggerSource, filters.triggerSource));\n }\n if (filters?.createdFrom) {\n conditions.push(gte(workflowRuns.createdAt, filters.createdFrom));\n }\n if (filters?.createdTo) {\n conditions.push(lte(workflowRuns.createdAt, filters.createdTo));\n }\n return conditions;\n}\n\nexport async function listWorkflowRuns(\n params: ListWorkflowRunsParams,\n): Promise<ListWorkflowRunsResult> {\n const conditions = buildWorkflowRunListConditions(params);\n const rows = await db()\n .select()\n .from(workflowRuns)\n .where(and(...conditions))\n .orderBy(desc(workflowRuns.createdAt), desc(workflowRuns.id))\n .limit(params.limit + 1);\n\n let totalCount: number | null = null;\n if (params.includeTotal) {\n const [{value} = {value: 0}] = await db()\n .select({value: count()})\n .from(workflowRuns)\n .where(\n and(\n ...buildWorkflowRunListConditions({projectId: params.projectId, filters: params.filters}),\n ),\n );\n totalCount = value;\n }\n\n const page = paginateTimestampIdRows({rows, limit: params.limit, timestampKey: 'createdAt'});\n\n return {\n runs: page.pageRows.map(toWorkflowRun),\n nextCursor: page.nextCursor,\n filteredTotalCount: totalCount,\n };\n}\n\n/** The run whose jobs to fetch, pinned to the attempt the caller already read. */\nexport interface WorkflowRunJobSummaryTarget {\n id: string;\n currentAttempt: number;\n}\n\n/**\n * A page row's jobs: a bounded slice to draw, and totals describing all of them.\n *\n * The preview is what a row can show; `statusCounts` is what it can say. Keeping the counts\n * server-side is what lets a row report a failure that sits past the preview.\n */\nexport interface WorkflowRunJobsSummary {\n preview: WorkflowRunJobSummary[];\n statusCounts: WorkflowRunJobStatusCount[];\n}\n\nexport interface WorkflowRunJobStatusCount {\n status: JobStatus;\n count: number;\n}\n\n/**\n * Jobs for a page of runs, keyed by run id.\n *\n * Issued once per page rather than once per run: the run list is the one surface that needs\n * every run's jobs at once, and a per-row query would put 50 round trips behind it.\n *\n * Both reads are bounded by the page, not by workflow size. A workflow has no job limit and\n * this list polls while runs are active, so returning every job of every row would let one\n * large workflow decide how much the endpoint moves every four seconds. The preview is cut\n * per run in the database, and everything past it is described by a grouped count instead.\n *\n * The attempt comes from the caller's own read rather than from a second look at\n * `current_attempt`. Re-reading it here would let a re-run landing between the queries pair\n * attempt 1's run metadata with attempt 2's jobs, and the row would report a status its strip\n * contradicts.\n *\n * The two reads share one repeatable-read snapshot. They describe the same jobs at the same\n * instant, and the strip combines them into a single glyph row, so under the default\n * read-committed isolation a job settling between the statements would draw a pending glyph\n * beside a summary counting it as failed. Sequential inside one transaction is the cost of\n * that; at a four-second poll the extra round trip does not register.\n */\nexport async function listWorkflowRunJobSummaries(\n runs: readonly WorkflowRunJobSummaryTarget[],\n): Promise<Map<string, WorkflowRunJobsSummary>> {\n const summaries = new Map<string, WorkflowRunJobsSummary>();\n if (runs.length === 0) return summaries;\n\n // A row-constructor IN over (run, attempt) so each pair is one lookup on the unique index\n // that already covers those two columns.\n const attemptPairs = sql.join(\n runs.map((run) => sql`(${run.id}::uuid, ${run.currentAttempt})`),\n sql`, `,\n );\n const attemptFilter = sql`(${workflowRunAttempts.workflowRunId}, ${workflowRunAttempts.attempt}) in (${attemptPairs})`;\n\n const {previewRows, countRows} = await db().transaction(\n async (tx) => {\n const ranked = tx\n .select({\n workflowRunId: workflowRunAttempts.workflowRunId,\n id: jobs.id,\n key: jobs.key,\n name: jobs.name,\n status: jobs.status,\n position: jobs.position,\n rank: sql<number>`row_number() over (partition by ${workflowRunAttempts.workflowRunId} order by ${jobs.position} asc, ${jobs.id} asc)`.as(\n 'rank',\n ),\n })\n .from(jobs)\n .innerJoin(workflowRunAttempts, eq(jobs.workflowRunAttemptId, workflowRunAttempts.id))\n .where(attemptFilter)\n .as('ranked');\n\n return {\n previewRows: await tx\n .select({\n workflowRunId: ranked.workflowRunId,\n id: ranked.id,\n key: ranked.key,\n name: ranked.name,\n status: ranked.status,\n position: ranked.position,\n })\n .from(ranked)\n .where(lte(ranked.rank, WORKFLOW_RUN_JOB_PREVIEW_LIMIT))\n .orderBy(asc(ranked.workflowRunId), asc(ranked.position), asc(ranked.id)),\n countRows: await tx\n .select({\n workflowRunId: workflowRunAttempts.workflowRunId,\n status: jobs.status,\n count: count(),\n })\n .from(jobs)\n .innerJoin(workflowRunAttempts, eq(jobs.workflowRunAttemptId, workflowRunAttempts.id))\n .where(attemptFilter)\n .groupBy(workflowRunAttempts.workflowRunId, jobs.status),\n };\n },\n {isolationLevel: 'repeatable read', accessMode: 'read only'},\n );\n\n for (const {workflowRunId, ...summary} of previewRows) {\n summaryFor(summaries, workflowRunId).preview.push(summary);\n }\n for (const {workflowRunId, status, count: statusCount} of countRows) {\n summaryFor(summaries, workflowRunId).statusCounts.push({status, count: statusCount});\n }\n\n return summaries;\n}\n\nfunction summaryFor(\n summaries: Map<string, WorkflowRunJobsSummary>,\n workflowRunId: string,\n): WorkflowRunJobsSummary {\n const existing = summaries.get(workflowRunId);\n if (existing) return existing;\n const created: WorkflowRunJobsSummary = {preview: [], statusCounts: []};\n summaries.set(workflowRunId, created);\n return created;\n}\n\nexport async function listWorkflowRunsByProject(projectId: string): Promise<WorkflowRun[]> {\n const result = await listWorkflowRuns({projectId, limit: 100});\n return result.runs;\n}\n\nexport async function getWorkflowRunAggregates(params: {\n projectId: string;\n filters?: WorkflowRunFilters | undefined;\n}): Promise<WorkflowRunAggregates> {\n const [statusRows, triggerRows, workflowRows] = await Promise.all([\n db()\n .select({value: workflowRuns.status, count: count()})\n .from(workflowRuns)\n .where(\n and(\n ...buildWorkflowRunListConditions({\n projectId: params.projectId,\n filters: params.filters,\n omit: 'status',\n }),\n ),\n )\n .groupBy(workflowRuns.status),\n db()\n .select({value: workflowRuns.triggerSource, count: count()})\n .from(workflowRuns)\n .where(\n and(\n ...buildWorkflowRunListConditions({\n projectId: params.projectId,\n filters: params.filters,\n omit: 'triggerSource',\n }),\n ),\n )\n .groupBy(workflowRuns.triggerSource),\n db()\n .select({value: workflowRuns.definitionId, count: count()})\n .from(workflowRuns)\n .where(\n and(\n ...buildWorkflowRunListConditions({\n projectId: params.projectId,\n filters: params.filters,\n omit: 'definitionId',\n }),\n ),\n )\n .groupBy(workflowRuns.definitionId),\n ]);\n\n return {\n status: statusRows,\n triggerSource: triggerRows,\n workflow: workflowRows,\n };\n}\n\nexport async function getWorkflowJobExecutionDepth(\n params: WorkflowJobExecutionDepthParams = {},\n): Promise<WorkflowJobExecutionDepth> {\n const runConditions = [eq(workflowRuns.status, 'running')];\n const jobConditions = [eq(jobExecutions.status, 'running')];\n if (params.workspaceId) {\n runConditions.push(eq(workflowRuns.workspaceId, params.workspaceId));\n jobConditions.push(eq(workflowRuns.workspaceId, params.workspaceId));\n }\n\n const [runRows, jobRows] = await Promise.all([\n db()\n .select({value: count()})\n .from(workflowRuns)\n .where(and(...runConditions)),\n db()\n .select({value: count()})\n .from(jobExecutions)\n .innerJoin(jobs, eq(jobExecutions.jobId, jobs.id))\n .innerJoin(workflowRunAttempts, eq(jobs.workflowRunAttemptId, workflowRunAttempts.id))\n .innerJoin(workflowRuns, eq(workflowRunAttempts.workflowRunId, workflowRuns.id))\n .where(and(...jobConditions)),\n ]);\n\n return {\n runningRuns: runRows[0]?.value ?? 0,\n runningJobExecutions: jobRows[0]?.value ?? 0,\n };\n}\n\nexport async function getWorkflowRunDetail(\n workflowRunId: string,\n attempt?: number | undefined,\n): Promise<WorkflowRunDetail | undefined> {\n const [target] = await db()\n .select({run: workflowRuns, attempt: workflowRunAttempts})\n .from(workflowRuns)\n .innerJoin(\n workflowRunAttempts,\n and(\n eq(workflowRunAttempts.workflowRunId, workflowRuns.id),\n eq(workflowRunAttempts.attempt, attempt ?? workflowRuns.currentAttempt),\n ),\n )\n .where(eq(workflowRuns.id, workflowRunId))\n .limit(1);\n if (!target) return undefined;\n\n const latestAttempt = await getLatestAttempt({\n workflowRunId: target.run.id,\n projectId: target.run.projectId,\n });\n\n const rows = await db()\n .select({\n run: workflowRuns,\n job: jobs,\n jobExecution: jobExecutions,\n step: steps,\n stepAttempt: stepAttempts,\n })\n .from(workflowRuns)\n .innerJoin(workflowRunAttempts, eq(workflowRunAttempts.id, target.attempt.id))\n .leftJoin(jobs, eq(jobs.workflowRunAttemptId, workflowRunAttempts.id))\n .leftJoin(jobExecutions, eq(jobExecutions.jobId, jobs.id))\n .leftJoin(steps, eq(steps.jobExecutionId, jobExecutions.id))\n .leftJoin(stepAttempts, eq(stepAttempts.stepId, steps.id))\n .where(eq(workflowRuns.id, workflowRunId))\n .orderBy(\n asc(jobs.position),\n asc(jobs.id),\n asc(jobExecutions.sequence),\n asc(jobExecutions.id),\n asc(steps.position),\n asc(steps.id),\n asc(stepAttempts.executionOrder),\n asc(stepAttempts.id),\n );\n\n return hydrateWorkflowRunDetail(rows, target.attempt, latestAttempt);\n}\n\nexport async function getJobExecutionDetail(\n jobExecutionId: string,\n): Promise<JobExecutionDetail | undefined> {\n const rows = await db()\n .select({\n job: jobs,\n jobExecution: jobExecutions,\n step: steps,\n stepAttempt: stepAttempts,\n })\n .from(jobExecutions)\n .innerJoin(jobs, eq(jobExecutions.jobId, jobs.id))\n .innerJoin(workflowRunAttempts, eq(jobs.workflowRunAttemptId, workflowRunAttempts.id))\n .innerJoin(workflowRuns, eq(workflowRunAttempts.workflowRunId, workflowRuns.id))\n .leftJoin(steps, eq(steps.jobExecutionId, jobExecutions.id))\n .leftJoin(stepAttempts, eq(stepAttempts.stepId, steps.id))\n .where(eq(jobExecutions.id, jobExecutionId))\n .orderBy(\n asc(steps.position),\n asc(steps.id),\n asc(stepAttempts.executionOrder),\n asc(stepAttempts.id),\n );\n\n const first = rows[0];\n if (!first) return undefined;\n\n const detail: JobExecutionDetail = {\n ...toJobExecution(first.jobExecution, first.job.name ?? first.job.key),\n steps: [],\n };\n const stepById = new Map<string, StepDetail>();\n for (const row of rows) {\n if (row.step) {\n const step = getOrCreateStepDetail(stepById, detail.steps, row.step);\n if (row.stepAttempt) {\n step.attempts.push(toStepAttempt(row.stepAttempt));\n }\n }\n }\n\n return detail;\n}\n\nfunction hydrateWorkflowRunDetail(\n rows: {\n run: typeof workflowRuns.$inferSelect;\n job: typeof jobs.$inferSelect | null;\n jobExecution: typeof jobExecutions.$inferSelect | null;\n step: typeof steps.$inferSelect | null;\n stepAttempt: typeof stepAttempts.$inferSelect | null;\n }[],\n attempt: typeof workflowRunAttempts.$inferSelect,\n latestAttempt: number,\n): WorkflowRunDetail | undefined {\n const first = rows[0];\n if (!first) return undefined;\n\n const detail: WorkflowRunDetail = {\n ...toWorkflowRun(first.run),\n runAttempt: toWorkflowRunAttempt(attempt),\n latestAttempt,\n jobs: [],\n };\n const jobById = new Map<string, WorkflowJobDetail>();\n const jobExecutionById = new Map<string, JobExecutionDetail>();\n const stepById = new Map<string, StepDetail>();\n\n for (const row of rows) {\n if (!row.job) continue;\n let job = jobById.get(row.job.id);\n if (!job) {\n job = {...toJob(row.job), jobExecutions: []};\n jobById.set(row.job.id, job);\n detail.jobs.push(job);\n }\n\n if (!row.jobExecution) continue;\n let jobExecution = jobExecutionById.get(row.jobExecution.id);\n if (!jobExecution) {\n jobExecution = {\n ...toJobExecution(row.jobExecution, row.job.name ?? row.job.key),\n steps: [],\n };\n jobExecutionById.set(row.jobExecution.id, jobExecution);\n job.jobExecutions.push(jobExecution);\n }\n\n if (!row.step) continue;\n const step = getOrCreateStepDetail(stepById, jobExecution.steps, row.step);\n if (row.stepAttempt) {\n step.attempts.push(toStepAttempt(row.stepAttempt));\n }\n }\n\n return detail;\n}\n\nfunction getOrCreateStepDetail(\n stepById: Map<string, StepDetail>,\n target: StepDetail[],\n row: typeof steps.$inferSelect,\n): StepDetail {\n let step = stepById.get(row.id);\n if (!step) {\n step = {...toStep(row), attempts: []};\n stepById.set(row.id, step);\n target.push(step);\n }\n return step;\n}\n"],"names":["WORKFLOW_RUN_JOB_PREVIEW_LIMIT","paginateTimestampIdRows","timestampIdCursorWhere","and","asc","count","desc","eq","gte","lte","sql","db","jobExecutions","toJobExecution","jobs","toJob","stepAttempts","toStepAttempt","steps","toStep","toWorkflowRunAttempt","workflowRunAttempts","toWorkflowRun","workflowRuns","getWorkflowRunById","id","rows","select","from","where","limit","row","undefined","getWorkflowRunByAttemptId","workflowRunAttemptId","run","innerJoin","workflowRunId","getWorkflowRunAttemptById","listRunAttempts","params","attempt","projectId","orderBy","map","getLatestAttempt","value","Number","buildWorkflowRunListConditions","filters","conditions","cursorCondition","timestampColumn","createdAt","idColumn","cursor","push","status","omit","definitionId","triggerSource","createdFrom","createdTo","listWorkflowRuns","totalCount","includeTotal","page","timestampKey","runs","pageRows","nextCursor","filteredTotalCount","listWorkflowRunJobSummaries","summaries","Map","length","attemptPairs","join","currentAttempt","attemptFilter","previewRows","countRows","transaction","tx","ranked","key","name","position","rank","as","groupBy","isolationLevel","accessMode","summary","summaryFor","preview","statusCount","statusCounts","existing","get","created","set","listWorkflowRunsByProject","result","getWorkflowRunAggregates","statusRows","triggerRows","workflowRows","Promise","all","workflow","getWorkflowJobExecutionDepth","runConditions","jobConditions","workspaceId","runRows","jobRows","jobId","runningRuns","runningJobExecutions","getWorkflowRunDetail","target","latestAttempt","job","jobExecution","step","stepAttempt","leftJoin","jobExecutionId","stepId","sequence","executionOrder","hydrateWorkflowRunDetail","getJobExecutionDetail","first","detail","stepById","getOrCreateStepDetail","attempts","runAttempt","jobById","jobExecutionById"],"mappings":"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"}
@@ -19,6 +19,7 @@ export interface CreateWorkflowRunParams {
19
19
  name?: string | undefined;
20
20
  model: WorkflowModel;
21
21
  triggerPayload: TriggerPayload;
22
+ triggerConnectionId?: string | undefined;
22
23
  inputs?: Record<string, unknown> | undefined;
23
24
  sourceSnapshot?: WorkflowSourceSnapshot | null | undefined;
24
25
  triggerIdempotencyKey?: string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"run-create.d.ts","sourceRoot":"","sources":["../../../src/db/workflow-runs/run-create.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,KAAK,aAAa,EAAC,MAAM,8BAA8B,CAAC;AAC7F,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,gDAAgD,CAAC;AAC7F,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,wCAAwC,CAAC;AACjF,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,uCAAuC,CAAC;AAIpF,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,yBAAyB,CAAC;AAKnE,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,sBAAsB,EACvB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAC,8BAA8B,EAAC,MAAM,iBAAiB,CAAC;AAa/D,MAAM,MAAM,gBAAgB,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,8BAA8B,CAAC,OAAO,CAAC,CAAC;IACxD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,KAAK,EAAE,aAAa,CAAC;IACrB,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC7C,cAAc,CAAC,EAAE,sBAAsB,GAAG,IAAI,GAAG,SAAS,CAAC;IAC3D,qBAAqB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,oBAAoB,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;IACzD,OAAO,CAAC,EAAE,IAAI,CAAC,wBAAwB,EAAE,yBAAyB,CAAC,GAAG,SAAS,CAAC;IAChF,YAAY,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;IACpD,QAAQ,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;CAC7C;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,WAAW,CAAC,CA6H7F;AAED,wBAAsB,uBAAuB,CAAC,MAAM,EAAE;IACpD,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,gBAAgB,EAAE,GAAG,SAAS,CAAC;IACxD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,wBAAwB,EAAE,yBAAyB,CAAC,GAAG,SAAS,CAAC;CAC1F,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,CAsB9C"}
1
+ {"version":3,"file":"run-create.d.ts","sourceRoot":"","sources":["../../../src/db/workflow-runs/run-create.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,gDAAgD,CAAC;AAC7F,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,wCAAwC,CAAC;AACjF,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,uCAAuC,CAAC;AAQpF,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,yBAAyB,CAAC;AAKnE,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,sBAAsB,EACvB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAC,8BAA8B,EAAC,MAAM,iBAAiB,CAAC;AAoB/D,MAAM,MAAM,gBAAgB,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,8BAA8B,CAAC,OAAO,CAAC,CAAC;IACxD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,KAAK,EAAE,aAAa,CAAC;IACrB,cAAc,EAAE,cAAc,CAAC;IAC/B,mBAAmB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC7C,cAAc,CAAC,EAAE,sBAAsB,GAAG,IAAI,GAAG,SAAS,CAAC;IAC3D,qBAAqB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,oBAAoB,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;IACzD,OAAO,CAAC,EAAE,IAAI,CAAC,wBAAwB,EAAE,yBAAyB,CAAC,GAAG,SAAS,CAAC;IAChF,YAAY,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;IACpD,QAAQ,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;CAC7C;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,WAAW,CAAC,CAqM7F;AAeD,wBAAsB,uBAAuB,CAAC,MAAM,EAAE;IACpD,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,gBAAgB,EAAE,GAAG,SAAS,CAAC;IACxD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,wBAAwB,EAAE,yBAAyB,CAAC,GAAG,SAAS,CAAC;CAC1F,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,CAkC9C"}
@@ -1,16 +1,28 @@
1
- import { createWorkflowModelSnapshot } from '@shipfox/api-definitions-dto';
1
+ import { createWorkflowModelSnapshot, WORKFLOW_MODEL_CHECKOUT_TARGET_FIELDS } from '@shipfox/api-definitions-dto';
2
2
  import { analyzeContextKeyAccess } from '@shipfox/expression';
3
3
  import { logger } from '@shipfox/node-opentelemetry';
4
- import { eq } from 'drizzle-orm';
4
+ import { eq, sql } from 'drizzle-orm';
5
5
  import { createAgentToolMaterializationSnapshot, loadAgentToolMaterializationContext } from '#core/agent-tools.js';
6
6
  import { InterpolationUnresolvableError } from '#core/errors.js';
7
+ import { resolveWorkflowRunTriggerReference } from '#core/resolve-trigger-reference.js';
8
+ import { assembleCreationContext } from '#core/step-config/assemble-run-context.js';
9
+ import { resolveWorkflowRunName } from '#core/step-config/resolve-workflow-run-name.js';
7
10
  import { deriveInitialJobExecutionPlan, materializeWorkflowRunJobs } from '#core/workflow-run-creation.js';
8
- import { recordWorkflowRunCreated } from '#metrics/instance.js';
11
+ import { recordWorkflowDisplayNameResolutionDegraded, recordWorkflowRunCreated } from '#metrics/instance.js';
9
12
  import { db } from '../db.js';
10
13
  import { workflowRunAttempts } from '../schema/workflow-run-attempts.js';
14
+ import { workflowRunCounters } from '../schema/workflow-run-counters.js';
11
15
  import { toWorkflowRun, workflowRuns } from '../schema/workflow-runs.js';
12
16
  import { persistMaterializedRunGraph } from './run-graph.js';
13
17
  export async function createWorkflowRun(params) {
18
+ const triggerReference = await resolveWorkflowRunTriggerReference({
19
+ workspaceId: params.workspaceId,
20
+ triggerConnectionId: params.triggerConnectionId,
21
+ triggerPayload: params.triggerPayload,
22
+ integrations: params.integrations,
23
+ projects: params.projects
24
+ });
25
+ const staticName = params.name ?? params.model.name;
14
26
  const agentToolContext = params.integrations === undefined ? undefined : await loadAgentToolMaterializationContext({
15
27
  model: params.model,
16
28
  workspaceId: params.workspaceId,
@@ -23,17 +35,35 @@ export async function createWorkflowRun(params) {
23
35
  context: agentToolContext
24
36
  });
25
37
  const result = await db().transaction(async (tx)=>{
38
+ // Serialize idempotent trigger resolution separately from per-definition number
39
+ // allocation so a replay never consumes a number, including when two deliveries
40
+ // race before either run is visible.
41
+ if (params.triggerIdempotencyKey) {
42
+ await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${params.triggerIdempotencyKey}))`);
43
+ const existing = await tx.select().from(workflowRuns).where(eq(workflowRuns.triggerIdempotencyKey, params.triggerIdempotencyKey)).limit(1);
44
+ const existingRow = existing[0];
45
+ if (existingRow) return {
46
+ run: toWorkflowRun(existingRow),
47
+ created: false
48
+ };
49
+ }
50
+ // Keep allocation on the existing transaction so a trigger burst cannot pin
51
+ // every pool connection and then wait for a second connection per run.
52
+ const number = await allocateWorkflowRunNumber(tx, params.definitionId);
26
53
  const insertResult = await tx.insert(workflowRuns).values({
27
54
  workspaceId: params.workspaceId,
28
55
  projectId: params.projectId,
29
56
  definitionId: params.definitionId,
30
- name: params.name ?? params.model.name,
57
+ number,
58
+ name: null,
59
+ workflowName: staticName,
31
60
  status: 'pending',
32
61
  currentAttempt: 1,
33
62
  triggerProvider: params.triggerPayload.provider ?? null,
34
63
  triggerSource: params.triggerPayload.source,
35
64
  triggerEvent: params.triggerPayload.event,
36
65
  triggerPayload: params.triggerPayload,
66
+ triggerReference,
37
67
  inputs: params.inputs ?? null,
38
68
  sourceSnapshot: params.sourceSnapshot ?? null,
39
69
  triggerIdempotencyKey: params.triggerIdempotencyKey ?? null
@@ -56,18 +86,12 @@ export async function createWorkflowRun(params) {
56
86
  created: false
57
87
  };
58
88
  }
59
- const run = toWorkflowRun(runRow);
60
- const [attemptRow] = await tx.insert(workflowRunAttempts).values({
61
- workflowRunId: runRow.id,
62
- attempt: 1,
63
- status: 'pending',
64
- model: createWorkflowModelSnapshot(params.model),
65
- agentToolMaterialization
66
- }).returning();
67
- if (!attemptRow) throw new Error('Insert returned no rows');
68
- // Resolving one-shot templates here gives interpolation access to the inserted run id.
69
- // If resolution fails, the transaction rolls back the run, jobs, steps, and outbox event together.
70
- // Listening steps are resolved later when a job execution is created.
89
+ // Resolving run-creation templates and predicates here gives them a stable variable snapshot
90
+ // and interpolation access to the inserted run id. Run-name resolution is display-only and
91
+ // persists only a resolved override. If resolution fails, the transaction rolls back the run,
92
+ // jobs, steps, and outbox event together. Listening steps are resolved later when a job
93
+ // execution is created.
94
+ const provisionalRun = toWorkflowRun(runRow);
71
95
  const oneShotJobs = params.model.jobs.filter((job)=>job.mode !== 'listening');
72
96
  const vars = await loadReferencedVariables({
73
97
  model: params.model,
@@ -77,6 +101,30 @@ export async function createWorkflowRun(params) {
77
101
  definitionId: params.definitionId,
78
102
  secrets: params.secrets
79
103
  });
104
+ const runNameResolution = resolveWorkflowRunName({
105
+ runName: params.model.runName,
106
+ context: assembleCreationContext({
107
+ run: provisionalRun,
108
+ triggerPayload: params.triggerPayload,
109
+ inputs: params.inputs ?? null,
110
+ vars
111
+ }).values
112
+ });
113
+ const [resolvedRunRow] = await tx.update(workflowRuns).set({
114
+ name: runNameResolution.value,
115
+ updatedAt: new Date()
116
+ }).where(eq(workflowRuns.id, provisionalRun.id)).returning();
117
+ if (!resolvedRunRow) throw new Error(`Workflow run missing after name resolution: ${runRow.id}`);
118
+ const run = toWorkflowRun(resolvedRunRow);
119
+ const [attemptRow] = await tx.insert(workflowRunAttempts).values({
120
+ workflowRunId: runRow.id,
121
+ attempt: 1,
122
+ status: 'pending',
123
+ model: createWorkflowModelSnapshot(params.model),
124
+ vars,
125
+ agentToolMaterialization
126
+ }).returning();
127
+ if (!attemptRow) throw new Error('Insert returned no rows');
80
128
  const materializedJobs = await materializeWorkflowRunJobs({
81
129
  run,
82
130
  model: params.model,
@@ -109,27 +157,65 @@ export async function createWorkflowRun(params) {
109
157
  });
110
158
  return {
111
159
  run,
112
- created: true
160
+ created: true,
161
+ nameDegradation: runNameResolution.degradation
113
162
  };
114
163
  });
115
- if (result.created) recordWorkflowRunCreated(result.run.triggerPayload.provider ?? result.run.triggerSource);
164
+ if (result.created && result.nameDegradation !== undefined) {
165
+ recordWorkflowDisplayNameResolutionDegraded('workflow.run_name', result.nameDegradation.cause);
166
+ logger().warn({
167
+ workflowRunId: result.run.id,
168
+ definitionId: result.run.definitionId,
169
+ field: 'workflow.run_name',
170
+ cause: result.nameDegradation.cause,
171
+ ...result.nameDegradation.expression === undefined ? {} : {
172
+ expression: result.nameDegradation.expression.slice(0, 256)
173
+ }
174
+ }, 'Workflow run name resolution degraded to the static workflow name');
175
+ }
176
+ if (result.created) {
177
+ recordWorkflowRunCreated(result.run.triggerPayload.provider ?? result.run.triggerSource);
178
+ }
116
179
  return result.run;
117
180
  }
181
+ async function allocateWorkflowRunNumber(tx, definitionId) {
182
+ const [counterRow] = await tx.insert(workflowRunCounters).values({
183
+ definitionId,
184
+ nextNumber: 2
185
+ }).onConflictDoUpdate({
186
+ target: workflowRunCounters.definitionId,
187
+ set: {
188
+ nextNumber: sql`${workflowRunCounters.nextNumber} + 1`
189
+ }
190
+ }).returning({
191
+ number: sql`${workflowRunCounters.nextNumber} - 1`
192
+ });
193
+ if (!counterRow) throw new Error('Run counter allocation returned no rows');
194
+ return counterRow.number;
195
+ }
118
196
  export async function loadReferencedVariables(params) {
119
197
  const references = referencedVariables(params.model, params.jobs ?? params.model.jobs);
120
198
  const keys = [
121
199
  ...new Set(references.map((reference)=>reference.key))
122
200
  ].sort();
123
201
  if (keys.length === 0) return undefined;
124
- if (!params.secrets) throw new Error('Secrets client is not configured.');
202
+ const requiresSecrets = (reference)=>reference.field !== 'job.execution_name' && reference.field !== 'workflow.run_name';
203
+ const requiredReferences = references.filter(requiresSecrets);
204
+ const requiredKeys = new Set(requiredReferences.map((reference)=>reference.key));
205
+ if (!params.secrets) {
206
+ if (requiredKeys.size === 0) return undefined;
207
+ throw new Error('Secrets client is not configured.');
208
+ }
125
209
  const { values: vars } = await params.secrets.getVariablesByNamespace({
126
210
  workspaceId: params.workspaceId,
127
211
  projectId: params.projectId,
128
212
  namespace: ''
129
213
  });
130
- const missingKey = keys.find((key)=>!(key in vars));
214
+ const missingKey = [
215
+ ...requiredKeys
216
+ ].find((key)=>!(key in vars));
131
217
  if (missingKey !== undefined) {
132
- const reference = references.find((candidate)=>candidate.key === missingKey);
218
+ const reference = requiredReferences.find((candidate)=>candidate.key === missingKey);
133
219
  throw new InterpolationUnresolvableError(params.definitionId, {
134
220
  field: reference?.field ?? 'env',
135
221
  source: reference?.source ?? `vars.${missingKey}`,
@@ -138,14 +224,19 @@ export async function loadReferencedVariables(params) {
138
224
  }
139
225
  });
140
226
  }
141
- return vars;
227
+ const referencedVars = {};
228
+ for (const key of keys){
229
+ const value = vars[key];
230
+ if (value !== undefined) referencedVars[key] = value;
231
+ }
232
+ return referencedVars;
142
233
  }
143
234
  function materializeRunGraphJobs(params) {
144
235
  return params.materializedJobs.map((job, jobIndex)=>({
145
236
  job: {
146
237
  key: job.key,
147
238
  mode: job.mode,
148
- name: workflowTemplateSource(job.name),
239
+ name: job.name ?? null,
149
240
  status: 'pending',
150
241
  checkoutPersistCredentials: job.checkout.persistCredentials,
151
242
  checkoutPermissionsContents: job.checkout.permissions.contents,
@@ -173,7 +264,7 @@ function materializeRunGraphJobs(params) {
173
264
  },
174
265
  createExecution: (jobRow)=>{
175
266
  if (jobRow.mode === 'listening') return undefined;
176
- const fallbackName = `${jobRow.key} #1`;
267
+ const fallbackName = jobRow.name ?? jobRow.key;
177
268
  const modelJob = params.params.model.jobs[jobIndex];
178
269
  if (!modelJob) return undefined;
179
270
  const executionPlan = deriveInitialJobExecutionPlan({
@@ -189,7 +280,9 @@ function materializeRunGraphJobs(params) {
189
280
  });
190
281
  return {
191
282
  sequence: 1,
192
- name: executionPlan.name,
283
+ // Persist only the resolved override. The core entity supplies the
284
+ // static job name/key when this is null.
285
+ name: executionPlan.nameOverride,
193
286
  runner: [
194
287
  ...executionPlan.runner
195
288
  ],
@@ -213,12 +306,29 @@ function materializeRunGraphJobs(params) {
213
306
  }
214
307
  function referencedVariables(model, jobs) {
215
308
  const references = [];
309
+ for (const job of model.jobs){
310
+ collectPredicateVariableReferences(job.if, references);
311
+ collectPredicateVariableReferences(job.success, references);
312
+ for (const trigger of [
313
+ ...job.listening?.on ?? [],
314
+ ...job.listening?.until ?? []
315
+ ]){
316
+ collectPredicateVariableReferences(trigger.filter, references);
317
+ }
318
+ for (const step of job.steps){
319
+ collectPredicateVariableReferences(step.if, references);
320
+ collectPredicateVariableReferences(step.gate?.success, references);
321
+ }
322
+ }
323
+ collectFieldVariableReferences(model.runName, references, {
324
+ field: 'workflow.run_name'
325
+ });
216
326
  if (jobs.length > 0) {
217
327
  collectTemplateVariableReferences(model.templates?.env, references);
218
328
  }
219
329
  for (const job of jobs){
220
- collectFieldVariableReferences(job.name, references, {
221
- field: 'job.name'
330
+ collectFieldVariableReferences(job.executionName, references, {
331
+ field: 'job.execution_name'
222
332
  });
223
333
  for (const template of job.runnerTemplates ?? []){
224
334
  collectFieldVariableReferences(template, references, {
@@ -233,12 +343,15 @@ function referencedVariables(model, jobs) {
233
343
  collectFieldVariableReferences(step.templates?.name, references, {
234
344
  field: 'step.name'
235
345
  });
346
+ collectFieldVariableReferences(step.templates?.workingDirectory, references, {
347
+ field: 'step.working_directory'
348
+ });
236
349
  if (step.kind === 'run') {
237
350
  collectFieldVariableReferences(step.templates?.command, references, {
238
351
  field: 'run'
239
352
  });
240
353
  collectTemplateVariableReferences(step.templates?.env, references);
241
- } else {
354
+ } else if (step.kind === 'agent') {
242
355
  collectFieldVariableReferences(step.templates?.prompt, references, {
243
356
  field: 'agent.prompt'
244
357
  });
@@ -248,11 +361,29 @@ function referencedVariables(model, jobs) {
248
361
  collectFieldVariableReferences(step.templates?.provider, references, {
249
362
  field: 'agent.provider'
250
363
  });
364
+ } else if (step.kind === 'checkout') {
365
+ for (const [key, field] of WORKFLOW_MODEL_CHECKOUT_TARGET_FIELDS){
366
+ collectFieldVariableReferences(step.checkout.templates?.[key], references, {
367
+ field
368
+ });
369
+ }
251
370
  }
252
371
  }
253
372
  }
254
373
  return references;
255
374
  }
375
+ function collectPredicateVariableReferences(expression, references) {
376
+ if (expression === undefined) return;
377
+ const keyAccess = analyzeContextKeyAccess(expression);
378
+ for (const reference of keyAccess.references){
379
+ if (reference.root !== 'vars') continue;
380
+ references.push({
381
+ key: reference.key,
382
+ field: 'env',
383
+ source: typeof expression === 'string' ? expression : expression.source
384
+ });
385
+ }
386
+ }
256
387
  function collectTemplateVariableReferences(templates, references, source) {
257
388
  for (const [envKey, template] of Object.entries(templates ?? {})){
258
389
  collectFieldVariableReferences(template, references, source === undefined ? {
@@ -276,10 +407,6 @@ function collectFieldVariableReferences(template, references, source) {
276
407
  }
277
408
  }
278
409
  }
279
- function workflowTemplateSource(template) {
280
- if (template === undefined) return null;
281
- return template.map((segment)=>segment.kind === 'literal' ? segment.value : `$${'{{'} ${segment.expression.source} ${'}}'}`).join('');
282
- }
283
410
  function logTemplateDiagnostics(params) {
284
411
  if (params.diagnostics.length === 0) return;
285
412
  logger().warn({