@tellescope/sdk 1.256.14 → 1.256.15

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 (283) hide show
  1. package/lib/cjs/tests/api_tests/auto_merge_form_submission.test.js +1 -1
  2. package/lib/cjs/tests/api_tests/auto_merge_form_submission.test.js.map +1 -1
  3. package/lib/cjs/tests/api_tests/enduser_observations_auto_review.test.d.ts +5 -0
  4. package/lib/cjs/tests/api_tests/enduser_observations_auto_review.test.d.ts.map +1 -0
  5. package/lib/cjs/tests/api_tests/enduser_observations_auto_review.test.js +388 -0
  6. package/lib/cjs/tests/api_tests/enduser_observations_auto_review.test.js.map +1 -0
  7. package/lib/cjs/tests/api_tests/integrations_redacted.test.js +3 -3
  8. package/lib/cjs/tests/api_tests/integrations_redacted.test.js.map +1 -1
  9. package/lib/cjs/tests/api_tests/organization_signup.test.d.ts +1 -1
  10. package/lib/cjs/tests/api_tests/organization_signup.test.js +1 -1
  11. package/lib/cjs/tests/api_tests/purchase_made_trigger.test.d.ts.map +1 -1
  12. package/lib/cjs/tests/api_tests/purchase_made_trigger.test.js +103 -162
  13. package/lib/cjs/tests/api_tests/purchase_made_trigger.test.js.map +1 -1
  14. package/lib/cjs/tests/api_tests/security/F-0200-form-logic-js-execution.test.d.ts +33 -0
  15. package/lib/cjs/tests/api_tests/security/F-0200-form-logic-js-execution.test.d.ts.map +1 -0
  16. package/lib/cjs/tests/api_tests/security/F-0200-form-logic-js-execution.test.js +249 -0
  17. package/lib/cjs/tests/api_tests/security/F-0200-form-logic-js-execution.test.js.map +1 -0
  18. package/lib/cjs/tests/api_tests/security/add-to-journey-foreign-enduserid.test.d.ts +42 -0
  19. package/lib/cjs/tests/api_tests/security/add-to-journey-foreign-enduserid.test.d.ts.map +1 -0
  20. package/lib/cjs/tests/api_tests/security/add-to-journey-foreign-enduserid.test.js +281 -0
  21. package/lib/cjs/tests/api_tests/security/add-to-journey-foreign-enduserid.test.js.map +1 -0
  22. package/lib/cjs/tests/api_tests/security/ai-conversations-rbac.test.d.ts +38 -0
  23. package/lib/cjs/tests/api_tests/security/ai-conversations-rbac.test.d.ts.map +1 -0
  24. package/lib/cjs/tests/api_tests/security/ai-conversations-rbac.test.js +390 -0
  25. package/lib/cjs/tests/api_tests/security/ai-conversations-rbac.test.js.map +1 -0
  26. package/lib/cjs/tests/api_tests/security/allowed-paths-confinement.test.d.ts +6 -0
  27. package/lib/cjs/tests/api_tests/security/allowed-paths-confinement.test.d.ts.map +1 -0
  28. package/lib/cjs/tests/api_tests/security/allowed-paths-confinement.test.js +1003 -0
  29. package/lib/cjs/tests/api_tests/security/allowed-paths-confinement.test.js.map +1 -0
  30. package/lib/cjs/tests/api_tests/security/automated-actions-process-gate.test.d.ts +42 -0
  31. package/lib/cjs/tests/api_tests/security/automated-actions-process-gate.test.d.ts.map +1 -0
  32. package/lib/cjs/tests/api_tests/security/automated-actions-process-gate.test.js +323 -0
  33. package/lib/cjs/tests/api_tests/security/automated-actions-process-gate.test.js.map +1 -0
  34. package/lib/cjs/tests/api_tests/security/booking-info-idor-token-mint.test.d.ts +29 -0
  35. package/lib/cjs/tests/api_tests/security/booking-info-idor-token-mint.test.d.ts.map +1 -0
  36. package/lib/cjs/tests/api_tests/security/booking-info-idor-token-mint.test.js +335 -0
  37. package/lib/cjs/tests/api_tests/security/booking-info-idor-token-mint.test.js.map +1 -0
  38. package/lib/cjs/tests/api_tests/security/cascade-role-rename-cross-tenant.test.d.ts +32 -0
  39. package/lib/cjs/tests/api_tests/security/cascade-role-rename-cross-tenant.test.d.ts.map +1 -0
  40. package/lib/cjs/tests/api_tests/security/cascade-role-rename-cross-tenant.test.js +237 -0
  41. package/lib/cjs/tests/api_tests/security/cascade-role-rename-cross-tenant.test.js.map +1 -0
  42. package/lib/cjs/tests/api_tests/security/data-sync-redaction-bypass.test.d.ts +28 -0
  43. package/lib/cjs/tests/api_tests/security/data-sync-redaction-bypass.test.d.ts.map +1 -0
  44. package/lib/cjs/tests/api_tests/security/data-sync-redaction-bypass.test.js +349 -0
  45. package/lib/cjs/tests/api_tests/security/data-sync-redaction-bypass.test.js.map +1 -0
  46. package/lib/cjs/tests/api_tests/security/develop-health-benefit-verification-rbac.test.d.ts +30 -0
  47. package/lib/cjs/tests/api_tests/security/develop-health-benefit-verification-rbac.test.d.ts.map +1 -0
  48. package/lib/cjs/tests/api_tests/security/develop-health-benefit-verification-rbac.test.js +314 -0
  49. package/lib/cjs/tests/api_tests/security/develop-health-benefit-verification-rbac.test.js.map +1 -0
  50. package/lib/cjs/tests/api_tests/security/enduser-cross-create.test.d.ts +21 -0
  51. package/lib/cjs/tests/api_tests/security/enduser-cross-create.test.d.ts.map +1 -0
  52. package/lib/cjs/tests/api_tests/security/enduser-cross-create.test.js +362 -0
  53. package/lib/cjs/tests/api_tests/security/enduser-cross-create.test.js.map +1 -0
  54. package/lib/cjs/tests/api_tests/security/enduser-write-restrictions.test.d.ts +21 -0
  55. package/lib/cjs/tests/api_tests/security/enduser-write-restrictions.test.d.ts.map +1 -0
  56. package/lib/cjs/tests/api_tests/security/enduser-write-restrictions.test.js +366 -0
  57. package/lib/cjs/tests/api_tests/security/enduser-write-restrictions.test.js.map +1 -0
  58. package/lib/cjs/tests/api_tests/security/form-logic-js-execution.test.d.ts +32 -0
  59. package/lib/cjs/tests/api_tests/security/form-logic-js-execution.test.d.ts.map +1 -0
  60. package/lib/cjs/tests/api_tests/security/form-logic-js-execution.test.js +248 -0
  61. package/lib/cjs/tests/api_tests/security/form-logic-js-execution.test.js.map +1 -0
  62. package/lib/cjs/tests/api_tests/security/globalunique-conflict-redaction.test.d.ts +19 -0
  63. package/lib/cjs/tests/api_tests/security/globalunique-conflict-redaction.test.d.ts.map +1 -0
  64. package/lib/cjs/tests/api_tests/security/globalunique-conflict-redaction.test.js +138 -0
  65. package/lib/cjs/tests/api_tests/security/globalunique-conflict-redaction.test.js.map +1 -0
  66. package/lib/cjs/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.d.ts +24 -0
  67. package/lib/cjs/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.d.ts.map +1 -0
  68. package/lib/cjs/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.js +201 -0
  69. package/lib/cjs/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.js.map +1 -0
  70. package/lib/cjs/tests/api_tests/security/invite-user-enumeration.test.d.ts +29 -0
  71. package/lib/cjs/tests/api_tests/security/invite-user-enumeration.test.d.ts.map +1 -0
  72. package/lib/cjs/tests/api_tests/security/invite-user-enumeration.test.js +278 -0
  73. package/lib/cjs/tests/api_tests/security/invite-user-enumeration.test.js.map +1 -0
  74. package/lib/cjs/tests/api_tests/security/load-inbox-redaction.test.d.ts +17 -0
  75. package/lib/cjs/tests/api_tests/security/load-inbox-redaction.test.d.ts.map +1 -0
  76. package/lib/cjs/tests/api_tests/security/load-inbox-redaction.test.js +155 -0
  77. package/lib/cjs/tests/api_tests/security/load-inbox-redaction.test.js.map +1 -0
  78. package/lib/cjs/tests/api_tests/security/prototype-pollution.test.d.ts +2 -0
  79. package/lib/cjs/tests/api_tests/security/prototype-pollution.test.d.ts.map +1 -0
  80. package/lib/cjs/tests/api_tests/security/prototype-pollution.test.js +88 -0
  81. package/lib/cjs/tests/api_tests/security/prototype-pollution.test.js.map +1 -0
  82. package/lib/cjs/tests/api_tests/security/proxy-image-unauth-ssrf.test.d.ts +34 -0
  83. package/lib/cjs/tests/api_tests/security/proxy-image-unauth-ssrf.test.d.ts.map +1 -0
  84. package/lib/cjs/tests/api_tests/security/proxy-image-unauth-ssrf.test.js +230 -0
  85. package/lib/cjs/tests/api_tests/security/proxy-image-unauth-ssrf.test.js.map +1 -0
  86. package/lib/cjs/tests/api_tests/security/sanitize-user-html-with-iframes.test.d.ts +2 -0
  87. package/lib/cjs/tests/api_tests/security/sanitize-user-html-with-iframes.test.d.ts.map +1 -0
  88. package/lib/cjs/tests/api_tests/security/sanitize-user-html-with-iframes.test.js +242 -0
  89. package/lib/cjs/tests/api_tests/security/sanitize-user-html-with-iframes.test.js.map +1 -0
  90. package/lib/cjs/tests/api_tests/security/sanitize-user-html.test.d.ts +2 -0
  91. package/lib/cjs/tests/api_tests/security/sanitize-user-html.test.d.ts.map +1 -0
  92. package/lib/cjs/tests/api_tests/security/sanitize-user-html.test.js +148 -0
  93. package/lib/cjs/tests/api_tests/security/sanitize-user-html.test.js.map +1 -0
  94. package/lib/cjs/tests/api_tests/security/schema-adminonly-enforcement.test.d.ts +45 -0
  95. package/lib/cjs/tests/api_tests/security/schema-adminonly-enforcement.test.d.ts.map +1 -0
  96. package/lib/cjs/tests/api_tests/security/schema-adminonly-enforcement.test.js +388 -0
  97. package/lib/cjs/tests/api_tests/security/schema-adminonly-enforcement.test.js.map +1 -0
  98. package/lib/cjs/tests/api_tests/security/self-admin-role-assignment.test.d.ts +38 -0
  99. package/lib/cjs/tests/api_tests/security/self-admin-role-assignment.test.d.ts.map +1 -0
  100. package/lib/cjs/tests/api_tests/security/self-admin-role-assignment.test.js +222 -0
  101. package/lib/cjs/tests/api_tests/security/self-admin-role-assignment.test.js.map +1 -0
  102. package/lib/cjs/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.d.ts +6 -0
  103. package/lib/cjs/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.d.ts.map +1 -0
  104. package/lib/cjs/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.js +354 -0
  105. package/lib/cjs/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.js.map +1 -0
  106. package/lib/cjs/tests/api_tests/security/webhook-outbound-ssrf.test.d.ts +28 -0
  107. package/lib/cjs/tests/api_tests/security/webhook-outbound-ssrf.test.d.ts.map +1 -0
  108. package/lib/cjs/tests/api_tests/security/webhook-outbound-ssrf.test.js +442 -0
  109. package/lib/cjs/tests/api_tests/security/webhook-outbound-ssrf.test.js.map +1 -0
  110. package/lib/cjs/tests/api_tests/security/webhook-timeout.test.d.ts +19 -0
  111. package/lib/cjs/tests/api_tests/security/webhook-timeout.test.d.ts.map +1 -0
  112. package/lib/cjs/tests/api_tests/security/webhook-timeout.test.js +156 -0
  113. package/lib/cjs/tests/api_tests/security/webhook-timeout.test.js.map +1 -0
  114. package/lib/cjs/tests/api_tests/webhook_error_handling.test.js +2 -2
  115. package/lib/cjs/tests/api_tests/webhook_error_handling.test.js.map +1 -1
  116. package/lib/cjs/tests/tests.d.ts.map +1 -1
  117. package/lib/cjs/tests/tests.js +58 -46
  118. package/lib/cjs/tests/tests.js.map +1 -1
  119. package/lib/cjs/tests/unit_tests/openapi_spec_freshness.test.d.ts +1 -1
  120. package/lib/cjs/tests/unit_tests/openapi_spec_freshness.test.js +1 -1
  121. package/lib/cjs/tsconfig.cjs.tsbuildinfo +1 -0
  122. package/lib/esm/enduser.d.ts +0 -1
  123. package/lib/esm/enduser.d.ts.map +1 -1
  124. package/lib/esm/sdk.d.ts +2 -3
  125. package/lib/esm/sdk.d.ts.map +1 -1
  126. package/lib/esm/session.d.ts +0 -1
  127. package/lib/esm/session.d.ts.map +1 -1
  128. package/lib/esm/tests/api_tests/auto_merge_form_submission.test.js +1 -1
  129. package/lib/esm/tests/api_tests/auto_merge_form_submission.test.js.map +1 -1
  130. package/lib/esm/tests/api_tests/enduser_observations_auto_review.test.d.ts +5 -0
  131. package/lib/esm/tests/api_tests/enduser_observations_auto_review.test.d.ts.map +1 -0
  132. package/lib/esm/tests/api_tests/enduser_observations_auto_review.test.js +383 -0
  133. package/lib/esm/tests/api_tests/enduser_observations_auto_review.test.js.map +1 -0
  134. package/lib/esm/tests/api_tests/integrations_redacted.test.js +3 -3
  135. package/lib/esm/tests/api_tests/integrations_redacted.test.js.map +1 -1
  136. package/lib/esm/tests/api_tests/organization_signup.test.d.ts +1 -1
  137. package/lib/esm/tests/api_tests/organization_signup.test.js +1 -1
  138. package/lib/esm/tests/api_tests/purchase_made_trigger.test.d.ts.map +1 -1
  139. package/lib/esm/tests/api_tests/purchase_made_trigger.test.js +104 -163
  140. package/lib/esm/tests/api_tests/purchase_made_trigger.test.js.map +1 -1
  141. package/lib/esm/tests/api_tests/security/F-0200-form-logic-js-execution.test.d.ts +33 -0
  142. package/lib/esm/tests/api_tests/security/F-0200-form-logic-js-execution.test.d.ts.map +1 -0
  143. package/lib/esm/tests/api_tests/security/F-0200-form-logic-js-execution.test.js +244 -0
  144. package/lib/esm/tests/api_tests/security/F-0200-form-logic-js-execution.test.js.map +1 -0
  145. package/lib/esm/tests/api_tests/security/add-to-journey-foreign-enduserid.test.d.ts +42 -0
  146. package/lib/esm/tests/api_tests/security/add-to-journey-foreign-enduserid.test.d.ts.map +1 -0
  147. package/lib/esm/tests/api_tests/security/add-to-journey-foreign-enduserid.test.js +276 -0
  148. package/lib/esm/tests/api_tests/security/add-to-journey-foreign-enduserid.test.js.map +1 -0
  149. package/lib/esm/tests/api_tests/security/ai-conversations-rbac.test.d.ts +38 -0
  150. package/lib/esm/tests/api_tests/security/ai-conversations-rbac.test.d.ts.map +1 -0
  151. package/lib/esm/tests/api_tests/security/ai-conversations-rbac.test.js +386 -0
  152. package/lib/esm/tests/api_tests/security/ai-conversations-rbac.test.js.map +1 -0
  153. package/lib/esm/tests/api_tests/security/allowed-paths-confinement.test.d.ts +6 -0
  154. package/lib/esm/tests/api_tests/security/allowed-paths-confinement.test.d.ts.map +1 -0
  155. package/lib/esm/tests/api_tests/security/allowed-paths-confinement.test.js +996 -0
  156. package/lib/esm/tests/api_tests/security/allowed-paths-confinement.test.js.map +1 -0
  157. package/lib/esm/tests/api_tests/security/automated-actions-process-gate.test.d.ts +42 -0
  158. package/lib/esm/tests/api_tests/security/automated-actions-process-gate.test.d.ts.map +1 -0
  159. package/lib/esm/tests/api_tests/security/automated-actions-process-gate.test.js +316 -0
  160. package/lib/esm/tests/api_tests/security/automated-actions-process-gate.test.js.map +1 -0
  161. package/lib/esm/tests/api_tests/security/booking-info-idor-token-mint.test.d.ts +29 -0
  162. package/lib/esm/tests/api_tests/security/booking-info-idor-token-mint.test.d.ts.map +1 -0
  163. package/lib/esm/tests/api_tests/security/booking-info-idor-token-mint.test.js +331 -0
  164. package/lib/esm/tests/api_tests/security/booking-info-idor-token-mint.test.js.map +1 -0
  165. package/lib/esm/tests/api_tests/security/cascade-role-rename-cross-tenant.test.d.ts +32 -0
  166. package/lib/esm/tests/api_tests/security/cascade-role-rename-cross-tenant.test.d.ts.map +1 -0
  167. package/lib/esm/tests/api_tests/security/cascade-role-rename-cross-tenant.test.js +233 -0
  168. package/lib/esm/tests/api_tests/security/cascade-role-rename-cross-tenant.test.js.map +1 -0
  169. package/lib/esm/tests/api_tests/security/data-sync-redaction-bypass.test.d.ts +28 -0
  170. package/lib/esm/tests/api_tests/security/data-sync-redaction-bypass.test.d.ts.map +1 -0
  171. package/lib/esm/tests/api_tests/security/data-sync-redaction-bypass.test.js +345 -0
  172. package/lib/esm/tests/api_tests/security/data-sync-redaction-bypass.test.js.map +1 -0
  173. package/lib/esm/tests/api_tests/security/develop-health-benefit-verification-rbac.test.d.ts +30 -0
  174. package/lib/esm/tests/api_tests/security/develop-health-benefit-verification-rbac.test.d.ts.map +1 -0
  175. package/lib/esm/tests/api_tests/security/develop-health-benefit-verification-rbac.test.js +310 -0
  176. package/lib/esm/tests/api_tests/security/develop-health-benefit-verification-rbac.test.js.map +1 -0
  177. package/lib/esm/tests/api_tests/security/enduser-cross-create.test.d.ts +21 -0
  178. package/lib/esm/tests/api_tests/security/enduser-cross-create.test.d.ts.map +1 -0
  179. package/lib/esm/tests/api_tests/security/enduser-cross-create.test.js +358 -0
  180. package/lib/esm/tests/api_tests/security/enduser-cross-create.test.js.map +1 -0
  181. package/lib/esm/tests/api_tests/security/enduser-write-restrictions.test.d.ts +21 -0
  182. package/lib/esm/tests/api_tests/security/enduser-write-restrictions.test.d.ts.map +1 -0
  183. package/lib/esm/tests/api_tests/security/enduser-write-restrictions.test.js +362 -0
  184. package/lib/esm/tests/api_tests/security/enduser-write-restrictions.test.js.map +1 -0
  185. package/lib/esm/tests/api_tests/security/form-logic-js-execution.test.d.ts +32 -0
  186. package/lib/esm/tests/api_tests/security/form-logic-js-execution.test.d.ts.map +1 -0
  187. package/lib/esm/tests/api_tests/security/form-logic-js-execution.test.js +243 -0
  188. package/lib/esm/tests/api_tests/security/form-logic-js-execution.test.js.map +1 -0
  189. package/lib/esm/tests/api_tests/security/globalunique-conflict-redaction.test.d.ts +19 -0
  190. package/lib/esm/tests/api_tests/security/globalunique-conflict-redaction.test.d.ts.map +1 -0
  191. package/lib/esm/tests/api_tests/security/globalunique-conflict-redaction.test.js +134 -0
  192. package/lib/esm/tests/api_tests/security/globalunique-conflict-redaction.test.js.map +1 -0
  193. package/lib/esm/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.d.ts +24 -0
  194. package/lib/esm/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.d.ts.map +1 -0
  195. package/lib/esm/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.js +194 -0
  196. package/lib/esm/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.js.map +1 -0
  197. package/lib/esm/tests/api_tests/security/invite-user-enumeration.test.d.ts +29 -0
  198. package/lib/esm/tests/api_tests/security/invite-user-enumeration.test.d.ts.map +1 -0
  199. package/lib/esm/tests/api_tests/security/invite-user-enumeration.test.js +271 -0
  200. package/lib/esm/tests/api_tests/security/invite-user-enumeration.test.js.map +1 -0
  201. package/lib/esm/tests/api_tests/security/load-inbox-redaction.test.d.ts +17 -0
  202. package/lib/esm/tests/api_tests/security/load-inbox-redaction.test.d.ts.map +1 -0
  203. package/lib/esm/tests/api_tests/security/load-inbox-redaction.test.js +151 -0
  204. package/lib/esm/tests/api_tests/security/load-inbox-redaction.test.js.map +1 -0
  205. package/lib/esm/tests/api_tests/security/prototype-pollution.test.d.ts +2 -0
  206. package/lib/esm/tests/api_tests/security/prototype-pollution.test.d.ts.map +1 -0
  207. package/lib/esm/tests/api_tests/security/prototype-pollution.test.js +84 -0
  208. package/lib/esm/tests/api_tests/security/prototype-pollution.test.js.map +1 -0
  209. package/lib/esm/tests/api_tests/security/proxy-image-unauth-ssrf.test.d.ts +34 -0
  210. package/lib/esm/tests/api_tests/security/proxy-image-unauth-ssrf.test.d.ts.map +1 -0
  211. package/lib/esm/tests/api_tests/security/proxy-image-unauth-ssrf.test.js +223 -0
  212. package/lib/esm/tests/api_tests/security/proxy-image-unauth-ssrf.test.js.map +1 -0
  213. package/lib/esm/tests/api_tests/security/sanitize-user-html-with-iframes.test.d.ts +2 -0
  214. package/lib/esm/tests/api_tests/security/sanitize-user-html-with-iframes.test.d.ts.map +1 -0
  215. package/lib/esm/tests/api_tests/security/sanitize-user-html-with-iframes.test.js +238 -0
  216. package/lib/esm/tests/api_tests/security/sanitize-user-html-with-iframes.test.js.map +1 -0
  217. package/lib/esm/tests/api_tests/security/sanitize-user-html.test.d.ts +2 -0
  218. package/lib/esm/tests/api_tests/security/sanitize-user-html.test.d.ts.map +1 -0
  219. package/lib/esm/tests/api_tests/security/sanitize-user-html.test.js +144 -0
  220. package/lib/esm/tests/api_tests/security/sanitize-user-html.test.js.map +1 -0
  221. package/lib/esm/tests/api_tests/security/schema-adminonly-enforcement.test.d.ts +45 -0
  222. package/lib/esm/tests/api_tests/security/schema-adminonly-enforcement.test.d.ts.map +1 -0
  223. package/lib/esm/tests/api_tests/security/schema-adminonly-enforcement.test.js +381 -0
  224. package/lib/esm/tests/api_tests/security/schema-adminonly-enforcement.test.js.map +1 -0
  225. package/lib/esm/tests/api_tests/security/self-admin-role-assignment.test.d.ts +38 -0
  226. package/lib/esm/tests/api_tests/security/self-admin-role-assignment.test.d.ts.map +1 -0
  227. package/lib/esm/tests/api_tests/security/self-admin-role-assignment.test.js +218 -0
  228. package/lib/esm/tests/api_tests/security/self-admin-role-assignment.test.js.map +1 -0
  229. package/lib/esm/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.d.ts +6 -0
  230. package/lib/esm/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.d.ts.map +1 -0
  231. package/lib/esm/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.js +350 -0
  232. package/lib/esm/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.js.map +1 -0
  233. package/lib/esm/tests/api_tests/security/webhook-outbound-ssrf.test.d.ts +28 -0
  234. package/lib/esm/tests/api_tests/security/webhook-outbound-ssrf.test.d.ts.map +1 -0
  235. package/lib/esm/tests/api_tests/security/webhook-outbound-ssrf.test.js +435 -0
  236. package/lib/esm/tests/api_tests/security/webhook-outbound-ssrf.test.js.map +1 -0
  237. package/lib/esm/tests/api_tests/security/webhook-timeout.test.d.ts +19 -0
  238. package/lib/esm/tests/api_tests/security/webhook-timeout.test.d.ts.map +1 -0
  239. package/lib/esm/tests/api_tests/security/webhook-timeout.test.js +149 -0
  240. package/lib/esm/tests/api_tests/security/webhook-timeout.test.js.map +1 -0
  241. package/lib/esm/tests/api_tests/webhook_error_handling.test.js +2 -2
  242. package/lib/esm/tests/api_tests/webhook_error_handling.test.js.map +1 -1
  243. package/lib/esm/tests/tests.d.ts.map +1 -1
  244. package/lib/esm/tests/tests.js +36 -24
  245. package/lib/esm/tests/tests.js.map +1 -1
  246. package/lib/esm/tests/unit_tests/openapi_spec_freshness.test.d.ts +1 -1
  247. package/lib/esm/tests/unit_tests/openapi_spec_freshness.test.js +1 -1
  248. package/lib/tsconfig.tsbuildinfo +1 -1
  249. package/package.json +10 -10
  250. package/src/tests/api_tests/auto_merge_form_submission.test.ts +1 -1
  251. package/src/tests/api_tests/enduser_observations_auto_review.test.ts +358 -0
  252. package/src/tests/api_tests/integrations_redacted.test.ts +1 -1
  253. package/src/tests/api_tests/organization_signup.test.ts +2 -2
  254. package/src/tests/api_tests/purchase_made_trigger.test.ts +29 -41
  255. package/src/tests/api_tests/security/{F-0196-add-to-journey-foreign-enduserid.test.ts → add-to-journey-foreign-enduserid.test.ts} +6 -7
  256. package/src/tests/api_tests/security/{F-0005-ai-conversations-rbac.test.ts → ai-conversations-rbac.test.ts} +14 -14
  257. package/src/tests/api_tests/security/{F-0166-allowed-paths-wildcard-bypass.test.ts → allowed-paths-confinement.test.ts} +11 -11
  258. package/src/tests/api_tests/security/{F-0192-automated-actions-process-gate.test.ts → automated-actions-process-gate.test.ts} +6 -7
  259. package/src/tests/api_tests/security/{F-0179-booking-info-idor-token-mint.test.ts → booking-info-idor-token-mint.test.ts} +5 -6
  260. package/src/tests/api_tests/security/{F-0053-cascade-role-rename-cross-tenant.test.ts → cascade-role-rename-cross-tenant.test.ts} +10 -10
  261. package/src/tests/api_tests/security/{F-0001-data-sync-redaction-bypass.test.ts → data-sync-redaction-bypass.test.ts} +9 -9
  262. package/src/tests/api_tests/security/{F-0006-develop-health-benefit-verification-rbac.test.ts → develop-health-benefit-verification-rbac.test.ts} +7 -8
  263. package/src/tests/api_tests/security/{F-0116-F-0119-enduser-cross-create.test.ts → enduser-cross-create.test.ts} +25 -25
  264. package/src/tests/api_tests/security/{F-0106-F-0110-enduser-write-restrictions.test.ts → enduser-write-restrictions.test.ts} +12 -14
  265. package/src/tests/api_tests/security/form-logic-js-execution.test.ts +183 -0
  266. package/src/tests/api_tests/security/{F-0145-globalunique-leak.test.ts → globalunique-conflict-redaction.test.ts} +5 -6
  267. package/src/tests/api_tests/security/{F-0008-handle-incoming-communication-cross-tenant.test.ts → handle-incoming-communication-cross-tenant.test.ts} +8 -8
  268. package/src/tests/api_tests/security/{F-0007-invite-user-enumeration.test.ts → invite-user-enumeration.test.ts} +8 -8
  269. package/src/tests/api_tests/security/{F-0151-load-inbox-redaction.test.ts → load-inbox-redaction.test.ts} +5 -6
  270. package/src/tests/api_tests/security/{F-0016-prototype-pollution.test.ts → prototype-pollution.test.ts} +4 -4
  271. package/src/tests/api_tests/security/{F-0025-proxy-image-unauth-ssrf.test.ts → proxy-image-unauth-ssrf.test.ts} +11 -12
  272. package/src/tests/api_tests/security/{F-0013-sanitize-user-html-with-iframes.test.ts → sanitize-user-html-with-iframes.test.ts} +5 -5
  273. package/src/tests/api_tests/security/{F-0013-sanitize-user-html.test.ts → sanitize-user-html.test.ts} +4 -4
  274. package/src/tests/api_tests/security/{F-0191-schema-adminonly-enforcement.test.ts → schema-adminonly-enforcement.test.ts} +6 -7
  275. package/src/tests/api_tests/security/{F-0076-self-admin-role-assignment.test.ts → self-admin-role-assignment.test.ts} +13 -13
  276. package/src/tests/api_tests/security/{F-0185-startlinktoken-enduser-staff-escalation.test.ts → startlinktoken-enduser-staff-escalation.test.ts} +6 -6
  277. package/src/tests/api_tests/security/{F-0015-webhook-outbound-ssrf.test.ts → webhook-outbound-ssrf.test.ts} +13 -14
  278. package/src/tests/api_tests/security/{F-0155-webhook-timeout.test.ts → webhook-timeout.test.ts} +6 -7
  279. package/src/tests/api_tests/webhook_error_handling.test.ts +1 -1
  280. package/src/tests/tests.ts +41 -24
  281. package/src/tests/unit_tests/openapi_spec_freshness.test.ts +1 -1
  282. package/test_generated.pdf +0 -0
  283. package/src/tests/api_tests/security/readonly-enduser-preview.test.ts +0 -301
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tellescope/sdk",
3
- "version": "1.256.14",
3
+ "version": "1.256.15",
4
4
  "description": "Code for interacting with the Tellescope API",
