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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. package/dist/document-models/facet/v1/actions.d.ts +3 -1
  2. package/dist/document-models/facet/v1/actions.d.ts.map +1 -1
  3. package/dist/document-models/facet/v1/gen/document-model.d.ts.map +1 -1
  4. package/dist/document-models/facet/v1/gen/document-model.js +31 -7
  5. package/dist/document-models/facet/v1/gen/document-schema.d.ts +6 -6
  6. package/dist/document-models/facet/v1/gen/index.d.ts.map +1 -1
  7. package/dist/document-models/facet/v1/gen/index.js +2 -0
  8. package/dist/document-models/facet/v1/gen/option-management/error.d.ts +27 -1
  9. package/dist/document-models/facet/v1/gen/option-management/error.d.ts.map +1 -1
  10. package/dist/document-models/facet/v1/gen/option-management/error.js +23 -1
  11. package/dist/document-models/facet/v1/gen/ph-factories.js +2 -2
  12. package/dist/document-models/facet/v1/gen/schema/types.d.ts +2 -2
  13. package/dist/document-models/facet/v1/gen/schema/types.d.ts.map +1 -1
  14. package/dist/document-models/facet/v1/gen/schema/zod.js +2 -2
  15. package/dist/document-models/facet/v1/gen/utils.js +2 -2
  16. package/dist/document-models/facet/v1/module.d.ts +1 -1
  17. package/dist/document-models/facet/v1/module.d.ts.map +1 -1
  18. package/dist/document-models/facet/v1/module.js +4 -1
  19. package/dist/document-models/resource-instance/v1/actions.d.ts +4 -1
  20. package/dist/document-models/resource-instance/v1/actions.d.ts.map +1 -1
  21. package/dist/document-models/resource-instance/v1/gen/configuration-management/error.d.ts +34 -1
  22. package/dist/document-models/resource-instance/v1/gen/configuration-management/error.d.ts.map +1 -1
  23. package/dist/document-models/resource-instance/v1/gen/configuration-management/error.js +32 -1
  24. package/dist/document-models/resource-instance/v1/gen/document-model.d.ts.map +1 -1
  25. package/dist/document-models/resource-instance/v1/gen/document-model.js +222 -70
  26. package/dist/document-models/resource-instance/v1/gen/document-schema.d.ts +0 -6
  27. package/dist/document-models/resource-instance/v1/gen/document-schema.d.ts.map +1 -1
  28. package/dist/document-models/resource-instance/v1/gen/index.d.ts.map +1 -1
  29. package/dist/document-models/resource-instance/v1/gen/index.js +2 -0
  30. package/dist/document-models/resource-instance/v1/gen/instance-management/actions.d.ts +6 -2
  31. package/dist/document-models/resource-instance/v1/gen/instance-management/actions.d.ts.map +1 -1
  32. package/dist/document-models/resource-instance/v1/gen/instance-management/creators.d.ts +3 -2
  33. package/dist/document-models/resource-instance/v1/gen/instance-management/creators.d.ts.map +1 -1
  34. package/dist/document-models/resource-instance/v1/gen/instance-management/creators.js +2 -1
  35. package/dist/document-models/resource-instance/v1/gen/instance-management/error.d.ts +98 -1
  36. package/dist/document-models/resource-instance/v1/gen/instance-management/error.d.ts.map +1 -1
  37. package/dist/document-models/resource-instance/v1/gen/instance-management/error.js +112 -1
  38. package/dist/document-models/resource-instance/v1/gen/instance-management/operations.d.ts +2 -1
  39. package/dist/document-models/resource-instance/v1/gen/instance-management/operations.d.ts.map +1 -1
  40. package/dist/document-models/resource-instance/v1/gen/ph-factories.d.ts.map +1 -1
  41. package/dist/document-models/resource-instance/v1/gen/ph-factories.js +0 -2
  42. package/dist/document-models/resource-instance/v1/gen/reducer.d.ts.map +1 -1
  43. package/dist/document-models/resource-instance/v1/gen/reducer.js +6 -1
  44. package/dist/document-models/resource-instance/v1/gen/schema/types.d.ts +3 -3
  45. package/dist/document-models/resource-instance/v1/gen/schema/types.d.ts.map +1 -1
  46. package/dist/document-models/resource-instance/v1/gen/schema/zod.d.ts +2 -1
  47. package/dist/document-models/resource-instance/v1/gen/schema/zod.d.ts.map +1 -1
  48. package/dist/document-models/resource-instance/v1/gen/schema/zod.js +5 -3
  49. package/dist/document-models/resource-instance/v1/gen/utils.d.ts.map +1 -1
  50. package/dist/document-models/resource-instance/v1/gen/utils.js +0 -2
  51. package/dist/document-models/resource-instance/v1/module.d.ts +1 -1
  52. package/dist/document-models/resource-instance/v1/module.d.ts.map +1 -1
  53. package/dist/document-models/resource-instance/v1/module.js +4 -1
  54. package/dist/document-models/resource-instance/v1/src/reducers/configuration-management.d.ts.map +1 -1
  55. package/dist/document-models/resource-instance/v1/src/reducers/configuration-management.js +57 -53
  56. package/dist/document-models/resource-instance/v1/src/reducers/instance-management.d.ts.map +1 -1
  57. package/dist/document-models/resource-instance/v1/src/reducers/instance-management.js +57 -21
  58. package/dist/document-models/resource-instance/v1/tests/instance-management.test.js +11 -1
  59. package/dist/document-models/resource-template/v1/actions.d.ts +3 -1
  60. package/dist/document-models/resource-template/v1/actions.d.ts.map +1 -1
  61. package/dist/document-models/resource-template/v1/gen/audience-management/error.d.ts +20 -1
  62. package/dist/document-models/resource-template/v1/gen/audience-management/error.d.ts.map +1 -1
  63. package/dist/document-models/resource-template/v1/gen/audience-management/error.js +16 -1
  64. package/dist/document-models/resource-template/v1/gen/document-model.d.ts.map +1 -1
  65. package/dist/document-models/resource-template/v1/gen/document-model.js +207 -89
  66. package/dist/document-models/resource-template/v1/gen/document-schema.d.ts +12 -12
  67. package/dist/document-models/resource-template/v1/gen/facet-targeting/error.d.ts +27 -1
  68. package/dist/document-models/resource-template/v1/gen/facet-targeting/error.d.ts.map +1 -1
  69. package/dist/document-models/resource-template/v1/gen/facet-targeting/error.js +23 -1
  70. package/dist/document-models/resource-template/v1/gen/index.d.ts.map +1 -1
  71. package/dist/document-models/resource-template/v1/gen/index.js +2 -0
  72. package/dist/document-models/resource-template/v1/gen/option-group-management/error.d.ts +27 -1
  73. package/dist/document-models/resource-template/v1/gen/option-group-management/error.d.ts.map +1 -1
  74. package/dist/document-models/resource-template/v1/gen/option-group-management/error.js +23 -1
  75. package/dist/document-models/resource-template/v1/gen/ph-factories.js +3 -3
  76. package/dist/document-models/resource-template/v1/gen/schema/types.d.ts +4 -4
  77. package/dist/document-models/resource-template/v1/gen/schema/types.d.ts.map +1 -1
  78. package/dist/document-models/resource-template/v1/gen/schema/zod.js +4 -4
  79. package/dist/document-models/resource-template/v1/gen/service-management/error.d.ts +51 -1
  80. package/dist/document-models/resource-template/v1/gen/service-management/error.d.ts.map +1 -1
  81. package/dist/document-models/resource-template/v1/gen/service-management/error.js +49 -1
  82. package/dist/document-models/resource-template/v1/gen/utils.js +3 -3
  83. package/dist/document-models/resource-template/v1/module.d.ts +1 -1
  84. package/dist/document-models/resource-template/v1/module.d.ts.map +1 -1
  85. package/dist/document-models/resource-template/v1/module.js +4 -1
  86. package/dist/document-models/resource-template/v1/src/reducers/option-group-management.d.ts.map +1 -1
  87. package/dist/document-models/resource-template/v1/src/reducers/option-group-management.js +2 -21
  88. package/dist/document-models/service-offering/v1/actions.d.ts +3 -1
  89. package/dist/document-models/service-offering/v1/actions.d.ts.map +1 -1
  90. package/dist/document-models/service-offering/v1/gen/document-model.d.ts.map +1 -1
  91. package/dist/document-models/service-offering/v1/gen/document-model.js +421 -199
  92. package/dist/document-models/service-offering/v1/gen/document-schema.d.ts +9 -9
  93. package/dist/document-models/service-offering/v1/gen/index.d.ts.map +1 -1
  94. package/dist/document-models/service-offering/v1/gen/index.js +2 -0
  95. package/dist/document-models/service-offering/v1/gen/offering/error.d.ts +41 -1
  96. package/dist/document-models/service-offering/v1/gen/offering/error.d.ts.map +1 -1
  97. package/dist/document-models/service-offering/v1/gen/offering/error.js +37 -1
  98. package/dist/document-models/service-offering/v1/gen/option-groups/error.d.ts +55 -1
  99. package/dist/document-models/service-offering/v1/gen/option-groups/error.d.ts.map +1 -1
  100. package/dist/document-models/service-offering/v1/gen/option-groups/error.js +53 -1
  101. package/dist/document-models/service-offering/v1/gen/ph-factories.js +3 -3
  102. package/dist/document-models/service-offering/v1/gen/schema/types.d.ts +134 -61
  103. package/dist/document-models/service-offering/v1/gen/schema/types.d.ts.map +1 -1
  104. package/dist/document-models/service-offering/v1/gen/schema/zod.d.ts +35 -10
  105. package/dist/document-models/service-offering/v1/gen/schema/zod.d.ts.map +1 -1
  106. package/dist/document-models/service-offering/v1/gen/schema/zod.js +182 -64
  107. package/dist/document-models/service-offering/v1/gen/services/error.d.ts +20 -1
  108. package/dist/document-models/service-offering/v1/gen/services/error.d.ts.map +1 -1
  109. package/dist/document-models/service-offering/v1/gen/services/error.js +16 -1
  110. package/dist/document-models/service-offering/v1/gen/tiers/error.d.ts +100 -1
  111. package/dist/document-models/service-offering/v1/gen/tiers/error.d.ts.map +1 -1
  112. package/dist/document-models/service-offering/v1/gen/tiers/error.js +106 -1
  113. package/dist/document-models/service-offering/v1/gen/utils.js +4 -4
  114. package/dist/document-models/service-offering/v1/module.d.ts +1 -1
  115. package/dist/document-models/service-offering/v1/module.d.ts.map +1 -1
  116. package/dist/document-models/service-offering/v1/module.js +4 -1
  117. package/dist/document-models/service-offering/v1/src/reducers/offering.d.ts.map +1 -1
  118. package/dist/document-models/service-offering/v1/src/reducers/offering.js +20 -12
  119. package/dist/document-models/service-offering/v1/src/reducers/option-groups.d.ts.map +1 -1
  120. package/dist/document-models/service-offering/v1/src/reducers/option-groups.js +157 -39
  121. package/dist/document-models/service-offering/v1/src/reducers/services.d.ts.map +1 -1
  122. package/dist/document-models/service-offering/v1/src/reducers/services.js +17 -14
  123. package/dist/document-models/service-offering/v1/src/reducers/tiers.d.ts.map +1 -1
  124. package/dist/document-models/service-offering/v1/src/reducers/tiers.js +111 -78
  125. package/dist/document-models/service-offering/v1/src/utils.d.ts +60 -1
  126. package/dist/document-models/service-offering/v1/src/utils.d.ts.map +1 -1
  127. package/dist/document-models/service-offering/v1/src/utils.js +173 -1
  128. package/dist/document-models/service-offering/v1/tests/option-groups.test.js +1 -1
  129. package/dist/document-models/service-offering/v1/utils.d.ts +3 -0
  130. package/dist/document-models/service-offering/v1/utils.d.ts.map +1 -1
  131. package/dist/document-models/subscription-instance/v1/actions.d.ts +3 -1
  132. package/dist/document-models/subscription-instance/v1/actions.d.ts.map +1 -1
  133. package/dist/document-models/subscription-instance/v1/gen/document-model.d.ts.map +1 -1
  134. package/dist/document-models/subscription-instance/v1/gen/document-model.js +488 -246
  135. package/dist/document-models/subscription-instance/v1/gen/document-schema.d.ts +3 -3
  136. package/dist/document-models/subscription-instance/v1/gen/index.d.ts.map +1 -1
  137. package/dist/document-models/subscription-instance/v1/gen/index.js +2 -0
  138. package/dist/document-models/subscription-instance/v1/gen/metrics/error.d.ts +73 -1
  139. package/dist/document-models/subscription-instance/v1/gen/metrics/error.d.ts.map +1 -1
  140. package/dist/document-models/subscription-instance/v1/gen/metrics/error.js +86 -1
  141. package/dist/document-models/subscription-instance/v1/gen/ph-factories.js +1 -1
  142. package/dist/document-models/subscription-instance/v1/gen/schema/types.d.ts +199 -82
  143. package/dist/document-models/subscription-instance/v1/gen/schema/types.d.ts.map +1 -1
  144. package/dist/document-models/subscription-instance/v1/gen/schema/zod.d.ts +22 -12
  145. package/dist/document-models/subscription-instance/v1/gen/schema/zod.d.ts.map +1 -1
  146. package/dist/document-models/subscription-instance/v1/gen/schema/zod.js +230 -84
  147. package/dist/document-models/subscription-instance/v1/gen/service/error.d.ts +62 -1
  148. package/dist/document-models/subscription-instance/v1/gen/service/error.d.ts.map +1 -1
  149. package/dist/document-models/subscription-instance/v1/gen/service/error.js +60 -1
  150. package/dist/document-models/subscription-instance/v1/gen/service-group/error.d.ts +39 -1
  151. package/dist/document-models/subscription-instance/v1/gen/service-group/error.d.ts.map +1 -1
  152. package/dist/document-models/subscription-instance/v1/gen/service-group/error.js +39 -1
  153. package/dist/document-models/subscription-instance/v1/gen/subscription/error.d.ts +55 -1
  154. package/dist/document-models/subscription-instance/v1/gen/subscription/error.d.ts.map +1 -1
  155. package/dist/document-models/subscription-instance/v1/gen/subscription/error.js +51 -1
  156. package/dist/document-models/subscription-instance/v1/gen/utils.js +2 -2
  157. package/dist/document-models/subscription-instance/v1/module.d.ts +1 -1
  158. package/dist/document-models/subscription-instance/v1/module.d.ts.map +1 -1
  159. package/dist/document-models/subscription-instance/v1/module.js +4 -1
  160. package/dist/document-models/subscription-instance/v1/src/reducers/customer.d.ts.map +1 -1
  161. package/dist/document-models/subscription-instance/v1/src/reducers/customer.js +1 -0
  162. package/dist/document-models/subscription-instance/v1/src/reducers/metrics.d.ts.map +1 -1
  163. package/dist/document-models/subscription-instance/v1/src/reducers/metrics.js +70 -45
  164. package/dist/document-models/subscription-instance/v1/src/reducers/service-group.d.ts.map +1 -1
  165. package/dist/document-models/subscription-instance/v1/src/reducers/service-group.js +108 -30
  166. package/dist/document-models/subscription-instance/v1/src/reducers/service.d.ts.map +1 -1
  167. package/dist/document-models/subscription-instance/v1/src/reducers/service.js +108 -39
  168. package/dist/document-models/subscription-instance/v1/src/reducers/subscription.d.ts.map +1 -1
  169. package/dist/document-models/subscription-instance/v1/src/reducers/subscription.js +193 -35
  170. package/dist/document-models/upgrade-manifests.d.ts.map +1 -1
  171. package/dist/document-models/upgrade-manifests.js +0 -2
  172. package/dist/editors/resource-instance-editor/editor.d.ts.map +1 -1
  173. package/dist/editors/resource-instance-editor/editor.js +13 -3
  174. package/dist/editors/service-offering-editor/components/ResourceTemplateSelector.d.ts.map +1 -1
  175. package/dist/editors/service-offering-editor/components/ResourceTemplateSelector.js +4 -2
  176. package/dist/editors/service-offering-editor/components/ServiceCatalog.d.ts.map +1 -1
  177. package/dist/editors/service-offering-editor/components/ServiceCatalog.js +189 -32
  178. package/dist/editors/service-offering-editor/components/TheMatrix.d.ts +1 -1
  179. package/dist/editors/service-offering-editor/components/TheMatrix.d.ts.map +1 -1
  180. package/dist/editors/service-offering-editor/components/TheMatrix.js +295 -140
  181. package/dist/editors/service-offering-editor/components/TierDefinition.d.ts.map +1 -1
  182. package/dist/editors/service-offering-editor/components/TierDefinition.js +2 -0
  183. package/dist/editors/service-offering-editor/components/TierPricingOptionsPanel.js +3 -3
  184. package/dist/editors/service-offering-editor/components/pricing-utils.d.ts.map +1 -1
  185. package/dist/editors/service-offering-editor/components/pricing-utils.js +26 -7
  186. package/dist/editors/service-offering-editor/editor.css +119 -0
  187. package/dist/editors/subscription-instance-editor/components/BillingPanel.d.ts.map +1 -1
  188. package/dist/editors/subscription-instance-editor/components/BillingPanel.js +4 -4
  189. package/dist/editors/subscription-instance-editor/components/CustomerInfo.d.ts.map +1 -1
  190. package/dist/editors/subscription-instance-editor/components/CustomerInfo.js +3 -2
  191. package/dist/editors/subscription-instance-editor/components/ImportServiceConfigButton.d.ts +3 -0
  192. package/dist/editors/subscription-instance-editor/components/ImportServiceConfigButton.d.ts.map +1 -1
  193. package/dist/editors/subscription-instance-editor/components/ImportServiceConfigButton.js +12 -0
  194. package/dist/editors/subscription-instance-editor/components/MetricActions.d.ts.map +1 -1
  195. package/dist/editors/subscription-instance-editor/components/MetricActions.js +4 -2
  196. package/dist/editors/subscription-instance-editor/components/MockDataButton.d.ts.map +1 -1
  197. package/dist/editors/subscription-instance-editor/components/MockDataButton.js +214 -2
  198. package/dist/editors/subscription-instance-editor/components/OperatorNotes.js +1 -1
  199. package/dist/editors/subscription-instance-editor/components/ServicesPanel.d.ts.map +1 -1
  200. package/dist/editors/subscription-instance-editor/components/ServicesPanel.js +9 -20
  201. package/dist/editors/subscription-instance-editor/components/SubscriptionActions.d.ts.map +1 -1
  202. package/dist/editors/subscription-instance-editor/components/SubscriptionActions.js +8 -9
  203. package/dist/editors/subscription-instance-editor/components/SubscriptionHeader.d.ts.map +1 -1
  204. package/dist/editors/subscription-instance-editor/components/SubscriptionHeader.js +1 -1
  205. package/dist/editors/subscription-instance-editor/components/billing-utils.d.ts +14 -6
  206. package/dist/editors/subscription-instance-editor/components/billing-utils.d.ts.map +1 -1
  207. package/dist/editors/subscription-instance-editor/components/billing-utils.js +19 -23
  208. package/dist/editors/subscription-instance-editor/components/mapOfferingToSubscription.d.ts +16 -2
  209. package/dist/editors/subscription-instance-editor/components/mapOfferingToSubscription.d.ts.map +1 -1
  210. package/dist/editors/subscription-instance-editor/components/mapOfferingToSubscription.js +155 -6
  211. package/dist/powerhouse.manifest.json +29 -3
  212. package/dist/style.css +14 -0
  213. package/dist/subgraphs/resources-services/resolvers.d.ts +2 -2
  214. package/dist/subgraphs/resources-services/resolvers.d.ts.map +1 -1
  215. package/dist/subgraphs/resources-services/resolvers.js +301 -215
  216. package/package.json +24 -19
  217. package/dist/document-models/facet/gen/schema/types.d.ts +0 -195
  218. package/dist/document-models/facet/gen/schema/types.d.ts.map +0 -1
  219. package/dist/document-models/facet/gen/schema/types.js +0 -1
  220. package/dist/document-models/facet/gen/schema/zod.d.ts +0 -18
  221. package/dist/document-models/facet/gen/schema/zod.d.ts.map +0 -1
  222. package/dist/document-models/facet/gen/schema/zod.js +0 -69
  223. package/dist/document-models/resource-instance/gen/schema/types.d.ts +0 -272
  224. package/dist/document-models/resource-instance/gen/schema/types.d.ts.map +0 -1
  225. package/dist/document-models/resource-instance/gen/schema/types.js +0 -1
  226. package/dist/document-models/resource-instance/gen/schema/zod.d.ts +0 -43
  227. package/dist/document-models/resource-instance/gen/schema/zod.d.ts.map +0 -1
  228. package/dist/document-models/resource-instance/gen/schema/zod.js +0 -185
  229. package/dist/document-models/resource-template/gen/schema/types.d.ts +0 -371
  230. package/dist/document-models/resource-template/gen/schema/types.d.ts.map +0 -1
  231. package/dist/document-models/resource-template/gen/schema/types.js +0 -1
  232. package/dist/document-models/resource-template/gen/schema/zod.d.ts +0 -52
  233. package/dist/document-models/resource-template/gen/schema/zod.d.ts.map +0 -1
  234. package/dist/document-models/resource-template/gen/schema/zod.js +0 -312
  235. package/dist/document-models/service-offering/gen/schema/types.d.ts +0 -451
  236. package/dist/document-models/service-offering/gen/schema/types.d.ts.map +0 -1
  237. package/dist/document-models/service-offering/gen/schema/types.js +0 -1
  238. package/dist/document-models/service-offering/gen/schema/zod.d.ts +0 -89
  239. package/dist/document-models/service-offering/gen/schema/zod.d.ts.map +0 -1
  240. package/dist/document-models/service-offering/gen/schema/zod.js +0 -419
  241. package/dist/document-models/subscription-instance/gen/schema/types.d.ts +0 -435
  242. package/dist/document-models/subscription-instance/gen/schema/types.d.ts.map +0 -1
  243. package/dist/document-models/subscription-instance/gen/schema/types.js +0 -1
  244. package/dist/document-models/subscription-instance/gen/schema/zod.d.ts +0 -99
  245. package/dist/document-models/subscription-instance/gen/schema/zod.d.ts.map +0 -1
  246. package/dist/document-models/subscription-instance/gen/schema/zod.js +0 -410
