@powerhousedao/service-offering 1.0.0-dev.1 → 1.0.0-dev.11

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 (246) hide show
  1. package/dist/document-models/facet/v1/actions.d.ts +3 -1
  2. package/dist/document-models/facet/v1/actions.d.ts.map +1 -1
  3. package/dist/document-models/facet/v1/gen/document-model.d.ts.map +1 -1
  4. package/dist/document-models/facet/v1/gen/document-model.js +31 -7
  5. package/dist/document-models/facet/v1/gen/document-schema.d.ts +6 -6
  6. package/dist/document-models/facet/v1/gen/index.d.ts.map +1 -1
  7. package/dist/document-models/facet/v1/gen/index.js +2 -0
  8. package/dist/document-models/facet/v1/gen/option-management/error.d.ts +27 -1
  9. package/dist/document-models/facet/v1/gen/option-management/error.d.ts.map +1 -1
  10. package/dist/document-models/facet/v1/gen/option-management/error.js +23 -1
  11. package/dist/document-models/facet/v1/gen/ph-factories.js +2 -2
  12. package/dist/document-models/facet/v1/gen/schema/types.d.ts +2 -2
  13. package/dist/document-models/facet/v1/gen/schema/types.d.ts.map +1 -1
  14. package/dist/document-models/facet/v1/gen/schema/zod.js +2 -2
  15. package/dist/document-models/facet/v1/gen/utils.js +2 -2
  16. package/dist/document-models/facet/v1/module.d.ts +1 -1
  17. package/dist/document-models/facet/v1/module.d.ts.map +1 -1
  18. package/dist/document-models/facet/v1/module.js +4 -1
  19. package/dist/document-models/resource-instance/v1/actions.d.ts +4 -1
  20. package/dist/document-models/resource-instance/v1/actions.d.ts.map +1 -1
  21. package/dist/document-models/resource-instance/v1/gen/configuration-management/error.d.ts +34 -1
  22. package/dist/document-models/resource-instance/v1/gen/configuration-management/error.d.ts.map +1 -1
  23. package/dist/document-models/resource-instance/v1/gen/configuration-management/error.js +32 -1
  24. package/dist/document-models/resource-instance/v1/gen/document-model.d.ts.map +1 -1
  25. package/dist/document-models/resource-instance/v1/gen/document-model.js +222 -70
  26. package/dist/document-models/resource-instance/v1/gen/document-schema.d.ts +0 -6
  27. package/dist/document-models/resource-instance/v1/gen/document-schema.d.ts.map +1 -1
  28. package/dist/document-models/resource-instance/v1/gen/index.d.ts.map +1 -1
  29. package/dist/document-models/resource-instance/v1/gen/index.js +2 -0
  30. package/dist/document-models/resource-instance/v1/gen/instance-management/actions.d.ts +6 -2
  31. package/dist/document-models/resource-instance/v1/gen/instance-management/actions.d.ts.map +1 -1
  32. package/dist/document-models/resource-instance/v1/gen/instance-management/creators.d.ts +3 -2
  33. package/dist/document-models/resource-instance/v1/gen/instance-management/creators.d.ts.map +1 -1
  34. package/dist/document-models/resource-instance/v1/gen/instance-management/creators.js +2 -1
  35. package/dist/document-models/resource-instance/v1/gen/instance-management/error.d.ts +98 -1
  36. package/dist/document-models/resource-instance/v1/gen/instance-management/error.d.ts.map +1 -1
  37. package/dist/document-models/resource-instance/v1/gen/instance-management/error.js +112 -1
  38. package/dist/document-models/resource-instance/v1/gen/instance-management/operations.d.ts +2 -1
  39. package/dist/document-models/resource-instance/v1/gen/instance-management/operations.d.ts.map +1 -1
  40. package/dist/document-models/resource-instance/v1/gen/ph-factories.d.ts.map +1 -1
  41. package/dist/document-models/resource-instance/v1/gen/ph-factories.js +0 -2
  42. package/dist/document-models/resource-instance/v1/gen/reducer.d.ts.map +1 -1
  43. package/dist/document-models/resource-instance/v1/gen/reducer.js +6 -1
  44. package/dist/document-models/resource-instance/v1/gen/schema/types.d.ts +3 -3
  45. package/dist/document-models/resource-instance/v1/gen/schema/types.d.ts.map +1 -1
  46. package/dist/document-models/resource-instance/v1/gen/schema/zod.d.ts +2 -1
  47. package/dist/document-models/resource-instance/v1/gen/schema/zod.d.ts.map +1 -1
  48. package/dist/document-models/resource-instance/v1/gen/schema/zod.js +5 -3
  49. package/dist/document-models/resource-instance/v1/gen/utils.d.ts.map +1 -1
  50. package/dist/document-models/resource-instance/v1/gen/utils.js +0 -2
  51. package/dist/document-models/resource-instance/v1/module.d.ts +1 -1
  52. package/dist/document-models/resource-instance/v1/module.d.ts.map +1 -1
  53. package/dist/document-models/resource-instance/v1/module.js +4 -1
  54. package/dist/document-models/resource-instance/v1/src/reducers/configuration-management.d.ts.map +1 -1
  55. package/dist/document-models/resource-instance/v1/src/reducers/configuration-management.js +57 -53
  56. package/dist/document-models/resource-instance/v1/src/reducers/instance-management.d.ts.map +1 -1
  57. package/dist/document-models/resource-instance/v1/src/reducers/instance-management.js +57 -21
  58. package/dist/document-models/resource-instance/v1/tests/instance-management.test.js +11 -1
  59. package/dist/document-models/resource-template/v1/actions.d.ts +3 -1
  60. package/dist/document-models/resource-template/v1/actions.d.ts.map +1 -1
  61. package/dist/document-models/resource-template/v1/gen/audience-management/error.d.ts +20 -1
  62. package/dist/document-models/resource-template/v1/gen/audience-management/error.d.ts.map +1 -1
  63. package/dist/document-models/resource-template/v1/gen/audience-management/error.js +16 -1
  64. package/dist/document-models/resource-template/v1/gen/document-model.d.ts.map +1 -1
  65. package/dist/document-models/resource-template/v1/gen/document-model.js +207 -89
  66. package/dist/document-models/resource-template/v1/gen/document-schema.d.ts +12 -12
  67. package/dist/document-models/resource-template/v1/gen/facet-targeting/error.d.ts +27 -1
  68. package/dist/document-models/resource-template/v1/gen/facet-targeting/error.d.ts.map +1 -1
  69. package/dist/document-models/resource-template/v1/gen/facet-targeting/error.js +23 -1
  70. package/dist/document-models/resource-template/v1/gen/index.d.ts.map +1 -1
  71. package/dist/document-models/resource-template/v1/gen/index.js +2 -0
  72. package/dist/document-models/resource-template/v1/gen/option-group-management/error.d.ts +27 -1
  73. package/dist/document-models/resource-template/v1/gen/option-group-management/error.d.ts.map +1 -1
  74. package/dist/document-models/resource-template/v1/gen/option-group-management/error.js +23 -1
  75. package/dist/document-models/resource-template/v1/gen/ph-factories.js +3 -3
  76. package/dist/document-models/resource-template/v1/gen/schema/types.d.ts +4 -4
  77. package/dist/document-models/resource-template/v1/gen/schema/types.d.ts.map +1 -1
  78. package/dist/document-models/resource-template/v1/gen/schema/zod.js +4 -4
  79. package/dist/document-models/resource-template/v1/gen/service-management/error.d.ts +51 -1
  80. package/dist/document-models/resource-template/v1/gen/service-management/error.d.ts.map +1 -1
  81. package/dist/document-models/resource-template/v1/gen/service-management/error.js +49 -1
  82. package/dist/document-models/resource-template/v1/gen/utils.js +3 -3
  83. package/dist/document-models/resource-template/v1/module.d.ts +1 -1
  84. package/dist/document-models/resource-template/v1/module.d.ts.map +1 -1
  85. package/dist/document-models/resource-template/v1/module.js +4 -1
  86. package/dist/document-models/resource-template/v1/src/reducers/option-group-management.d.ts.map +1 -1
  87. package/dist/document-models/resource-template/v1/src/reducers/option-group-management.js +2 -21
  88. package/dist/document-models/service-offering/v1/actions.d.ts +3 -1
  89. package/dist/document-models/service-offering/v1/actions.d.ts.map +1 -1
  90. package/dist/document-models/service-offering/v1/gen/document-model.d.ts.map +1 -1
  91. package/dist/document-models/service-offering/v1/gen/document-model.js +421 -199
  92. package/dist/document-models/service-offering/v1/gen/document-schema.d.ts +9 -9
  93. package/dist/document-models/service-offering/v1/gen/index.d.ts.map +1 -1
  94. package/dist/document-models/service-offering/v1/gen/index.js +2 -0
  95. package/dist/document-models/service-offering/v1/gen/offering/error.d.ts +41 -1
  96. package/dist/document-models/service-offering/v1/gen/offering/error.d.ts.map +1 -1
  97. package/dist/document-models/service-offering/v1/gen/offering/error.js +37 -1
  98. package/dist/document-models/service-offering/v1/gen/option-groups/error.d.ts +55 -1
  99. package/dist/document-models/service-offering/v1/gen/option-groups/error.d.ts.map +1 -1
  100. package/dist/document-models/service-offering/v1/gen/option-groups/error.js +53 -1
  101. package/dist/document-models/service-offering/v1/gen/ph-factories.js +3 -3
  102. package/dist/document-models/service-offering/v1/gen/schema/types.d.ts +134 -61
  103. package/dist/document-models/service-offering/v1/gen/schema/types.d.ts.map +1 -1
  104. package/dist/document-models/service-offering/v1/gen/schema/zod.d.ts +35 -10
  105. package/dist/document-models/service-offering/v1/gen/schema/zod.d.ts.map +1 -1
  106. package/dist/document-models/service-offering/v1/gen/schema/zod.js +182 -64
  107. package/dist/document-models/service-offering/v1/gen/services/error.d.ts +20 -1
  108. package/dist/document-models/service-offering/v1/gen/services/error.d.ts.map +1 -1
  109. package/dist/document-models/service-offering/v1/gen/services/error.js +16 -1
  110. package/dist/document-models/service-offering/v1/gen/tiers/error.d.ts +100 -1
  111. package/dist/document-models/service-offering/v1/gen/tiers/error.d.ts.map +1 -1
  112. package/dist/document-models/service-offering/v1/gen/tiers/error.js +106 -1
  113. package/dist/document-models/service-offering/v1/gen/utils.js +4 -4
  114. package/dist/document-models/service-offering/v1/module.d.ts +1 -1
  115. package/dist/document-models/service-offering/v1/module.d.ts.map +1 -1
  116. package/dist/document-models/service-offering/v1/module.js +4 -1
  117. package/dist/document-models/service-offering/v1/src/reducers/offering.d.ts.map +1 -1
  118. package/dist/document-models/service-offering/v1/src/reducers/offering.js +20 -12
  119. package/dist/document-models/service-offering/v1/src/reducers/option-groups.d.ts.map +1 -1
  120. package/dist/document-models/service-offering/v1/src/reducers/option-groups.js +157 -39
  121. package/dist/document-models/service-offering/v1/src/reducers/services.d.ts.map +1 -1
  122. package/dist/document-models/service-offering/v1/src/reducers/services.js +17 -14
  123. package/dist/document-models/service-offering/v1/src/reducers/tiers.d.ts.map +1 -1
  124. package/dist/document-models/service-offering/v1/src/reducers/tiers.js +111 -78
  125. package/dist/document-models/service-offering/v1/src/utils.d.ts +60 -1
  126. package/dist/document-models/service-offering/v1/src/utils.d.ts.map +1 -1
  127. package/dist/document-models/service-offering/v1/src/utils.js +173 -1
  128. package/dist/document-models/service-offering/v1/tests/option-groups.test.js +1 -1
  129. package/dist/document-models/service-offering/v1/utils.d.ts +3 -0
  130. package/dist/document-models/service-offering/v1/utils.d.ts.map +1 -1
  131. package/dist/document-models/subscription-instance/v1/actions.d.ts +3 -1
  132. package/dist/document-models/subscription-instance/v1/actions.d.ts.map +1 -1
  133. package/dist/document-models/subscription-instance/v1/gen/document-model.d.ts.map +1 -1
  134. package/dist/document-models/subscription-instance/v1/gen/document-model.js +488 -246
  135. package/dist/document-models/subscription-instance/v1/gen/document-schema.d.ts +3 -3
  136. package/dist/document-models/subscription-instance/v1/gen/index.d.ts.map +1 -1
  137. package/dist/document-models/subscription-instance/v1/gen/index.js +2 -0
  138. package/dist/document-models/subscription-instance/v1/gen/metrics/error.d.ts +73 -1
  139. package/dist/document-models/subscription-instance/v1/gen/metrics/error.d.ts.map +1 -1
  140. package/dist/document-models/subscription-instance/v1/gen/metrics/error.js +86 -1
  141. package/dist/document-models/subscription-instance/v1/gen/ph-factories.js +1 -1
  142. package/dist/document-models/subscription-instance/v1/gen/schema/types.d.ts +199 -82
  143. package/dist/document-models/subscription-instance/v1/gen/schema/types.d.ts.map +1 -1
  144. package/dist/document-models/subscription-instance/v1/gen/schema/zod.d.ts +22 -12
  145. package/dist/document-models/subscription-instance/v1/gen/schema/zod.d.ts.map +1 -1
  146. package/dist/document-models/subscription-instance/v1/gen/schema/zod.js +230 -84
  147. package/dist/document-models/subscription-instance/v1/gen/service/error.d.ts +62 -1
  148. package/dist/document-models/subscription-instance/v1/gen/service/error.d.ts.map +1 -1
  149. package/dist/document-models/subscription-instance/v1/gen/service/error.js +60 -1
  150. package/dist/document-models/subscription-instance/v1/gen/service-group/error.d.ts +39 -1
  151. package/dist/document-models/subscription-instance/v1/gen/service-group/error.d.ts.map +1 -1
  152. package/dist/document-models/subscription-instance/v1/gen/service-group/error.js +39 -1
  153. package/dist/document-models/subscription-instance/v1/gen/subscription/error.d.ts +55 -1
  154. package/dist/document-models/subscription-instance/v1/gen/subscription/error.d.ts.map +1 -1
  155. package/dist/document-models/subscription-instance/v1/gen/subscription/error.js +51 -1
  156. package/dist/document-models/subscription-instance/v1/gen/utils.js +2 -2
  157. package/dist/document-models/subscription-instance/v1/module.d.ts +1 -1
  158. package/dist/document-models/subscription-instance/v1/module.d.ts.map +1 -1
  159. package/dist/document-models/subscription-instance/v1/module.js +4 -1
  160. package/dist/document-models/subscription-instance/v1/src/reducers/customer.d.ts.map +1 -1
  161. package/dist/document-models/subscription-instance/v1/src/reducers/customer.js +1 -0
  162. package/dist/document-models/subscription-instance/v1/src/reducers/metrics.d.ts.map +1 -1
  163. package/dist/document-models/subscription-instance/v1/src/reducers/metrics.js +70 -45
  164. package/dist/document-models/subscription-instance/v1/src/reducers/service-group.d.ts.map +1 -1
  165. package/dist/document-models/subscription-instance/v1/src/reducers/service-group.js +108 -30
  166. package/dist/document-models/subscription-instance/v1/src/reducers/service.d.ts.map +1 -1
  167. package/dist/document-models/subscription-instance/v1/src/reducers/service.js +108 -39
  168. package/dist/document-models/subscription-instance/v1/src/reducers/subscription.d.ts.map +1 -1
  169. package/dist/document-models/subscription-instance/v1/src/reducers/subscription.js +193 -35
  170. package/dist/document-models/upgrade-manifests.d.ts.map +1 -1
  171. package/dist/document-models/upgrade-manifests.js +0 -2
  172. package/dist/editors/resource-instance-editor/editor.d.ts.map +1 -1
  173. package/dist/editors/resource-instance-editor/editor.js +13 -3
  174. package/dist/editors/service-offering-editor/components/ResourceTemplateSelector.d.ts.map +1 -1
  175. package/dist/editors/service-offering-editor/components/ResourceTemplateSelector.js +4 -2
  176. package/dist/editors/service-offering-editor/components/ServiceCatalog.d.ts.map +1 -1
  177. package/dist/editors/service-offering-editor/components/ServiceCatalog.js +189 -32
  178. package/dist/editors/service-offering-editor/components/TheMatrix.d.ts +1 -1
  179. package/dist/editors/service-offering-editor/components/TheMatrix.d.ts.map +1 -1
  180. package/dist/editors/service-offering-editor/components/TheMatrix.js +295 -140
  181. package/dist/editors/service-offering-editor/components/TierDefinition.d.ts.map +1 -1
  182. package/dist/editors/service-offering-editor/components/TierDefinition.js +2 -0
  183. package/dist/editors/service-offering-editor/components/TierPricingOptionsPanel.js +3 -3
  184. package/dist/editors/service-offering-editor/components/pricing-utils.d.ts.map +1 -1
  185. package/dist/editors/service-offering-editor/components/pricing-utils.js +26 -7
  186. package/dist/editors/service-offering-editor/editor.css +119 -0
  187. package/dist/editors/subscription-instance-editor/components/BillingPanel.d.ts.map +1 -1
  188. package/dist/editors/subscription-instance-editor/components/BillingPanel.js +4 -4
  189. package/dist/editors/subscription-instance-editor/components/CustomerInfo.d.ts.map +1 -1
  190. package/dist/editors/subscription-instance-editor/components/CustomerInfo.js +3 -2
  191. package/dist/editors/subscription-instance-editor/components/ImportServiceConfigButton.d.ts +3 -0
  192. package/dist/editors/subscription-instance-editor/components/ImportServiceConfigButton.d.ts.map +1 -1
  193. package/dist/editors/subscription-instance-editor/components/ImportServiceConfigButton.js +12 -0
  194. package/dist/editors/subscription-instance-editor/components/MetricActions.d.ts.map +1 -1
  195. package/dist/editors/subscription-instance-editor/components/MetricActions.js +4 -2
  196. package/dist/editors/subscription-instance-editor/components/MockDataButton.d.ts.map +1 -1
  197. package/dist/editors/subscription-instance-editor/components/MockDataButton.js +214 -2
  198. package/dist/editors/subscription-instance-editor/components/OperatorNotes.js +1 -1
  199. package/dist/editors/subscription-instance-editor/components/ServicesPanel.d.ts.map +1 -1
  200. package/dist/editors/subscription-instance-editor/components/ServicesPanel.js +9 -20
  201. package/dist/editors/subscription-instance-editor/components/SubscriptionActions.d.ts.map +1 -1
  202. package/dist/editors/subscription-instance-editor/components/SubscriptionActions.js +8 -9
  203. package/dist/editors/subscription-instance-editor/components/SubscriptionHeader.d.ts.map +1 -1
  204. package/dist/editors/subscription-instance-editor/components/SubscriptionHeader.js +1 -1
  205. package/dist/editors/subscription-instance-editor/components/billing-utils.d.ts +14 -6
  206. package/dist/editors/subscription-instance-editor/components/billing-utils.d.ts.map +1 -1
  207. package/dist/editors/subscription-instance-editor/components/billing-utils.js +19 -23
  208. package/dist/editors/subscription-instance-editor/components/mapOfferingToSubscription.d.ts +16 -2
  209. package/dist/editors/subscription-instance-editor/components/mapOfferingToSubscription.d.ts.map +1 -1
  210. package/dist/editors/subscription-instance-editor/components/mapOfferingToSubscription.js +155 -6
  211. package/dist/powerhouse.manifest.json +29 -3
  212. package/dist/style.css +14 -0
  213. package/dist/subgraphs/resources-services/resolvers.d.ts +2 -2
  214. package/dist/subgraphs/resources-services/resolvers.d.ts.map +1 -1
  215. package/dist/subgraphs/resources-services/resolvers.js +301 -215
  216. package/package.json +24 -19
  217. package/dist/document-models/facet/gen/schema/types.d.ts +0 -195
  218. package/dist/document-models/facet/gen/schema/types.d.ts.map +0 -1
  219. package/dist/document-models/facet/gen/schema/types.js +0 -1
  220. package/dist/document-models/facet/gen/schema/zod.d.ts +0 -18
  221. package/dist/document-models/facet/gen/schema/zod.d.ts.map +0 -1
  222. package/dist/document-models/facet/gen/schema/zod.js +0 -69
  223. package/dist/document-models/resource-instance/gen/schema/types.d.ts +0 -272
  224. package/dist/document-models/resource-instance/gen/schema/types.d.ts.map +0 -1
  225. package/dist/document-models/resource-instance/gen/schema/types.js +0 -1
  226. package/dist/document-models/resource-instance/gen/schema/zod.d.ts +0 -43
  227. package/dist/document-models/resource-instance/gen/schema/zod.d.ts.map +0 -1
  228. package/dist/document-models/resource-instance/gen/schema/zod.js +0 -185
  229. package/dist/document-models/resource-template/gen/schema/types.d.ts +0 -371
  230. package/dist/document-models/resource-template/gen/schema/types.d.ts.map +0 -1
  231. package/dist/document-models/resource-template/gen/schema/types.js +0 -1
  232. package/dist/document-models/resource-template/gen/schema/zod.d.ts +0 -52
  233. package/dist/document-models/resource-template/gen/schema/zod.d.ts.map +0 -1
  234. package/dist/document-models/resource-template/gen/schema/zod.js +0 -312
  235. package/dist/document-models/service-offering/gen/schema/types.d.ts +0 -451
  236. package/dist/document-models/service-offering/gen/schema/types.d.ts.map +0 -1
  237. package/dist/document-models/service-offering/gen/schema/types.js +0 -1
  238. package/dist/document-models/service-offering/gen/schema/zod.d.ts +0 -89
  239. package/dist/document-models/service-offering/gen/schema/zod.d.ts.map +0 -1
  240. package/dist/document-models/service-offering/gen/schema/zod.js +0 -419
  241. package/dist/document-models/subscription-instance/gen/schema/types.d.ts +0 -435
  242. package/dist/document-models/subscription-instance/gen/schema/types.d.ts.map +0 -1
  243. package/dist/document-models/subscription-instance/gen/schema/types.js +0 -1
  244. package/dist/document-models/subscription-instance/gen/schema/zod.d.ts +0 -99
  245. package/dist/document-models/subscription-instance/gen/schema/zod.d.ts.map +0 -1
  246. package/dist/document-models/subscription-instance/gen/schema/zod.js +0 -410