5
5
  "main": "./lib/cjs/sdk.js",
6
6
  "module": "./lib/esm/sdk.js",
@@ -32,14 +32,14 @@
32
32
  },
33
33
  "homepage": "https://github.com/tellescope-os/tellescope#readme",
34
34
  "dependencies": {
35
- "@tellescope/constants": "1.256.14",
36
- "@tellescope/schema": "1.256.14",
37
- "@tellescope/testing": "1.256.14",
38
- "@tellescope/types-client": "1.256.14",
39
- "@tellescope/types-models": "1.256.14",
40
- "@tellescope/types-utilities": "1.256.14",
41
- "@tellescope/utilities": "1.256.14",
42
- "@tellescope/validation": "1.256.14",
35
+ "@tellescope/constants": "1.256.15",
36
+ "@tellescope/schema": "1.256.15",
37
+ "@tellescope/testing": "1.256.15",
38
+ "@tellescope/types-client": "1.256.15",
39
+ "@tellescope/types-models": "1.256.15",
40
+ "@tellescope/types-utilities": "1.256.15",
41
+ "@tellescope/utilities": "1.256.15",
42
+ "@tellescope/validation": "1.256.15",
43
43
  "axios": "0.30.3",
44
44
  "dotenv": "14.3.2",
45
45
  "form-data": "4.0.4",
@@ -55,5 +55,5 @@
55
55
  "publishConfig": {
56
56
  "access": "public"
57
57
  },
58
- "gitHead": "0b32ba0040e286c4a1013287f9e154e612db11af"
58
+ "gitHead": "180f82301125bdd5e73608991061e49ed3d41e96"
59
59
  }