@@ -10,28 +10,240 @@ export function MockDataButton({ document, dispatch }) {
10
10
  const oneMonthAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString();
11
11
  const oneMonthFromNow = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString();
12
12
  const twoMonthsFromNow = new Date(Date.now() + 60 * 24 * 60 * 60 * 1000).toISOString();
13
+ // 1. Initialize subscription with full service group structure
14
+ // Pricing lives at the SERVICE GROUP level, not per-service
13
15
  if (!document.state.global.customerId) {
14
16
  dispatch(initializeSubscription({
15
17
  createdAt: oneMonthAgo,
16
18
  customerId: `phid:customer:${generateId()}`,
17
19
  customerName: "Acme Corporation",
18
20
  customerEmail: "billing@acme.example.com",
21
+ resourceId: `phid:resource:${generateId()}`,
22
+ resourceLabel: "Enterprise Cloud Platform",
19
23
  tierName: "Professional",
20
24
  tierPricingOptionId: generateId(),
21
25
  tierPrice: 726,
22
26
  tierCurrency: "USD",
23
- tierPricingMode: "FIXED",
27
+ tierPricingMode: "CALCULATED",
24
28
  selectedBillingCycle: "MONTHLY",
25
29
  globalCurrency: "USD",
30
+ autoRenew: true,
31
+ serviceGroups: [
32
+ // === Core Infrastructure (recurring, group-level price: $726/mo) ===
33
+ {
34
+ id: generateId(),
35
+ name: "Core Infrastructure",
36
+ optional: false,
37
+ costType: "RECURRING",
38
+ recurringAmount: 726,
39
+ recurringCurrency: "USD",
40
+ recurringBillingCycle: "MONTHLY",
41
+ setupAmount: 500,
42
+ setupCurrency: "USD",
43
+ services: [
44
+ {
45
+ id: generateId(),
46
+ name: "Cloud Compute",
47
+ description: "Scalable virtual machines with automatic load balancing",
48
+ metrics: [
49
+ {
50
+ id: generateId(),
51
+ name: "vCPU Hours",
52
+ unitName: "hours",
53
+ currentUsage: 1250,
54
+ freeLimit: 1000,
55
+ paidLimit: 2000,
56
+ unitCostAmount: 0.05,
57
+ unitCostCurrency: "USD",
58
+ unitCostBillingCycle: "MONTHLY",
59
+ usageResetPeriod: "MONTHLY",
60
+ },
61
+ {
62
+ id: generateId(),
63
+ name: "RAM GB-Hours",
64
+ unitName: "GB-hours",
65
+ currentUsage: 3200,
66
+ freeLimit: 3000,
67
+ paidLimit: 5000,
68
+ usageResetPeriod: "MONTHLY",
69
+ },
70
+ {
71
+ id: generateId(),
72
+ name: "Active Instances",
73
+ unitName: "instances",
74
+ currentUsage: 8,
75
+ freeLimit: 10,
76
+ paidLimit: 20,
77
+ },
78
+ ],
79
+ },
80
+ {
81
+ id: generateId(),
82
+ name: "Object Storage",
83
+ description: "Unlimited cloud storage with CDN integration",
84
+ metrics: [
85
+ {
86
+ id: generateId(),
87
+ name: "Storage Used",
88
+ unitName: "GB",
89
+ currentUsage: 450,
90
+ freeLimit: 500,
91
+ paidLimit: 2000,
92
+ unitCostAmount: 0.02,
93
+ unitCostCurrency: "USD",
94
+ unitCostBillingCycle: "MONTHLY",
95
+ },
96
+ {
97
+ id: generateId(),
98
+ name: "Bandwidth Out",
99
+ unitName: "GB",
100
+ currentUsage: 280,
101
+ freeLimit: 500,
102
+ usageResetPeriod: "MONTHLY",
103
+ },
104
+ {
105
+ id: generateId(),
106
+ name: "API Requests",
107
+ unitName: "requests",
108
+ currentUsage: 125000,
109
+ freeLimit: 100000,
110
+ paidLimit: 500000,
111
+ unitCostAmount: 0.001,
112
+ unitCostCurrency: "USD",
113
+ unitCostBillingCycle: "MONTHLY",
114
+ usageResetPeriod: "MONTHLY",
115
+ },
116
+ ],
117
+ },
118
+ {
119
+ id: generateId(),
120
+ name: "Managed Database",
121
+ description: "PostgreSQL with automatic backups and failover",
122
+ metrics: [
123
+ {
124
+ id: generateId(),
125
+ name: "Database Size",
126
+ unitName: "GB",
127
+ currentUsage: 85,
128
+ freeLimit: 50,
129
+ paidLimit: 100,
130
+ unitCostAmount: 0.5,
131
+ unitCostCurrency: "USD",
132
+ unitCostBillingCycle: "MONTHLY",
133
+ },
134
+ {
135
+ id: generateId(),
136
+ name: "Connections",
137
+ unitName: "connections",
138
+ currentUsage: 45,
139
+ freeLimit: 50,
140
+ paidLimit: 100,
141
+ },
142
+ ],
143
+ },
144
+ {
145
+ id: generateId(),
146
+ name: "Global CDN",
147
+ description: "Content delivery network with edge caching",
148
+ metrics: [
149
+ {
150
+ id: generateId(),
151
+ name: "Cache Hit Rate",
152
+ unitName: "%",
153
+ currentUsage: 94,
154
+ limit: 100,
155
+ },
156
+ {
157
+ id: generateId(),
158
+ name: "Edge Requests",
159
+ unitName: "M requests",
160
+ currentUsage: 12,
161
+ freeLimit: 10,
162
+ paidLimit: 50,
163
+ unitCostAmount: 5,
164
+ unitCostCurrency: "USD",
165
+ unitCostBillingCycle: "MONTHLY",
166
+ usageResetPeriod: "MONTHLY",
167
+ },
168
+ ],
169
+ },
170
+ ],
171
+ },
172
+ // === Security Suite (optional add-on, group-level price: $178/mo) ===
173
+ {
174
+ id: generateId(),
175
+ name: "Security Suite",
176
+ optional: true,
177
+ costType: "RECURRING",
178
+ recurringAmount: 178,
179
+ recurringCurrency: "USD",
180
+ recurringBillingCycle: "MONTHLY",
181
+ setupAmount: 750,
182
+ setupCurrency: "USD",
183
+ services: [
184
+ {
185
+ id: generateId(),
186
+ name: "DDoS Protection",
187
+ description: "Advanced DDoS mitigation with real-time monitoring",
188
+ },
189
+ {
190
+ id: generateId(),
191
+ name: "WAF",
192
+ description: "Web Application Firewall with custom rules",
193
+ },
194
+ {
195
+ id: generateId(),
196
+ name: "Security Audit & Onboarding",
197
+ description: "Initial security assessment and configuration",
198
+ },
199
+ ],
200
+ },
201
+ // === Premium Support (optional add-on, group-level price: $498/mo) ===
202
+ {
203
+ id: generateId(),
204
+ name: "Premium Support",
205
+ optional: true,
206
+ costType: "RECURRING",
207
+ recurringAmount: 498,
208
+ recurringCurrency: "USD",
209
+ recurringBillingCycle: "MONTHLY",
210
+ setupAmount: 1200,
211
+ setupCurrency: "USD",
212
+ services: [
213
+ {
214
+ id: generateId(),
215
+ name: "24/7 Priority Support",
216
+ description: "Direct access to senior engineers with 15-min response time",
217
+ },
218
+ {
219
+ id: generateId(),
220
+ name: "Dedicated Account Manager",
221
+ description: "Personal account manager for strategic guidance",
222
+ },
223
+ {
224
+ id: generateId(),
225
+ name: "Team Onboarding Workshop",
226
+ description: "Customized training sessions for your engineering team",
227
+ },
228
+ ],
229
+ },
230
+ ],
26
231
  }));
27
232
  }
233
+ // 2. Activate subscription
28
234
  dispatch(activateSubscription({
29
- activatedAt: oneMonthAgo,
235
+ activatedSince: oneMonthAgo,
30
236
  }));
237
+ // 3. Set renewal date
31
238
  dispatch(setRenewalDate({ renewalDate: twoMonthsFromNow }));
239
+ // 4. Set customer type
32
240
  dispatch(setCustomerType({
33
241
  customerType: "TEAM",
242
+ teamMemberCount: 12,
34
243
  }));
244
+ // 5. Billing projection
245
+ // Core: $726/mo + Security: $178/mo + Support: $498/mo = $1,402/mo
246
+ // Plus metric overages: vCPU 250 × $0.05 = $12.50, API 25k × $0.001 = $25, DB 35 × $0.50 = $17.50, Edge 2M × $5 = $10
35
247
  dispatch(updateBillingProjection({
36
248
  nextBillingDate: oneMonthFromNow,
37
249
  projectedBillAmount: 1467,
@@ -6,7 +6,7 @@ export function OperatorNotes({ document, dispatch }) {
6
6
  const [isEditing, setIsEditing] = useState(false);
7
7
  const [notes, setNotes] = useState(currentNotes);
8
8
  const handleSave = useCallback(() => {
9
- dispatch(setOperatorNotes({ notes: notes || null }));
9
+ dispatch(setOperatorNotes({ operatorNotes: notes || null }));
10
10
  setIsEditing(false);
11
11
  }, [dispatch, notes]);
12
12
  const handleCancel = useCallback(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"ServicesPanel.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/ServicesPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC7B,MAAM,uEAAuE,CAAC;AAK/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAI5C,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,4BAA4B,CAAC;IACvC,QAAQ,EAAE,gBAAgB,CAAC,0BAA0B,CAAC,CAAC;IACvD,IAAI,EAAE,QAAQ,CAAC;CAChB;AAkKD,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,QAAQ,EACR,IAAI,GACL,EAAE,kBAAkB,2CAmKpB"}
1
+ {"version":3,"file":"ServicesPanel.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/ServicesPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC7B,MAAM,uEAAuE,CAAC;AAK/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAQ5C,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,4BAA4B,CAAC;IACvC,QAAQ,EAAE,gBAAgB,CAAC,0BAA0B,CAAC,CAAC;IACvD,IAAI,EAAE,QAAQ,CAAC;CAChB;AAkKD,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,QAAQ,EACR,IAAI,GACL,EAAE,kBAAkB,2CA6KpB"}
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { MetricActions } from "./MetricActions.js";
3
- import { formatCurrency as fmtCurrency } from "./billing-utils.js";
4
- function UsageBar({ serviceId, metric, dispatch, isOperator, customerName, currency, }) {
3
+ import { formatCurrency as fmtCurrency, formatBillingCycleSuffix, formatDiscountBadge, } from "./billing-utils.js";
4
+ function UsageBar({ serviceId, metric, dispatch, isOperator, customerName, }) {
5
5
  const freeLimit = metric.freeLimit ?? metric.limit ?? 0;
6
6
  const paidLimit = metric.paidLimit ?? null;
7
7
  const displayLimit = paidLimit ?? freeLimit;
@@ -17,35 +17,24 @@ function UsageBar({ serviceId, metric, dispatch, isOperator, customerName, curre
17
17
  return "si-usage-bar__fill--normal";
18
18
  };
19
19
  const isOverFree = metric.currentUsage > freeLimit && freeLimit > 0;
20
- return (_jsxs("div", { className: "si-metric", children: [_jsxs("div", { className: "si-metric__header", children: [_jsx("span", { className: "si-metric__name", children: metric.name }), _jsxs("span", { className: "si-metric__value", children: [metric.currentUsage.toLocaleString(), displayLimit > 0 && ` / ${displayLimit.toLocaleString()}`, _jsxs("span", { className: "si-metric__unit", children: [" ", metric.unitName] })] })] }), _jsxs("div", { className: "si-metric__body", children: [displayLimit > 0 && (_jsxs("div", { className: "si-usage-bar", children: [paidLimit != null && freeLimit > 0 && freeLimit < paidLimit && (_jsx("div", { className: "si-usage-bar__free-marker", style: { left: `${freePortion}%` }, title: `${freeLimit.toLocaleString()} free` })), _jsx("div", { className: `si-usage-bar__fill ${getBarColor()}`, style: { width: `${percentage}%` }, role: "progressbar", "aria-valuenow": metric.currentUsage, "aria-valuemin": 0, "aria-valuemax": displayLimit })] })), _jsx(MetricActions, { serviceId: serviceId, metric: metric, dispatch: dispatch, isOperator: isOperator, customerName: customerName })] }), paidLimit != null && freeLimit > 0 && freeLimit !== paidLimit && (_jsxs("p", { className: "si-metric__paid-limit", children: [freeLimit.toLocaleString(), " free \u00B7 ", paidLimit.toLocaleString(), " max", metric.unitCost != null && (_jsxs("span", { children: [" · ", "overage: ", fmtCurrency(metric.unitCost, currency), "/", metric.unitName] }))] })), isOverFree && metric.unitCost != null && (_jsxs("div", { className: "si-metric__overage", children: [_jsx("strong", { children: (metric.currentUsage - freeLimit).toLocaleString() }), " ", metric.unitName, " over free limit"] })), (metric.nextUsageReset || metric.usageResetPeriod) && (_jsxs("p", { className: "si-metric__reset", children: [metric.usageResetPeriod && (_jsxs("span", { className: "si-metric__reset-period", children: [metric.usageResetPeriod.charAt(0) +
20
+ return (_jsxs("div", { className: "si-metric", children: [_jsxs("div", { className: "si-metric__header", children: [_jsx("span", { className: "si-metric__name", children: metric.name }), _jsxs("span", { className: "si-metric__value", children: [metric.currentUsage.toLocaleString(), displayLimit > 0 && ` / ${displayLimit.toLocaleString()}`, _jsxs("span", { className: "si-metric__unit", children: [" ", metric.unitName] })] })] }), _jsxs("div", { className: "si-metric__body", children: [displayLimit > 0 && (_jsxs("div", { className: "si-usage-bar", children: [paidLimit != null && freeLimit > 0 && freeLimit < paidLimit && (_jsx("div", { className: "si-usage-bar__free-marker", style: { left: `${freePortion}%` }, title: `${freeLimit.toLocaleString()} free` })), _jsx("div", { className: `si-usage-bar__fill ${getBarColor()}`, style: { width: `${percentage}%` }, role: "progressbar", "aria-valuenow": metric.currentUsage, "aria-valuemin": 0, "aria-valuemax": displayLimit })] })), _jsx(MetricActions, { serviceId: serviceId, metric: metric, dispatch: dispatch, isOperator: isOperator, customerName: customerName })] }), paidLimit != null && freeLimit > 0 && freeLimit !== paidLimit && (_jsxs("p", { className: "si-metric__paid-limit", children: [freeLimit.toLocaleString(), " free \u00B7 ", paidLimit.toLocaleString(), " max", metric.unitCost && (_jsxs("span", { children: [" · ", "overage:", " ", fmtCurrency(metric.unitCost.amount, metric.unitCost.currency), "/", metric.unitName] }))] })), isOverFree && metric.unitCost && (_jsxs("div", { className: "si-metric__overage", children: [_jsx("strong", { children: (metric.currentUsage - freeLimit).toLocaleString() }), " ", metric.unitName, " over free limit"] })), (metric.nextUsageReset || metric.usageResetPeriod) && (_jsxs("p", { className: "si-metric__reset", children: [metric.usageResetPeriod && (_jsxs("span", { className: "si-metric__reset-period", children: [metric.usageResetPeriod.charAt(0) +
21
21
  metric.usageResetPeriod.slice(1).toLowerCase(), " ", "reset"] })), metric.nextUsageReset && (_jsxs("span", { children: [metric.usageResetPeriod ? " · " : "Resets ", new Date(metric.nextUsageReset).toLocaleDateString()] }))] }))] }));
22
22
  }
23
- function ServiceCard({ service, mode, dispatch, customerName, currency, }) {
24
- return (_jsxs("div", { className: "si-service-card", children: [_jsxs("div", { className: "si-service-card__header", children: [_jsx("h4", { className: "si-service-card__name", children: service.name || "Service" }), service.customValue && (_jsx("span", { className: "si-service-card__custom-value", children: service.customValue }))] }), service.description && (_jsx("p", { className: "si-service-card__desc", children: service.description })), service.metrics.length > 0 && (_jsx("div", { className: "si-service-card__metrics", children: service.metrics.map((metric) => (_jsx(UsageBar, { serviceId: service.id, metric: metric, dispatch: dispatch, isOperator: mode === "operator", customerName: customerName, currency: currency }, metric.id))) }))] }));
23
+ function ServiceCard({ service, mode, dispatch, customerName, }) {
24
+ return (_jsxs("div", { className: "si-service-card", children: [_jsxs("div", { className: "si-service-card__header", children: [_jsx("h4", { className: "si-service-card__name", children: service.name || "Service" }), service.customValue && (_jsx("span", { className: "si-service-card__custom-value", children: service.customValue }))] }), service.description && (_jsx("p", { className: "si-service-card__desc", children: service.description })), service.metrics.length > 0 && (_jsx("div", { className: "si-service-card__metrics", children: service.metrics.map((metric) => (_jsx(UsageBar, { serviceId: service.id, metric: metric, dispatch: dispatch, isOperator: mode === "operator", customerName: customerName }, metric.id))) }))] }));
25
25
  }
26
26
  export function ServicesPanel({ document, dispatch, mode, }) {
27
27
  const state = document.state.global;
28
- const currency = state.globalCurrency || state.tierCurrency || "USD";
29
- const allGroupedServiceIds = new Set(state.serviceGroups.flatMap((g) => g.services));
30
- const standaloneServices = state.services.filter((s) => !allGroupedServiceIds.has(s.id));
28
+ // Split groups into recurring (non-optional) and add-ons (optional)
31
29
  const recurringGroups = state.serviceGroups.filter((g) => !g.optional);
32
30
  const addonGroups = state.serviceGroups.filter((g) => g.optional);
33
- const hasRecurring = standaloneServices.length > 0 || recurringGroups.length > 0;
31
+ const hasRecurring = state.services.length > 0 || recurringGroups.length > 0;
34
32
  const hasAddons = addonGroups.length > 0;
35
- const recurringServiceCount = standaloneServices.length +
33
+ const recurringServiceCount = state.services.length +
36
34
  recurringGroups.reduce((acc, g) => acc + g.services.length, 0);
37
35
  const addonServiceCount = addonGroups.reduce((acc, g) => acc + g.services.length, 0);
38
36
  if (!hasRecurring && !hasAddons) {
39
37
  return (_jsxs("div", { className: "si-panel", children: [_jsx("div", { className: "si-panel__header", children: _jsx("h3", { className: "si-panel__title", children: "Services" }) }), _jsxs("div", { className: "si-empty", children: [_jsx("svg", { className: "si-empty__icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.5, children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" }) }), _jsx("p", { className: "si-empty__text", children: "No services configured" })] })] }));
40
38
  }
41
- const resolveGroupServices = (serviceIds) => serviceIds
42
- .map((id) => state.services.find((s) => s.id === id))
43
- .filter((s) => s != null);
44
- return (_jsxs(_Fragment, { children: [hasRecurring && (_jsxs("div", { className: "si-panel", children: [_jsxs("div", { className: "si-panel__header", children: [_jsx("h3", { className: "si-panel__title", children: "Recurring Services" }), _jsxs("span", { className: "si-panel__count", children: [recurringServiceCount, " services"] })] }), standaloneServices.length > 0 && (_jsx("div", { className: "si-services-grid", children: standaloneServices.map((service) => (_jsx(ServiceCard, { service: service, mode: mode, dispatch: dispatch, customerName: state.customerName, currency: currency }, service.id))) })), recurringGroups.map((group) => {
45
- const groupServices = resolveGroupServices(group.services);
46
- return (_jsxs("div", { className: "si-service-group", children: [_jsxs("div", { className: "si-service-group__header", children: [_jsx("h4", { className: "si-service-group__name", children: group.name }), group.recurringCost && (_jsx("span", { className: "si-service-group__price", children: fmtCurrency(group.recurringCost.amount, group.recurringCost.currency) }))] }), _jsx("div", { className: "si-services-grid", children: groupServices.map((service) => (_jsx(ServiceCard, { service: service, mode: mode, dispatch: dispatch, customerName: state.customerName, currency: currency }, service.id))) })] }, group.id));
47
- })] })), hasAddons && (_jsxs("div", { className: "si-panel", children: [_jsxs("div", { className: "si-panel__header", children: [_jsx("h3", { className: "si-panel__title", children: "Add-ons" }), _jsxs("span", { className: "si-panel__count", children: [addonGroups.length, " groups, ", addonServiceCount, " services"] })] }), addonGroups.map((group) => {
48
- const groupServices = resolveGroupServices(group.services);
49
- return (_jsxs("div", { className: "si-service-group", children: [_jsxs("div", { className: "si-service-group__header", children: [_jsx("h4", { className: "si-service-group__name", children: group.name }), _jsx("span", { className: "si-badge si-badge--violet si-badge--sm", children: "Optional" }), group.recurringCost && (_jsx("span", { className: "si-service-group__price", children: fmtCurrency(group.recurringCost.amount, group.recurringCost.currency) }))] }), _jsx("div", { className: "si-services-grid", children: groupServices.map((service) => (_jsx(ServiceCard, { service: service, mode: mode, dispatch: dispatch, customerName: state.customerName, currency: currency }, service.id))) })] }, group.id));
50
- })] }))] }));
39
+ return (_jsxs(_Fragment, { children: [hasRecurring && (_jsxs("div", { className: "si-panel", children: [_jsxs("div", { className: "si-panel__header", children: [_jsx("h3", { className: "si-panel__title", children: "Recurring Services" }), _jsxs("span", { className: "si-panel__count", children: [recurringServiceCount, " services"] })] }), state.services.length > 0 && (_jsx("div", { className: "si-services-grid", children: state.services.map((service) => (_jsx(ServiceCard, { service: service, mode: mode, dispatch: dispatch, customerName: state.customerName }, service.id))) })), recurringGroups.map((group) => (_jsxs("div", { className: "si-service-group", children: [_jsxs("div", { className: "si-service-group__header", children: [_jsx("h4", { className: "si-service-group__name", children: group.name }), group.recurringCost && (_jsxs("span", { className: "si-service-group__price", children: [group.recurringCost.discount && (_jsxs(_Fragment, { children: [_jsx("span", { className: "si-service-group__original-price", children: fmtCurrency(group.recurringCost.discount.originalAmount, group.recurringCost.currency) }), _jsx("span", { className: "si-service-group__discount-badge", children: formatDiscountBadge(group.recurringCost.discount) })] })), fmtCurrency(group.recurringCost.amount, group.recurringCost.currency), formatBillingCycleSuffix(group.recurringCost.billingCycle)] }))] }), _jsx("div", { className: "si-services-grid", children: group.services.map((service) => (_jsx(ServiceCard, { service: service, mode: mode, dispatch: dispatch, customerName: state.customerName }, service.id))) })] }, group.id)))] })), hasAddons && (_jsxs("div", { className: "si-panel", children: [_jsxs("div", { className: "si-panel__header", children: [_jsx("h3", { className: "si-panel__title", children: "Add-ons" }), _jsxs("span", { className: "si-panel__count", children: [addonGroups.length, " groups, ", addonServiceCount, " services"] })] }), addonGroups.map((group) => (_jsxs("div", { className: "si-service-group", children: [_jsxs("div", { className: "si-service-group__header", children: [_jsx("h4", { className: "si-service-group__name", children: group.name }), _jsx("span", { className: "si-badge si-badge--violet si-badge--sm", children: "Optional" }), group.recurringCost && (_jsxs("span", { className: "si-service-group__price", children: [group.recurringCost.discount && (_jsxs(_Fragment, { children: [_jsx("span", { className: "si-service-group__original-price", children: fmtCurrency(group.recurringCost.discount.originalAmount, group.recurringCost.currency) }), _jsx("span", { className: "si-service-group__discount-badge", children: formatDiscountBadge(group.recurringCost.discount) })] })), fmtCurrency(group.recurringCost.amount, group.recurringCost.currency), formatBillingCycleSuffix(group.recurringCost.billingCycle)] }))] }), _jsx("div", { className: "si-services-grid", children: group.services.map((service) => (_jsx(ServiceCard, { service: service, mode: mode, dispatch: dispatch, customerName: state.customerName }, service.id))) })] }, group.id)))] }))] }));
51
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SubscriptionActions.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/SubscriptionActions.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC7B,MAAM,uEAAuE,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAS5C,UAAU,wBAAwB;IAChC,QAAQ,EAAE,4BAA4B,CAAC;IACvC,QAAQ,EAAE,gBAAgB,CAAC,0BAA0B,CAAC,CAAC;IACvD,IAAI,EAAE,QAAQ,CAAC;CAChB;AAsED,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,QAAQ,EACR,IAAI,GACL,EAAE,wBAAwB,2CA2P1B"}
1
+ {"version":3,"file":"SubscriptionActions.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/SubscriptionActions.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC7B,MAAM,uEAAuE,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAS5C,UAAU,wBAAwB;IAChC,QAAQ,EAAE,4BAA4B,CAAC;IACvC,QAAQ,EAAE,gBAAgB,CAAC,0BAA0B,CAAC,CAAC;IACvD,IAAI,EAAE,QAAQ,CAAC;CAChB;AAsED,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,QAAQ,EACR,IAAI,GACL,EAAE,wBAAwB,2CA2P1B"}
@@ -1,6 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useState, useCallback } from "react";
3
- import { generateId } from "document-model/core";
4
3
  import { activateSubscription, pauseSubscription, resumeSubscription, cancelSubscription, renewExpiringSubscription, } from "../../../document-models/subscription-instance/v1/gen/subscription/creators.js";
5
4
  function ConfirmModal({ isOpen, title, message, confirmLabel, confirmVariant = "primary", onConfirm, onCancel, showReasonInput, reason, onReasonChange, }) {
6
5
  if (!isOpen)
@@ -19,32 +18,32 @@ export function SubscriptionActions({ document, dispatch, mode, }) {
19
18
  // Operator direct actions
20
19
  const handleActivate = useCallback(() => {
21
20
  dispatch(activateSubscription({
22
- activatedAt: new Date().toISOString(),
21
+ activatedSince: new Date().toISOString(),
23
22
  }));
24
23
  }, [dispatch]);
25
24
  const handleOperatorPause = useCallback(() => {
26
25
  dispatch(pauseSubscription({
27
- pausedAt: new Date().toISOString(),
26
+ pausedSince: new Date().toISOString(),
28
27
  }));
29
28
  setConfirmAction(null);
30
29
  }, [dispatch]);
31
30
  const handleOperatorResume = useCallback(() => {
32
31
  dispatch(resumeSubscription({
33
- resumedAt: new Date().toISOString(),
32
+ timestamp: new Date().toISOString(),
34
33
  }));
35
34
  setConfirmAction(null);
36
35
  }, [dispatch]);
37
36
  const handleOperatorCancel = useCallback(() => {
38
37
  dispatch(cancelSubscription({
39
- cancelledAt: new Date().toISOString(),
40
- reason: reason || undefined,
38
+ cancelledSince: new Date().toISOString(),
39
+ cancellationReason: reason || null,
41
40
  }));
42
41
  setConfirmAction(null);
43
42
  setReason("");
44
43
  }, [dispatch, reason]);
45
44
  const handleOperatorRenew = useCallback(() => {
46
45
  dispatch(renewExpiringSubscription({
47
- renewedAt: new Date().toISOString(),
46
+ timestamp: new Date().toISOString(),
48
47
  }));
49
48
  setConfirmAction(null);
50
49
  }, [dispatch]);
@@ -70,12 +69,12 @@ export function SubscriptionActions({ document, dispatch, mode, }) {
70
69
  handleOperatorCancel,
71
70
  handleOperatorRenew,
72
71
  ]);
73
- const isDraft = state.status === "DRAFT";
72
+ const isPending = state.status === "PENDING";
74
73
  const isActive = state.status === "ACTIVE";
75
74
  const isPaused = state.status === "PAUSED";
76
75
  const isExpiring = state.status === "EXPIRING";
77
76
  const isCancelled = state.status === "CANCELLED";
78
- return (_jsxs(_Fragment, { children: [_jsx("div", { className: "si-actions", children: mode === "operator" && (_jsxs("div", { className: "si-actions__buttons", children: [isDraft && (_jsxs("button", { type: "button", className: "si-btn si-btn--sm si-btn--success", onClick: handleActivate, children: [_jsx("svg", { className: "si-btn__icon", viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z", clipRule: "evenodd" }) }), "Activate"] })), isActive && (_jsxs("button", { type: "button", className: "si-btn si-btn--sm si-btn--warning", onClick: () => setConfirmAction("pause"), children: [_jsx("svg", { className: "si-btn__icon", viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zM7 8a1 1 0 012 0v4a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v4a1 1 0 102 0V8a1 1 0 00-1-1z", clipRule: "evenodd" }) }), "Pause"] })), isPaused && (_jsxs("button", { type: "button", className: "si-btn si-btn--sm si-btn--success", onClick: () => setConfirmAction("resume"), children: [_jsx("svg", { className: "si-btn__icon", viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8v4a1 1 0 001.555.832l3-2a1 1 0 000-1.664l-3-2z", clipRule: "evenodd" }) }), "Resume"] })), isExpiring && (_jsxs("button", { type: "button", className: "si-btn si-btn--sm si-btn--primary", onClick: () => setConfirmAction("renew"), children: [_jsx("svg", { className: "si-btn__icon", viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { fillRule: "evenodd", d: "M4 2a1 1 0 011 1v2.101a7.002 7.002 0 0111.601 2.566 1 1 0 11-1.885.666A5.002 5.002 0 005.999 7H9a1 1 0 010 2H4a1 1 0 01-1-1V3a1 1 0 011-1zm.008 9.057a1 1 0 011.276.61A5.002 5.002 0 0014.001 13H11a1 1 0 110-2h5a1 1 0 011 1v5a1 1 0 11-2 0v-2.101a7.002 7.002 0 01-11.601-2.566 1 1 0 01.61-1.276z", clipRule: "evenodd" }) }), "Renew"] })), !isCancelled && (_jsxs("button", { type: "button", className: "si-btn si-btn--sm si-btn--danger-ghost", onClick: () => setConfirmAction("cancel"), children: [_jsx("svg", { className: "si-btn__icon", viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z", clipRule: "evenodd" }) }), "Cancel"] }))] })) }), _jsx(ConfirmModal, { isOpen: confirmAction === "pause", title: "Pause Subscription", message: "Are you sure you want to pause this subscription? Services will be temporarily suspended.", confirmLabel: "Pause Subscription", confirmVariant: "warning", onConfirm: handleConfirm, onCancel: () => {
77
+ return (_jsxs(_Fragment, { children: [_jsx("div", { className: "si-actions", children: mode === "operator" && (_jsxs("div", { className: "si-actions__buttons", children: [isPending && (_jsxs("button", { type: "button", className: "si-btn si-btn--sm si-btn--success", onClick: handleActivate, children: [_jsx("svg", { className: "si-btn__icon", viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z", clipRule: "evenodd" }) }), "Activate"] })), isActive && (_jsxs("button", { type: "button", className: "si-btn si-btn--sm si-btn--warning", onClick: () => setConfirmAction("pause"), children: [_jsx("svg", { className: "si-btn__icon", viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zM7 8a1 1 0 012 0v4a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v4a1 1 0 102 0V8a1 1 0 00-1-1z", clipRule: "evenodd" }) }), "Pause"] })), isPaused && (_jsxs("button", { type: "button", className: "si-btn si-btn--sm si-btn--success", onClick: () => setConfirmAction("resume"), children: [_jsx("svg", { className: "si-btn__icon", viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8v4a1 1 0 001.555.832l3-2a1 1 0 000-1.664l-3-2z", clipRule: "evenodd" }) }), "Resume"] })), isExpiring && (_jsxs("button", { type: "button", className: "si-btn si-btn--sm si-btn--primary", onClick: () => setConfirmAction("renew"), children: [_jsx("svg", { className: "si-btn__icon", viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { fillRule: "evenodd", d: "M4 2a1 1 0 011 1v2.101a7.002 7.002 0 0111.601 2.566 1 1 0 11-1.885.666A5.002 5.002 0 005.999 7H9a1 1 0 010 2H4a1 1 0 01-1-1V3a1 1 0 011-1zm.008 9.057a1 1 0 011.276.61A5.002 5.002 0 0014.001 13H11a1 1 0 110-2h5a1 1 0 011 1v5a1 1 0 11-2 0v-2.101a7.002 7.002 0 01-11.601-2.566 1 1 0 01.61-1.276z", clipRule: "evenodd" }) }), "Renew"] })), !isCancelled && (_jsxs("button", { type: "button", className: "si-btn si-btn--sm si-btn--danger-ghost", onClick: () => setConfirmAction("cancel"), children: [_jsx("svg", { className: "si-btn__icon", viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z", clipRule: "evenodd" }) }), "Cancel"] }))] })) }), _jsx(ConfirmModal, { isOpen: confirmAction === "pause", title: "Pause Subscription", message: "Are you sure you want to pause this subscription? Services will be temporarily suspended.", confirmLabel: "Pause Subscription", confirmVariant: "warning", onConfirm: handleConfirm, onCancel: () => {
79
78
  setConfirmAction(null);
80
79
  setReason("");
81
80
  } }), _jsx(ConfirmModal, { isOpen: confirmAction === "resume", title: "Resume Subscription", message: "Are you sure you want to resume this subscription? Services will be reactivated.", confirmLabel: "Resume Subscription", confirmVariant: "primary", onConfirm: handleConfirm, onCancel: () => {
@@ -1 +1 @@
1
- {"version":3,"file":"SubscriptionHeader.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/SubscriptionHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC7B,MAAM,uEAAuE,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAiD5C,UAAU,uBAAuB;IAC/B,QAAQ,EAAE,4BAA4B,CAAC;IACvC,QAAQ,EAAE,gBAAgB,CAAC,0BAA0B,CAAC,CAAC;IACvD,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,QAAQ,EACR,IAAI,GACL,EAAE,uBAAuB,2CAwIzB"}
1
+ {"version":3,"file":"SubscriptionHeader.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/SubscriptionHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC7B,MAAM,uEAAuE,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAiD5C,UAAU,uBAAuB;IAC/B,QAAQ,EAAE,4BAA4B,CAAC;IACvC,QAAQ,EAAE,gBAAgB,CAAC,0BAA0B,CAAC,CAAC;IACvD,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,QAAQ,EACR,IAAI,GACL,EAAE,uBAAuB,2CAkJzB"}
@@ -40,7 +40,7 @@ export function SubscriptionHeader({ document, dispatch, mode, }) {
40
40
  year: "numeric",
41
41
  });
42
42
  };
43
- return (_jsxs("div", { className: "si-header", children: [_jsxs("div", { className: "si-header__main", children: [_jsxs("div", { className: "si-header__title-row", children: [_jsx("div", { className: "si-header__info", children: _jsx("div", { children: _jsx("h1", { className: "si-header__title", children: state.tierName || "Subscription" }) }) }), _jsx(StatusBadge, { status: state.status })] }), _jsxs("div", { className: "si-header__meta", children: [mode === "operator" && state.customerName && (_jsxs("div", { className: "si-header__meta-item", children: [_jsx("span", { className: "si-header__meta-label", children: "Customer" }), _jsx("span", { className: "si-header__meta-value", children: state.customerName })] })), state.createdAt && (_jsxs("div", { className: "si-header__meta-item", children: [_jsx("span", { className: "si-header__meta-label", children: "Created" }), _jsx("span", { className: "si-header__meta-value", children: formatDate(state.createdAt) })] })), state.activatedSince && (_jsxs("div", { className: "si-header__meta-item", children: [_jsx("span", { className: "si-header__meta-label", children: "Active Since" }), _jsx("span", { className: "si-header__meta-value", children: formatDate(state.activatedSince) })] })), _jsxs("div", { className: "si-header__meta-item", children: [_jsx("span", { className: "si-header__meta-label", children: "Auto-Renew" }), _jsx("span", { className: "si-header__meta-value", style: {
43
+ return (_jsxs("div", { className: "si-header", children: [_jsxs("div", { className: "si-header__main", children: [_jsxs("div", { className: "si-header__title-row", children: [_jsxs("div", { className: "si-header__info", children: [state.resource?.thumbnailUrl && (_jsx("img", { src: state.resource.thumbnailUrl, alt: "", className: "si-header__thumbnail" })), _jsxs("div", { children: [_jsx("h1", { className: "si-header__title", children: state.resource?.label || state.tierName || "Subscription" }), state.tierName && state.resource?.label && (_jsxs("p", { className: "si-header__subtitle", children: [state.tierName, " Tier"] }))] })] }), _jsx(StatusBadge, { status: state.status })] }), _jsxs("div", { className: "si-header__meta", children: [mode === "operator" && state.customerName && (_jsxs("div", { className: "si-header__meta-item", children: [_jsx("span", { className: "si-header__meta-label", children: "Customer" }), _jsx("span", { className: "si-header__meta-value", children: state.customerName })] })), state.createdAt && (_jsxs("div", { className: "si-header__meta-item", children: [_jsx("span", { className: "si-header__meta-label", children: "Created" }), _jsx("span", { className: "si-header__meta-value", children: formatDate(state.createdAt) })] })), state.activatedSince && (_jsxs("div", { className: "si-header__meta-item", children: [_jsx("span", { className: "si-header__meta-label", children: "Active Since" }), _jsx("span", { className: "si-header__meta-value", children: formatDate(state.activatedSince) })] })), _jsxs("div", { className: "si-header__meta-item", children: [_jsx("span", { className: "si-header__meta-label", children: "Auto-Renew" }), _jsx("span", { className: "si-header__meta-value", style: {
44
44
  color: state.autoRenew
45
45
  ? "var(--si-emerald-600)"
46
46
  : "var(--si-slate-400)",
@@ -1,12 +1,9 @@
1
- import type { SubscriptionInstanceState, ServiceMetric } from "../../../document-models/subscription-instance/v1/gen/schema/types.js";
1
+ import type { SubscriptionInstanceState, ServiceMetric, DiscountInfo } from "../../../document-models/subscription-instance/v1/gen/schema/types.js";
2
2
  export declare function formatCurrency(amount: number, currency: string): string;
3
3
  export declare function formatDate(date: string | null | undefined): string;
4
4
  export declare function formatBillingCycleSuffix(cycle: string | null | undefined): string;
5
5
  export declare const BILLING_CYCLE_LABELS: Record<string, string>;
6
- export declare function formatDiscountBadge(discount: {
7
- discountType: string;
8
- discountValue: number;
9
- }): string;
6
+ export declare function formatDiscountBadge(discount: DiscountInfo): string;
10
7
  export declare function getDiscountSourceLabel(source: string): string;
11
8
  export interface MetricOverage {
12
9
  metricId: string;
@@ -20,13 +17,17 @@ export interface MetricOverage {
20
17
  unitCostCurrency: string;
21
18
  projectedCost: number;
22
19
  }
23
- export declare function computeMetricOverage(metric: ServiceMetric, currency?: string): MetricOverage | null;
20
+ export declare function computeMetricOverage(metric: ServiceMetric): MetricOverage | null;
24
21
  export interface GroupBillingBreakdown {
25
22
  groupId: string;
26
23
  groupName: string;
27
24
  optional: boolean;
25
+ /** Group-level recurring cost (fixed cost) */
28
26
  recurringAmount: number | null;
29
27
  recurringCurrency: string;
28
+ recurringCycle: string | null;
29
+ discount: DiscountInfo | null;
30
+ /** Dynamic costs from service metrics */
30
31
  metricOverages: MetricOverage[];
31
32
  dynamicTotal: number;
32
33
  }
@@ -39,12 +40,19 @@ export interface SetupCostLine {
39
40
  }
40
41
  export interface BillingBreakdown {
41
42
  currency: string;
43
+ /** Sum of group recurring costs */
42
44
  fixedTotal: number;
45
+ /** Sum of metric overage projections */
43
46
  dynamicTotal: number;
47
+ /** fixedTotal + dynamicTotal */
44
48
  projectedTotal: number;
49
+ /** Standalone service recurring costs (not in groups) */
45
50
  standaloneFixedTotal: number;
51
+ /** Breakdown per service group */
46
52
  groupBreakdowns: GroupBillingBreakdown[];
53
+ /** Standalone services with metrics */
47
54
  standaloneOverages: MetricOverage[];
55
+ /** All setup costs */
48
56
  setupLines: SetupCostLine[];
49
57
  setupTotal: number;
50
58
  billingCycle: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"billing-utils.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/billing-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,aAAa,EACd,MAAM,uEAAuE,CAAC;AAI/E,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAKvE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAOlE;AAUD,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC/B,MAAM,CAGR;AAED,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAMvD,CAAC;AAIF,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE;IAC5C,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,MAAM,CAKT;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAW7D;AAID,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,aAAa,EACrB,QAAQ,GAAE,MAAc,GACvB,aAAa,GAAG,IAAI,CAuBtB;AAID,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,eAAe,EAAE,qBAAqB,EAAE,CAAC;IACzC,kBAAkB,EAAE,aAAa,EAAE,CAAC;IACpC,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,yBAAyB,GAC/B,gBAAgB,CA8GlB"}
1
+ {"version":3,"file":"billing-utils.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/billing-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,aAAa,EACb,YAAY,EACb,MAAM,uEAAuE,CAAC;AAI/E,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAKvE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAOlE;AAUD,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC/B,MAAM,CAGR;AAED,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAMvD,CAAC;AAIF,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAKlE;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAW7D;AAID,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,aAAa,GACpB,aAAa,GAAG,IAAI,CAuBtB;AAID,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,8CAA8C;IAC9C,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,yCAAyC;IACzC,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,mCAAmC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB,gCAAgC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,yDAAyD;IACzD,oBAAoB,EAAE,MAAM,CAAC;IAC7B,kCAAkC;IAClC,eAAe,EAAE,qBAAqB,EAAE,CAAC;IACzC,uCAAuC;IACvC,kBAAkB,EAAE,aAAa,EAAE,CAAC;IACpC,sBAAsB;IACtB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,yBAAyB,GAC/B,gBAAgB,CAuGlB"}
@@ -52,48 +52,41 @@ export function getDiscountSourceLabel(source) {
52
52
  return "Discount";
53
53
  }
54
54
  }
55
- export function computeMetricOverage(metric, currency = "USD") {
55
+ export function computeMetricOverage(metric) {
56
56
  const freeLimit = metric.freeLimit ?? metric.limit ?? 0;
57
57
  const paidLimit = metric.paidLimit ?? null;
58
58
  if (freeLimit <= 0 && paidLimit == null)
59
59
  return null;
60
60
  if (metric.currentUsage <= freeLimit)
61
61
  return null;
62
- if (metric.unitCost == null)
62
+ if (!metric.unitCost)
63
63
  return null;
64
64
  const excess = metric.currentUsage - freeLimit;
65
- const projectedCost = excess * metric.unitCost;
65
+ const projectedCost = excess * metric.unitCost.amount;
66
66
  return {
67
67
  metricId: metric.id,
68
68
  metricName: metric.name,
69
- unitName: metric.unitName ?? "units",
69
+ unitName: metric.unitName,
70
70
  currentUsage: metric.currentUsage,
71
71
  freeLimit,
72
72
  paidLimit,
73
73
  excess,
74
- unitCostAmount: metric.unitCost,
75
- unitCostCurrency: currency,
74
+ unitCostAmount: metric.unitCost.amount,
75
+ unitCostCurrency: metric.unitCost.currency,
76
76
  projectedCost,
77
77
  };
78
78
  }
79
79
  export function computeBillingBreakdown(state) {
80
80
  const currency = state.globalCurrency || state.tierCurrency || "USD";
81
81
  const billingCycle = state.selectedBillingCycle || null;
82
+ // Group breakdowns
82
83
  const groupBreakdowns = [];
83
84
  const setupLines = [];
84
- const allGroupedServiceIds = new Set();
85
- for (const group of state.serviceGroups) {
86
- for (const svcId of group.services) {
87
- allGroupedServiceIds.add(svcId);
88
- }
89
- }
90
85
  for (const group of state.serviceGroups) {
91
86
  const metricOverages = [];
92
- const groupServiceIds = new Set(group.services);
93
- const groupServices = state.services.filter((svc) => groupServiceIds.has(svc.id));
94
- for (const svc of groupServices) {
87
+ for (const svc of group.services) {
95
88
  for (const metric of svc.metrics) {
96
- const overage = computeMetricOverage(metric, currency);
89
+ const overage = computeMetricOverage(metric);
97
90
  if (overage)
98
91
  metricOverages.push(overage);
99
92
  }
@@ -105,40 +98,43 @@ export function computeBillingBreakdown(state) {
105
98
  optional: group.optional,
106
99
  recurringAmount: group.recurringCost?.amount ?? null,
107
100
  recurringCurrency: group.recurringCost?.currency ?? currency,
101
+ recurringCycle: group.recurringCost?.billingCycle ?? billingCycle,
102
+ discount: group.recurringCost?.discount ?? null,
108
103
  metricOverages,
109
104
  dynamicTotal,
110
105
  });
106
+ // Collect setup costs from group level
111
107
  if (group.setupCost) {
112
108
  setupLines.push({
113
109
  name: group.name,
114
110
  amount: group.setupCost.amount,
115
111
  currency: group.setupCost.currency,
116
- paid: !!group.setupCost.paidAt,
112
+ paid: !!group.setupCost.paymentDate,
117
113
  source: "group",
118
114
  });
119
115
  }
120
- for (const svc of groupServices) {
116
+ // Collect setup costs from services in group
117
+ for (const svc of group.services) {
121
118
  if (svc.setupCost) {
122
119
  setupLines.push({
123
120
  name: `${svc.name || "Service"} (${group.name})`,
124
121
  amount: svc.setupCost.amount,
125
122
  currency: svc.setupCost.currency,
126
- paid: !!svc.setupCost.paidAt,
123
+ paid: !!svc.setupCost.paymentDate,
127
124
  source: "service",
128
125
  });
129
126
  }
130
127
  }
131
128
  }
129
+ // Standalone services (not in groups)
132
130
  const standaloneOverages = [];
133
131
  let standaloneFixedTotal = 0;
134
132
  for (const svc of state.services) {
135
- if (allGroupedServiceIds.has(svc.id))
136
- continue;
137
133
  if (svc.recurringCost) {
138
134
  standaloneFixedTotal += svc.recurringCost.amount;
139
135
  }
140
136
  for (const metric of svc.metrics) {
141
- const overage = computeMetricOverage(metric, currency);
137
+ const overage = computeMetricOverage(metric);
142
138
  if (overage)
143
139
  standaloneOverages.push(overage);
144
140
  }
@@ -147,7 +143,7 @@ export function computeBillingBreakdown(state) {
147
143
  name: svc.name || "Service",
148
144
  amount: svc.setupCost.amount,
149
145
  currency: svc.setupCost.currency,
150
- paid: !!svc.setupCost.paidAt,
146
+ paid: !!svc.setupCost.paymentDate,
151
147
  source: "service",
152
148
  });
153
149
  }