@urateam/core 0.1.4 → 0.1.9

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 (504) hide show
  1. package/dist/__tests__/agent-profiles.test.d.ts +2 -0
  2. package/dist/__tests__/agent-profiles.test.d.ts.map +1 -0
  3. package/dist/__tests__/agent-profiles.test.js +120 -0
  4. package/dist/__tests__/agent-profiles.test.js.map +1 -0
  5. package/dist/__tests__/audit/audit-e2e.test.d.ts +2 -0
  6. package/dist/__tests__/audit/audit-e2e.test.d.ts.map +1 -0
  7. package/dist/__tests__/audit/audit-e2e.test.js +56 -0
  8. package/dist/__tests__/audit/audit-e2e.test.js.map +1 -0
  9. package/dist/__tests__/audit/csv.test.d.ts +2 -0
  10. package/dist/__tests__/audit/csv.test.d.ts.map +1 -0
  11. package/dist/__tests__/audit/csv.test.js +134 -0
  12. package/dist/__tests__/audit/csv.test.js.map +1 -0
  13. package/dist/__tests__/audit/events.test.d.ts +2 -0
  14. package/dist/__tests__/audit/events.test.d.ts.map +1 -0
  15. package/dist/__tests__/audit/events.test.js +45 -0
  16. package/dist/__tests__/audit/events.test.js.map +1 -0
  17. package/dist/__tests__/audit/policy-events.test.d.ts +2 -0
  18. package/dist/__tests__/audit/policy-events.test.d.ts.map +1 -0
  19. package/dist/__tests__/audit/policy-events.test.js +49 -0
  20. package/dist/__tests__/audit/policy-events.test.js.map +1 -0
  21. package/dist/__tests__/audit/projection.test.d.ts +2 -0
  22. package/dist/__tests__/audit/projection.test.d.ts.map +1 -0
  23. package/dist/__tests__/audit/projection.test.js +76 -0
  24. package/dist/__tests__/audit/projection.test.js.map +1 -0
  25. package/dist/__tests__/audit/rbac-events.test.d.ts +2 -0
  26. package/dist/__tests__/audit/rbac-events.test.d.ts.map +1 -0
  27. package/dist/__tests__/audit/rbac-events.test.js +56 -0
  28. package/dist/__tests__/audit/rbac-events.test.js.map +1 -0
  29. package/dist/__tests__/audit/reader.test.d.ts +2 -0
  30. package/dist/__tests__/audit/reader.test.d.ts.map +1 -0
  31. package/dist/__tests__/audit/reader.test.js +133 -0
  32. package/dist/__tests__/audit/reader.test.js.map +1 -0
  33. package/dist/__tests__/audit/retention.test.d.ts +2 -0
  34. package/dist/__tests__/audit/retention.test.d.ts.map +1 -0
  35. package/dist/__tests__/audit/retention.test.js +48 -0
  36. package/dist/__tests__/audit/retention.test.js.map +1 -0
  37. package/dist/__tests__/audit/sso-events.test.d.ts +2 -0
  38. package/dist/__tests__/audit/sso-events.test.d.ts.map +1 -0
  39. package/dist/__tests__/audit/sso-events.test.js +49 -0
  40. package/dist/__tests__/audit/sso-events.test.js.map +1 -0
  41. package/dist/__tests__/audit/writer.test.d.ts +2 -0
  42. package/dist/__tests__/audit/writer.test.d.ts.map +1 -0
  43. package/dist/__tests__/audit/writer.test.js +67 -0
  44. package/dist/__tests__/audit/writer.test.js.map +1 -0
  45. package/dist/__tests__/audit-immutability.test.d.ts +2 -0
  46. package/dist/__tests__/audit-immutability.test.d.ts.map +1 -0
  47. package/dist/__tests__/audit-immutability.test.js +61 -0
  48. package/dist/__tests__/audit-immutability.test.js.map +1 -0
  49. package/dist/__tests__/audit-types.test.d.ts +2 -0
  50. package/dist/__tests__/audit-types.test.d.ts.map +1 -0
  51. package/dist/__tests__/audit-types.test.js +35 -0
  52. package/dist/__tests__/audit-types.test.js.map +1 -0
  53. package/dist/__tests__/auth/session-store.test.d.ts +2 -0
  54. package/dist/__tests__/auth/session-store.test.d.ts.map +1 -0
  55. package/dist/__tests__/auth/session-store.test.js +65 -0
  56. package/dist/__tests__/auth/session-store.test.js.map +1 -0
  57. package/dist/__tests__/auth/sso-config.test.d.ts +2 -0
  58. package/dist/__tests__/auth/sso-config.test.d.ts.map +1 -0
  59. package/dist/__tests__/auth/sso-config.test.js +75 -0
  60. package/dist/__tests__/auth/sso-config.test.js.map +1 -0
  61. package/dist/__tests__/auth/sso-feature-flag.test.d.ts +2 -0
  62. package/dist/__tests__/auth/sso-feature-flag.test.d.ts.map +1 -0
  63. package/dist/__tests__/auth/sso-feature-flag.test.js +33 -0
  64. package/dist/__tests__/auth/sso-feature-flag.test.js.map +1 -0
  65. package/dist/__tests__/auth/user-role-round-trip.test.d.ts +2 -0
  66. package/dist/__tests__/auth/user-role-round-trip.test.d.ts.map +1 -0
  67. package/dist/__tests__/auth/user-role-round-trip.test.js +30 -0
  68. package/dist/__tests__/auth/user-role-round-trip.test.js.map +1 -0
  69. package/dist/__tests__/auth/user-store.test.d.ts +2 -0
  70. package/dist/__tests__/auth/user-store.test.d.ts.map +1 -0
  71. package/dist/__tests__/auth/user-store.test.js +119 -0
  72. package/dist/__tests__/auth/user-store.test.js.map +1 -0
  73. package/dist/__tests__/auth/workos-client.test.d.ts +2 -0
  74. package/dist/__tests__/auth/workos-client.test.d.ts.map +1 -0
  75. package/dist/__tests__/auth/workos-client.test.js +17 -0
  76. package/dist/__tests__/auth/workos-client.test.js.map +1 -0
  77. package/dist/__tests__/auto-merge.test.js +2 -1
  78. package/dist/__tests__/auto-merge.test.js.map +1 -1
  79. package/dist/__tests__/cost/aggregate.test.d.ts +2 -0
  80. package/dist/__tests__/cost/aggregate.test.d.ts.map +1 -0
  81. package/dist/__tests__/cost/aggregate.test.js +358 -0
  82. package/dist/__tests__/cost/aggregate.test.js.map +1 -0
  83. package/dist/__tests__/cost/csv.test.d.ts +2 -0
  84. package/dist/__tests__/cost/csv.test.d.ts.map +1 -0
  85. package/dist/__tests__/cost/csv.test.js +109 -0
  86. package/dist/__tests__/cost/csv.test.js.map +1 -0
  87. package/dist/__tests__/cost/per-run.test.d.ts +2 -0
  88. package/dist/__tests__/cost/per-run.test.d.ts.map +1 -0
  89. package/dist/__tests__/cost/per-run.test.js +64 -0
  90. package/dist/__tests__/cost/per-run.test.js.map +1 -0
  91. package/dist/__tests__/cost/rates.test.d.ts +2 -0
  92. package/dist/__tests__/cost/rates.test.d.ts.map +1 -0
  93. package/dist/__tests__/cost/rates.test.js +47 -0
  94. package/dist/__tests__/cost/rates.test.js.map +1 -0
  95. package/dist/__tests__/cost/rollup.test.d.ts +2 -0
  96. package/dist/__tests__/cost/rollup.test.d.ts.map +1 -0
  97. package/dist/__tests__/cost/rollup.test.js +187 -0
  98. package/dist/__tests__/cost/rollup.test.js.map +1 -0
  99. package/dist/__tests__/cost-defensive.test.d.ts +2 -0
  100. package/dist/__tests__/cost-defensive.test.d.ts.map +1 -0
  101. package/dist/__tests__/cost-defensive.test.js +123 -0
  102. package/dist/__tests__/cost-defensive.test.js.map +1 -0
  103. package/dist/__tests__/cost-integration.test.d.ts +2 -0
  104. package/dist/__tests__/cost-integration.test.d.ts.map +1 -0
  105. package/dist/__tests__/cost-integration.test.js +80 -0
  106. package/dist/__tests__/cost-integration.test.js.map +1 -0
  107. package/dist/__tests__/cost-license.test.d.ts +2 -0
  108. package/dist/__tests__/cost-license.test.d.ts.map +1 -0
  109. package/dist/__tests__/cost-license.test.js +23 -0
  110. package/dist/__tests__/cost-license.test.js.map +1 -0
  111. package/dist/__tests__/cost-types.test.d.ts +2 -0
  112. package/dist/__tests__/cost-types.test.d.ts.map +1 -0
  113. package/dist/__tests__/cost-types.test.js +65 -0
  114. package/dist/__tests__/cost-types.test.js.map +1 -0
  115. package/dist/__tests__/db-audit-schema.test.d.ts +2 -0
  116. package/dist/__tests__/db-audit-schema.test.d.ts.map +1 -0
  117. package/dist/__tests__/db-audit-schema.test.js +35 -0
  118. package/dist/__tests__/db-audit-schema.test.js.map +1 -0
  119. package/dist/__tests__/db-cost-rollups-schema.test.d.ts +2 -0
  120. package/dist/__tests__/db-cost-rollups-schema.test.d.ts.map +1 -0
  121. package/dist/__tests__/db-cost-rollups-schema.test.js +28 -0
  122. package/dist/__tests__/db-cost-rollups-schema.test.js.map +1 -0
  123. package/dist/__tests__/db-rbac-schema.test.d.ts +2 -0
  124. package/dist/__tests__/db-rbac-schema.test.d.ts.map +1 -0
  125. package/dist/__tests__/db-rbac-schema.test.js +32 -0
  126. package/dist/__tests__/db-rbac-schema.test.js.map +1 -0
  127. package/dist/__tests__/db-sso-schema.test.d.ts +2 -0
  128. package/dist/__tests__/db-sso-schema.test.d.ts.map +1 -0
  129. package/dist/__tests__/db-sso-schema.test.js +48 -0
  130. package/dist/__tests__/db-sso-schema.test.js.map +1 -0
  131. package/dist/__tests__/executor.test.js +3 -1
  132. package/dist/__tests__/executor.test.js.map +1 -1
  133. package/dist/__tests__/extract-handoff.test.js +109 -0
  134. package/dist/__tests__/extract-handoff.test.js.map +1 -1
  135. package/dist/__tests__/helpers/license.d.ts +3 -0
  136. package/dist/__tests__/helpers/license.d.ts.map +1 -0
  137. package/dist/__tests__/helpers/license.js +74 -0
  138. package/dist/__tests__/helpers/license.js.map +1 -0
  139. package/dist/__tests__/license-audit-event.test.d.ts +2 -0
  140. package/dist/__tests__/license-audit-event.test.d.ts.map +1 -0
  141. package/dist/__tests__/license-audit-event.test.js +60 -0
  142. package/dist/__tests__/license-audit-event.test.js.map +1 -0
  143. package/dist/__tests__/license-end-to-end.test.d.ts +2 -0
  144. package/dist/__tests__/license-end-to-end.test.d.ts.map +1 -0
  145. package/dist/__tests__/license-end-to-end.test.js +75 -0
  146. package/dist/__tests__/license-end-to-end.test.js.map +1 -0
  147. package/dist/__tests__/license-public-key.test.d.ts +2 -0
  148. package/dist/__tests__/license-public-key.test.d.ts.map +1 -0
  149. package/dist/__tests__/license-public-key.test.js +18 -0
  150. package/dist/__tests__/license-public-key.test.js.map +1 -0
  151. package/dist/__tests__/license.test.js +195 -32
  152. package/dist/__tests__/license.test.js.map +1 -1
  153. package/dist/__tests__/pm-action-audit-events.test.d.ts +2 -0
  154. package/dist/__tests__/pm-action-audit-events.test.d.ts.map +1 -0
  155. package/dist/__tests__/pm-action-audit-events.test.js +185 -0
  156. package/dist/__tests__/pm-action-audit-events.test.js.map +1 -0
  157. package/dist/__tests__/pm-approvals.test.js +1 -1
  158. package/dist/__tests__/pm-approvals.test.js.map +1 -1
  159. package/dist/__tests__/pm-audit-retention-step.test.d.ts +2 -0
  160. package/dist/__tests__/pm-audit-retention-step.test.d.ts.map +1 -0
  161. package/dist/__tests__/pm-audit-retention-step.test.js +126 -0
  162. package/dist/__tests__/pm-audit-retention-step.test.js.map +1 -0
  163. package/dist/__tests__/pm-budget-alerts.test.d.ts +2 -0
  164. package/dist/__tests__/pm-budget-alerts.test.d.ts.map +1 -0
  165. package/dist/__tests__/pm-budget-alerts.test.js +128 -0
  166. package/dist/__tests__/pm-budget-alerts.test.js.map +1 -0
  167. package/dist/__tests__/pm-budget-refused-event.test.d.ts +2 -0
  168. package/dist/__tests__/pm-budget-refused-event.test.d.ts.map +1 -0
  169. package/dist/__tests__/pm-budget-refused-event.test.js +141 -0
  170. package/dist/__tests__/pm-budget-refused-event.test.js.map +1 -0
  171. package/dist/__tests__/pm-budget.test.js +138 -42
  172. package/dist/__tests__/pm-budget.test.js.map +1 -1
  173. package/dist/__tests__/pm-cost-rollup-step.test.d.ts +2 -0
  174. package/dist/__tests__/pm-cost-rollup-step.test.d.ts.map +1 -0
  175. package/dist/__tests__/pm-cost-rollup-step.test.js +113 -0
  176. package/dist/__tests__/pm-cost-rollup-step.test.js.map +1 -0
  177. package/dist/__tests__/pm-scheduler.test.js +48 -21
  178. package/dist/__tests__/pm-scheduler.test.js.map +1 -1
  179. package/dist/__tests__/pm-slack.test.js +37 -0
  180. package/dist/__tests__/pm-slack.test.js.map +1 -1
  181. package/dist/__tests__/pm-sso-prune-step.test.d.ts +2 -0
  182. package/dist/__tests__/pm-sso-prune-step.test.d.ts.map +1 -0
  183. package/dist/__tests__/pm-sso-prune-step.test.js +103 -0
  184. package/dist/__tests__/pm-sso-prune-step.test.js.map +1 -0
  185. package/dist/__tests__/pm-types.test.js +130 -1
  186. package/dist/__tests__/pm-types.test.js.map +1 -1
  187. package/dist/__tests__/policy/auto-merge-reviewer-gate.test.d.ts +2 -0
  188. package/dist/__tests__/policy/auto-merge-reviewer-gate.test.d.ts.map +1 -0
  189. package/dist/__tests__/policy/auto-merge-reviewer-gate.test.js +50 -0
  190. package/dist/__tests__/policy/auto-merge-reviewer-gate.test.js.map +1 -0
  191. package/dist/__tests__/policy/cost-gate.test.d.ts +2 -0
  192. package/dist/__tests__/policy/cost-gate.test.d.ts.map +1 -0
  193. package/dist/__tests__/policy/cost-gate.test.js +27 -0
  194. package/dist/__tests__/policy/cost-gate.test.js.map +1 -0
  195. package/dist/__tests__/policy/evaluate.test.d.ts +2 -0
  196. package/dist/__tests__/policy/evaluate.test.d.ts.map +1 -0
  197. package/dist/__tests__/policy/evaluate.test.js +105 -0
  198. package/dist/__tests__/policy/evaluate.test.js.map +1 -0
  199. package/dist/__tests__/policy/override.test.d.ts +2 -0
  200. package/dist/__tests__/policy/override.test.d.ts.map +1 -0
  201. package/dist/__tests__/policy/override.test.js +26 -0
  202. package/dist/__tests__/policy/override.test.js.map +1 -0
  203. package/dist/__tests__/policy/path-gate.test.d.ts +2 -0
  204. package/dist/__tests__/policy/path-gate.test.d.ts.map +1 -0
  205. package/dist/__tests__/policy/path-gate.test.js +31 -0
  206. package/dist/__tests__/policy/path-gate.test.js.map +1 -0
  207. package/dist/__tests__/policy/pr-reviewer-wiring.test.d.ts +2 -0
  208. package/dist/__tests__/policy/pr-reviewer-wiring.test.d.ts.map +1 -0
  209. package/dist/__tests__/policy/pr-reviewer-wiring.test.js +24 -0
  210. package/dist/__tests__/policy/pr-reviewer-wiring.test.js.map +1 -0
  211. package/dist/__tests__/policy/reviewer-gate.test.d.ts +2 -0
  212. package/dist/__tests__/policy/reviewer-gate.test.d.ts.map +1 -0
  213. package/dist/__tests__/policy/reviewer-gate.test.js +125 -0
  214. package/dist/__tests__/policy/reviewer-gate.test.js.map +1 -0
  215. package/dist/__tests__/policy-license.test.d.ts +2 -0
  216. package/dist/__tests__/policy-license.test.d.ts.map +1 -0
  217. package/dist/__tests__/policy-license.test.js +31 -0
  218. package/dist/__tests__/policy-license.test.js.map +1 -0
  219. package/dist/__tests__/policy-types.test.d.ts +2 -0
  220. package/dist/__tests__/policy-types.test.d.ts.map +1 -0
  221. package/dist/__tests__/policy-types.test.js +49 -0
  222. package/dist/__tests__/policy-types.test.js.map +1 -0
  223. package/dist/__tests__/ralph-gate.test.js +6 -4
  224. package/dist/__tests__/ralph-gate.test.js.map +1 -1
  225. package/dist/__tests__/rbac/bootstrap.test.d.ts +2 -0
  226. package/dist/__tests__/rbac/bootstrap.test.d.ts.map +1 -0
  227. package/dist/__tests__/rbac/bootstrap.test.js +62 -0
  228. package/dist/__tests__/rbac/bootstrap.test.js.map +1 -0
  229. package/dist/__tests__/rbac/matrix.test.d.ts +2 -0
  230. package/dist/__tests__/rbac/matrix.test.d.ts.map +1 -0
  231. package/dist/__tests__/rbac/matrix.test.js +62 -0
  232. package/dist/__tests__/rbac/matrix.test.js.map +1 -0
  233. package/dist/__tests__/rbac/user-role-store.test.d.ts +2 -0
  234. package/dist/__tests__/rbac/user-role-store.test.d.ts.map +1 -0
  235. package/dist/__tests__/rbac/user-role-store.test.js +78 -0
  236. package/dist/__tests__/rbac/user-role-store.test.js.map +1 -0
  237. package/dist/__tests__/rbac-defensive.test.d.ts +2 -0
  238. package/dist/__tests__/rbac-defensive.test.d.ts.map +1 -0
  239. package/dist/__tests__/rbac-defensive.test.js +29 -0
  240. package/dist/__tests__/rbac-defensive.test.js.map +1 -0
  241. package/dist/__tests__/rbac-integration.test.d.ts +2 -0
  242. package/dist/__tests__/rbac-integration.test.d.ts.map +1 -0
  243. package/dist/__tests__/rbac-integration.test.js +58 -0
  244. package/dist/__tests__/rbac-integration.test.js.map +1 -0
  245. package/dist/__tests__/rbac-license.test.d.ts +2 -0
  246. package/dist/__tests__/rbac-license.test.d.ts.map +1 -0
  247. package/dist/__tests__/rbac-license.test.js +27 -0
  248. package/dist/__tests__/rbac-license.test.js.map +1 -0
  249. package/dist/__tests__/reproduce-bec113-pagination-warning.test.js +14 -2
  250. package/dist/__tests__/reproduce-bec113-pagination-warning.test.js.map +1 -1
  251. package/dist/__tests__/reproduce-bec62.test.js +10 -3
  252. package/dist/__tests__/reproduce-bec62.test.js.map +1 -1
  253. package/dist/__tests__/reproduce-bec91-stuck-in-progress.test.js +24 -4
  254. package/dist/__tests__/reproduce-bec91-stuck-in-progress.test.js.map +1 -1
  255. package/dist/__tests__/server.test.js +46 -2
  256. package/dist/__tests__/server.test.js.map +1 -1
  257. package/dist/__tests__/sso-license.test.d.ts +2 -0
  258. package/dist/__tests__/sso-license.test.d.ts.map +1 -0
  259. package/dist/__tests__/sso-license.test.js +49 -0
  260. package/dist/__tests__/sso-license.test.js.map +1 -0
  261. package/dist/__tests__/stage-models.test.js.map +1 -1
  262. package/dist/__tests__/start-todo.test.js +5 -0
  263. package/dist/__tests__/start-todo.test.js.map +1 -1
  264. package/dist/__tests__/webhook-handler.test.js +138 -0
  265. package/dist/__tests__/webhook-handler.test.js.map +1 -1
  266. package/dist/audit/config-fingerprint.d.ts +10 -0
  267. package/dist/audit/config-fingerprint.d.ts.map +1 -0
  268. package/dist/audit/config-fingerprint.js +20 -0
  269. package/dist/audit/config-fingerprint.js.map +1 -0
  270. package/dist/audit/csv.d.ts +8 -0
  271. package/dist/audit/csv.d.ts.map +1 -0
  272. package/dist/audit/csv.js +56 -0
  273. package/dist/audit/csv.js.map +1 -0
  274. package/dist/audit/events.d.ts +107 -0
  275. package/dist/audit/events.d.ts.map +1 -0
  276. package/dist/audit/events.js +221 -0
  277. package/dist/audit/events.js.map +1 -0
  278. package/dist/audit/index.d.ts +7 -0
  279. package/dist/audit/index.d.ts.map +1 -0
  280. package/dist/audit/index.js +7 -0
  281. package/dist/audit/index.js.map +1 -0
  282. package/dist/audit/projection.d.ts +38 -0
  283. package/dist/audit/projection.d.ts.map +1 -0
  284. package/dist/audit/projection.js +109 -0
  285. package/dist/audit/projection.js.map +1 -0
  286. package/dist/audit/reader.d.ts +42 -0
  287. package/dist/audit/reader.d.ts.map +1 -0
  288. package/dist/audit/reader.js +243 -0
  289. package/dist/audit/reader.js.map +1 -0
  290. package/dist/audit/retention.d.ts +12 -0
  291. package/dist/audit/retention.d.ts.map +1 -0
  292. package/dist/audit/retention.js +23 -0
  293. package/dist/audit/retention.js.map +1 -0
  294. package/dist/audit/writer.d.ts +26 -0
  295. package/dist/audit/writer.d.ts.map +1 -0
  296. package/dist/audit/writer.js +54 -0
  297. package/dist/audit/writer.js.map +1 -0
  298. package/dist/auth/index.d.ts +5 -0
  299. package/dist/auth/index.d.ts.map +1 -0
  300. package/dist/auth/index.js +5 -0
  301. package/dist/auth/index.js.map +1 -0
  302. package/dist/auth/session-store.d.ts +17 -0
  303. package/dist/auth/session-store.d.ts.map +1 -0
  304. package/dist/auth/session-store.js +59 -0
  305. package/dist/auth/session-store.js.map +1 -0
  306. package/dist/auth/sso-config.d.ts +14 -0
  307. package/dist/auth/sso-config.d.ts.map +1 -0
  308. package/dist/auth/sso-config.js +50 -0
  309. package/dist/auth/sso-config.js.map +1 -0
  310. package/dist/auth/user-store.d.ts +33 -0
  311. package/dist/auth/user-store.d.ts.map +1 -0
  312. package/dist/auth/user-store.js +71 -0
  313. package/dist/auth/user-store.js.map +1 -0
  314. package/dist/auth/workos-client.d.ts +46 -0
  315. package/dist/auth/workos-client.d.ts.map +1 -0
  316. package/dist/auth/workos-client.js +66 -0
  317. package/dist/auth/workos-client.js.map +1 -0
  318. package/dist/cost/aggregate.d.ts +49 -0
  319. package/dist/cost/aggregate.d.ts.map +1 -0
  320. package/dist/cost/aggregate.js +364 -0
  321. package/dist/cost/aggregate.js.map +1 -0
  322. package/dist/cost/csv.d.ts +12 -0
  323. package/dist/cost/csv.d.ts.map +1 -0
  324. package/dist/cost/csv.js +79 -0
  325. package/dist/cost/csv.js.map +1 -0
  326. package/dist/cost/index.d.ts +7 -0
  327. package/dist/cost/index.d.ts.map +1 -0
  328. package/dist/cost/index.js +7 -0
  329. package/dist/cost/index.js.map +1 -0
  330. package/dist/cost/per-run.d.ts +31 -0
  331. package/dist/cost/per-run.d.ts.map +1 -0
  332. package/dist/cost/per-run.js +35 -0
  333. package/dist/cost/per-run.js.map +1 -0
  334. package/dist/cost/rates.d.ts +27 -0
  335. package/dist/cost/rates.d.ts.map +1 -0
  336. package/dist/cost/rates.js +26 -0
  337. package/dist/cost/rates.js.map +1 -0
  338. package/dist/cost/rollup.d.ts +17 -0
  339. package/dist/cost/rollup.d.ts.map +1 -0
  340. package/dist/cost/rollup.js +164 -0
  341. package/dist/cost/rollup.js.map +1 -0
  342. package/dist/cost/types.d.ts +54 -0
  343. package/dist/cost/types.d.ts.map +1 -0
  344. package/dist/cost/types.js +2 -0
  345. package/dist/cost/types.js.map +1 -0
  346. package/dist/db/client.d.ts.map +1 -1
  347. package/dist/db/client.js +79 -1
  348. package/dist/db/client.js.map +1 -1
  349. package/dist/db/migrations/postgres/006_spend_caps.sql +14 -0
  350. package/dist/db/migrations/postgres/007_audit_events.sql +19 -0
  351. package/dist/db/migrations/postgres/008_cost_rollups.sql +19 -0
  352. package/dist/db/migrations/postgres/008_sso.sql +20 -0
  353. package/dist/db/migrations/sqlite/005_spend_caps.sql +16 -0
  354. package/dist/db/migrations/sqlite/006_audit_events.sql +19 -0
  355. package/dist/db/migrations/sqlite/007_cost_rollups.sql +19 -0
  356. package/dist/db/migrations/sqlite/007_sso.sql +20 -0
  357. package/dist/db/schema.d.ts +802 -0
  358. package/dist/db/schema.d.ts.map +1 -1
  359. package/dist/db/schema.js +80 -1
  360. package/dist/db/schema.js.map +1 -1
  361. package/dist/executor/executor.js +2 -2
  362. package/dist/executor/executor.js.map +1 -1
  363. package/dist/executor/extract-handoff.d.ts +7 -1
  364. package/dist/executor/extract-handoff.d.ts.map +1 -1
  365. package/dist/executor/extract-handoff.js +51 -11
  366. package/dist/executor/extract-handoff.js.map +1 -1
  367. package/dist/executor/handoff.d.ts.map +1 -1
  368. package/dist/executor/handoff.js +6 -0
  369. package/dist/executor/handoff.js.map +1 -1
  370. package/dist/executor/index.d.ts +1 -1
  371. package/dist/executor/index.d.ts.map +1 -1
  372. package/dist/executor/index.js +1 -1
  373. package/dist/executor/index.js.map +1 -1
  374. package/dist/executor/profiles.d.ts +42 -0
  375. package/dist/executor/profiles.d.ts.map +1 -1
  376. package/dist/executor/profiles.js +147 -2
  377. package/dist/executor/profiles.js.map +1 -1
  378. package/dist/index.d.ts +7 -1
  379. package/dist/index.d.ts.map +1 -1
  380. package/dist/index.js +8 -1
  381. package/dist/index.js.map +1 -1
  382. package/dist/license-public-key.d.ts +15 -0
  383. package/dist/license-public-key.d.ts.map +1 -0
  384. package/dist/license-public-key.js +15 -0
  385. package/dist/license-public-key.js.map +1 -0
  386. package/dist/license.d.ts +30 -5
  387. package/dist/license.d.ts.map +1 -1
  388. package/dist/license.js +142 -12
  389. package/dist/license.js.map +1 -1
  390. package/dist/pipeline/runner.d.ts +1 -7
  391. package/dist/pipeline/runner.d.ts.map +1 -1
  392. package/dist/pipeline/runner.js +168 -21
  393. package/dist/pipeline/runner.js.map +1 -1
  394. package/dist/pm/actions/promote.d.ts +3 -0
  395. package/dist/pm/actions/promote.d.ts.map +1 -1
  396. package/dist/pm/actions/promote.js +12 -0
  397. package/dist/pm/actions/promote.js.map +1 -1
  398. package/dist/pm/actions/resolve-approvals.d.ts.map +1 -1
  399. package/dist/pm/actions/resolve-approvals.js +16 -0
  400. package/dist/pm/actions/resolve-approvals.js.map +1 -1
  401. package/dist/pm/actions/start-todo.d.ts +3 -0
  402. package/dist/pm/actions/start-todo.d.ts.map +1 -1
  403. package/dist/pm/actions/start-todo.js +5 -1
  404. package/dist/pm/actions/start-todo.js.map +1 -1
  405. package/dist/pm/actions/triage.d.ts +3 -0
  406. package/dist/pm/actions/triage.d.ts.map +1 -1
  407. package/dist/pm/actions/triage.js +8 -0
  408. package/dist/pm/actions/triage.js.map +1 -1
  409. package/dist/pm/budget-alerts.d.ts +18 -0
  410. package/dist/pm/budget-alerts.d.ts.map +1 -0
  411. package/dist/pm/budget-alerts.js +100 -0
  412. package/dist/pm/budget-alerts.js.map +1 -0
  413. package/dist/pm/budget.d.ts +28 -5
  414. package/dist/pm/budget.d.ts.map +1 -1
  415. package/dist/pm/budget.js +115 -39
  416. package/dist/pm/budget.js.map +1 -1
  417. package/dist/pm/scheduler.d.ts +8 -4
  418. package/dist/pm/scheduler.d.ts.map +1 -1
  419. package/dist/pm/scheduler.js +128 -5
  420. package/dist/pm/scheduler.js.map +1 -1
  421. package/dist/pm/slack.d.ts.map +1 -1
  422. package/dist/pm/slack.js +11 -0
  423. package/dist/pm/slack.js.map +1 -1
  424. package/dist/pm/types.d.ts +36 -0
  425. package/dist/pm/types.d.ts.map +1 -1
  426. package/dist/pm/types.js +12 -0
  427. package/dist/pm/types.js.map +1 -1
  428. package/dist/policy/cost-gate.d.ts +3 -0
  429. package/dist/policy/cost-gate.d.ts.map +1 -0
  430. package/dist/policy/cost-gate.js +11 -0
  431. package/dist/policy/cost-gate.js.map +1 -0
  432. package/dist/policy/evaluate.d.ts +32 -0
  433. package/dist/policy/evaluate.d.ts.map +1 -0
  434. package/dist/policy/evaluate.js +61 -0
  435. package/dist/policy/evaluate.js.map +1 -0
  436. package/dist/policy/index.d.ts +7 -0
  437. package/dist/policy/index.d.ts.map +1 -0
  438. package/dist/policy/index.js +7 -0
  439. package/dist/policy/index.js.map +1 -0
  440. package/dist/policy/override.d.ts +23 -0
  441. package/dist/policy/override.d.ts.map +1 -0
  442. package/dist/policy/override.js +26 -0
  443. package/dist/policy/override.js.map +1 -0
  444. package/dist/policy/path-gate.d.ts +3 -0
  445. package/dist/policy/path-gate.d.ts.map +1 -0
  446. package/dist/policy/path-gate.js +20 -0
  447. package/dist/policy/path-gate.js.map +1 -0
  448. package/dist/policy/reviewer-gate.d.ts +45 -0
  449. package/dist/policy/reviewer-gate.d.ts.map +1 -0
  450. package/dist/policy/reviewer-gate.js +77 -0
  451. package/dist/policy/reviewer-gate.js.map +1 -0
  452. package/dist/policy/types.d.ts +7 -0
  453. package/dist/policy/types.d.ts.map +1 -0
  454. package/dist/policy/types.js +2 -0
  455. package/dist/policy/types.js.map +1 -0
  456. package/dist/rbac/errors.d.ts +7 -0
  457. package/dist/rbac/errors.d.ts.map +1 -0
  458. package/dist/rbac/errors.js +13 -0
  459. package/dist/rbac/errors.js.map +1 -0
  460. package/dist/rbac/index.d.ts +5 -0
  461. package/dist/rbac/index.d.ts.map +1 -0
  462. package/dist/rbac/index.js +5 -0
  463. package/dist/rbac/index.js.map +1 -0
  464. package/dist/rbac/matrix.d.ts +35 -0
  465. package/dist/rbac/matrix.d.ts.map +1 -0
  466. package/dist/rbac/matrix.js +42 -0
  467. package/dist/rbac/matrix.js.map +1 -0
  468. package/dist/rbac/types.d.ts +2 -0
  469. package/dist/rbac/types.d.ts.map +1 -0
  470. package/dist/rbac/types.js +2 -0
  471. package/dist/rbac/types.js.map +1 -0
  472. package/dist/rbac/user-role-store.d.ts +27 -0
  473. package/dist/rbac/user-role-store.d.ts.map +1 -0
  474. package/dist/rbac/user-role-store.js +148 -0
  475. package/dist/rbac/user-role-store.js.map +1 -0
  476. package/dist/repo/git.d.ts +9 -0
  477. package/dist/repo/git.d.ts.map +1 -1
  478. package/dist/repo/git.js +11 -0
  479. package/dist/repo/git.js.map +1 -1
  480. package/dist/repo/github.d.ts +4 -0
  481. package/dist/repo/github.d.ts.map +1 -1
  482. package/dist/repo/github.js +27 -0
  483. package/dist/repo/github.js.map +1 -1
  484. package/dist/repo/gitlab.d.ts +4 -0
  485. package/dist/repo/gitlab.d.ts.map +1 -1
  486. package/dist/repo/gitlab.js +7 -0
  487. package/dist/repo/gitlab.js.map +1 -1
  488. package/dist/server.d.ts +6 -0
  489. package/dist/server.d.ts.map +1 -1
  490. package/dist/server.js +16 -10
  491. package/dist/server.js.map +1 -1
  492. package/dist/types.d.ts +155 -0
  493. package/dist/types.d.ts.map +1 -1
  494. package/dist/types.js +83 -0
  495. package/dist/types.js.map +1 -1
  496. package/dist/util/glob.d.ts +7 -0
  497. package/dist/util/glob.d.ts.map +1 -0
  498. package/dist/util/glob.js +20 -0
  499. package/dist/util/glob.js.map +1 -0
  500. package/dist/webhook/handler.d.ts +3 -0
  501. package/dist/webhook/handler.d.ts.map +1 -1
  502. package/dist/webhook/handler.js +36 -2
  503. package/dist/webhook/handler.js.map +1 -1
  504. package/package.json +2 -1