@@ -1,9 +1,11 @@
1
- import {} from "@powerhousedao/reactor-api";
1
+ import { getUserSelectionPriceBreakdown, } from "../../document-models/service-offering/v1/src/utils.js";
2
2
  import { createAction, generateId } from "document-model/core";
3
- import { addFile } from "document-drive";
4
- import { ResourceInstanceV1, SubscriptionInstanceV1, } from "@powerhousedao/service-offering/document-models";
3
+ import { addFile, addFolder, driveCreateDocument } from "document-drive";
4
+ import { ResourceInstance } from "../../document-models/resource-instance/v1/module.js";
5
+ import { SubscriptionInstance } from "../../document-models/subscription-instance/v1/module.js";
6
+ import { mapOfferingToSubscription } from "../../editors/subscription-instance-editor/components/mapOfferingToSubscription.js";
5
7
  export const getResolvers = (subgraph) => {
6
- const reactor = subgraph.reactor;
8
+ const reactorClient = subgraph.reactorClient;
7
9
  return {
8
10
  Query: {
9
11
  resourceTemplates: async (_, args) => {
@@ -11,17 +13,15 @@ export const getResolvers = (subgraph) => {
11
13
  // If filtering by specific id, try to fetch directly
12
14
  if (id) {
13
15
  try {
14
- const doc = await reactor.getDocument(id);
16
+ const doc = await reactorClient.get(id);
15
17
  if (doc &&
16
18
  doc.header.documentType === "powerhouse/resource-template") {
17
19
  const state = doc.state.global;
18
- // Check status filter if provided
19
20
  if (status &&
20
21
  status.length > 0 &&
21
22
  !status.includes(state.status)) {
22
23
  return [];
23
24
  }
24
- // Check operatorId filter if provided
25
25
  if (operatorId && state.operatorId !== operatorId) {
26
26
  return [];
27
27
  }
@@ -33,42 +33,26 @@ export const getResolvers = (subgraph) => {
33
33
  }
34
34
  return [];
35
35
  }
36
- // Scan all drives for resource template documents
37
- const drives = await reactor.getDrives();
36
+ // Find all resource template documents
37
+ const { results: docs } = await reactorClient.find({
38
+ type: "powerhouse/resource-template",
39
+ });
38
40
  const resourceTemplates = [];
39
- for (const driveId of drives) {
40
- try {
41
- const docIds = await reactor.getDocuments(driveId);
42
- const docs = await Promise.all(docIds.map(async (docId) => {
43
- try {
44
- return await reactor.getDocument(docId);
45
- }
46
- catch {
47
- return null;
48
- }
49
- }));
50
- for (const doc of docs) {
51
- if (doc &&
52
- doc.header.documentType === "powerhouse/resource-template") {
53
- const resourceDoc = doc;
54
- const state = resourceDoc.state.global;
55
- // Apply status filter if provided
56
- if (status &&
57
- status.length > 0 &&
58
- !status.includes(state.status)) {
59
- continue;
60
- }
61
- // Apply operatorId filter if provided
62
- if (operatorId && state.operatorId !== operatorId) {
63
- continue;
64
- }
65
- resourceTemplates.push(mapResourceTemplateState(state, doc));
66
- }
67
- }
41
+ for (const doc of docs) {
42
+ const resourceDoc = doc;
43
+ const state = resourceDoc.state.global;
44
+ // Skip documents missing required fields
45
+ if (!state.operatorId)
46
+ continue;
47
+ // Apply status filter if provided
48
+ if (status && status.length > 0 && !status.includes(state.status)) {
49
+ continue;
68
50
  }
69
- catch (error) {
70
- console.warn(`Failed to inspect drive ${driveId}:`, error);
51
+ // Apply operatorId filter if provided
52
+ if (operatorId && state.operatorId !== operatorId) {
53
+ continue;
71
54
  }
55
+ resourceTemplates.push(mapResourceTemplateState(state, doc));
72
56
  }
73
57
  return resourceTemplates;
74
58
  },
@@ -77,21 +61,18 @@ export const getResolvers = (subgraph) => {
77
61
  // If filtering by specific id, try to fetch directly
78
62
  if (id) {
79
63
  try {
80
- const doc = await reactor.getDocument(id);
64
+ const doc = await reactorClient.get(id);
81
65
  if (doc &&
82
66
  doc.header.documentType === "powerhouse/service-offering") {
83
67
  const state = doc.state.global;
84
- // Check status filter if provided
85
68
  if (status &&
86
69
  status.length > 0 &&
87
70
  !status.includes(state.status)) {
88
71
  return [];
89
72
  }
90
- // Check operatorId filter if provided
91
73
  if (operatorId && state.operatorId !== operatorId) {
92
74
  return [];
93
75
  }
94
- // Check resourceTemplateId filter if provided
95
76
  if (resourceTemplateId &&
96
77
  state.resourceTemplateId !== resourceTemplateId) {
97
78
  return [];
@@ -104,47 +85,31 @@ export const getResolvers = (subgraph) => {
104
85
  }
105
86
  return [];
106
87
  }
107
- // Scan all drives for service offering documents
108
- const drives = await reactor.getDrives();
88
+ // Find all service offering documents
89
+ const { results: docs } = await reactorClient.find({
90
+ type: "powerhouse/service-offering",
91
+ });
109
92
  const serviceOfferings = [];
110
- for (const driveId of drives) {
111
- try {
112
- const docIds = await reactor.getDocuments(driveId);
113
- const docs = await Promise.all(docIds.map(async (docId) => {
114
- try {
115
- return await reactor.getDocument(docId);
116
- }
117
- catch {
118
- return null;
119
- }
120
- }));
121
- for (const doc of docs) {
122
- if (doc &&
123
- doc.header.documentType === "powerhouse/service-offering") {
124
- const offeringDoc = doc;
125
- const state = offeringDoc.state.global;
126
- // Apply status filter if provided
127
- if (status &&
128
- status.length > 0 &&
129
- !status.includes(state.status)) {
130
- continue;
131
- }
132
- // Apply operatorId filter if provided
133
- if (operatorId && state.operatorId !== operatorId) {
134
- continue;
135
- }
136
- // Apply resourceTemplateId filter if provided
137
- if (resourceTemplateId &&
138
- state.resourceTemplateId !== resourceTemplateId) {
139
- continue;
140
- }
141
- serviceOfferings.push(mapServiceOfferingState(state, doc));
142
- }
143
- }
93
+ for (const doc of docs) {
94
+ const offeringDoc = doc;
95
+ const state = offeringDoc.state.global;
96
+ // Skip documents missing required fields
97
+ if (!state.operatorId)
98
+ continue;
99
+ // Apply status filter if provided
100
+ if (status && status.length > 0 && !status.includes(state.status)) {
101
+ continue;
144
102
  }
145
- catch (error) {
146
- console.warn(`Failed to inspect drive ${driveId}:`, error);
103
+ // Apply operatorId filter if provided
104
+ if (operatorId && state.operatorId !== operatorId) {
105
+ continue;
147
106
  }
107
+ // Apply resourceTemplateId filter if provided
108
+ if (resourceTemplateId &&
109
+ state.resourceTemplateId !== resourceTemplateId) {
110
+ continue;
111
+ }
112
+ serviceOfferings.push(mapServiceOfferingState(state, doc));
148
113
  }
149
114
  return serviceOfferings;
150
115
  },
@@ -230,7 +195,7 @@ export const getResolvers = (subgraph) => {
230
195
  };
231
196
  }
232
197
  // Fetch the service offering
233
- const serviceOfferingDoc = await reactor.getDocument(serviceOfferingId);
198
+ const serviceOfferingDoc = await reactorClient.get(serviceOfferingId);
234
199
  if (!serviceOfferingDoc) {
235
200
  return {
236
201
  success: false,
@@ -247,13 +212,38 @@ export const getResolvers = (subgraph) => {
247
212
  errors: ["Service offering has no associated resource template"],
248
213
  };
249
214
  }
250
- // Find the selected tier
251
- const selectedTier = serviceOfferingState.tiers.find((t) => t.id === userSelection.tierId);
252
- if (!selectedTier) {
215
+ // Convert GraphQL overrides to Record<string, BillingCycle>
216
+ const groupBillingCycleOverrides = {};
217
+ for (const o of userSelection.groupBillingCycleOverrides ?? []) {
218
+ groupBillingCycleOverrides[o.groupId] =
219
+ o.billingCycle;
220
+ }
221
+ const addonBillingCycleOverrides = {};
222
+ for (const o of userSelection.addonBillingCycleOverrides ?? []) {
223
+ addonBillingCycleOverrides[o.groupId] =
224
+ o.billingCycle;
225
+ }
226
+ // Compute price breakdown from user selection
227
+ const selection = {
228
+ tierId: userSelection.tierId,
229
+ billingCycle: userSelection.billingCycle,
230
+ optionGroupIds: userSelection.optionGroupIds ?? [],
231
+ groupBillingCycleOverrides,
232
+ addonBillingCycleOverrides,
233
+ };
234
+ let priceBreakdown;
235
+ try {
236
+ priceBreakdown = getUserSelectionPriceBreakdown(serviceOfferingDoc.state, selection);
237
+ }
238
+ catch (error) {
253
239
  return {
254
240
  success: false,
255
241
  data: null,
256
- errors: ["Selected tier not found in service offering"],
242
+ errors: [
243
+ error instanceof Error
244
+ ? error.message
245
+ : "Failed to compute price breakdown from user selection",
246
+ ],
257
247
  };
258
248
  }
259
249
  // Sanitize names for use as drive id/slug: lowercase, trim, collapse whitespace, replace spaces with hyphens
@@ -262,103 +252,129 @@ export const getResolvers = (subgraph) => {
262
252
  .toLowerCase()
263
253
  .replace(/\s+/g, "-")
264
254
  .replace(/_/g, "-");
265
- const parsedName = name
266
- .trim()
267
- .toLowerCase()
268
- .replace(/\s+/g, "-")
269
- .replace(/_/g, "-");
270
255
  try {
271
256
  // create team-builder-admin drive
272
- const teamBuilderAdminDrive = await reactor.addDrive({
273
- global: {
274
- name: teamName,
275
- icon: "https://cdn-icons-png.flaticon.com/512/6020/6020347.png",
276
- },
277
- id: generateId(),
278
- slug: parsedTeamName,
279
- preferredEditor: "builder-team-admin",
280
- });
281
- // create builder-profile doc inside the team-builder-admin drive
282
- const builderProfileDoc = await reactor.addDocument("powerhouse/builder-profile");
283
- await reactor.addAction(teamBuilderAdminDrive.header.id, addFile({
284
- documentType: "powerhouse/builder-profile",
285
- id: builderProfileDoc.header.id,
286
- name: `${parsedTeamName} Builder Profile`,
287
- parentFolder: teamBuilderAdminDrive.state.global.nodes?.find((node) => node.kind === "folder")?.parentFolder,
288
- }));
289
- await reactor.addAction(builderProfileDoc.header.id, createAction("UPDATE_PROFILE", { name: parsedTeamName }, undefined, undefined, "global"));
290
- // create resource-instance and subscription-instance docs
291
- const resourceInstanceDoc = await reactor.addDocument("powerhouse/resource-instance");
292
- const subscriptionInstanceDoc = await reactor.addDocument("powerhouse/subscription-instance");
293
- // resolve parent folders for both drives
294
- const teamParentFolder = teamBuilderAdminDrive.state.global.nodes?.find((node) => node.kind === "folder")?.parentFolder;
295
- const operatorDrive = await getOperatorDrive(reactor, resourceTemplateId);
296
- if (!operatorDrive) {
297
- throw new Error(`Operator drive not found for resource template ${resourceTemplateId}`);
298
- }
299
- // get operator profile id from operator drive
300
- const operatorProfileId = operatorDrive.state.global.nodes
301
- .filter((node) => node.kind === "file")
302
- .find((node) => node.documentType === "powerhouse/builder-profile")?.id;
303
- if (!operatorProfileId) {
304
- throw new Error(`Operator profile not found for drive ${operatorDrive.header.id}`);
305
- }
306
- const operatorParentFolder = operatorDrive.state.global.nodes.find((node) => node.kind === "folder")?.parentFolder;
307
- // batch add resource-instance and subscription-instance to team-builder-admin drive
308
- await reactor.addActions(teamBuilderAdminDrive.header.id, [
257
+ const driveDoc = driveCreateDocument();
258
+ driveDoc.header.name = teamName;
259
+ driveDoc.state.global.name = teamName;
260
+ driveDoc.state.global.icon =
261
+ "https://cdn-icons-png.flaticon.com/512/6020/6020347.png";
262
+ driveDoc.header.slug = parsedTeamName;
263
+ if (!driveDoc.header.meta)
264
+ driveDoc.header.meta = {};
265
+ driveDoc.header.meta.preferredEditor = "builder-team-admin";
266
+ const teamBuilderAdminDrive = await reactorClient.create(driveDoc);
267
+ const driveId = teamBuilderAdminDrive.header.id;
268
+ // create documents as children of the drive so Connect can sync them
269
+ const builderProfileDoc = await reactorClient.createEmpty("powerhouse/builder-profile", { parentIdentifier: driveId });
270
+ const resourceInstanceDoc = await reactorClient.createEmpty("powerhouse/resource-instance", { parentIdentifier: driveId });
271
+ const subscriptionInstanceDoc = await reactorClient.createEmpty("powerhouse/subscription-instance", { parentIdentifier: driveId });
272
+ // create "Service Subscriptions" folder and organize files in team drive
273
+ const teamServiceSubsFolderId = generateId();
274
+ await reactorClient.execute(driveId, "main", [
275
+ addFolder({
276
+ id: teamServiceSubsFolderId,
277
+ name: "Service Subscriptions",
278
+ }),
279
+ addFile({
280
+ documentType: "powerhouse/builder-profile",
281
+ id: builderProfileDoc.header.id,
282
+ name: `${parsedTeamName} Builder Profile`,
283
+ }),
309
284
  addFile({
310
285
  documentType: "powerhouse/resource-instance",
311
286
  id: resourceInstanceDoc.header.id,
312
287
  name: `${parsedTeamName} Resource Instance`,
313
- parentFolder: teamParentFolder,
288
+ parentFolder: teamServiceSubsFolderId,
314
289
  }),
315
290
  addFile({
316
291
  documentType: "powerhouse/subscription-instance",
317
292
  id: subscriptionInstanceDoc.header.id,
318
293
  name: `${parsedTeamName} Subscription Instance`,
319
- parentFolder: teamParentFolder,
294
+ parentFolder: teamServiceSubsFolderId,
320
295
  }),
321
296
  ]);
322
- // batch add resource-instance and subscription-instance to operator drive
323
- await reactor.addActions(operatorDrive.header.id, [
297
+ // update builder profile
298
+ await reactorClient.execute(builderProfileDoc.header.id, "main", [
299
+ createAction("UPDATE_PROFILE", { name: parsedTeamName }, undefined, undefined, "global"),
300
+ ]);
301
+ // find operator drive and add references there too
302
+ const operatorDrive = await getOperatorDrive(reactorClient, resourceTemplateId);
303
+ if (!operatorDrive) {
304
+ throw new Error(`Operator drive not found for resource template ${resourceTemplateId}`);
305
+ }
306
+ // get operator profile id from operator drive
307
+ const operatorProfileId = operatorDrive.state.global.nodes
308
+ .filter((node) => node.kind === "file")
309
+ .find((node) => node.documentType === "powerhouse/builder-profile")?.id;
310
+ if (!operatorProfileId) {
311
+ throw new Error(`Operator profile not found for drive ${operatorDrive.header.id}`);
312
+ }
313
+ // find or create "Service Subscriptions" folder in the operator drive
314
+ let serviceSubscriptionsFolderId = operatorDrive.state.global.nodes.find((node) => node.kind === "folder" &&
315
+ node.name === "Service Subscriptions")?.id;
316
+ if (!serviceSubscriptionsFolderId) {
317
+ serviceSubscriptionsFolderId = generateId();
318
+ await reactorClient.execute(operatorDrive.header.id, "main", [
319
+ addFolder({
320
+ id: serviceSubscriptionsFolderId,
321
+ name: "Service Subscriptions",
322
+ }),
323
+ ]);
324
+ }
325
+ // add reactor-level relationships so Connect syncs the child documents
326
+ // (createEmpty guarantees CREATE_DOCUMENT is persisted before this runs)
327
+ await reactorClient.addChildren(operatorDrive.header.id, [
328
+ resourceInstanceDoc.header.id,
329
+ subscriptionInstanceDoc.header.id,
330
+ ]);
331
+ // add file references to operator drive under "Service Subscriptions"
332
+ await reactorClient.execute(operatorDrive.header.id, "main", [
324
333
  addFile({
325
334
  documentType: "powerhouse/resource-instance",
326
335
  id: resourceInstanceDoc.header.id,
327
336
  name: `${parsedTeamName} Resource Instance`,
328
- parentFolder: operatorParentFolder,
337
+ parentFolder: serviceSubscriptionsFolderId,
329
338
  }),
330
339
  addFile({
331
340
  documentType: "powerhouse/subscription-instance",
332
341
  id: subscriptionInstanceDoc.header.id,
333
342
  name: `${parsedTeamName} Subscription Instance`,
334
- parentFolder: operatorParentFolder,
343
+ parentFolder: serviceSubscriptionsFolderId,
335
344
  }),
336
345
  ]);
337
346
  // populate documents after all files are added to both drives
338
- await populateResourceInstance(reactor, resourceInstanceDoc.header.id, resourceTemplateId, operatorProfileId, // operator profile id
347
+ await populateResourceInstance(reactorClient, resourceInstanceDoc.header.id, resourceTemplateId, operatorProfileId, // operator profile id
339
348
  builderProfileDoc.header.id, // customer id
340
349
  parsedTeamName);
341
350
  const now = new Date().toISOString();
342
- await reactor.addAction(subscriptionInstanceDoc.header.id, SubscriptionInstanceV1.actions.initializeSubscription({
343
- createdAt: now,
351
+ const subscriptionInput = mapOfferingToSubscription({
352
+ offering: serviceOfferingState,
353
+ tierId: selection.tierId,
354
+ selectedBillingCycle: selection.billingCycle,
344
355
  customerId: builderProfileDoc.header.id,
345
356
  customerName: name,
346
357
  customerEmail,
347
- serviceOfferingId,
348
- tierName: selectedTier.name,
349
- tierPricingOptionId: selectedTier.id,
350
- tierPrice: selectedTier.pricing?.amount ?? undefined,
351
- tierCurrency: selectedTier.pricing?.currency ?? "USD",
352
- tierPricingMode: selectedTier.pricingMode,
353
- selectedBillingCycle: userSelection.billingCycle,
354
- globalCurrency: selectedTier.pricing?.currency ?? "USD",
355
- }));
356
- const projectedAmount = selectedTier.pricing?.amount;
358
+ createdAt: now,
359
+ priceBreakdown,
360
+ });
361
+ await reactorClient.execute(subscriptionInstanceDoc.header.id, "main", [
362
+ SubscriptionInstance.actions.initializeSubscription({
363
+ ...subscriptionInput,
364
+ resourceId: resourceInstanceDoc.header.id,
365
+ resourceLabel: parsedTeamName,
366
+ resourceThumbnailUrl: serviceOfferingState.thumbnailUrl,
367
+ }),
368
+ ]);
369
+ // Set billing projection from tier price
370
+ const projectedAmount = subscriptionInput.tierPrice ?? priceBreakdown.tierCycleTotal;
357
371
  if (projectedAmount != null) {
358
- await reactor.addAction(subscriptionInstanceDoc.header.id, SubscriptionInstanceV1.actions.updateBillingProjection({
359
- projectedBillAmount: projectedAmount,
360
- projectedBillCurrency: selectedTier.pricing?.currency || "USD",
361
- }));
372
+ await reactorClient.execute(subscriptionInstanceDoc.header.id, "main", [
373
+ SubscriptionInstance.actions.updateBillingProjection({
374
+ projectedBillAmount: projectedAmount,
375
+ projectedBillCurrency: priceBreakdown.tierCurrency || "USD",
376
+ }),
377
+ ]);
362
378
  }
363
379
  return {
364
380
  success: true,
@@ -389,7 +405,7 @@ export const getResolvers = (subgraph) => {
389
405
  * Uses the drive slug in the switchboard URL path.
390
406
  */
391
407
  function getDriveLink(driveSlug) {
392
- const baseUri = process.env.BASE_URI || "";
408
+ const baseUri = typeof process !== "undefined" ? process.env.BASE_URI || "" : "";
393
409
  if (baseUri.includes("-dev.")) {
394
410
  return `https://connect-dev.powerhouse.xyz/?driveUrl=https://switchboard-dev.powerhouse.xyz/d/${driveSlug}`;
395
411
  }
@@ -415,18 +431,18 @@ function mapResourceTemplateState(state, doc) {
415
431
  infoLink: state.infoLink || null,
416
432
  status: state.status,
417
433
  lastModified: state.lastModified,
418
- targetAudiences: state.targetAudiences.map((audience) => ({
434
+ targetAudiences: (state.targetAudiences || []).map((audience) => ({
419
435
  id: audience.id,
420
436
  label: audience.label,
421
437
  color: audience.color || null,
422
438
  })),
423
- setupServices: state.setupServices,
424
- recurringServices: state.recurringServices,
425
- facetTargets: state.facetTargets.map((facet) => ({
439
+ setupServices: state.setupServices || [],
440
+ recurringServices: state.recurringServices || [],
441
+ facetTargets: (state.facetTargets || []).map((facet) => ({
426
442
  id: facet.id,
427
443
  categoryKey: facet.categoryKey,
428
444
  categoryLabel: facet.categoryLabel,
429
- selectedOptions: facet.selectedOptions,
445
+ selectedOptions: facet.selectedOptions || [],
430
446
  })),
431
447
  services: (state.services || []).map((service) => ({
432
448
  id: service.id,
@@ -436,6 +452,12 @@ function mapResourceTemplateState(state, doc) {
436
452
  parentServiceId: service.parentServiceId || null,
437
453
  isSetupFormation: service.isSetupFormation,
438
454
  optionGroupId: service.optionGroupId || null,
455
+ facetBindings: (service.facetBindings || []).map((binding) => ({
456
+ id: binding.id,
457
+ facetName: binding.facetName,
458
+ facetType: binding.facetType,
459
+ supportedOptions: binding.supportedOptions || [],
460
+ })),
439
461
  })),
440
462
  optionGroups: (state.optionGroups || []).map((group) => ({
441
463
  id: group.id,
@@ -450,7 +472,7 @@ function mapResourceTemplateState(state, doc) {
450
472
  answer: faq.answer || null,
451
473
  displayOrder: faq.displayOrder,
452
474
  })),
453
- contentSections: state.contentSections.map((section) => ({
475
+ contentSections: (state.contentSections || []).map((section) => ({
454
476
  id: section.id,
455
477
  title: section.title,
456
478
  content: section.content,
@@ -462,35 +484,50 @@ function mapResourceTemplateState(state, doc) {
462
484
  * Populate a resource-instance document with data from a resource-template.
463
485
  * Initializes basic info and sets facet configuration from template facetTargets.
464
486
  */
465
- async function populateResourceInstance(reactor, resourceInstanceDocId, resourceTemplateId, operatorId, customerId, customerName) {
466
- const resourceTemplateDoc = await reactor.getDocument(resourceTemplateId);
487
+ async function populateResourceInstance(reactorClient, resourceInstanceDocId, resourceTemplateId, operatorId, customerId, customerName) {
488
+ const resourceTemplateDoc = await reactorClient.get(resourceTemplateId);
467
489
  if (!resourceTemplateDoc)
468
490
  return;
469
491
  const templateState = resourceTemplateDoc.state.global;
470
492
  // Initialize instance with basic info from template
471
- await reactor.addAction(resourceInstanceDocId, ResourceInstanceV1.actions.initializeInstance({
472
- operatorId,
473
- operatorDocumentType: "powerhouse/builder-profile",
474
- resourceTemplateId,
475
- customerId,
476
- customerName,
477
- templateName: templateState.title,
478
- thumbnailUrl: templateState.thumbnailUrl,
479
- infoLink: templateState.infoLink,
480
- description: templateState.description,
481
- }));
493
+ await reactorClient.execute(resourceInstanceDocId, "main", [
494
+ ResourceInstance.actions.initializeInstance({
495
+ operatorId,
496
+ operatorDocumentType: "powerhouse/builder-profile",
497
+ resourceTemplateId,
498
+ customerId,
499
+ customerName,
500
+ templateName: templateState.title,
501
+ thumbnailUrl: templateState.thumbnailUrl,
502
+ infoLink: templateState.infoLink,
503
+ description: templateState.description,
504
+ }),
505
+ ]);
482
506
  // Populate facet configuration from template's facetTargets
483
507
  for (const facetTarget of templateState.facetTargets) {
484
508
  if (facetTarget.selectedOptions.length > 0) {
485
- await reactor.addAction(resourceInstanceDocId, ResourceInstanceV1.actions.setInstanceFacet({
486
- id: facetTarget.id,
487
- categoryKey: facetTarget.categoryKey,
488
- categoryLabel: facetTarget.categoryLabel,
489
- selectedOption: facetTarget.selectedOptions[0],
490
- }));
509
+ await reactorClient.execute(resourceInstanceDocId, "main", [
510
+ ResourceInstance.actions.setInstanceFacet({
511
+ id: facetTarget.id,
512
+ categoryKey: facetTarget.categoryKey,
513
+ categoryLabel: facetTarget.categoryLabel,
514
+ selectedOption: facetTarget.selectedOptions[0],
515
+ }),
516
+ ]);
491
517
  }
492
518
  }
493
519
  }
520
+ /**
521
+ * Map a DiscountRule to the GraphQL shape, or null
522
+ */
523
+ function mapDiscountRule(rule) {
524
+ if (!rule)
525
+ return null;
526
+ return {
527
+ discountType: rule.discountType,
528
+ discountValue: rule.discountValue,
529
+ };
530
+ }
494
531
  /**
495
532
  * Map ServiceOfferingState from document model to GraphQL response
496
533
  */
@@ -506,14 +543,14 @@ function mapServiceOfferingState(state, doc) {
506
543
  infoLink: state.infoLink || null,
507
544
  status: state.status,
508
545
  lastModified: state.lastModified,
509
- availableBillingCycles: state.availableBillingCycles,
510
- facetTargets: state.facetTargets.map((facet) => ({
546
+ availableBillingCycles: state.availableBillingCycles || [],
547
+ facetTargets: (state.facetTargets || []).map((facet) => ({
511
548
  id: facet.id,
512
549
  categoryKey: facet.categoryKey,
513
550
  categoryLabel: facet.categoryLabel,
514
- selectedOptions: facet.selectedOptions,
551
+ selectedOptions: facet.selectedOptions || [],
515
552
  })),
516
- services: state.services.map((service) => ({
553
+ services: (state.services || []).map((service) => ({
517
554
  id: service.id,
518
555
  title: service.title,
519
556
  description: service.description || null,
@@ -521,37 +558,45 @@ function mapServiceOfferingState(state, doc) {
521
558
  isSetupFormation: service.isSetupFormation,
522
559
  optionGroupId: service.optionGroupId || null,
523
560
  })),
524
- tiers: state.tiers.map((tier) => ({
561
+ tiers: (state.tiers || []).map((tier) => ({
525
562
  id: tier.id,
526
563
  name: tier.name,
527
564
  description: tier.description || null,
528
565
  isCustomPricing: tier.isCustomPricing,
529
566
  pricingMode: tier.pricingMode || null,
530
- pricing: tier.pricing
531
- ? {
532
- amount: tier.pricing.amount ?? null,
533
- currency: tier.pricing.currency,
534
- }
535
- : null,
567
+ pricing: {
568
+ amount: tier.pricing?.amount ?? null,
569
+ currency: tier.pricing?.currency ?? "USD",
570
+ },
536
571
  defaultBillingCycle: tier.defaultBillingCycle || null,
537
- billingCycleDiscounts: tier.billingCycleDiscounts.map((d) => ({
538
- cycle: d.cycle,
539
- discountType: d.discountType,
540
- discountValue: d.discountValue,
572
+ billingCycleDiscounts: (tier.billingCycleDiscounts || []).map((d) => ({
573
+ billingCycle: d.billingCycle,
574
+ discountRule: {
575
+ discountType: d.discountRule?.discountType,
576
+ discountValue: d.discountRule?.discountValue,
577
+ },
541
578
  })),
542
- serviceLevels: tier.serviceLevels.map((level) => ({
579
+ serviceLevels: (tier.serviceLevels || []).map((level) => ({
543
580
  id: level.id,
544
581
  serviceId: level.serviceId,
545
582
  level: level.level,
583
+ customValue: level.customValue || null,
584
+ optionGroupId: level.optionGroupId || null,
546
585
  })),
547
- usageLimits: tier.usageLimits.map((limit) => ({
586
+ usageLimits: (tier.usageLimits || []).map((limit) => ({
548
587
  id: limit.id,
549
- name: limit.name,
550
- limit: limit.limit,
551
- unit: limit.unit || null,
588
+ serviceId: limit.serviceId,
589
+ metric: limit.metric,
590
+ unitName: limit.unitName || null,
591
+ freeLimit: limit.freeLimit ?? null,
592
+ paidLimit: limit.paidLimit ?? null,
593
+ resetCycle: limit.resetCycle || null,
594
+ notes: limit.notes || null,
595
+ unitPrice: limit.unitPrice ?? null,
596
+ unitPriceCurrency: limit.unitPriceCurrency || null,
552
597
  })),
553
598
  })),
554
- optionGroups: state.optionGroups.map((group) => ({
599
+ optionGroups: (state.optionGroups || []).map((group) => ({
555
600
  id: group.id,
556
601
  name: group.name,
557
602
  description: group.description || null,
@@ -560,21 +605,55 @@ function mapServiceOfferingState(state, doc) {
560
605
  pricingMode: group.pricingMode || null,
561
606
  standalonePricing: group.standalonePricing
562
607
  ? {
563
- amount: group.standalonePricing.amount,
564
- currency: group.standalonePricing.currency,
608
+ setupCost: group.standalonePricing.setupCost
609
+ ? {
610
+ amount: group.standalonePricing.setupCost.amount,
611
+ currency: group.standalonePricing.setupCost.currency,
612
+ discount: mapDiscountRule(group.standalonePricing.setupCost.discount),
613
+ }
614
+ : null,
615
+ recurringPricing: (group.standalonePricing.recurringPricing || []).map((rp) => ({
616
+ id: rp.id,
617
+ billingCycle: rp.billingCycle,
618
+ amount: rp.amount,
619
+ currency: rp.currency,
620
+ discount: mapDiscountRule(rp.discount),
621
+ })),
565
622
  }
566
623
  : null,
567
624
  tierDependentPricing: (group.tierDependentPricing || []).map((tp) => ({
625
+ id: tp.id,
568
626
  tierId: tp.tierId,
569
- amount: tp.amount,
570
- currency: tp.currency,
627
+ setupCost: tp.setupCost
628
+ ? {
629
+ amount: tp.setupCost.amount,
630
+ currency: tp.setupCost.currency,
631
+ discount: mapDiscountRule(tp.setupCost.discount),
632
+ }
633
+ : null,
634
+ setupCostDiscounts: (tp.setupCostDiscounts || []).map((d) => ({
635
+ billingCycle: d.billingCycle,
636
+ discountRule: {
637
+ discountType: d.discountRule?.discountType,
638
+ discountValue: d.discountRule?.discountValue,
639
+ },
640
+ })),
641
+ recurringPricing: (tp.recurringPricing || []).map((rp) => ({
642
+ id: rp.id,
643
+ billingCycle: rp.billingCycle,
644
+ amount: rp.amount,
645
+ currency: rp.currency,
646
+ discount: mapDiscountRule(rp.discount),
647
+ })),
571
648
  })),
572
649
  costType: group.costType || null,
573
650
  availableBillingCycles: group.availableBillingCycles || [],
574
- billingCycleDiscounts: group.billingCycleDiscounts.map((d) => ({
575
- cycle: d.cycle,
576
- discountType: d.discountType,
577
- discountValue: d.discountValue,
651
+ billingCycleDiscounts: (group.billingCycleDiscounts || []).map((d) => ({
652
+ billingCycle: d.billingCycle,
653
+ discountRule: {
654
+ discountType: d.discountRule?.discountType,
655
+ discountValue: d.discountRule?.discountValue,
656
+ },
578
657
  })),
579
658
  discountMode: group.discountMode || null,
580
659
  price: group.price ?? null,
@@ -582,12 +661,19 @@ function mapServiceOfferingState(state, doc) {
582
661
  })),
583
662
  };
584
663
  }
585
- async function getOperatorDrive(reactor, resourceTemplateId) {
586
- const drives = await reactor.getDrives();
587
- const results = await Promise.all(drives.map(async (drive) => {
588
- const docIds = await reactor.getDocuments(drive);
589
- return docIds.includes(resourceTemplateId) ? drive : null;
590
- }));
591
- const driveId = results.find((id) => id !== null);
592
- return driveId ? reactor.getDrive(driveId) : undefined;
664
+ async function getOperatorDrive(reactorClient, resourceTemplateId) {
665
+ // Find all drives
666
+ const { results: drives } = await reactorClient.find({
667
+ type: "powerhouse/document-drive",
668
+ });
669
+ for (const drive of drives) {
670
+ const driveDoc = drive;
671
+ // Check if this drive contains the resource template as a child
672
+ const { results: children } = await reactorClient.getChildren(driveDoc.header.id);
673
+ const hasTemplate = children.some((child) => child.header.id === resourceTemplateId);
674
+ if (hasTemplate) {
675
+ return driveDoc;
676
+ }
677
+ }
678
+ return undefined;
593
679
  }