@@ -589,7 +589,7 @@ export const auto_merge_form_submission_tests = async ({ sdk, sdkNonAdmin }: { s
589
589
  // Filling a BLANK phone is deliberately blocked too — contact-less patients are the primary
590
590
  // takeover target, so "fill only if empty" would not close the hole. Staff update these fields.
591
591
  // Previously this test asserted `phone === newPhone`; that behaviour was the vulnerability.
592
- // See api_tests/security/public_endpoint_auth_field_lock.test.ts (G26).
592
+ // See api_tests/security/public_endpoint_auth_field_lock.test.ts.
593
593
  && !updatedDestination.phone
594
594
  && updatedDestination.email === testEmail
595
595
  },
@@ -0,0 +1,358 @@
1
+ require('source-map-support').install();
2
+
3
+ import { SYSTEM_REVIEWER_ID } from "@tellescope/constants"
4
+ import {
5
+ assert_checks,
6
+ Check,
7
+ setup_isolated_tenant,
8
+ } from "../setup_isolated"
9
+
10
+ const host = process.env.API_URL || 'http://localhost:8080' as const
11
+
12
+ const RAND = () => Math.random().toString(36).slice(2, 10)
13
+
14
+ /**
15
+ * Coverage for auto-review of in-range vital readings — the `autoReview` flag on
16
+ * `vital_configurations.ranges`, applied inside `handle_vital_create` at the moment a reading is
17
+ * classified. For RPM-style programs most readings are in range, and clearing them one at a time
18
+ * out of the unreviewed-vitals queue is pure busywork; a range marked auto-review sets
19
+ * `reviewedAt` + `reviewedBy = SYSTEM_REVIEWER_ID` on the same update that writes classifications.
20
+ *
21
+ * The rule under test is deliberately strict: a reading gets one classification per MATCHING
22
+ * configuration, and auto-review happens only when EVERY one of those classifications came from an
23
+ * autoReview range. C is the check that pins this — a reading that is in-range under one
24
+ * configuration but caught by a non-auto-review range under another still needs a human, because
25
+ * the second configuration is the one expressing clinical concern.
26
+ *
27
+ * Vital configurations are business-wide (the handler reads them with `enduserId: { $exists: false }`
28
+ * over the caller's businessId), so this suite provisions its own throwaway tenant: without that it
29
+ * would classify — and auto-review — other concurrently running suites' readings, and theirs would
30
+ * bleed into these checks. It never calls `sdk.reset_db()`, which clears global throttle namespaces.
31
+ *
32
+ * Units come from the fixed VITAL_UNITS list, so checks that must not see each other's
33
+ * configurations are separated by unit rather than by name: SBP for A/B, DBP for the multi-config
34
+ * rule, A1C for the uncovered case.
35
+ *
36
+ * Classification is an asynchronous create side effect, so every read polls.
37
+ */
38
+
39
+ const poll_for = async <T,>(get: () => Promise<T>, done: (v: T) => boolean, attempts=20): Promise<T> => {
40
+ let value = await get()
41
+ for (let i = 0; i < attempts && !done(value); i++) {
42
+ await new Promise(resolve => setTimeout(resolve, 250))
43
+ value = await get()
44
+ }
45
+ return value
46
+ }
47
+
48
+ export const enduser_observations_auto_review_checks = async (): Promise<Check[]> => {
49
+ const checks: Check[] = []
50
+ const record = (label: string, pass: boolean, detail: string) => checks.push({ label, pass, detail })
51
+
52
+ let tenant: Awaited<ReturnType<typeof setup_isolated_tenant>> | undefined
53
+
54
+ try {
55
+ tenant = await setup_isolated_tenant({
56
+ name: `VitalAutoReview ${RAND()}`,
57
+ users: [{ isAdmin: true }],
58
+ apiKeys: 0,
59
+ })
60
+ const { sdk } = tenant
61
+
62
+ const enduser = await sdk.api.endusers.createOne({ fname: 'AutoReview', lname: 'Patient' })
63
+
64
+ const create_reading = (unit: string, value: number) => (
65
+ sdk.api.enduser_observations.createOne({
66
+ category: 'vital-signs',
67
+ status: 'final',
68
+ enduserId: enduser.id,
69
+ measurement: { unit, value },
70
+ timestamp: new Date(),
71
+ })
72
+ )
73
+
74
+ /* ===== A / B: one configuration, Target auto-reviews and High does not ===== */
75
+
76
+ await sdk.api.vital_configurations.createOne({
77
+ title: `AutoReview SBP ${RAND()}`,
78
+ unit: 'SBP',
79
+ ranges: [
80
+ {
81
+ classification: 'Target',
82
+ comparison: { type: 'Between', value: { lower: 100, upper: 200 } },
83
+ autoReview: true,
84
+ },
85
+ {
86
+ classification: 'High',
87
+ comparison: { type: 'Greater Than', value: 200 },
88
+ },
89
+ ],
90
+ })
91
+
92
+ /* ===== A: an in-range reading is reviewed automatically ===== */
93
+
94
+ const inRange = await create_reading('SBP', 150)
95
+ const inRangeAfter = await poll_for(
96
+ () => sdk.api.enduser_observations.getOne(inRange.id),
97
+ o => !!o.reviewedAt,
98
+ )
99
+ record(
100
+ 'A1: a reading matching an auto-review range is marked reviewed',
101
+ !!inRangeAfter.reviewedAt,
102
+ `reviewedAt=${JSON.stringify(inRangeAfter.reviewedAt)} classifications=${JSON.stringify(inRangeAfter.classifications)}`
103
+ + ` — must be set by handle_vital_create, not by an acknowledge call`,
104
+ )
105
+ record(
106
+ 'A2: reviewedBy records the system sentinel, not a user id',
107
+ inRangeAfter.reviewedBy === SYSTEM_REVIEWER_ID,
108
+ `reviewedBy=${JSON.stringify(inRangeAfter.reviewedBy)} (want ${JSON.stringify(SYSTEM_REVIEWER_ID)})`,
109
+ )
110
+ record(
111
+ 'A3: the auto-reviewed reading still carries its classification',
112
+ inRangeAfter.classifications?.length === 1 && inRangeAfter.classifications?.[0].classification === 'Target',
113
+ `classifications=${JSON.stringify(inRangeAfter.classifications)} (want exactly one, Target)`,
114
+ )
115
+
116
+ /* ===== B: an out-of-range reading is classified but left for a human ===== */
117
+
118
+ const outOfRange = await create_reading('SBP', 250)
119
+ const outOfRangeAfter = await poll_for(
120
+ () => sdk.api.enduser_observations.getOne(outOfRange.id),
121
+ o => !!o.classifications?.length,
122
+ )
123
+ record(
124
+ 'B1: an out-of-range reading is classified High',
125
+ outOfRangeAfter.classifications?.length === 1 && outOfRangeAfter.classifications?.[0].classification === 'High',
126
+ `classifications=${JSON.stringify(outOfRangeAfter.classifications)} (want exactly one, High)`,
127
+ )
128
+ record(
129
+ 'B2: an out-of-range reading is NOT auto-reviewed',
130
+ !outOfRangeAfter.reviewedAt && !outOfRangeAfter.reviewedBy,
131
+ `reviewedAt=${JSON.stringify(outOfRangeAfter.reviewedAt)} reviewedBy=${JSON.stringify(outOfRangeAfter.reviewedBy)} (want neither set)`,
132
+ )
133
+
134
+ /* ===== C: strict multi-config rule — one non-auto-review match blocks auto-review =====
135
+ * On its own unit (DBP) so these two configurations cannot affect A/B/D. */
136
+
137
+ await sdk.api.vital_configurations.createOne({
138
+ title: `AutoReview DBP target ${RAND()}`,
139
+ unit: 'DBP',
140
+ ranges: [
141
+ {
142
+ classification: 'Target',
143
+ comparison: { type: 'Between', value: { lower: 100, upper: 200 } },
144
+ autoReview: true,
145
+ },
146
+ ],
147
+ })
148
+ await sdk.api.vital_configurations.createOne({
149
+ title: `AutoReview DBP catchall ${RAND()}`,
150
+ unit: 'DBP',
151
+ // catch-all with autoReview off: this configuration always has an opinion, and it is never
152
+ // "clear this automatically"
153
+ ranges: [
154
+ {
155
+ classification: 'Low',
156
+ comparison: { type: 'Greater Than', value: 0 },
157
+ },
158
+ ],
159
+ })
160
+
161
+ const multiConfig = await create_reading('DBP', 150)
162
+ const multiConfigAfter = await poll_for(
163
+ () => sdk.api.enduser_observations.getOne(multiConfig.id),
164
+ o => (o.classifications?.length ?? 0) >= 2,
165
+ )
166
+ record(
167
+ 'C1: a reading matched by two configurations gets one classification from each',
168
+ multiConfigAfter.classifications?.length === 2,
169
+ `classifications=${JSON.stringify(multiConfigAfter.classifications)} (want 2 — one per matching configuration)`,
170
+ )
171
+ record(
172
+ 'C2: auto-review requires EVERY matched classification to come from an auto-review range',
173
+ !multiConfigAfter.reviewedAt && !multiConfigAfter.reviewedBy,
174
+ `reviewedAt=${JSON.stringify(multiConfigAfter.reviewedAt)} reviewedBy=${JSON.stringify(multiConfigAfter.reviewedBy)}`
175
+ + ` — in range under one configuration, but the other's non-auto-review range also matched`,
176
+ )
177
+
178
+ /* ===== D: a reading no configuration covers is never auto-reviewed ===== */
179
+
180
+ const uncovered = await create_reading('A1C', 150)
181
+ // nothing to wait for turning true, so poll for the negative to settle instead of reading once
182
+ const uncoveredAfter = await poll_for(
183
+ () => sdk.api.enduser_observations.getOne(uncovered.id),
184
+ o => !!o.reviewedAt || !!o.classifications?.length,
185
+ 8,
186
+ )
187
+ record(
188
+ 'D1: a reading on an uncovered unit gets no classifications and is not auto-reviewed',
189
+ !uncoveredAfter.classifications?.length && !uncoveredAfter.reviewedAt && !uncoveredAfter.reviewedBy,
190
+ `classifications=${JSON.stringify(uncoveredAfter.classifications)} reviewedAt=${JSON.stringify(uncoveredAfter.reviewedAt)}`
191
+ + ` reviewedBy=${JSON.stringify(uncoveredAfter.reviewedBy)} (want all empty — no configuration covers A1C here)`,
192
+ )
193
+
194
+ /* ===== E: a manual acknowledge still records the real reviewer ===== */
195
+
196
+ await sdk.api.enduser_observations.acknowledge({ ids: [outOfRange.id] })
197
+ const acknowledged = await sdk.api.enduser_observations.getOne(outOfRange.id)
198
+ record(
199
+ 'E1: manual acknowledge still sets reviewedBy to the acting user',
200
+ !!acknowledged.reviewedAt && acknowledged.reviewedBy === tenant.users[0].id,
201
+ `reviewedAt=${JSON.stringify(acknowledged.reviewedAt)} reviewedBy=${JSON.stringify(acknowledged.reviewedBy)}`
202
+ + ` (want the acting user ${tenant.users[0].id}, NOT the sentinel)`,
203
+ )
204
+
205
+ /* ===== F/G/H: enduser-conditional auto-review =====
206
+ * A range's autoReviewConditions gate auto-review on the enduser: the range still classifies the
207
+ * reading, but only auto-reviews when the enduser satisfies the conditions. Separate endusers whose
208
+ * custom field `arField` matches vs. does not, on their own units so configs stay isolated. */
209
+
210
+ const matchingEnduser = await sdk.api.endusers.createOne({ fname: 'Match', lname: 'Patient', fields: { arField: 'yes' } })
211
+ const nonMatchingEnduser = await sdk.api.endusers.createOne({ fname: 'NoMatch', lname: 'Patient', fields: { arField: 'no' } })
212
+
213
+ const create_reading_for = (enduserId: string, unit: string, value: number) => (
214
+ sdk.api.enduser_observations.createOne({
215
+ category: 'vital-signs',
216
+ status: 'final',
217
+ enduserId,
218
+ measurement: { unit, value },
219
+ timestamp: new Date(),
220
+ })
221
+ )
222
+
223
+ /* ===== F: a Target range that auto-reviews only for endusers matching a custom-field condition ===== */
224
+
225
+ await sdk.api.vital_configurations.createOne({
226
+ title: `AutoReview BPM conditional ${RAND()}`,
227
+ unit: 'BPM',
228
+ ranges: [
229
+ {
230
+ classification: 'Target',
231
+ comparison: { type: 'Between', value: { lower: 60, upper: 100 } },
232
+ autoReview: true,
233
+ autoReviewConditions: { $and: [{ condition: { arField: 'yes' } }] },
234
+ },
235
+ ],
236
+ })
237
+
238
+ const condMatch = await create_reading_for(matchingEnduser.id, 'BPM', 80)
239
+ const condMatchAfter = await poll_for(
240
+ () => sdk.api.enduser_observations.getOne(condMatch.id),
241
+ o => !!o.reviewedAt || !!o.classifications?.length,
242
+ )
243
+ record(
244
+ 'F1: a reading for an enduser matching the auto-review conditions IS auto-reviewed',
245
+ !!condMatchAfter.reviewedAt && condMatchAfter.reviewedBy === SYSTEM_REVIEWER_ID
246
+ && condMatchAfter.classifications?.[0]?.classification === 'Target',
247
+ `reviewedAt=${JSON.stringify(condMatchAfter.reviewedAt)} reviewedBy=${JSON.stringify(condMatchAfter.reviewedBy)}`
248
+ + ` classifications=${JSON.stringify(condMatchAfter.classifications)} (enduser arField=yes matches)`,
249
+ )
250
+
251
+ const condNoMatch = await create_reading_for(nonMatchingEnduser.id, 'BPM', 80)
252
+ const condNoMatchAfter = await poll_for(
253
+ () => sdk.api.enduser_observations.getOne(condNoMatch.id),
254
+ o => !!o.classifications?.length,
255
+ )
256
+ record(
257
+ 'F2: the same reading for an enduser NOT matching the conditions is classified but NOT auto-reviewed',
258
+ condNoMatchAfter.classifications?.[0]?.classification === 'Target'
259
+ && !condNoMatchAfter.reviewedAt && !condNoMatchAfter.reviewedBy,
260
+ `reviewedAt=${JSON.stringify(condNoMatchAfter.reviewedAt)} reviewedBy=${JSON.stringify(condNoMatchAfter.reviewedBy)}`
261
+ + ` classifications=${JSON.stringify(condNoMatchAfter.classifications)} (enduser arField=no does not match)`,
262
+ )
263
+
264
+ /* ===== G: $or conditions — matching either branch auto-reviews ===== */
265
+
266
+ await sdk.api.vital_configurations.createOne({
267
+ title: `AutoReview O2 or-conditions ${RAND()}`,
268
+ unit: 'O2 Sat%',
269
+ ranges: [
270
+ {
271
+ classification: 'Target',
272
+ comparison: { type: 'Greater Than', value: 90 },
273
+ autoReview: true,
274
+ autoReviewConditions: { $or: [{ condition: { arField: 'other' } }, { condition: { arField: 'yes' } }] },
275
+ },
276
+ ],
277
+ })
278
+
279
+ const orMatch = await create_reading_for(matchingEnduser.id, 'O2 Sat%', 98)
280
+ const orMatchAfter = await poll_for(
281
+ () => sdk.api.enduser_observations.getOne(orMatch.id),
282
+ o => !!o.reviewedAt || !!o.classifications?.length,
283
+ )
284
+ record(
285
+ 'G1: an enduser matching either $or branch is auto-reviewed',
286
+ !!orMatchAfter.reviewedAt && orMatchAfter.reviewedBy === SYSTEM_REVIEWER_ID,
287
+ `reviewedAt=${JSON.stringify(orMatchAfter.reviewedAt)} reviewedBy=${JSON.stringify(orMatchAfter.reviewedBy)}`
288
+ + ` (arField=yes matches the second $or branch)`,
289
+ )
290
+
291
+ /* ===== H: multi-config safety — a failing condition in one config blocks auto-review =====
292
+ * matchingEnduser (arField=yes) matches config-1's Target but NOT config-2's catch-all condition. */
293
+
294
+ await sdk.api.vital_configurations.createOne({
295
+ title: `AutoReview L/min target ${RAND()}`,
296
+ unit: 'L/min',
297
+ ranges: [
298
+ {
299
+ classification: 'Target',
300
+ comparison: { type: 'Between', value: { lower: 100, upper: 600 } },
301
+ autoReview: true,
302
+ autoReviewConditions: { $and: [{ condition: { arField: 'yes' } }] },
303
+ },
304
+ ],
305
+ })
306
+ await sdk.api.vital_configurations.createOne({
307
+ title: `AutoReview L/min catchall ${RAND()}`,
308
+ unit: 'L/min',
309
+ ranges: [
310
+ {
311
+ classification: 'Low',
312
+ comparison: { type: 'Greater Than', value: 0 },
313
+ autoReview: true,
314
+ // enduser arField=yes, so this condition (arField=other) fails: config-2 is not auto-reviewable
315
+ autoReviewConditions: { $and: [{ condition: { arField: 'other' } }] },
316
+ },
317
+ ],
318
+ })
319
+
320
+ const condMultiConfig = await create_reading_for(matchingEnduser.id, 'L/min', 300)
321
+ const condMultiConfigAfter = await poll_for(
322
+ () => sdk.api.enduser_observations.getOne(condMultiConfig.id),
323
+ o => (o.classifications?.length ?? 0) >= 2,
324
+ )
325
+ record(
326
+ 'H1: auto-review requires EVERY matched range to be auto-reviewable for this enduser',
327
+ condMultiConfigAfter.classifications?.length === 2
328
+ && !condMultiConfigAfter.reviewedAt && !condMultiConfigAfter.reviewedBy,
329
+ `reviewedAt=${JSON.stringify(condMultiConfigAfter.reviewedAt)} reviewedBy=${JSON.stringify(condMultiConfigAfter.reviewedBy)}`
330
+ + ` classifications=${JSON.stringify(condMultiConfigAfter.classifications)}`
331
+ + ` — config-1 conditions match, config-2 conditions do not, so a human is still required`,
332
+ )
333
+ } finally {
334
+ // Teardown BEFORE anything asserts — assert calls process.exit, which would strand this tenant.
335
+ if (tenant) { try { await tenant.teardown() } catch (e) { console.error('teardown failed', e) } }
336
+ }
337
+
338
+ return checks
339
+ }
340
+
341
+ /** Asserting wrapper, for standalone runs and for sequential use in the suite. */
342
+ export const enduser_observations_auto_review_tests = async () => {
343
+ assert_checks('Vital auto-review on create', await enduser_observations_auto_review_checks())
344
+ }
345
+
346
+ // Allow running this test file independently
347
+ if (require.main === module) {
348
+ console.log(`🌐 Using API URL: ${host}`)
349
+ enduser_observations_auto_review_tests()
350
+ .then(() => {
351
+ console.log("✅ Vital auto-review test suite completed successfully")
352
+ process.exit(0)
353
+ })
354
+ .catch((error) => {
355
+ console.error("❌ Vital auto-review test suite failed:", error)
356
+ process.exit(1)
357
+ })
358
+ }
@@ -207,7 +207,7 @@ export const integrations_redacted_tests = async ({ sdk, sdkNonAdmin } : { sdk:
207
207
  }}
208
208
  )