@@ -0,0 +1,71 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { eq } from "drizzle-orm";
3
+ import { dashboardUsers } from "../db/schema.js";
4
+ function normalizeEmail(email) {
5
+ return email.trim().toLowerCase();
6
+ }
7
+ /**
8
+ * Insert or update a dashboard user by normalized email. Returns the
9
+ * canonical user id. On update, `name`, `workosUserId`, and `lastLoginAt`
10
+ * are refreshed; `id` and `createdAt` are preserved.
11
+ *
12
+ * Implemented as an atomic upsert (`onConflictDoUpdate` on the unique
13
+ * `email` column) so that two concurrent `/auth/callback` requests for the
14
+ * same email cannot both see `existing.length === 0` and race on INSERT.
15
+ * The generated `id` is only used if no row exists; on conflict we read
16
+ * back the canonical id from the surviving row.
17
+ */
18
+ export async function upsertUser(db, input) {
19
+ const email = normalizeEmail(input.email);
20
+ const now = new Date();
21
+ const id = `usr_${randomUUID()}`;
22
+ await db
23
+ .insert(dashboardUsers)
24
+ .values({
25
+ id,
26
+ email,
27
+ name: input.name,
28
+ workosUserId: input.workosUserId,
29
+ createdAt: now,
30
+ lastLoginAt: now,
31
+ })
32
+ .onConflictDoUpdate({
33
+ target: dashboardUsers.email,
34
+ set: {
35
+ name: input.name,
36
+ workosUserId: input.workosUserId,
37
+ lastLoginAt: now,
38
+ },
39
+ });
40
+ // Read back the canonical id — it may be a pre-existing row's id, not
41
+ // the one we just generated above.
42
+ const rows = await db
43
+ .select()
44
+ .from(dashboardUsers)
45
+ .where(eq(dashboardUsers.email, email))
46
+ .limit(1);
47
+ return rows[0].id;
48
+ }
49
+ /**
50
+ * Look up a dashboard user by id. Returns `null` when not found.
51
+ */
52
+ export async function getUserById(db, id) {
53
+ const rows = await db
54
+ .select()
55
+ .from(dashboardUsers)
56
+ .where(eq(dashboardUsers.id, id))
57
+ .limit(1);
58
+ if (rows.length === 0)
59
+ return null;
60
+ const row = rows[0];
61
+ return {
62
+ id: row.id,
63
+ email: row.email,
64
+ name: row.name ?? null,
65
+ workosUserId: row.workosUserId ?? null,
66
+ createdAt: row.createdAt,
67
+ lastLoginAt: row.lastLoginAt ?? null,
68
+ role: (row.role ?? "viewer"),
69
+ };
70
+ }
71
+ //# sourceMappingURL=user-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-store.js","sourceRoot":"","sources":["../../src/auth/user-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAEjC,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAmBjD,SAAS,cAAc,CAAC,KAAa;IACnC,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AACpC,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,EAAS,EACT,KAAsB;IAEtB,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,EAAE,GAAG,OAAO,UAAU,EAAE,EAAE,CAAC;IAEjC,MAAM,EAAE;SACL,MAAM,CAAC,cAAc,CAAC;SACtB,MAAM,CAAC;QACN,EAAE;QACF,KAAK;QACL,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,SAAS,EAAE,GAAG;QACd,WAAW,EAAE,GAAG;KACjB,CAAC;SACD,kBAAkB,CAAC;QAClB,MAAM,EAAE,cAAc,CAAC,KAAK;QAC5B,GAAG,EAAE;YACH,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,WAAW,EAAE,GAAG;SACjB;KACF,CAAC,CAAC;IAEL,sEAAsE;IACtE,mCAAmC;IACnC,MAAM,IAAI,GAAG,MAAM,EAAE;SAClB,MAAM,EAAE;SACR,IAAI,CAAC,cAAc,CAAC;SACpB,KAAK,CAAC,EAAE,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;SACtC,KAAK,CAAC,CAAC,CAAC,CAAC;IACZ,OAAO,IAAI,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,EAAS,EACT,EAAU;IAEV,MAAM,IAAI,GAAG,MAAM,EAAE;SAClB,MAAM,EAAE;SACR,IAAI,CAAC,cAAc,CAAC;SACpB,KAAK,CAAC,EAAE,CAAC,cAAc,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;SAChC,KAAK,CAAC,CAAC,CAAC,CAAC;IACZ,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;IACrB,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,IAAI;QACtB,YAAY,EAAE,GAAG,CAAC,YAAY,IAAI,IAAI;QACtC,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,IAAI;QACpC,IAAI,EAAE,CAAE,GAAgC,CAAC,IAAI,IAAI,QAAQ,CAAS;KACnE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Thin interface over @workos-inc/node so tests can inject a stub
3
+ * without importing the SDK or hitting the network.
4
+ */
5
+ export interface WorkosAuthorizeArgs {
6
+ clientId: string;
7
+ redirectUri: string;
8
+ state: string;
9
+ }
10
+ export interface WorkosAuthenticateArgs {
11
+ clientId: string;
12
+ code: string;
13
+ }
14
+ export interface WorkosUserProfile {
15
+ id: string;
16
+ email: string;
17
+ firstName: string | null;
18
+ lastName: string | null;
19
+ }
20
+ export interface WorkosAuthenticateResult {
21
+ user: WorkosUserProfile;
22
+ }
23
+ export interface WorkosClient {
24
+ getAuthorizationUrl(args: WorkosAuthorizeArgs): Promise<string>;
25
+ authenticateWithCode(args: WorkosAuthenticateArgs): Promise<WorkosAuthenticateResult>;
26
+ }
27
+ /**
28
+ * Default WorkOS client. Lazily instantiates the SDK on first use so test
29
+ * environments that never call this never need the SDK installed.
30
+ *
31
+ * NOTE: The singleton cache is not keyed on apiKey. If the API key is
32
+ * rotated, the process must be restarted to pick up the new key. The cache
33
+ * is also coupled to the license cache: if a future change introduces
34
+ * in-process license refresh (see `_resetLicenseCache`), call
35
+ * `_resetWorkosClient()` too so the next call re-evaluates the gate.
36
+ *
37
+ * Throws `LicenseRequiredError` if the `sso` feature is not licensed. This is
38
+ * a defensive library-boundary gate: even though dashboard wiring already
39
+ * skips SSO mounting in OSS mode, any direct caller of this function (CLI
40
+ * bootstrap, future routes, third-party integrations) cannot accidentally
41
+ * load the WorkOS SDK without a license.
42
+ */
43
+ export declare function getDefaultWorkosClient(apiKey: string): Promise<WorkosClient>;
44
+ /** Test-only: reset the cached client. */
45
+ export declare function _resetWorkosClient(): void;
46
+ //# sourceMappingURL=workos-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workos-client.d.ts","sourceRoot":"","sources":["../../src/auth/workos-client.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,iBAAiB,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,mBAAmB,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAChE,oBAAoB,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;CACvF;AAID;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CA0ClF;AAED,0CAA0C;AAC1C,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
@@ -0,0 +1,66 @@
1
+ import { checkLicense, LicenseRequiredError } from "../license.js";
2
+ import { createLogger } from "../logger.js";
3
+ const log = createLogger({ component: "auth.workos" });
4
+ let cached = null;
5
+ /**
6
+ * Default WorkOS client. Lazily instantiates the SDK on first use so test
7
+ * environments that never call this never need the SDK installed.
8
+ *
9
+ * NOTE: The singleton cache is not keyed on apiKey. If the API key is
10
+ * rotated, the process must be restarted to pick up the new key. The cache
11
+ * is also coupled to the license cache: if a future change introduces
12
+ * in-process license refresh (see `_resetLicenseCache`), call
13
+ * `_resetWorkosClient()` too so the next call re-evaluates the gate.
14
+ *
15
+ * Throws `LicenseRequiredError` if the `sso` feature is not licensed. This is
16
+ * a defensive library-boundary gate: even though dashboard wiring already
17
+ * skips SSO mounting in OSS mode, any direct caller of this function (CLI
18
+ * bootstrap, future routes, third-party integrations) cannot accidentally
19
+ * load the WorkOS SDK without a license.
20
+ */
21
+ export async function getDefaultWorkosClient(apiKey) {
22
+ const status = checkLicense();
23
+ if (!status.features.has("sso")) {
24
+ log.warn({ feature: "sso", tier: status.tier }, "getDefaultWorkosClient called without an enterprise license — refusing to load WorkOS SDK");
25
+ throw new LicenseRequiredError("sso", status.tier);
26
+ }
27
+ if (cached)
28
+ return cached;
29
+ // Dynamic import so the dep is loaded only when actually used.
30
+ // The SDK lives in @urateam/dashboard (the only package that activates SSO),
31
+ // so core does not declare it as a dependency. Suppress the missing-types
32
+ // error here — the dashboard provides the resolved module at runtime.
33
+ // @ts-expect-error — @workos-inc/node is an optional runtime dep provided by dashboard
34
+ const { WorkOS } = await import("@workos-inc/node");
35
+ const workos = new WorkOS(apiKey);
36
+ cached = {
37
+ async getAuthorizationUrl(args) {
38
+ return workos.userManagement.getAuthorizationUrl({
39
+ clientId: args.clientId,
40
+ redirectUri: args.redirectUri,
41
+ state: args.state,
42
+ provider: "authkit",
43
+ });
44
+ },
45
+ async authenticateWithCode(args) {
46
+ const result = await workos.userManagement.authenticateWithCode({
47
+ clientId: args.clientId,
48
+ code: args.code,
49
+ });
50
+ return {
51
+ user: {
52
+ id: result.user.id,
53
+ email: result.user.email,
54
+ firstName: result.user.firstName ?? null,
55
+ lastName: result.user.lastName ?? null,
56
+ },
57
+ };
58
+ },
59
+ };
60
+ return cached;
61
+ }
62
+ /** Test-only: reset the cached client. */
63
+ export function _resetWorkosClient() {
64
+ cached = null;
65
+ }
66
+ //# sourceMappingURL=workos-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workos-client.js","sourceRoot":"","sources":["../../src/auth/workos-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,GAAG,GAAG,YAAY,CAAC,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC,CAAC;AAiCvD,IAAI,MAAM,GAAwB,IAAI,CAAC;AAEvC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,MAAc;IACzD,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,GAAG,CAAC,IAAI,CACN,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,EACrC,2FAA2F,CAC5F,CAAC;QACF,MAAM,IAAI,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IACrD,CAAC;IACD,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,+DAA+D;IAC/D,6EAA6E;IAC7E,0EAA0E;IAC1E,sEAAsE;IACtE,uFAAuF;IACvF,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;IACpD,MAAM,MAAM,GAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,GAAG;QACP,KAAK,CAAC,mBAAmB,CAAC,IAAI;YAC5B,OAAO,MAAM,CAAC,cAAc,CAAC,mBAAmB,CAAC;gBAC/C,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE,SAAS;aACpB,CAAC,CAAC;QACL,CAAC;QACD,KAAK,CAAC,oBAAoB,CAAC,IAAI;YAC7B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,oBAAoB,CAAC;gBAC9D,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,IAAI,EAAE,IAAI,CAAC,IAAI;aAChB,CAAC,CAAC;YACH,OAAO;gBACL,IAAI,EAAE;oBACJ,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE;oBAClB,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK;oBACxB,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI;oBACxC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI;iBACvC;aACF,CAAC;QACJ,CAAC;KACF,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,kBAAkB;IAChC,MAAM,GAAG,IAAI,CAAC;AAChB,CAAC"}
@@ -0,0 +1,49 @@
1
+ import type { AnyDb } from "../db/client.js";
2
+ import type { AggregateResult } from "./types.js";
3
+ export declare function normalizeTeamId(id: string | null | undefined): {
4
+ key: string;
5
+ label: string;
6
+ };
7
+ export interface AggregateFilters {
8
+ from: Date;
9
+ to: Date;
10
+ }
11
+ interface CostConfig {
12
+ costs?: {
13
+ hourlyEngRate?: number;
14
+ modelPricing?: Record<string, {
15
+ inputPerMillion: number;
16
+ outputPerMillion: number;
17
+ }>;
18
+ timeSavedPerPrDefault?: number;
19
+ };
20
+ pipelineConfigs?: Record<string, any>;
21
+ }
22
+ export declare function aggregateAll(db: AnyDb, filters: AggregateFilters, config: CostConfig, opts?: {
23
+ maxRuns?: number;
24
+ }): Promise<AggregateResult>;
25
+ /** Snap a Date down to the start of its UTC day (00:00:00.000 UTC). */
26
+ export declare function snapToUtcDayStart(d: Date): Date;
27
+ /**
28
+ * Hybrid aggregate: uses pre-computed rollup rows for whole UTC days before
29
+ * today, and live `aggregateAll` for today's partial data. The two halves are
30
+ * summed into a single `AggregateResult`.
31
+ *
32
+ * When `opts.enableRollups` is false (the default for arbitrary custom
33
+ * windows), falls back to pure live aggregation.
34
+ *
35
+ * IMPORTANT: `filters.from` must be at a UTC day boundary (00:00 UTC) for
36
+ * rollup-backed reads to be exact — the rollup table stores per-day totals.
37
+ * For preset windows (7d/30d/90d/365d) the caller is expected to snap `from`
38
+ * via `snapToUtcDayStart`. For non-aligned `from`, this function still routes
39
+ * through rollups but will slightly over-count by including the full first
40
+ * UTC day — acceptable for preset usage, unsuitable for arbitrary windows
41
+ * (hence the opt-in `enableRollups` flag).
42
+ */
43
+ export declare function aggregateHybrid(db: AnyDb, filters: AggregateFilters, config: CostConfig, opts?: {
44
+ maxRuns?: number;
45
+ now?: Date;
46
+ enableRollups?: boolean;
47
+ }): Promise<AggregateResult>;
48
+ export {};
49
+ //# sourceMappingURL=aggregate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aggregate.d.ts","sourceRoot":"","sources":["../../src/cost/aggregate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAK7C,OAAO,KAAK,EAAE,eAAe,EAAuC,MAAM,YAAY,CAAC;AAmBvF,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAK7F;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,IAAI,CAAC;IACX,EAAE,EAAE,IAAI,CAAC;CACV;AAED,UAAU,UAAU;IAClB,KAAK,CAAC,EAAE;QACN,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;YAAE,eAAe,EAAE,MAAM,CAAC;YAAC,gBAAgB,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACrF,qBAAqB,CAAC,EAAE,MAAM,CAAC;KAChC,CAAC;IACF,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACvC;AAeD,wBAAsB,YAAY,CAChC,EAAE,EAAE,KAAK,EACT,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,UAAU,EAClB,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9B,OAAO,CAAC,eAAe,CAAC,CAiI1B;AAED,uEAAuE;AACvE,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,CAE/C;AAyID;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,CACnC,EAAE,EAAE,KAAK,EACT,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,UAAU,EAClB,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,IAAI,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAO,GACnE,OAAO,CAAC,eAAe,CAAC,CAmF1B"}
@@ -0,0 +1,364 @@
1
+ import { and, gte, lt, inArray } from "drizzle-orm";
2
+ import { pipelineRuns, stageRuns, costRollupsDaily } from "../db/schema.js";
3
+ import { computeRunCost } from "./per-run.js";
4
+ import { createLogger } from "../logger.js";
5
+ import { isFeatureLicensed } from "../license.js";
6
+ const log = createLogger({ component: "cost.aggregate" });
7
+ function emptyAggregateResult(filters) {
8
+ return {
9
+ summary: {
10
+ window: { from: filters.from, to: filters.to },
11
+ runs: 0, prsMerged: 0, inputTokens: 0, outputTokens: 0,
12
+ dollars: 0, timeSavedHours: 0, roiMultiplier: 0,
13
+ },
14
+ byTeam: [], byRepo: [], byPipeline: [], byDay: [],
15
+ };
16
+ }
17
+ const DEFAULT_MAX_RUNS = 10_000;
18
+ const UNASSIGNED_TEAM = "(unassigned)";
19
+ export function normalizeTeamId(id) {
20
+ if (id === null || id === undefined || id === "") {
21
+ return { key: "team:unassigned", label: UNASSIGNED_TEAM };
22
+ }
23
+ return { key: `team:${id}`, label: id };
24
+ }
25
+ function emptyBucket(key, label) {
26
+ return {
27
+ key, label, runs: 0, prsMerged: 0,
28
+ inputTokens: 0, outputTokens: 0,
29
+ dollars: 0, timeSavedHours: 0, roiMultiplier: 0,
30
+ };
31
+ }
32
+ function finalizeRoi(row, hourlyRate) {
33
+ if (row.dollars === 0)
34
+ return row.timeSavedHours > 0 ? Infinity : 0;
35
+ return (row.timeSavedHours * hourlyRate) / row.dollars;
36
+ }
37
+ export async function aggregateAll(db, filters, config, opts = {}) {
38
+ if (!isFeatureLicensed("cost-roi")) {
39
+ log.warn({ feature: "cost-roi" }, "aggregateAll called without an enterprise license — returning empty result");
40
+ return emptyAggregateResult(filters);
41
+ }
42
+ const hourlyRate = config.costs?.hourlyEngRate ?? 50;
43
+ const maxRuns = opts.maxRuns ?? DEFAULT_MAX_RUNS;
44
+ const runs = await db.select().from(pipelineRuns).where(and(gte(pipelineRuns.completedAt, filters.from),
45
+ // half-open [from, to) — matches rollup.ts convention and avoids double-counting at the boundary
46
+ lt(pipelineRuns.completedAt, filters.to)));
47
+ let truncated = false;
48
+ if (runs.length > maxRuns) {
49
+ log.warn({ runs: runs.length, maxRuns, from: filters.from, to: filters.to }, "aggregateAll: runs exceed cap, truncating to most recent");
50
+ // Sort by completedAt DESC (nulls last) and keep only the most recent `maxRuns`.
51
+ runs.sort((a, b) => {
52
+ const ta = a.completedAt ? new Date(a.completedAt).getTime() : 0;
53
+ const tb = b.completedAt ? new Date(b.completedAt).getTime() : 0;
54
+ return tb - ta;
55
+ });
56
+ runs.splice(maxRuns);
57
+ truncated = true;
58
+ }
59
+ if (runs.length === 0) {
60
+ return {
61
+ summary: {
62
+ window: { from: filters.from, to: filters.to },
63
+ runs: 0, prsMerged: 0, inputTokens: 0, outputTokens: 0,
64
+ dollars: 0, timeSavedHours: 0, roiMultiplier: 0,
65
+ },
66
+ byTeam: [], byRepo: [], byPipeline: [], byDay: [],
67
+ };
68
+ }
69
+ const runIds = runs.map((r) => r.id);
70
+ const stages = await db.select().from(stageRuns).where(inArray(stageRuns.pipelineRunId, runIds));
71
+ const stagesByRun = new Map();
72
+ for (const s of stages) {
73
+ const arr = stagesByRun.get(s.pipelineRunId) ?? [];
74
+ arr.push(s);
75
+ stagesByRun.set(s.pipelineRunId, arr);
76
+ }
77
+ const summary = {
78
+ window: { from: filters.from, to: filters.to },
79
+ runs: 0, prsMerged: 0, inputTokens: 0, outputTokens: 0,
80
+ dollars: 0, timeSavedHours: 0, roiMultiplier: 0,
81
+ ...(truncated ? { truncated: true } : {}),
82
+ };
83
+ const byTeam = new Map();
84
+ const byRepo = new Map();
85
+ const byPipeline = new Map();
86
+ const byDay = new Map();
87
+ for (const run of runs) {
88
+ const runStages = stagesByRun.get(run.id) ?? [];
89
+ const cost = computeRunCost(run, runStages, config);
90
+ const isMergedPr = run.status === "completed" && run.runType !== "review-feedback";
91
+ summary.runs += 1;
92
+ summary.inputTokens += cost.inputTokens;
93
+ summary.outputTokens += cost.outputTokens;
94
+ summary.dollars += cost.dollars;
95
+ summary.timeSavedHours += cost.timeSavedHours;
96
+ if (isMergedPr)
97
+ summary.prsMerged += 1;
98
+ // completedAt is guaranteed non-null here — the WHERE clause above filters
99
+ // on `gte(completedAt, from)` and `lt(completedAt, to)`, which excludes
100
+ // rows where completedAt IS NULL (SQL NULL comparisons are falsy).
101
+ const dateStr = new Date(run.completedAt).toISOString().slice(0, 10);
102
+ let dr = byDay.get(dateStr);
103
+ if (!dr) {
104
+ dr = { date: dateStr, runs: 0, prsMerged: 0, dollars: 0, timeSavedHours: 0 };
105
+ byDay.set(dateStr, dr);
106
+ }
107
+ dr.runs += 1;
108
+ dr.dollars += cost.dollars;
109
+ dr.timeSavedHours += cost.timeSavedHours;
110
+ if (isMergedPr)
111
+ dr.prsMerged += 1;
112
+ const { key: teamKey, label: teamLabel } = normalizeTeamId(run.linearTeamId);
113
+ if (!byTeam.has(teamKey))
114
+ byTeam.set(teamKey, emptyBucket(teamKey, teamLabel));
115
+ const tb = byTeam.get(teamKey);
116
+ tb.runs += 1;
117
+ tb.inputTokens += cost.inputTokens;
118
+ tb.outputTokens += cost.outputTokens;
119
+ tb.dollars += cost.dollars;
120
+ tb.timeSavedHours += cost.timeSavedHours;
121
+ if (isMergedPr)
122
+ tb.prsMerged += 1;
123
+ const repoKey = `repo:${run.repoUrl}`;
124
+ if (!byRepo.has(repoKey))
125
+ byRepo.set(repoKey, emptyBucket(repoKey, run.repoUrl));
126
+ const rb = byRepo.get(repoKey);
127
+ rb.runs += 1;
128
+ rb.inputTokens += cost.inputTokens;
129
+ rb.outputTokens += cost.outputTokens;
130
+ rb.dollars += cost.dollars;
131
+ rb.timeSavedHours += cost.timeSavedHours;
132
+ if (isMergedPr)
133
+ rb.prsMerged += 1;
134
+ const pipelineKey = `pipeline:${run.pipelineKey}`;
135
+ if (!byPipeline.has(pipelineKey))
136
+ byPipeline.set(pipelineKey, emptyBucket(pipelineKey, run.pipelineKey));
137
+ const pb = byPipeline.get(pipelineKey);
138
+ pb.runs += 1;
139
+ pb.inputTokens += cost.inputTokens;
140
+ pb.outputTokens += cost.outputTokens;
141
+ pb.dollars += cost.dollars;
142
+ pb.timeSavedHours += cost.timeSavedHours;
143
+ if (isMergedPr)
144
+ pb.prsMerged += 1;
145
+ }
146
+ summary.roiMultiplier = finalizeRoi(summary, hourlyRate);
147
+ const sort = (a, b) => b.dollars - a.dollars;
148
+ const finalize = (rows) => {
149
+ for (const r of rows)
150
+ r.roiMultiplier = finalizeRoi(r, hourlyRate);
151
+ return rows.sort(sort);
152
+ };
153
+ return {
154
+ summary,
155
+ byTeam: finalize(Array.from(byTeam.values())),
156
+ byRepo: finalize(Array.from(byRepo.values())),
157
+ byPipeline: finalize(Array.from(byPipeline.values())),
158
+ byDay: Array.from(byDay.values()).sort((a, b) => a.date.localeCompare(b.date)),
159
+ };
160
+ }
161
+ /** Snap a Date down to the start of its UTC day (00:00:00.000 UTC). */
162
+ export function snapToUtcDayStart(d) {
163
+ return new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()));
164
+ }
165
+ function utcDateStr(d) {
166
+ return d.toISOString().slice(0, 10);
167
+ }
168
+ /**
169
+ * Aggregate pre-computed rollup rows for UTC dates in [fromDate, toDate).
170
+ * Both bounds are YYYY-MM-DD strings. Returns an AggregateResult whose
171
+ * window.from/to reflect the caller-supplied Date objects (not the date
172
+ * strings), so the summary is consistent with the caller's framing.
173
+ */
174
+ async function aggregateFromRollups(db, fromDate, toDate, window, hourlyRate) {
175
+ // Half-open [fromDate, toDate) — use gte(date) + lt(date) on the date string.
176
+ const rows = await db.select().from(costRollupsDaily).where(and(gte(costRollupsDaily.date, fromDate), lt(costRollupsDaily.date, toDate)));
177
+ const summary = {
178
+ window,
179
+ runs: 0, prsMerged: 0, inputTokens: 0, outputTokens: 0,
180
+ dollars: 0, timeSavedHours: 0, roiMultiplier: 0,
181
+ };
182
+ const byTeam = new Map();
183
+ const byRepo = new Map();
184
+ const byPipeline = new Map();
185
+ const byDay = new Map();
186
+ for (const r of rows) {
187
+ summary.runs += r.runs;
188
+ summary.prsMerged += r.prsMerged;
189
+ summary.inputTokens += r.inputTokens;
190
+ summary.outputTokens += r.outputTokens;
191
+ summary.dollars += r.dollars;
192
+ summary.timeSavedHours += r.timeSavedHours;
193
+ // Rollup rows are already bucketed by date × pipeline × team × repo,
194
+ // so multiple rollup rows can share the same date.
195
+ let dr = byDay.get(r.date);
196
+ if (!dr) {
197
+ dr = { date: r.date, runs: 0, prsMerged: 0, dollars: 0, timeSavedHours: 0 };
198
+ byDay.set(r.date, dr);
199
+ }
200
+ dr.runs += r.runs;
201
+ dr.prsMerged += r.prsMerged;
202
+ dr.dollars += r.dollars;
203
+ dr.timeSavedHours += r.timeSavedHours;
204
+ // rollup stores linearTeamId as "" sentinel for unassigned (see rollup.ts)
205
+ const teamId = r.linearTeamId === "" ? null : r.linearTeamId;
206
+ const { key: teamKey, label: teamLabel } = normalizeTeamId(teamId);
207
+ if (!byTeam.has(teamKey))
208
+ byTeam.set(teamKey, emptyBucket(teamKey, teamLabel));
209
+ const tb = byTeam.get(teamKey);
210
+ tb.runs += r.runs;
211
+ tb.prsMerged += r.prsMerged;
212
+ tb.inputTokens += r.inputTokens;
213
+ tb.outputTokens += r.outputTokens;
214
+ tb.dollars += r.dollars;
215
+ tb.timeSavedHours += r.timeSavedHours;
216
+ const repoKey = `repo:${r.repoUrl}`;
217
+ if (!byRepo.has(repoKey))
218
+ byRepo.set(repoKey, emptyBucket(repoKey, r.repoUrl));
219
+ const rb = byRepo.get(repoKey);
220
+ rb.runs += r.runs;
221
+ rb.prsMerged += r.prsMerged;
222
+ rb.inputTokens += r.inputTokens;
223
+ rb.outputTokens += r.outputTokens;
224
+ rb.dollars += r.dollars;
225
+ rb.timeSavedHours += r.timeSavedHours;
226
+ const pipelineKey = `pipeline:${r.pipelineKey}`;
227
+ if (!byPipeline.has(pipelineKey))
228
+ byPipeline.set(pipelineKey, emptyBucket(pipelineKey, r.pipelineKey));
229
+ const pb = byPipeline.get(pipelineKey);
230
+ pb.runs += r.runs;
231
+ pb.prsMerged += r.prsMerged;
232
+ pb.inputTokens += r.inputTokens;
233
+ pb.outputTokens += r.outputTokens;
234
+ pb.dollars += r.dollars;
235
+ pb.timeSavedHours += r.timeSavedHours;
236
+ }
237
+ summary.roiMultiplier = finalizeRoi(summary, hourlyRate);
238
+ const sort = (a, b) => b.dollars - a.dollars;
239
+ const finalize = (rows) => {
240
+ for (const r of rows)
241
+ r.roiMultiplier = finalizeRoi(r, hourlyRate);
242
+ return rows.sort(sort);
243
+ };
244
+ return {
245
+ summary,
246
+ byTeam: finalize(Array.from(byTeam.values())),
247
+ byRepo: finalize(Array.from(byRepo.values())),
248
+ byPipeline: finalize(Array.from(byPipeline.values())),
249
+ byDay: Array.from(byDay.values()).sort((a, b) => a.date.localeCompare(b.date)),
250
+ };
251
+ }
252
+ function mergeDailyRows(a, b) {
253
+ const byDate = new Map();
254
+ for (const row of [...a, ...b]) {
255
+ const existing = byDate.get(row.date);
256
+ if (!existing) {
257
+ byDate.set(row.date, { ...row });
258
+ }
259
+ else {
260
+ existing.runs += row.runs;
261
+ existing.prsMerged += row.prsMerged;
262
+ existing.dollars += row.dollars;
263
+ existing.timeSavedHours += row.timeSavedHours;
264
+ }
265
+ }
266
+ return Array.from(byDate.values()).sort((x, y) => x.date.localeCompare(y.date));
267
+ }
268
+ function mergeBreakdowns(a, b, hourlyRate) {
269
+ const byKey = new Map();
270
+ for (const row of [...a, ...b]) {
271
+ const existing = byKey.get(row.key);
272
+ if (!existing) {
273
+ byKey.set(row.key, { ...row });
274
+ }
275
+ else {
276
+ existing.runs += row.runs;
277
+ existing.prsMerged += row.prsMerged;
278
+ existing.inputTokens += row.inputTokens;
279
+ existing.outputTokens += row.outputTokens;
280
+ existing.dollars += row.dollars;
281
+ existing.timeSavedHours += row.timeSavedHours;
282
+ }
283
+ }
284
+ const merged = Array.from(byKey.values());
285
+ for (const r of merged)
286
+ r.roiMultiplier = finalizeRoi(r, hourlyRate);
287
+ return merged.sort((x, y) => y.dollars - x.dollars);
288
+ }
289
+ /**
290
+ * Hybrid aggregate: uses pre-computed rollup rows for whole UTC days before
291
+ * today, and live `aggregateAll` for today's partial data. The two halves are
292
+ * summed into a single `AggregateResult`.
293
+ *
294
+ * When `opts.enableRollups` is false (the default for arbitrary custom
295
+ * windows), falls back to pure live aggregation.
296
+ *
297
+ * IMPORTANT: `filters.from` must be at a UTC day boundary (00:00 UTC) for
298
+ * rollup-backed reads to be exact — the rollup table stores per-day totals.
299
+ * For preset windows (7d/30d/90d/365d) the caller is expected to snap `from`
300
+ * via `snapToUtcDayStart`. For non-aligned `from`, this function still routes
301
+ * through rollups but will slightly over-count by including the full first
302
+ * UTC day — acceptable for preset usage, unsuitable for arbitrary windows
303
+ * (hence the opt-in `enableRollups` flag).
304
+ */
305
+ export async function aggregateHybrid(db, filters, config, opts = {}) {
306
+ if (!isFeatureLicensed("cost-roi")) {
307
+ log.warn({ feature: "cost-roi" }, "aggregateHybrid called without an enterprise license — returning empty result");
308
+ return emptyAggregateResult(filters);
309
+ }
310
+ const enableRollups = opts.enableRollups ?? false;
311
+ if (!enableRollups) {
312
+ return aggregateAll(db, filters, config, opts);
313
+ }
314
+ const hourlyRate = config.costs?.hourlyEngRate ?? 50;
315
+ const now = opts.now ?? new Date();
316
+ const todayUtcStart = snapToUtcDayStart(now);
317
+ // If the window doesn't span any completed UTC days, fall through to pure live.
318
+ if (filters.from >= todayUtcStart) {
319
+ return aggregateAll(db, filters, config, opts);
320
+ }
321
+ // Compute the rollup window (whole UTC days) and the live remainder (today).
322
+ const rollupEndDateStr = utcDateStr(todayUtcStart);
323
+ const rollupFromDateStr = utcDateStr(filters.from);
324
+ // If the user's window ends before today's UTC midnight, rollup covers the
325
+ // full window and there's no live component.
326
+ const rollupOnlyCutoff = filters.to <= todayUtcStart ? filters.to : todayUtcStart;
327
+ const rollupToDateStr = utcDateStr(rollupOnlyCutoff);
328
+ const rollupPart = await aggregateFromRollups(db, rollupFromDateStr,
329
+ // Upper bound is exclusive (lt on date string). `rollupEndDateStr` is
330
+ // today's date, so lt excludes today and includes through yesterday.
331
+ // When the window ends before today (rollup-only path), the upper bound
332
+ // is the window's `to` date so lt(date, windowTo) includes everything
333
+ // strictly before windowTo's UTC date.
334
+ rollupOnlyCutoff < todayUtcStart ? rollupToDateStr : rollupEndDateStr, { from: filters.from, to: filters.to }, hourlyRate);
335
+ // If the window ends before today's midnight, we're done.
336
+ if (filters.to <= todayUtcStart) {
337
+ log.debug({ from: rollupFromDateStr, to: rollupToDateStr }, "aggregateHybrid: rollup-only path");
338
+ return rollupPart;
339
+ }
340
+ // Live query for today's partial data [todayUtcStart, filters.to).
341
+ const livePart = await aggregateAll(db, { from: todayUtcStart, to: filters.to }, config, opts);
342
+ log.debug({ rollupDays: rollupFromDateStr + "..." + rollupEndDateStr, liveFrom: todayUtcStart.toISOString() }, "aggregateHybrid: rollup + live merge");
343
+ // Merge summary
344
+ const mergedSummary = {
345
+ window: { from: filters.from, to: filters.to },
346
+ runs: rollupPart.summary.runs + livePart.summary.runs,
347
+ prsMerged: rollupPart.summary.prsMerged + livePart.summary.prsMerged,
348
+ inputTokens: rollupPart.summary.inputTokens + livePart.summary.inputTokens,
349
+ outputTokens: rollupPart.summary.outputTokens + livePart.summary.outputTokens,
350
+ dollars: rollupPart.summary.dollars + livePart.summary.dollars,
351
+ timeSavedHours: rollupPart.summary.timeSavedHours + livePart.summary.timeSavedHours,
352
+ roiMultiplier: 0,
353
+ ...(livePart.summary.truncated ? { truncated: true } : {}),
354
+ };
355
+ mergedSummary.roiMultiplier = finalizeRoi(mergedSummary, hourlyRate);
356
+ return {
357
+ summary: mergedSummary,
358
+ byTeam: mergeBreakdowns(rollupPart.byTeam, livePart.byTeam, hourlyRate),
359
+ byRepo: mergeBreakdowns(rollupPart.byRepo, livePart.byRepo, hourlyRate),
360
+ byPipeline: mergeBreakdowns(rollupPart.byPipeline, livePart.byPipeline, hourlyRate),
361
+ byDay: mergeDailyRows(rollupPart.byDay, livePart.byDay),
362
+ };
363
+ }
364
+ //# sourceMappingURL=aggregate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aggregate.js","sourceRoot":"","sources":["../../src/cost/aggregate.ts"],"names":[],"mappings":"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"}