@powerhousedao/service-offering 1.0.0-dev.3 → 1.0.0-dev.5

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