209
209
 
210
- // F-0049: connect_stripe must reject caller-supplied accountId (Stripe-account-spoofing defense).
210
+ // connect_stripe must reject caller-supplied accountId (Stripe-account-spoofing defense).
211
211
  // Stripe Connect is deprecated in Tellescope; accountId was a test shortcut, kept rejected to preserve SDK shape.
212
212
  await async_test(
213
213
  "connect_stripe rejects caller-supplied accountId",
@@ -23,7 +23,7 @@ const SEEDED_TEST_BUSINESS_ID = '60398b1131a295e64f084ff6'
23
23
  * Covers the self-service organization signup chain, which had ZERO test coverage:
24
24
  * `users.register` -> `users.submit_email_verification` -> `organizations.create_and_join`.
25
25
  *
26
- * That gap is why F-0191 nearly shipped a schema `adminOnly` flag on create_and_join that would have
26
+ * That gap is why an earlier review nearly shipped a schema `adminOnly` flag on create_and_join that would have
27
27
  * 401'd every new organization — a freshly registered user has no `roles`, because create_and_join is
28
28
  * itself what grants Admin. This test is the regression guard for that.
29
29
  *
@@ -136,7 +136,7 @@ export const organization_signup_checks = async (): Promise<Check[]> => {
136
136
  `status=${verified.status} authToken=${!!verified.data?.authToken}`,
137
137
  )
138
138
 
139
- /* ===== D: create_and_join — what F-0191's flag would have broken ===== */
139
+ /* ===== D: create_and_join — what that flag would have broken ===== */
140
140
 
141
141
  const subdomain = `signup-${RAND()}`
142
142
  const joined = await axios.request({