@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
@@ -5,7 +5,7 @@ export const documentModel = {
5
5
  name: "Powerhouse",
6
6
  website: "https://www.powerhouse.inc/",
7
7
  },
8
- extension: "phso",
8
+ extension: "",
9
9
  description: "Defines a service offering with tiered pricing, service groups, option groups, and facet-based targeting.",
10
10
  specifications: [
11
11
  {
@@ -16,420 +16,642 @@ export const documentModel = {
16
16
  initialValue: "",
17
17
  },
18
18
  global: {
19
- schema: "type ServiceOfferingState {\n id: PHID!\n operatorId: PHID!\n resourceTemplateId: PHID\n title: String!\n summary: String!\n description: String\n thumbnailUrl: URL\n infoLink: URL\n status: ServiceStatus!\n lastModified: DateTime!\n availableBillingCycles: [BillingCycle!]!\n facetTargets: [FacetTarget!]!\n services: [Service!]!\n tiers: [ServiceSubscriptionTier!]!\n optionGroups: [OptionGroup!]!\n}\n\nenum ServiceStatus {\n DRAFT\n COMING_SOON\n ACTIVE\n DEPRECATED\n}\n\nenum BillingCycle {\n MONTHLY\n QUARTERLY\n SEMI_ANNUAL\n ANNUAL\n}\n\ntype FacetTarget {\n id: OID!\n categoryKey: String!\n categoryLabel: String!\n selectedOptions: [String!]!\n}\n\ntype Service {\n id: OID!\n title: String!\n description: String\n displayOrder: Int\n isSetupFormation: Boolean!\n optionGroupId: OID\n}\n\ntype ServiceSubscriptionTier {\n id: OID!\n name: String!\n description: String\n isCustomPricing: Boolean!\n pricingMode: TierPricingMode!\n pricing: TierPricing\n defaultBillingCycle: BillingCycle\n billingCycleDiscounts: [BillingCycleDiscount!]!\n serviceLevels: [TierServiceLevel!]!\n usageLimits: [UsageLimit!]!\n}\n\nenum TierPricingMode {\n FIXED\n PER_SEAT\n CUSTOM\n}\n\ntype TierPricing {\n amount: Amount_Money!\n currency: Currency!\n}\n\ntype BillingCycleDiscount {\n cycle: BillingCycle!\n discountType: DiscountType!\n discountValue: Float!\n}\n\nenum DiscountType {\n PERCENTAGE\n FIXED_AMOUNT\n}\n\ntype TierServiceLevel {\n id: OID!\n serviceId: OID!\n level: String!\n description: String\n}\n\ntype UsageLimit {\n id: OID!\n name: String!\n limit: Int!\n unit: String\n}\n\ntype OptionGroup {\n id: OID!\n name: String!\n description: String\n isAddOn: Boolean!\n defaultSelected: Boolean!\n pricingMode: AddOnPricingMode!\n standalonePricing: TierPricing\n tierDependentPricing: [TierDependentPricing!]!\n costType: GroupCostType\n availableBillingCycles: [BillingCycle!]!\n billingCycleDiscounts: [BillingCycleDiscount!]!\n discountMode: DiscountMode\n price: Amount_Money\n currency: Currency\n}\n\nenum AddOnPricingMode {\n STANDALONE\n TIER_DEPENDENT\n}\n\nenum GroupCostType {\n SETUP\n RECURRING\n}\n\nenum DiscountMode {\n OWN_DISCOUNTS\n INHERIT_TIER\n}\n\ntype TierDependentPricing {\n tierId: OID!\n amount: Amount_Money!\n currency: Currency!\n}",
19
+ schema: "type ServiceOfferingState {\n id: PHID\n operatorId: PHID\n resourceTemplateId: PHID\n title: String!\n summary: String!\n description: String\n thumbnailUrl: URL\n infoLink: URL\n status: ServiceStatus!\n lastModified: DateTime\n availableBillingCycles: [BillingCycle!]!\n facetTargets: [FacetTarget!]!\n services: [Service!]!\n tiers: [ServiceSubscriptionTier!]!\n optionGroups: [OptionGroup!]!\n}\n\nenum ServiceStatus {\n DRAFT\n COMING_SOON\n ACTIVE\n DEPRECATED\n}\n\ntype FacetTarget {\n id: OID!\n categoryKey: String!\n categoryLabel: String!\n selectedOptions: [String!]!\n}\n\ntype DiscountRule {\n discountType: DiscountType!\n discountValue: Float!\n}\n\nenum DiscountType {\n PERCENTAGE\n FLAT_AMOUNT\n}\n\ntype BillingCycleDiscount {\n billingCycle: BillingCycle!\n discountRule: DiscountRule!\n}\n\ntype SetupCost {\n amount: Amount_Money!\n currency: Currency!\n discount: DiscountRule\n}\n\ntype RecurringPriceOption {\n id: OID!\n billingCycle: BillingCycle!\n amount: Amount_Money!\n currency: Currency!\n discount: DiscountRule\n}\n\ntype Service {\n id: OID!\n title: String!\n description: String\n displayOrder: Int\n isSetupFormation: Boolean!\n optionGroupId: OID\n}\n\ntype ServiceSubscriptionTier {\n id: OID!\n name: String!\n description: String\n isCustomPricing: Boolean!\n pricingMode: TierPricingMode\n pricing: ServicePricing!\n defaultBillingCycle: BillingCycle\n billingCycleDiscounts: [BillingCycleDiscount!]!\n serviceLevels: [ServiceLevelBinding!]!\n usageLimits: [ServiceUsageLimit!]!\n}\n\ntype ServicePricing {\n amount: Amount_Money\n currency: Currency!\n}\n\nenum BillingCycle {\n MONTHLY\n QUARTERLY\n SEMI_ANNUAL\n ANNUAL\n ONE_TIME\n}\n\ntype ServiceLevelBinding {\n id: OID!\n serviceId: OID!\n level: ServiceLevel!\n customValue: String\n optionGroupId: OID\n}\n\nenum ServiceLevel {\n INCLUDED\n NOT_INCLUDED\n OPTIONAL\n CUSTOM\n VARIABLE\n NOT_APPLICABLE\n}\n\ntype ServiceUsageLimit {\n id: OID!\n serviceId: OID!\n metric: String!\n unitName: String\n freeLimit: Int\n paidLimit: Int\n resetCycle: UsageResetCycle\n notes: String\n unitPrice: Amount_Money\n unitPriceCurrency: Currency\n}\n\nenum UsageResetCycle {\n NONE\n HOURLY\n DAILY\n WEEKLY\n MONTHLY\n QUARTERLY\n SEMI_ANNUAL\n ANNUAL\n}\n\ntype OptionGroup {\n id: OID!\n name: String!\n description: String\n isAddOn: Boolean!\n defaultSelected: Boolean!\n pricingMode: AddOnPricingMode\n standalonePricing: StandalonePricing\n tierDependentPricing: [OptionGroupTierPricing!]\n costType: GroupCostType\n availableBillingCycles: [BillingCycle!]!\n billingCycleDiscounts: [BillingCycleDiscount!]!\n discountMode: DiscountMode\n price: Amount_Money\n currency: Currency\n}\n\nenum AddOnPricingMode {\n TIER_DEPENDENT\n STANDALONE\n}\n\nenum DiscountMode {\n INHERIT_TIER\n INDEPENDENT\n}\n\nenum TierPricingMode {\n CALCULATED\n MANUAL_OVERRIDE\n}\n\ntype StandalonePricing {\n setupCost: SetupCost\n recurringPricing: [RecurringPriceOption!]!\n}\n\ntype OptionGroupTierPricing {\n id: OID!\n tierId: OID!\n setupCost: SetupCost\n setupCostDiscounts: [BillingCycleDiscount!]!\n recurringPricing: [RecurringPriceOption!]!\n}\n\nenum GroupCostType {\n RECURRING\n SETUP\n}",
20
20
  examples: [],
21
- initialValue: '{"id": "", "operatorId": "", "resourceTemplateId": null, "title": "", "summary": "", "description": null, "thumbnailUrl": null, "infoLink": null, "status": "DRAFT", "lastModified": "1970-01-01T00:00:00.000Z", "availableBillingCycles": [], "facetTargets": [], "services": [], "tiers": [], "optionGroups": []}',
21
+ initialValue: '{\n "id": null,\n "operatorId": null,\n "resourceTemplateId": null,\n "title": "",\n "summary": "",\n "description": null,\n "thumbnailUrl": null,\n "infoLink": null,\n "status": "DRAFT",\n "lastModified": null,\n "availableBillingCycles": [],\n "facetTargets": [],\n "services": [],\n "tiers": [],\n "optionGroups": []\n}',
22
22
  },
23
23
  },
24
24
  modules: [
25
25
  {
26
- id: "offering",
27
- name: "Offering",
28
- description: "Operations for managing offering metadata and facet targeting",
26
+ id: "mod-offering",
27
+ name: "offering",
28
+ description: "Offering-level metadata, status, target audiences, facet targets, and resource templates",
29
29
  operations: [
30
30
  {
31
- id: "update-offering-info",
31
+ id: "op-update-offering-info",
32
32
  name: "UPDATE_OFFERING_INFO",
33
- description: "Updates offering info",
33
+ description: "Update offering title, summary, description, URLs",
34
34
  schema: "input UpdateOfferingInfoInput {\n title: String\n summary: String\n description: String\n thumbnailUrl: URL\n infoLink: URL\n lastModified: DateTime!\n}",
35
- template: "Updates offering info",
35
+ template: "Update offering title, summary, description, URLs",
36
36
  reducer: "if (action.input.title) state.title = action.input.title;\nif (action.input.summary) state.summary = action.input.summary;\nif (action.input.description !== undefined) state.description = action.input.description || null;\nif (action.input.thumbnailUrl !== undefined) state.thumbnailUrl = action.input.thumbnailUrl || null;\nif (action.input.infoLink !== undefined) state.infoLink = action.input.infoLink || null;\nstate.lastModified = action.input.lastModified;",
37
37
  errors: [],
38
38
  examples: [],
39
39
  scope: "global",
40
40
  },
41
41
  {
42
- id: "update-offering-status",
42
+ id: "op-update-offering-status",
43
43
  name: "UPDATE_OFFERING_STATUS",
44
- description: "Updates offering status",
44
+ description: "Change offering status",
45
45
  schema: "input UpdateOfferingStatusInput {\n status: ServiceStatus!\n lastModified: DateTime!\n}",
46
- template: "Updates offering status",
46
+ template: "Change offering status",
47
47
  reducer: "state.status = action.input.status;\nstate.lastModified = action.input.lastModified;",
48
48
  errors: [],
49
49
  examples: [],
50
50
  scope: "global",
51
51
  },
52
52
  {
53
- id: "set-operator",
53
+ id: "op-set-operator",
54
54
  name: "SET_OPERATOR",
55
- description: "Sets the operator",
55
+ description: "Set operator ID",
56
56
  schema: "input SetOperatorInput {\n operatorId: PHID!\n lastModified: DateTime!\n}",
57
- template: "Sets the operator",
57
+ template: "Set operator ID",
58
58
  reducer: "state.operatorId = action.input.operatorId;\nstate.lastModified = action.input.lastModified;",
59
59
  errors: [],
60
60
  examples: [],
61
61
  scope: "global",
62
62
  },
63
63
  {
64
- id: "set-offering-id",
64
+ id: "op-set-offering-id",
65
65
  name: "SET_OFFERING_ID",
66
- description: "Sets the offering ID",
66
+ description: "Set offering ID",
67
67
  schema: "input SetOfferingIdInput {\n id: PHID!\n lastModified: DateTime!\n}",
68
- template: "Sets the offering ID",
68
+ template: "Set offering ID",
69
69
  reducer: "state.id = action.input.id;\nstate.lastModified = action.input.lastModified;",
70
70
  errors: [],
71
71
  examples: [],
72
72
  scope: "global",
73
73
  },
74
74
  {
75
- id: "set-facet-target",
75
+ id: "op-set-facet-target",
76
76
  name: "SET_FACET_TARGET",
77
- description: "Sets a facet target",
77
+ description: "Set or upsert a facet target category",
78
78
  schema: "input SetFacetTargetInput {\n id: OID!\n categoryKey: String!\n categoryLabel: String!\n selectedOptions: [String!]!\n lastModified: DateTime!\n}",
79
- template: "Sets a facet target",
80
- reducer: "const existingIndex = state.facetTargets.findIndex(ft => ft.categoryKey === action.input.categoryKey);\nif (existingIndex !== -1) {\n state.facetTargets[existingIndex] = { id: action.input.id, categoryKey: action.input.categoryKey, categoryLabel: action.input.categoryLabel, selectedOptions: action.input.selectedOptions };\n} else {\n state.facetTargets.push({ id: action.input.id, categoryKey: action.input.categoryKey, categoryLabel: action.input.categoryLabel, selectedOptions: action.input.selectedOptions });\n}\nstate.lastModified = action.input.lastModified;",
79
+ template: "Set or upsert a facet target category",
80
+ reducer: "const existingIndex = state.facetTargets.findIndex(ft => ft.categoryKey === action.input.categoryKey);\nconst facetTarget = {\n id: action.input.id,\n categoryKey: action.input.categoryKey,\n categoryLabel: action.input.categoryLabel,\n selectedOptions: action.input.selectedOptions,\n};\nif (existingIndex !== -1) {\n state.facetTargets[existingIndex] = facetTarget;\n} else {\n state.facetTargets.push(facetTarget);\n}\nstate.lastModified = action.input.lastModified;",
81
81
  errors: [],
82
82
  examples: [],
83
83
  scope: "global",
84
84
  },
85
85
  {
86
- id: "remove-facet-target",
86
+ id: "op-remove-facet-target",
87
87
  name: "REMOVE_FACET_TARGET",
88
- description: "Removes a facet target",
88
+ description: "Remove a facet target by category key",
89
89
  schema: "input RemoveFacetTargetInput {\n categoryKey: String!\n lastModified: DateTime!\n}",
90
- template: "Removes a facet target",
91
- reducer: "const facetIndex = state.facetTargets.findIndex(ft => ft.categoryKey === action.input.categoryKey);\nif (facetIndex !== -1) { state.facetTargets.splice(facetIndex, 1); }\nstate.lastModified = action.input.lastModified;",
92
- errors: [],
90
+ template: "Remove a facet target by category key",
91
+ reducer: "const index = state.facetTargets.findIndex(ft => ft.categoryKey === action.input.categoryKey);\nif (index === -1) {\n throw new RemoveFacetTargetNotFoundError(`Facet target with category key ${action.input.categoryKey} not found`);\n}\nstate.facetTargets.splice(index, 1);\nstate.lastModified = action.input.lastModified;",
92
+ errors: [
93
+ {
94
+ id: "err-remove-ft-not-found",
95
+ name: "RemoveFacetTargetNotFoundError",
96
+ code: "FACET_TARGET_NOT_FOUND",
97
+ description: "Facet target with given category key not found",
98
+ template: "",
99
+ },
100
+ ],
93
101
  examples: [],
94
102
  scope: "global",
95
103
  },
96
104
  {
97
- id: "add-facet-option",
105
+ id: "op-add-facet-option",
98
106
  name: "ADD_FACET_OPTION",
99
- description: "Adds a facet option",
107
+ description: "Add an option to an existing facet target",
100
108
  schema: "input AddFacetOptionInput {\n categoryKey: String!\n optionId: String!\n lastModified: DateTime!\n}",
101
- template: "Adds a facet option",
102
- reducer: "const facetTarget = state.facetTargets.find(ft => ft.categoryKey === action.input.categoryKey);\nif (facetTarget && !facetTarget.selectedOptions.includes(action.input.optionId)) {\n facetTarget.selectedOptions.push(action.input.optionId);\n}\nstate.lastModified = action.input.lastModified;",
103
- errors: [],
109
+ template: "Add an option to an existing facet target",
110
+ reducer: "const facetTarget = state.facetTargets.find(ft => ft.categoryKey === action.input.categoryKey);\nif (!facetTarget) {\n throw new AddFacetOptionTargetNotFoundError(`Facet target with category key ${action.input.categoryKey} not found`);\n}\nfacetTarget.selectedOptions.push(action.input.optionId);\nstate.lastModified = action.input.lastModified;",
111
+ errors: [
112
+ {
113
+ id: "err-add-fo-target-not-found",
114
+ name: "AddFacetOptionTargetNotFoundError",
115
+ code: "FACET_TARGET_NOT_FOUND",
116
+ description: "Facet target with given category key not found",
117
+ template: "",
118
+ },
119
+ ],
104
120
  examples: [],
105
121
  scope: "global",
106
122
  },
107
123
  {
108
- id: "remove-facet-option",
124
+ id: "op-remove-facet-option",
109
125
  name: "REMOVE_FACET_OPTION",
110
- description: "Removes a facet option",
126
+ description: "Remove an option from a facet target",
111
127
  schema: "input RemoveFacetOptionInput {\n categoryKey: String!\n optionId: String!\n lastModified: DateTime!\n}",
112
- template: "Removes a facet option",
113
- reducer: "const facetTarget = state.facetTargets.find(ft => ft.categoryKey === action.input.categoryKey);\nif (facetTarget) {\n const optionIndex = facetTarget.selectedOptions.indexOf(action.input.optionId);\n if (optionIndex !== -1) { facetTarget.selectedOptions.splice(optionIndex, 1); }\n}\nstate.lastModified = action.input.lastModified;",
114
- errors: [],
128
+ template: "Remove an option from a facet target",
129
+ reducer: "const facetTarget = state.facetTargets.find(ft => ft.categoryKey === action.input.categoryKey);\nif (!facetTarget) {\n throw new RemoveFacetOptionTargetNotFoundError(`Facet target with category key ${action.input.categoryKey} not found`);\n}\nconst optIndex = facetTarget.selectedOptions.indexOf(action.input.optionId);\nif (optIndex !== -1) {\n facetTarget.selectedOptions.splice(optIndex, 1);\n}\nstate.lastModified = action.input.lastModified;",
130
+ errors: [
131
+ {
132
+ id: "err-remove-fo-target-not-found",
133
+ name: "RemoveFacetOptionTargetNotFoundError",
134
+ code: "FACET_TARGET_NOT_FOUND",
135
+ description: "Facet target with given category key not found",
136
+ template: "",
137
+ },
138
+ ],
115
139
  examples: [],
116
140
  scope: "global",
117
141
  },
118
142
  {
119
- id: "select-resource-template",
143
+ id: "op-select-resource-template",
120
144
  name: "SELECT_RESOURCE_TEMPLATE",
121
- description: "Selects a resource template",
145
+ description: "Select a resource template",
122
146
  schema: "input SelectResourceTemplateInput {\n resourceTemplateId: PHID!\n lastModified: DateTime!\n}",
123
- template: "Selects a resource template",
147
+ template: "Select a resource template",
124
148
  reducer: "state.resourceTemplateId = action.input.resourceTemplateId;\nstate.lastModified = action.input.lastModified;",
125
149
  errors: [],
126
150
  examples: [],
127
151
  scope: "global",
128
152
  },
129
153
  {
130
- id: "change-resource-template",
154
+ id: "op-change-resource-template",
131
155
  name: "CHANGE_RESOURCE_TEMPLATE",
132
- description: "Changes the resource template",
133
- schema: "input ChangeResourceTemplateInput {\n resourceTemplateId: PHID!\n lastModified: DateTime!\n}",
134
- template: "Changes the resource template",
135
- reducer: "state.resourceTemplateId = action.input.resourceTemplateId;\nstate.lastModified = action.input.lastModified;",
136
- errors: [],
156
+ description: "Change the resource template",
157
+ schema: "input ChangeResourceTemplateInput {\n previousTemplateId: PHID!\n newTemplateId: PHID!\n lastModified: DateTime!\n}",
158
+ template: "Change the resource template",
159
+ reducer: "if (state.resourceTemplateId !== action.input.previousTemplateId) {\n throw new ChangeResourceTemplateMismatchError(`Current template ${state.resourceTemplateId} does not match previous template ${action.input.previousTemplateId}`);\n}\nstate.resourceTemplateId = action.input.newTemplateId;\nstate.lastModified = action.input.lastModified;",
160
+ errors: [
161
+ {
162
+ id: "err-change-rt-mismatch",
163
+ name: "ChangeResourceTemplateMismatchError",
164
+ code: "TEMPLATE_MISMATCH",
165
+ description: "The previous template ID does not match the current resource template",
166
+ template: "",
167
+ },
168
+ ],
137
169
  examples: [],
138
170
  scope: "global",
139
171
  },
140
172
  {
141
- id: "set-available-billing-cycles",
173
+ id: "op-set-available-billing-cycles",
142
174
  name: "SET_AVAILABLE_BILLING_CYCLES",
143
- description: "Sets available billing cycles",
175
+ description: "Set the available billing cycles for the offering",
144
176
  schema: "input SetAvailableBillingCyclesInput {\n billingCycles: [BillingCycle!]!\n lastModified: DateTime!\n}",
145
- template: "Sets available billing cycles",
146
- reducer: "state.availableBillingCycles = action.input.billingCycles;\nstate.lastModified = action.input.lastModified;",
147
- errors: [],
177
+ template: "Set the available billing cycles for the offering",
178
+ reducer: 'if (action.input.billingCycles.length === 0) {\n throw new NoBillingCyclesSelectedError("At least one billing cycle must be selected");\n}\nstate.availableBillingCycles = action.input.billingCycles;\nstate.lastModified = action.input.lastModified;',
179
+ errors: [
180
+ {
181
+ id: "err-no-billing-cycles",
182
+ name: "NoBillingCyclesSelectedError",
183
+ code: "NO_BILLING_CYCLES_SELECTED",
184
+ description: "At least one billing cycle must be selected",
185
+ template: "",
186
+ },
187
+ ],
148
188
  examples: [],
149
189
  scope: "global",
150
190
  },
151
191
  ],
152
192
  },
153
193
  {
154
- id: "services",
155
- name: "Services",
156
- description: "Operations for managing services",
194
+ id: "mod-services",
195
+ name: "services",
196
+ description: "Service CRUD and facet bindings",
157
197
  operations: [
158
198
  {
159
- id: "add-service",
199
+ id: "op-add-service",
160
200
  name: "ADD_SERVICE",
161
- description: "Adds a service",
201
+ description: "Add a new service",
162
202
  schema: "input AddServiceInput {\n id: OID!\n title: String!\n description: String\n displayOrder: Int\n isSetupFormation: Boolean\n optionGroupId: OID\n lastModified: DateTime!\n}",
163
- template: "Adds a service",
164
- reducer: "state.services.push({ id: action.input.id, title: action.input.title, description: action.input.description || null, displayOrder: action.input.displayOrder || null, isSetupFormation: action.input.isSetupFormation || false, optionGroupId: action.input.optionGroupId || null });\nstate.lastModified = action.input.lastModified;",
203
+ template: "Add a new service",
204
+ reducer: "state.services.push({\n id: action.input.id,\n title: action.input.title,\n description: action.input.description || null,\n displayOrder: action.input.displayOrder || null,\n isSetupFormation: action.input.isSetupFormation || false,\n optionGroupId: action.input.optionGroupId || null,\n});\nstate.lastModified = action.input.lastModified;",
165
205
  errors: [],
166
206
  examples: [],
167
207
  scope: "global",
168
208
  },
169
209
  {
170
- id: "update-service",
210
+ id: "op-update-service",
171
211
  name: "UPDATE_SERVICE",
172
- description: "Updates a service",
212
+ description: "Update service fields",
173
213
  schema: "input UpdateServiceInput {\n id: OID!\n title: String\n description: String\n displayOrder: Int\n isSetupFormation: Boolean\n optionGroupId: OID\n lastModified: DateTime!\n}",
174
- template: "Updates a service",
175
- reducer: "const service = state.services.find(s => s.id === action.input.id);\nif (service) {\n if (action.input.title) service.title = action.input.title;\n if (action.input.description !== undefined) service.description = action.input.description || null;\n if (action.input.displayOrder !== undefined && action.input.displayOrder !== null) service.displayOrder = action.input.displayOrder;\n if (action.input.isSetupFormation !== undefined && action.input.isSetupFormation !== null) service.isSetupFormation = action.input.isSetupFormation;\n if (action.input.optionGroupId !== undefined) service.optionGroupId = action.input.optionGroupId || null;\n}\nstate.lastModified = action.input.lastModified;",
176
- errors: [],
214
+ template: "Update service fields",
215
+ reducer: "const service = state.services.find((s) => s.id === action.input.id);\nif (!service) {\n throw new UpdateServiceNotFoundError(`Service with ID ${action.input.id} not found`);\n}\nif (action.input.title) service.title = action.input.title;\nif (action.input.description !== undefined) service.description = action.input.description || null;\nif (action.input.displayOrder !== undefined) service.displayOrder = action.input.displayOrder || null;\nif (action.input.isSetupFormation !== undefined && action.input.isSetupFormation !== null) service.isSetupFormation = action.input.isSetupFormation;\nif (action.input.optionGroupId !== undefined) service.optionGroupId = action.input.optionGroupId || null;\nstate.lastModified = action.input.lastModified;",
216
+ errors: [
217
+ {
218
+ id: "err-update-service-not-found",
219
+ name: "UpdateServiceNotFoundError",
220
+ code: "SERVICE_NOT_FOUND",
221
+ description: "Service with given ID not found",
222
+ template: "",
223
+ },
224
+ ],
177
225
  examples: [],
178
226
  scope: "global",
179
227
  },
180
228
  {
181
- id: "delete-service",
229
+ id: "op-delete-service",
182
230
  name: "DELETE_SERVICE",
183
- description: "Deletes a service",
231
+ description: "Delete a service",
184
232
  schema: "input DeleteServiceInput {\n id: OID!\n lastModified: DateTime!\n}",
185
- template: "Deletes a service",
186
- reducer: "const serviceIndex = state.services.findIndex(s => s.id === action.input.id);\nif (serviceIndex !== -1) { state.services.splice(serviceIndex, 1); }\nstate.lastModified = action.input.lastModified;",
187
- errors: [],
233
+ template: "Delete a service",
234
+ reducer: "const index = state.services.findIndex(s => s.id === action.input.id);\nif (index === -1) {\n throw new DeleteServiceNotFoundError(`Service with ID ${action.input.id} not found`);\n}\nstate.services.splice(index, 1);\nstate.lastModified = action.input.lastModified;",
235
+ errors: [
236
+ {
237
+ id: "err-delete-service-not-found",
238
+ name: "DeleteServiceNotFoundError",
239
+ code: "SERVICE_NOT_FOUND",
240
+ description: "Service with given ID not found",
241
+ template: "",
242
+ },
243
+ ],
188
244
  examples: [],
189
245
  scope: "global",
190
246
  },
191
247
  ],
192
248
  },
193
249
  {
194
- id: "tiers",
195
- name: "Tiers",
196
- description: "Operations for managing subscription tiers",
250
+ id: "mod-tiers",
251
+ name: "tiers",
252
+ description: "Subscription tiers, service levels, usage limits, billing cycles, and discounts",
197
253
  operations: [
198
254
  {
199
- id: "add-tier",
255
+ id: "op-add-tier",
200
256
  name: "ADD_TIER",
201
- description: "Adds a tier",
202
- schema: "input AddTierInput {\n id: OID!\n name: String!\n description: String\n isCustomPricing: Boolean\n lastModified: DateTime!\n}",
203
- template: "Adds a tier",
204
- reducer: 'state.tiers.push({ id: action.input.id, name: action.input.name, description: action.input.description || null, isCustomPricing: action.input.isCustomPricing || false, pricingMode: "FIXED", pricing: null, defaultBillingCycle: null, billingCycleDiscounts: [], serviceLevels: [], usageLimits: [] });\nstate.lastModified = action.input.lastModified;',
257
+ description: "Add a subscription tier",
258
+ schema: "input AddTierInput {\n id: OID!\n name: String!\n description: String\n amount: Amount_Money\n currency: Currency!\n isCustomPricing: Boolean\n lastModified: DateTime!\n}",
259
+ template: "Add a subscription tier",
260
+ reducer: "state.tiers.push({\n id: action.input.id,\n name: action.input.name,\n description: action.input.description || null,\n isCustomPricing: action.input.isCustomPricing || false,\n pricingMode: null,\n pricing: {\n amount: action.input.amount || null,\n currency: action.input.currency,\n },\n defaultBillingCycle: null,\n billingCycleDiscounts: [],\n serviceLevels: [],\n usageLimits: [],\n});\nstate.lastModified = action.input.lastModified;",
205
261
  errors: [],
206
262
  examples: [],
207
263
  scope: "global",
208
264
  },
209
265
  {
210
- id: "update-tier",
266
+ id: "op-update-tier",
211
267
  name: "UPDATE_TIER",
212
- description: "Updates a tier",
268
+ description: "Update tier metadata",
213
269
  schema: "input UpdateTierInput {\n id: OID!\n name: String\n description: String\n isCustomPricing: Boolean\n lastModified: DateTime!\n}",
214
- template: "Updates a tier",
215
- reducer: "const tier = state.tiers.find(t => t.id === action.input.id);\nif (tier) {\n if (action.input.name) tier.name = action.input.name;\n if (action.input.description !== undefined) tier.description = action.input.description || null;\n if (action.input.isCustomPricing !== undefined && action.input.isCustomPricing !== null) tier.isCustomPricing = action.input.isCustomPricing;\n}\nstate.lastModified = action.input.lastModified;",
216
- errors: [],
270
+ template: "Update tier metadata",
271
+ reducer: "const tier = state.tiers.find(t => t.id === action.input.id);\nif (!tier) {\n throw new UpdateTierNotFoundError(`Tier with ID ${action.input.id} not found`);\n}\nif (action.input.name) tier.name = action.input.name;\nif (action.input.description !== undefined) tier.description = action.input.description || null;\nif (action.input.isCustomPricing !== undefined && action.input.isCustomPricing !== null) tier.isCustomPricing = action.input.isCustomPricing;\nstate.lastModified = action.input.lastModified;",
272
+ errors: [
273
+ {
274
+ id: "err-update-tier-not-found",
275
+ name: "UpdateTierNotFoundError",
276
+ code: "TIER_NOT_FOUND",
277
+ description: "Tier with given ID not found",
278
+ template: "",
279
+ },
280
+ ],
217
281
  examples: [],
218
282
  scope: "global",
219
283
  },
220
284
  {
221
- id: "update-tier-pricing",
285
+ id: "op-update-tier-pricing",
222
286
  name: "UPDATE_TIER_PRICING",
223
- description: "Updates tier pricing",
224
- schema: "input UpdateTierPricingInput {\n tierId: OID!\n amount: Amount_Money!\n currency: Currency!\n lastModified: DateTime!\n}",
225
- template: "Updates tier pricing",
226
- reducer: "const tier = state.tiers.find(t => t.id === action.input.tierId);\nif (tier) { tier.pricing = { amount: action.input.amount, currency: action.input.currency }; }\nstate.lastModified = action.input.lastModified;",
227
- errors: [],
287
+ description: "Update tier base pricing",
288
+ schema: "input UpdateTierPricingInput {\n tierId: OID!\n amount: Amount_Money\n currency: Currency\n lastModified: DateTime!\n}",
289
+ template: "Update tier base pricing",
290
+ reducer: "const tier = state.tiers.find(t => t.id === action.input.tierId);\nif (!tier) {\n throw new UpdateTierPricingNotFoundError(`Tier with ID ${action.input.tierId} not found`);\n}\nif (action.input.amount !== undefined) tier.pricing.amount = action.input.amount || null;\nif (action.input.currency) tier.pricing.currency = action.input.currency;\nstate.lastModified = action.input.lastModified;",
291
+ errors: [
292
+ {
293
+ id: "err-update-tier-pricing-not-found",
294
+ name: "UpdateTierPricingNotFoundError",
295
+ code: "TIER_NOT_FOUND",
296
+ description: "Tier with given ID not found",
297
+ template: "",
298
+ },
299
+ ],
228
300
  examples: [],
229
301
  scope: "global",
230
302
  },
231
303
  {
232
- id: "delete-tier",
304
+ id: "op-delete-tier",
233
305
  name: "DELETE_TIER",
234
- description: "Deletes a tier",
306
+ description: "Delete a tier",
235
307
  schema: "input DeleteTierInput {\n id: OID!\n lastModified: DateTime!\n}",
236
- template: "Deletes a tier",
237
- reducer: "const tierIndex = state.tiers.findIndex(t => t.id === action.input.id);\nif (tierIndex !== -1) { state.tiers.splice(tierIndex, 1); }\nstate.lastModified = action.input.lastModified;",
238
- errors: [],
308
+ template: "Delete a tier",
309
+ reducer: "const index = state.tiers.findIndex(t => t.id === action.input.id);\nif (index === -1) {\n throw new DeleteTierNotFoundError(`Tier with ID ${action.input.id} not found`);\n}\nstate.tiers.splice(index, 1);\nstate.lastModified = action.input.lastModified;",
310
+ errors: [
311
+ {
312
+ id: "err-delete-tier-not-found",
313
+ name: "DeleteTierNotFoundError",
314
+ code: "TIER_NOT_FOUND",
315
+ description: "Tier with given ID not found",
316
+ template: "",
317
+ },
318
+ ],
239
319
  examples: [],
240
320
  scope: "global",
241
321
  },
242
322
  {
243
- id: "add-service-level",
323
+ id: "op-add-service-level",
244
324
  name: "ADD_SERVICE_LEVEL",
245
- description: "Adds a service level to a tier",
246
- schema: "input AddServiceLevelInput {\n tierId: OID!\n id: OID!\n serviceId: OID!\n level: String!\n description: String\n lastModified: DateTime!\n}",
247
- template: "Adds a service level to a tier",
248
- reducer: "const tier = state.tiers.find(t => t.id === action.input.tierId);\nif (tier) { tier.serviceLevels.push({ id: action.input.id, serviceId: action.input.serviceId, level: action.input.level, description: action.input.description || null }); }\nstate.lastModified = action.input.lastModified;",
249
- errors: [],
325
+ description: "Bind a service level to a tier",
326
+ schema: "input AddServiceLevelInput {\n tierId: OID!\n serviceLevelId: OID!\n serviceId: OID!\n level: ServiceLevel!\n optionGroupId: OID\n customValue: String\n lastModified: DateTime!\n}",
327
+ template: "Bind a service level to a tier",
328
+ reducer: "const tier = state.tiers.find(t => t.id === action.input.tierId);\nif (!tier) {\n throw new AddServiceLevelTierNotFoundError(`Tier with ID ${action.input.tierId} not found`);\n}\ntier.serviceLevels.push({\n id: action.input.serviceLevelId,\n serviceId: action.input.serviceId,\n level: action.input.level,\n customValue: action.input.customValue || null,\n optionGroupId: action.input.optionGroupId || null,\n});\nstate.lastModified = action.input.lastModified;",
329
+ errors: [
330
+ {
331
+ id: "err-add-sl-tier-not-found",
332
+ name: "AddServiceLevelTierNotFoundError",
333
+ code: "TIER_NOT_FOUND",
334
+ description: "Tier with given ID not found",
335
+ template: "",
336
+ },
337
+ ],
250
338
  examples: [],
251
339
  scope: "global",
252
340
  },
253
341
  {
254
- id: "update-service-level",
342
+ id: "op-update-service-level",
255
343
  name: "UPDATE_SERVICE_LEVEL",
256
- description: "Updates a service level",
257
- schema: "input UpdateServiceLevelInput {\n tierId: OID!\n id: OID!\n level: String\n description: String\n lastModified: DateTime!\n}",
258
- template: "Updates a service level",
259
- reducer: "const tier = state.tiers.find(t => t.id === action.input.tierId);\nif (tier) {\n const sl = tier.serviceLevels.find(s => s.id === action.input.id);\n if (sl) {\n if (action.input.level) sl.level = action.input.level;\n if (action.input.description !== undefined) sl.description = action.input.description || null;\n }\n}\nstate.lastModified = action.input.lastModified;",
260
- errors: [],
261
- examples: [],
262
- scope: "global",
263
- },
264
- {
265
- id: "remove-service-level",
344
+ description: "Update a service level binding",
345
+ schema: "input UpdateServiceLevelInput {\n tierId: OID!\n serviceLevelId: OID!\n level: ServiceLevel\n optionGroupId: OID\n customValue: String\n lastModified: DateTime!\n}",
346
+ template: "Update a service level binding",
347
+ reducer: "const tier = state.tiers.find(t => t.id === action.input.tierId);\nif (!tier) {\n throw new UpdateServiceLevelTierNotFoundError(`Tier with ID ${action.input.tierId} not found`);\n}\nconst sl = tier.serviceLevels.find(s => s.id === action.input.serviceLevelId);\nif (!sl) {\n throw new UpdateServiceLevelNotFoundError(`Service level with ID ${action.input.serviceLevelId} not found`);\n}\nif (action.input.level) sl.level = action.input.level;\nif (action.input.customValue !== undefined) sl.customValue = action.input.customValue || null;\nif (action.input.optionGroupId !== undefined) sl.optionGroupId = action.input.optionGroupId || null;\nstate.lastModified = action.input.lastModified;",
348
+ errors: [
349
+ {
350
+ id: "err-update-sl-tier-not-found",
351
+ name: "UpdateServiceLevelTierNotFoundError",
352
+ code: "TIER_NOT_FOUND",
353
+ description: "Tier with given ID not found",
354
+ template: "",
355
+ },
356
+ {
357
+ id: "err-update-sl-not-found",
358
+ name: "UpdateServiceLevelNotFoundError",
359
+ code: "SERVICE_LEVEL_NOT_FOUND",
360
+ description: "Service level binding with given ID not found",
361
+ template: "",
362
+ },
363
+ ],
364
+ examples: [],
365
+ scope: "global",
366
+ },
367
+ {
368
+ id: "op-remove-service-level",
266
369
  name: "REMOVE_SERVICE_LEVEL",
267
- description: "Removes a service level",
268
- schema: "input RemoveServiceLevelInput {\n tierId: OID!\n id: OID!\n lastModified: DateTime!\n}",
269
- template: "Removes a service level",
270
- reducer: "const tier = state.tiers.find(t => t.id === action.input.tierId);\nif (tier) {\n const slIndex = tier.serviceLevels.findIndex(s => s.id === action.input.id);\n if (slIndex !== -1) { tier.serviceLevels.splice(slIndex, 1); }\n}\nstate.lastModified = action.input.lastModified;",
271
- errors: [],
370
+ description: "Remove a service level from a tier",
371
+ schema: "input RemoveServiceLevelInput {\n tierId: OID!\n serviceLevelId: OID!\n lastModified: DateTime!\n}",
372
+ template: "Remove a service level from a tier",
373
+ reducer: "const tier = state.tiers.find(t => t.id === action.input.tierId);\nif (!tier) {\n throw new RemoveServiceLevelTierNotFoundError(`Tier with ID ${action.input.tierId} not found`);\n}\nconst index = tier.serviceLevels.findIndex(s => s.id === action.input.serviceLevelId);\nif (index !== -1) {\n tier.serviceLevels.splice(index, 1);\n}\nstate.lastModified = action.input.lastModified;",
374
+ errors: [
375
+ {
376
+ id: "err-remove-sl-tier-not-found",
377
+ name: "RemoveServiceLevelTierNotFoundError",
378
+ code: "TIER_NOT_FOUND",
379
+ description: "Tier with given ID not found",
380
+ template: "",
381
+ },
382
+ ],
272
383
  examples: [],
273
384
  scope: "global",
274
385
  },
275
386
  {
276
- id: "add-usage-limit",
387
+ id: "op-add-usage-limit",
277
388
  name: "ADD_USAGE_LIMIT",
278
- description: "Adds a usage limit",
279
- schema: "input AddUsageLimitInput {\n tierId: OID!\n id: OID!\n name: String!\n limit: Int!\n unit: String\n lastModified: DateTime!\n}",
280
- template: "Adds a usage limit",
281
- reducer: "const tier = state.tiers.find(t => t.id === action.input.tierId);\nif (tier) { tier.usageLimits.push({ id: action.input.id, name: action.input.name, limit: action.input.limit, unit: action.input.unit || null }); }\nstate.lastModified = action.input.lastModified;",
282
- errors: [],
389
+ description: "Add a usage limit to a tier",
390
+ schema: "input AddUsageLimitInput {\n tierId: OID!\n limitId: OID!\n serviceId: OID!\n metric: String!\n unitName: String\n freeLimit: Int\n paidLimit: Int\n resetCycle: UsageResetCycle\n notes: String\n unitPrice: Amount_Money\n unitPriceCurrency: Currency\n lastModified: DateTime!\n}",
391
+ template: "Add a usage limit to a tier",
392
+ reducer: "const tier = state.tiers.find(t => t.id === action.input.tierId);\nif (!tier) {\n throw new AddUsageLimitTierNotFoundError(`Tier with ID ${action.input.tierId} not found`);\n}\ntier.usageLimits.push({\n id: action.input.limitId,\n serviceId: action.input.serviceId,\n metric: action.input.metric,\n unitName: action.input.unitName || null,\n freeLimit: action.input.freeLimit || null,\n paidLimit: action.input.paidLimit || null,\n resetCycle: action.input.resetCycle || null,\n notes: action.input.notes || null,\n unitPrice: action.input.unitPrice || null,\n unitPriceCurrency: action.input.unitPriceCurrency || null,\n});\nstate.lastModified = action.input.lastModified;",
393
+ errors: [
394
+ {
395
+ id: "err-add-ul-tier-not-found",
396
+ name: "AddUsageLimitTierNotFoundError",
397
+ code: "TIER_NOT_FOUND",
398
+ description: "Tier with given ID not found",
399
+ template: "",
400
+ },
401
+ ],
283
402
  examples: [],
284
403
  scope: "global",
285
404
  },
286
405
  {
287
- id: "update-usage-limit",
406
+ id: "op-update-usage-limit",
288
407
  name: "UPDATE_USAGE_LIMIT",
289
- description: "Updates a usage limit",
290
- schema: "input UpdateUsageLimitInput {\n tierId: OID!\n id: OID!\n name: String\n limit: Int\n unit: String\n lastModified: DateTime!\n}",
291
- template: "Updates a usage limit",
292
- reducer: "const tier = state.tiers.find(t => t.id === action.input.tierId);\nif (tier) {\n const ul = tier.usageLimits.find(u => u.id === action.input.id);\n if (ul) {\n if (action.input.name) ul.name = action.input.name;\n if (action.input.limit !== undefined && action.input.limit !== null) ul.limit = action.input.limit;\n if (action.input.unit !== undefined) ul.unit = action.input.unit || null;\n }\n}\nstate.lastModified = action.input.lastModified;",
293
- errors: [],
294
- examples: [],
295
- scope: "global",
296
- },
297
- {
298
- id: "remove-usage-limit",
408
+ description: "Update a usage limit",
409
+ schema: "input UpdateUsageLimitInput {\n tierId: OID!\n limitId: OID!\n metric: String\n unitName: String\n freeLimit: Int\n paidLimit: Int\n resetCycle: UsageResetCycle\n notes: String\n unitPrice: Amount_Money\n unitPriceCurrency: Currency\n lastModified: DateTime!\n}",
410
+ template: "Update a usage limit",
411
+ reducer: "const tier = state.tiers.find(t => t.id === action.input.tierId);\nif (!tier) {\n throw new UpdateUsageLimitTierNotFoundError(`Tier with ID ${action.input.tierId} not found`);\n}\nconst ul = tier.usageLimits.find(u => u.id === action.input.limitId);\nif (!ul) {\n throw new UpdateUsageLimitNotFoundError(`Usage limit with ID ${action.input.limitId} not found`);\n}\nif (action.input.metric) ul.metric = action.input.metric;\nif (action.input.unitName !== undefined) ul.unitName = action.input.unitName || null;\nif (action.input.freeLimit !== undefined) ul.freeLimit = action.input.freeLimit || null;\nif (action.input.paidLimit !== undefined) ul.paidLimit = action.input.paidLimit || null;\nif (action.input.resetCycle !== undefined) ul.resetCycle = action.input.resetCycle || null;\nif (action.input.notes !== undefined) ul.notes = action.input.notes || null;\nif (action.input.unitPrice !== undefined) ul.unitPrice = action.input.unitPrice || null;\nif (action.input.unitPriceCurrency !== undefined) ul.unitPriceCurrency = action.input.unitPriceCurrency || null;\nstate.lastModified = action.input.lastModified;",
412
+ errors: [
413
+ {
414
+ id: "err-update-ul-tier-not-found",
415
+ name: "UpdateUsageLimitTierNotFoundError",
416
+ code: "TIER_NOT_FOUND",
417
+ description: "Tier with given ID not found",
418
+ template: "",
419
+ },
420
+ {
421
+ id: "err-update-ul-not-found",
422
+ name: "UpdateUsageLimitNotFoundError",
423
+ code: "USAGE_LIMIT_NOT_FOUND",
424
+ description: "Usage limit with given ID not found",
425
+ template: "",
426
+ },
427
+ ],
428
+ examples: [],
429
+ scope: "global",
430
+ },
431
+ {
432
+ id: "op-remove-usage-limit",
299
433
  name: "REMOVE_USAGE_LIMIT",
300
- description: "Removes a usage limit",
301
- schema: "input RemoveUsageLimitInput {\n tierId: OID!\n id: OID!\n lastModified: DateTime!\n}",
302
- template: "Removes a usage limit",
303
- reducer: "const tier = state.tiers.find(t => t.id === action.input.tierId);\nif (tier) {\n const ulIndex = tier.usageLimits.findIndex(u => u.id === action.input.id);\n if (ulIndex !== -1) { tier.usageLimits.splice(ulIndex, 1); }\n}\nstate.lastModified = action.input.lastModified;",
304
- errors: [],
434
+ description: "Remove a usage limit from a tier",
435
+ schema: "input RemoveUsageLimitInput {\n tierId: OID!\n limitId: OID!\n lastModified: DateTime!\n}",
436
+ template: "Remove a usage limit from a tier",
437
+ reducer: "const tier = state.tiers.find(t => t.id === action.input.tierId);\nif (!tier) {\n throw new RemoveUsageLimitTierNotFoundError(`Tier with ID ${action.input.tierId} not found`);\n}\nconst index = tier.usageLimits.findIndex(u => u.id === action.input.limitId);\nif (index !== -1) {\n tier.usageLimits.splice(index, 1);\n}\nstate.lastModified = action.input.lastModified;",
438
+ errors: [
439
+ {
440
+ id: "err-remove-ul-tier-not-found",
441
+ name: "RemoveUsageLimitTierNotFoundError",
442
+ code: "TIER_NOT_FOUND",
443
+ description: "Tier with given ID not found",
444
+ template: "",
445
+ },
446
+ ],
305
447
  examples: [],
306
448
  scope: "global",
307
449
  },
308
450
  {
309
- id: "set-tier-default-billing-cycle",
451
+ id: "op-set-tier-default-billing-cycle",
310
452
  name: "SET_TIER_DEFAULT_BILLING_CYCLE",
311
- description: "Sets tier default billing cycle",
453
+ description: "Set the default billing cycle for a tier",
312
454
  schema: "input SetTierDefaultBillingCycleInput {\n tierId: OID!\n defaultBillingCycle: BillingCycle!\n lastModified: DateTime!\n}",
313
- template: "Sets tier default billing cycle",
314
- reducer: "const tier = state.tiers.find(t => t.id === action.input.tierId);\nif (tier) { tier.defaultBillingCycle = action.input.defaultBillingCycle; }\nstate.lastModified = action.input.lastModified;",
315
- errors: [],
455
+ template: "Set the default billing cycle for a tier",
456
+ reducer: "const tier = state.tiers.find(t => t.id === action.input.tierId);\nif (!tier) {\n throw new SetTierDefaultBillingCycleTierNotFoundError(`Tier with ID ${action.input.tierId} not found`);\n}\ntier.defaultBillingCycle = action.input.defaultBillingCycle;\nstate.lastModified = action.input.lastModified;",
457
+ errors: [
458
+ {
459
+ id: "err-set-tbc-tier-not-found",
460
+ name: "SetTierDefaultBillingCycleTierNotFoundError",
461
+ code: "TIER_NOT_FOUND",
462
+ description: "Tier with given ID not found",
463
+ template: "",
464
+ },
465
+ ],
316
466
  examples: [],
317
467
  scope: "global",
318
468
  },
319
469
  {
320
- id: "set-tier-billing-cycle-discounts",
470
+ id: "op-set-tier-billing-cycle-discounts",
321
471
  name: "SET_TIER_BILLING_CYCLE_DISCOUNTS",
322
- description: "Sets tier billing cycle discounts",
323
- schema: "input SetTierBillingCycleDiscountsInput {\n tierId: OID!\n discounts: [BillingCycleDiscountInput!]!\n lastModified: DateTime!\n}\n\ninput BillingCycleDiscountInput {\n cycle: BillingCycle!\n discountType: DiscountType!\n discountValue: Float!\n}",
324
- template: "Sets tier billing cycle discounts",
325
- reducer: "const tier = state.tiers.find(t => t.id === action.input.tierId);\nif (tier) { tier.billingCycleDiscounts = action.input.discounts.map(d => ({ cycle: d.cycle, discountType: d.discountType, discountValue: d.discountValue })); }\nstate.lastModified = action.input.lastModified;",
326
- errors: [],
472
+ description: "Set billing cycle discounts for a tier",
473
+ schema: "input DiscountRuleInput {\n discountType: DiscountType!\n discountValue: Float!\n}\n\ninput BillingCycleDiscountInput {\n billingCycle: BillingCycle!\n discountRule: DiscountRuleInput!\n}\n\ninput SetTierBillingCycleDiscountsInput {\n tierId: OID!\n discounts: [BillingCycleDiscountInput!]!\n lastModified: DateTime!\n}",
474
+ template: "Set billing cycle discounts for a tier",
475
+ reducer: "const tier = state.tiers.find(t => t.id === action.input.tierId);\nif (!tier) {\n throw new SetTierBillingCycleDiscountsTierNotFoundError(`Tier with ID ${action.input.tierId} not found`);\n}\ntier.billingCycleDiscounts = action.input.discounts.map(d => ({\n billingCycle: d.billingCycle,\n discountRule: {\n discountType: d.discountRule.discountType,\n discountValue: d.discountRule.discountValue,\n },\n}));\nstate.lastModified = action.input.lastModified;",
476
+ errors: [
477
+ {
478
+ id: "err-set-tbcd-tier-not-found",
479
+ name: "SetTierBillingCycleDiscountsTierNotFoundError",
480
+ code: "TIER_NOT_FOUND",
481
+ description: "Tier with given ID not found",
482
+ template: "",
483
+ },
484
+ ],
327
485
  examples: [],
328
486
  scope: "global",
329
487
  },
330
488
  {
331
- id: "set-tier-pricing-mode",
489
+ id: "op-set-tier-pricing-mode",
332
490
  name: "SET_TIER_PRICING_MODE",
333
- description: "Sets tier pricing mode",
491
+ description: "Set the pricing mode for a tier",
334
492
  schema: "input SetTierPricingModeInput {\n tierId: OID!\n pricingMode: TierPricingMode!\n lastModified: DateTime!\n}",
335
- template: "Sets tier pricing mode",
336
- reducer: "const tier = state.tiers.find(t => t.id === action.input.tierId);\nif (tier) { tier.pricingMode = action.input.pricingMode; }\nstate.lastModified = action.input.lastModified;",
337
- errors: [],
493
+ template: "Set the pricing mode for a tier",
494
+ reducer: "const tier = state.tiers.find(t => t.id === action.input.tierId);\nif (!tier) {\n throw new SetTierPricingModeTierNotFoundError(`Tier with ID ${action.input.tierId} not found`);\n}\ntier.pricingMode = action.input.pricingMode;\nstate.lastModified = action.input.lastModified;",
495
+ errors: [
496
+ {
497
+ id: "err-set-tpm-tier-not-found",
498
+ name: "SetTierPricingModeTierNotFoundError",
499
+ code: "TIER_NOT_FOUND",
500
+ description: "Tier with given ID not found",
501
+ template: "",
502
+ },
503
+ ],
338
504
  examples: [],
339
505
  scope: "global",
340
506
  },
341
507
  ],
342
508
  },
343
509
  {
344
- id: "option-groups",
345
- name: "Option Groups",
346
- description: "Operations for managing option groups and pricing",
510
+ id: "mod-option-groups",
511
+ name: "option-groups",
512
+ description: "Add-on option groups with standalone and tier-dependent pricing",
347
513
  operations: [
348
514
  {
349
- id: "add-option-group",
515
+ id: "op-add-option-group",
350
516
  name: "ADD_OPTION_GROUP",
351
- description: "Adds an option group",
352
- schema: "input AddOptionGroupInput {\n id: OID!\n name: String!\n description: String\n isAddOn: Boolean!\n defaultSelected: Boolean!\n lastModified: DateTime!\n}",
353
- template: "Adds an option group",
354
- reducer: 'state.optionGroups.push({ id: action.input.id, name: action.input.name, description: action.input.description || null, isAddOn: action.input.isAddOn, defaultSelected: action.input.defaultSelected, pricingMode: "STANDALONE", standalonePricing: null, tierDependentPricing: [], costType: null, availableBillingCycles: [], billingCycleDiscounts: [], discountMode: null, price: null, currency: null });\nstate.lastModified = action.input.lastModified;',
517
+ description: "Add an option group",
518
+ schema: "input AddOptionGroupInput {\n id: OID!\n name: String!\n description: String\n isAddOn: Boolean!\n defaultSelected: Boolean!\n costType: GroupCostType\n availableBillingCycles: [BillingCycle!]\n price: Amount_Money\n currency: Currency\n lastModified: DateTime!\n}",
519
+ template: "Add an option group",
520
+ reducer: "state.optionGroups.push({\n id: action.input.id,\n name: action.input.name,\n description: action.input.description || null,\n isAddOn: action.input.isAddOn,\n defaultSelected: action.input.defaultSelected,\n pricingMode: null,\n standalonePricing: null,\n tierDependentPricing: null,\n costType: action.input.costType || null,\n availableBillingCycles: action.input.availableBillingCycles || [],\n billingCycleDiscounts: [],\n discountMode: null,\n price: action.input.price || null,\n currency: action.input.currency || null,\n});\nstate.lastModified = action.input.lastModified;",
355
521
  errors: [],
356
522
  examples: [],
357
523
  scope: "global",
358
524
  },
359
525
  {
360
- id: "update-option-group",
526
+ id: "op-update-option-group",
361
527
  name: "UPDATE_OPTION_GROUP",
362
- description: "Updates an option group",
363
- schema: "input UpdateOptionGroupInput {\n id: OID!\n name: String\n description: String\n isAddOn: Boolean\n defaultSelected: Boolean\n lastModified: DateTime!\n}",
364
- template: "Updates an option group",
365
- reducer: "const og = state.optionGroups.find(g => g.id === action.input.id);\nif (og) {\n if (action.input.name) og.name = action.input.name;\n if (action.input.description !== undefined) og.description = action.input.description || null;\n if (action.input.isAddOn !== undefined && action.input.isAddOn !== null) og.isAddOn = action.input.isAddOn;\n if (action.input.defaultSelected !== undefined && action.input.defaultSelected !== null) og.defaultSelected = action.input.defaultSelected;\n}\nstate.lastModified = action.input.lastModified;",
366
- errors: [],
528
+ description: "Update option group fields",
529
+ schema: "input UpdateOptionGroupInput {\n id: OID!\n name: String\n description: String\n isAddOn: Boolean\n defaultSelected: Boolean\n costType: GroupCostType\n availableBillingCycles: [BillingCycle!]\n price: Amount_Money\n currency: Currency\n lastModified: DateTime!\n}",
530
+ template: "Update option group fields",
531
+ reducer: "const og = state.optionGroups.find(g => g.id === action.input.id);\nif (!og) {\n throw new UpdateOptionGroupNotFoundError(`Option group with ID ${action.input.id} not found`);\n}\nif (action.input.name) og.name = action.input.name;\nif (action.input.description !== undefined) og.description = action.input.description || null;\nif (action.input.isAddOn !== undefined && action.input.isAddOn !== null) og.isAddOn = action.input.isAddOn;\nif (action.input.defaultSelected !== undefined && action.input.defaultSelected !== null) og.defaultSelected = action.input.defaultSelected;\nif (action.input.costType !== undefined) og.costType = action.input.costType || null;\nif (action.input.availableBillingCycles) og.availableBillingCycles = action.input.availableBillingCycles;\nif (action.input.price !== undefined) og.price = action.input.price || null;\nif (action.input.currency !== undefined) og.currency = action.input.currency || null;\nstate.lastModified = action.input.lastModified;",
532
+ errors: [
533
+ {
534
+ id: "err-update-og-not-found",
535
+ name: "UpdateOptionGroupNotFoundError",
536
+ code: "OPTION_GROUP_NOT_FOUND",
537
+ description: "Option group with given ID not found",
538
+ template: "",
539
+ },
540
+ ],
367
541
  examples: [],
368
542
  scope: "global",
369
543
  },
370
544
  {
371
- id: "delete-option-group",
545
+ id: "op-delete-option-group",
372
546
  name: "DELETE_OPTION_GROUP",
373
- description: "Deletes an option group",
547
+ description: "Delete an option group",
374
548
  schema: "input DeleteOptionGroupInput {\n id: OID!\n lastModified: DateTime!\n}",
375
- template: "Deletes an option group",
376
- reducer: "const ogIndex = state.optionGroups.findIndex(g => g.id === action.input.id);\nif (ogIndex !== -1) { state.optionGroups.splice(ogIndex, 1); }\nstate.lastModified = action.input.lastModified;",
377
- errors: [],
549
+ template: "Delete an option group",
550
+ reducer: "const index = state.optionGroups.findIndex(g => g.id === action.input.id);\nif (index === -1) {\n throw new DeleteOptionGroupNotFoundError(`Option group with ID ${action.input.id} not found`);\n}\nstate.optionGroups.splice(index, 1);\nstate.lastModified = action.input.lastModified;",
551
+ errors: [
552
+ {
553
+ id: "err-delete-og-not-found",
554
+ name: "DeleteOptionGroupNotFoundError",
555
+ code: "OPTION_GROUP_NOT_FOUND",
556
+ description: "Option group with given ID not found",
557
+ template: "",
558
+ },
559
+ ],
378
560
  examples: [],
379
561
  scope: "global",
380
562
  },
381
563
  {
382
- id: "set-option-group-standalone-pricing",
564
+ id: "op-set-option-group-standalone-pricing",
383
565
  name: "SET_OPTION_GROUP_STANDALONE_PRICING",
384
- description: "Sets standalone pricing for an option group",
385
- schema: "input SetOptionGroupStandalonePricingInput {\n optionGroupId: OID!\n amount: Amount_Money!\n currency: Currency!\n lastModified: DateTime!\n}",
386
- template: "Sets standalone pricing for an option group",
387
- reducer: 'const og = state.optionGroups.find(g => g.id === action.input.optionGroupId);\nif (og) { og.pricingMode = "STANDALONE"; og.standalonePricing = { amount: action.input.amount, currency: action.input.currency }; }\nstate.lastModified = action.input.lastModified;',
388
- errors: [],
566
+ description: "Set standalone pricing for an option group",
567
+ schema: "input RecurringPriceOptionInput {\n id: OID!\n billingCycle: BillingCycle!\n amount: Amount_Money!\n currency: Currency!\n discount: DiscountRuleInput\n}\n\ninput SetupCostInput {\n amount: Amount_Money!\n currency: Currency!\n discount: DiscountRuleInput\n}\n\ninput SetOptionGroupStandalonePricingInput {\n optionGroupId: OID!\n setupCost: SetupCostInput\n recurringPricing: [RecurringPriceOptionInput!]!\n billingCycleDiscounts: [BillingCycleDiscountInput!]\n lastModified: DateTime!\n}",
568
+ template: "Set standalone pricing for an option group",
569
+ reducer: 'const og = state.optionGroups.find(g => g.id === action.input.optionGroupId);\nif (!og) {\n throw new SetOptionGroupStandalonePricingNotFoundError(`Option group with ID ${action.input.optionGroupId} not found`);\n}\nog.pricingMode = "STANDALONE";\nog.standalonePricing = {\n setupCost: action.input.setupCost ? {\n amount: action.input.setupCost.amount,\n currency: action.input.setupCost.currency,\n discount: action.input.setupCost.discount ? {\n discountType: action.input.setupCost.discount.discountType,\n discountValue: action.input.setupCost.discount.discountValue,\n } : null,\n } : null,\n recurringPricing: action.input.recurringPricing.map(rp => ({\n id: rp.id,\n billingCycle: rp.billingCycle,\n amount: rp.amount,\n currency: rp.currency,\n discount: rp.discount ? {\n discountType: rp.discount.discountType,\n discountValue: rp.discount.discountValue,\n } : null,\n })),\n};\nif (action.input.billingCycleDiscounts) {\n og.billingCycleDiscounts = action.input.billingCycleDiscounts.map(d => ({\n billingCycle: d.billingCycle,\n discountRule: {\n discountType: d.discountRule.discountType,\n discountValue: d.discountRule.discountValue,\n },\n }));\n}\nstate.lastModified = action.input.lastModified;',
570
+ errors: [
571
+ {
572
+ id: "err-set-ogsp-not-found",
573
+ name: "SetOptionGroupStandalonePricingNotFoundError",
574
+ code: "OPTION_GROUP_NOT_FOUND",
575
+ description: "Option group with given ID not found",
576
+ template: "",
577
+ },
578
+ ],
389
579
  examples: [],
390
580
  scope: "global",
391
581
  },
392
582
  {
393
- id: "add-option-group-tier-pricing",
583
+ id: "op-add-option-group-tier-pricing",
394
584
  name: "ADD_OPTION_GROUP_TIER_PRICING",
395
- description: "Adds tier-dependent pricing",
396
- schema: "input AddOptionGroupTierPricingInput {\n optionGroupId: OID!\n tierId: OID!\n amount: Amount_Money!\n currency: Currency!\n lastModified: DateTime!\n}",
397
- template: "Adds tier-dependent pricing",
398
- reducer: 'const og = state.optionGroups.find(g => g.id === action.input.optionGroupId);\nif (og) { og.pricingMode = "TIER_DEPENDENT"; og.tierDependentPricing.push({ tierId: action.input.tierId, amount: action.input.amount, currency: action.input.currency }); }\nstate.lastModified = action.input.lastModified;',
399
- errors: [],
585
+ description: "Add tier-dependent pricing to an option group",
586
+ schema: "input AddOptionGroupTierPricingInput {\n optionGroupId: OID!\n tierPricingId: OID!\n tierId: OID!\n setupCost: SetupCostInput\n setupCostDiscounts: [BillingCycleDiscountInput!]\n recurringPricing: [RecurringPriceOptionInput!]!\n lastModified: DateTime!\n}",
587
+ template: "Add tier-dependent pricing to an option group",
588
+ reducer: 'const og = state.optionGroups.find(g => g.id === action.input.optionGroupId);\nif (!og) {\n throw new AddOptionGroupTierPricingNotFoundError(`Option group with ID ${action.input.optionGroupId} not found`);\n}\nog.pricingMode = "TIER_DEPENDENT";\nif (!og.tierDependentPricing) {\n og.tierDependentPricing = [];\n}\nog.tierDependentPricing.push({\n id: action.input.tierPricingId,\n tierId: action.input.tierId,\n setupCost: action.input.setupCost ? {\n amount: action.input.setupCost.amount,\n currency: action.input.setupCost.currency,\n discount: action.input.setupCost.discount ? {\n discountType: action.input.setupCost.discount.discountType,\n discountValue: action.input.setupCost.discount.discountValue,\n } : null,\n } : null,\n setupCostDiscounts: (action.input.setupCostDiscounts || []).map(d => ({\n billingCycle: d.billingCycle,\n discountRule: {\n discountType: d.discountRule.discountType,\n discountValue: d.discountRule.discountValue,\n },\n })),\n recurringPricing: action.input.recurringPricing.map(rp => ({\n id: rp.id,\n billingCycle: rp.billingCycle,\n amount: rp.amount,\n currency: rp.currency,\n discount: rp.discount ? {\n discountType: rp.discount.discountType,\n discountValue: rp.discount.discountValue,\n } : null,\n })),\n});\nstate.lastModified = action.input.lastModified;',
589
+ errors: [
590
+ {
591
+ id: "err-add-ogtp-not-found",
592
+ name: "AddOptionGroupTierPricingNotFoundError",
593
+ code: "OPTION_GROUP_NOT_FOUND",
594
+ description: "Option group with given ID not found",
595
+ template: "",
596
+ },
597
+ ],
400
598
  examples: [],
401
599
  scope: "global",
402
600
  },
403
601
  {
404
- id: "update-option-group-tier-pricing",
602
+ id: "op-update-option-group-tier-pricing",
405
603
  name: "UPDATE_OPTION_GROUP_TIER_PRICING",
406
- description: "Updates tier-dependent pricing",
407
- schema: "input UpdateOptionGroupTierPricingInput {\n optionGroupId: OID!\n tierId: OID!\n amount: Amount_Money!\n currency: Currency!\n lastModified: DateTime!\n}",
408
- template: "Updates tier-dependent pricing",
409
- reducer: "const og = state.optionGroups.find(g => g.id === action.input.optionGroupId);\nif (og) {\n const tp = og.tierDependentPricing.find(p => p.tierId === action.input.tierId);\n if (tp) { tp.amount = action.input.amount; tp.currency = action.input.currency; }\n}\nstate.lastModified = action.input.lastModified;",
410
- errors: [],
604
+ description: "Update tier-dependent pricing for an option group",
605
+ schema: "input UpdateOptionGroupTierPricingInput {\n optionGroupId: OID!\n tierId: OID!\n setupCost: SetupCostInput\n setupCostDiscounts: [BillingCycleDiscountInput!]\n recurringPricing: [RecurringPriceOptionInput!]\n lastModified: DateTime!\n}",
606
+ template: "Update tier-dependent pricing for an option group",
607
+ reducer: "const og = state.optionGroups.find(g => g.id === action.input.optionGroupId);\nif (!og) {\n throw new UpdateOptionGroupTierPricingNotFoundError(`Option group with ID ${action.input.optionGroupId} not found`);\n}\nconst tp = og.tierDependentPricing?.find(t => t.tierId === action.input.tierId);\nif (tp) {\n if (action.input.setupCost !== undefined) {\n tp.setupCost = action.input.setupCost ? {\n amount: action.input.setupCost.amount,\n currency: action.input.setupCost.currency,\n discount: action.input.setupCost.discount ? {\n discountType: action.input.setupCost.discount.discountType,\n discountValue: action.input.setupCost.discount.discountValue,\n } : null,\n } : null;\n }\n if (action.input.setupCostDiscounts !== undefined && action.input.setupCostDiscounts !== null) {\n tp.setupCostDiscounts = action.input.setupCostDiscounts.map(d => ({\n billingCycle: d.billingCycle,\n discountRule: {\n discountType: d.discountRule.discountType,\n discountValue: d.discountRule.discountValue,\n },\n }));\n }\n if (action.input.recurringPricing) {\n tp.recurringPricing = action.input.recurringPricing.map(rp => ({\n id: rp.id,\n billingCycle: rp.billingCycle,\n amount: rp.amount,\n currency: rp.currency,\n discount: rp.discount ? {\n discountType: rp.discount.discountType,\n discountValue: rp.discount.discountValue,\n } : null,\n }));\n }\n}\nstate.lastModified = action.input.lastModified;",
608
+ errors: [
609
+ {
610
+ id: "err-update-ogtp-not-found",
611
+ name: "UpdateOptionGroupTierPricingNotFoundError",
612
+ code: "OPTION_GROUP_NOT_FOUND",
613
+ description: "Option group with given ID not found",
614
+ template: "",
615
+ },
616
+ ],
411
617
  examples: [],
412
618
  scope: "global",
413
619
  },
414
620
  {
415
- id: "remove-option-group-tier-pricing",
621
+ id: "op-remove-option-group-tier-pricing",
416
622
  name: "REMOVE_OPTION_GROUP_TIER_PRICING",
417
- description: "Removes tier-dependent pricing",
623
+ description: "Remove tier-dependent pricing from an option group",
418
624
  schema: "input RemoveOptionGroupTierPricingInput {\n optionGroupId: OID!\n tierId: OID!\n lastModified: DateTime!\n}",
419
- template: "Removes tier-dependent pricing",
420
- reducer: "const og = state.optionGroups.find(g => g.id === action.input.optionGroupId);\nif (og) {\n const tpIndex = og.tierDependentPricing.findIndex(p => p.tierId === action.input.tierId);\n if (tpIndex !== -1) { og.tierDependentPricing.splice(tpIndex, 1); }\n}\nstate.lastModified = action.input.lastModified;",
421
- errors: [],
625
+ template: "Remove tier-dependent pricing from an option group",
626
+ reducer: "const og = state.optionGroups.find(g => g.id === action.input.optionGroupId);\nif (!og) {\n throw new RemoveOptionGroupTierPricingNotFoundError(`Option group with ID ${action.input.optionGroupId} not found`);\n}\nif (og.tierDependentPricing) {\n const index = og.tierDependentPricing.findIndex(t => t.tierId === action.input.tierId);\n if (index !== -1) {\n og.tierDependentPricing.splice(index, 1);\n }\n}\nstate.lastModified = action.input.lastModified;",
627
+ errors: [
628
+ {
629
+ id: "err-remove-ogtp-not-found",
630
+ name: "RemoveOptionGroupTierPricingNotFoundError",
631
+ code: "OPTION_GROUP_NOT_FOUND",
632
+ description: "Option group with given ID not found",
633
+ template: "",
634
+ },
635
+ ],
422
636
  examples: [],
423
637
  scope: "global",
424
638
  },
425
639
  {
426
- id: "set-option-group-discount-mode",
640
+ id: "op-set-option-group-discount-mode",
427
641
  name: "SET_OPTION_GROUP_DISCOUNT_MODE",
428
- description: "Sets discount mode for an option group",
642
+ description: "Set the discount mode for an option group",
429
643
  schema: "input SetOptionGroupDiscountModeInput {\n optionGroupId: OID!\n discountMode: DiscountMode!\n lastModified: DateTime!\n}",
430
- template: "Sets discount mode for an option group",
431
- reducer: "const og = state.optionGroups.find(g => g.id === action.input.optionGroupId);\nif (og) { og.discountMode = action.input.discountMode; }\nstate.lastModified = action.input.lastModified;",
432
- errors: [],
644
+ template: "Set the discount mode for an option group",
645
+ reducer: "const og = state.optionGroups.find(g => g.id === action.input.optionGroupId);\nif (!og) {\n throw new SetOptionGroupDiscountModeNotFoundError(`Option group with ID ${action.input.optionGroupId} not found`);\n}\nog.discountMode = action.input.discountMode;\nstate.lastModified = action.input.lastModified;",
646
+ errors: [
647
+ {
648
+ id: "err-set-ogdm-not-found",
649
+ name: "SetOptionGroupDiscountModeNotFoundError",
650
+ code: "OPTION_GROUP_NOT_FOUND",
651
+ description: "Option group with given ID not found",
652
+ template: "",
653
+ },
654
+ ],
433
655
  examples: [],
434
656
  scope: "global",
435
657
  },