@spottoai/types-package 1.0.2-dev1138.1 → 1.0.2-dev1138.12

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 (523) hide show
  1. package/README.md +9 -0
  2. package/dist/accounts/accounts.d.ts +84 -5
  3. package/dist/accounts/accounts.d.ts.map +1 -1
  4. package/dist/accounts/accounts.js +2 -1
  5. package/dist/accounts/accounts.js.map +1 -1
  6. package/dist/accounts/azureManualOnboarding.d.ts +114 -0
  7. package/dist/accounts/azureManualOnboarding.d.ts.map +1 -0
  8. package/dist/accounts/azureManualOnboarding.js +12 -0
  9. package/dist/accounts/azureManualOnboarding.js.map +1 -0
  10. package/dist/accounts/azureSpSetup.d.ts +142 -31
  11. package/dist/accounts/azureSpSetup.d.ts.map +1 -1
  12. package/dist/accounts/azureSpSetup.js +15 -0
  13. package/dist/accounts/azureSpSetup.js.map +1 -1
  14. package/dist/accounts/azureSpSetupDurable.d.ts +8 -0
  15. package/dist/accounts/azureSpSetupDurable.d.ts.map +1 -1
  16. package/dist/accounts/azureSpSetupDurable.js +28 -0
  17. package/dist/accounts/azureSpSetupDurable.js.map +1 -1
  18. package/dist/accounts/index.d.ts +1 -0
  19. package/dist/accounts/index.d.ts.map +1 -1
  20. package/dist/accounts/index.js +1 -0
  21. package/dist/accounts/index.js.map +1 -1
  22. package/dist/accounts/readPermissions.d.ts +1 -1
  23. package/dist/accounts/readPermissions.d.ts.map +1 -1
  24. package/dist/accounts/readPermissions.js.map +1 -1
  25. package/dist/accounts/validation.d.ts +24 -0
  26. package/dist/accounts/validation.d.ts.map +1 -1
  27. package/dist/ai/conversationHistory.d.ts +52 -0
  28. package/dist/ai/conversationHistory.d.ts.map +1 -0
  29. package/dist/ai/conversationHistory.js +10 -0
  30. package/dist/ai/conversationHistory.js.map +1 -0
  31. package/dist/ai/grounding.d.ts +41 -0
  32. package/dist/ai/grounding.d.ts.map +1 -0
  33. package/dist/ai/grounding.js +86 -0
  34. package/dist/ai/grounding.js.map +1 -0
  35. package/dist/ai/index.d.ts +302 -6
  36. package/dist/ai/index.d.ts.map +1 -1
  37. package/dist/ai/index.js +25 -0
  38. package/dist/ai/index.js.map +1 -1
  39. package/dist/ai/workspaceArtifacts.d.ts +587 -0
  40. package/dist/ai/workspaceArtifacts.d.ts.map +1 -0
  41. package/dist/ai/workspaceArtifacts.js +162 -0
  42. package/dist/ai/workspaceArtifacts.js.map +1 -0
  43. package/dist/aws/commitments-planning.d.ts +5 -0
  44. package/dist/aws/commitments-planning.d.ts.map +1 -1
  45. package/dist/aws/commitments-planning.js +19 -0
  46. package/dist/aws/commitments-planning.js.map +1 -1
  47. package/dist/aws/estates.d.ts +1 -1
  48. package/dist/aws/estates.d.ts.map +1 -1
  49. package/dist/aws/estates.js +7 -1
  50. package/dist/aws/estates.js.map +1 -1
  51. package/dist/aws/index.d.ts +5 -0
  52. package/dist/aws/index.d.ts.map +1 -1
  53. package/dist/aws/index.js +5 -0
  54. package/dist/aws/index.js.map +1 -1
  55. package/dist/aws/onboarding.d.ts +3 -0
  56. package/dist/aws/onboarding.d.ts.map +1 -1
  57. package/dist/aws/organizationCommitments.d.ts +260 -0
  58. package/dist/aws/organizationCommitments.d.ts.map +1 -0
  59. package/dist/aws/organizationCommitments.js +53 -0
  60. package/dist/aws/organizationCommitments.js.map +1 -0
  61. package/dist/aws/organizationCommitmentsApiValidation.d.ts +21 -0
  62. package/dist/aws/organizationCommitmentsApiValidation.d.ts.map +1 -0
  63. package/dist/aws/organizationCommitmentsApiValidation.js +226 -0
  64. package/dist/aws/organizationCommitmentsApiValidation.js.map +1 -0
  65. package/dist/aws/organizationCommitmentsValidation.d.ts +12 -0
  66. package/dist/aws/organizationCommitmentsValidation.d.ts.map +1 -0
  67. package/dist/aws/organizationCommitmentsValidation.js +228 -0
  68. package/dist/aws/organizationCommitmentsValidation.js.map +1 -0
  69. package/dist/aws/portalOrganizationCommitmentsPlanningPublicArtifactValidation.d.ts +9 -0
  70. package/dist/aws/portalOrganizationCommitmentsPlanningPublicArtifactValidation.d.ts.map +1 -0
  71. package/dist/aws/portalOrganizationCommitmentsPlanningPublicArtifactValidation.js +407 -0
  72. package/dist/aws/portalOrganizationCommitmentsPlanningPublicArtifactValidation.js.map +1 -0
  73. package/dist/aws/portalOrganizationCommitmentsPlanningPublicArtifacts.d.ts +17 -0
  74. package/dist/aws/portalOrganizationCommitmentsPlanningPublicArtifacts.d.ts.map +1 -0
  75. package/dist/aws/portalOrganizationCommitmentsPlanningPublicArtifacts.js +6 -0
  76. package/dist/aws/portalOrganizationCommitmentsPlanningPublicArtifacts.js.map +1 -0
  77. package/dist/aws/requests.d.ts +13 -2
  78. package/dist/aws/requests.d.ts.map +1 -1
  79. package/dist/aws/requests.js +1 -1
  80. package/dist/aws/requests.js.map +1 -1
  81. package/dist/azure/activityLogAnalysis.d.ts +320 -0
  82. package/dist/azure/activityLogAnalysis.d.ts.map +1 -0
  83. package/dist/azure/activityLogAnalysis.js +70 -0
  84. package/dist/azure/activityLogAnalysis.js.map +1 -0
  85. package/dist/azure/activityLogAnalysisPublicValidation.d.ts +8 -0
  86. package/dist/azure/activityLogAnalysisPublicValidation.d.ts.map +1 -0
  87. package/dist/azure/activityLogAnalysisPublicValidation.js +368 -0
  88. package/dist/azure/activityLogAnalysisPublicValidation.js.map +1 -0
  89. package/dist/azure/activityLogAnalysisPublicValidationHelpers.d.ts +33 -0
  90. package/dist/azure/activityLogAnalysisPublicValidationHelpers.d.ts.map +1 -0
  91. package/dist/azure/activityLogAnalysisPublicValidationHelpers.js +197 -0
  92. package/dist/azure/activityLogAnalysisPublicValidationHelpers.js.map +1 -0
  93. package/dist/azure/activityLogAnalysisValidation.d.ts +5 -0
  94. package/dist/azure/activityLogAnalysisValidation.d.ts.map +1 -0
  95. package/dist/azure/activityLogAnalysisValidation.js +376 -0
  96. package/dist/azure/activityLogAnalysisValidation.js.map +1 -0
  97. package/dist/azure/activityLogs.d.ts +8 -0
  98. package/dist/azure/activityLogs.d.ts.map +1 -1
  99. package/dist/azure/activityLogs.js.map +1 -1
  100. package/dist/azure/benefits.d.ts +1 -1
  101. package/dist/azure/benefits.d.ts.map +1 -1
  102. package/dist/azure/billingPlots.d.ts +7 -1
  103. package/dist/azure/billingPlots.d.ts.map +1 -1
  104. package/dist/azure/billingPlots.js +45 -4
  105. package/dist/azure/billingPlots.js.map +1 -1
  106. package/dist/azure/commitmentsPlanning.d.ts +8 -2
  107. package/dist/azure/commitmentsPlanning.d.ts.map +1 -1
  108. package/dist/azure/common.d.ts +26 -5
  109. package/dist/azure/common.d.ts.map +1 -1
  110. package/dist/azure/common.js +30 -0
  111. package/dist/azure/common.js.map +1 -1
  112. package/dist/azure/costComposition.d.ts +11 -1
  113. package/dist/azure/costComposition.d.ts.map +1 -1
  114. package/dist/azure/costComposition.js +84 -1
  115. package/dist/azure/costComposition.js.map +1 -1
  116. package/dist/azure/dataProtection.d.ts +4 -4
  117. package/dist/azure/dataProtection.d.ts.map +1 -1
  118. package/dist/azure/financialAnalytics.d.ts +80 -8
  119. package/dist/azure/financialAnalytics.d.ts.map +1 -1
  120. package/dist/azure/financialAnalyticsDelivery.d.ts +72 -3
  121. package/dist/azure/financialAnalyticsDelivery.d.ts.map +1 -1
  122. package/dist/azure/financialAnalyticsDelivery.js +7 -1
  123. package/dist/azure/financialAnalyticsDelivery.js.map +1 -1
  124. package/dist/azure/financialAnalyticsDeliveryValidation.d.ts +9 -1
  125. package/dist/azure/financialAnalyticsDeliveryValidation.d.ts.map +1 -1
  126. package/dist/azure/financialAnalyticsDeliveryValidation.js +190 -10
  127. package/dist/azure/financialAnalyticsDeliveryValidation.js.map +1 -1
  128. package/dist/azure/financialAnalyticsDisplayKernel.d.ts +12 -0
  129. package/dist/azure/financialAnalyticsDisplayKernel.d.ts.map +1 -0
  130. package/dist/azure/financialAnalyticsDisplayKernel.js +144 -0
  131. package/dist/azure/financialAnalyticsDisplayKernel.js.map +1 -0
  132. package/dist/azure/financialAnalyticsValidation.d.ts.map +1 -1
  133. package/dist/azure/financialAnalyticsValidation.js +101 -19
  134. package/dist/azure/financialAnalyticsValidation.js.map +1 -1
  135. package/dist/azure/financialAuthorityProjectionKernel.d.ts +8 -0
  136. package/dist/azure/financialAuthorityProjectionKernel.d.ts.map +1 -0
  137. package/dist/azure/financialAuthorityProjectionKernel.js +269 -0
  138. package/dist/azure/financialAuthorityProjectionKernel.js.map +1 -0
  139. package/dist/azure/financialAuthorityView.d.ts +13 -0
  140. package/dist/azure/financialAuthorityView.d.ts.map +1 -1
  141. package/dist/azure/financialAuthorityView.js.map +1 -1
  142. package/dist/azure/financialAuthorityViewValidation.d.ts +3 -1
  143. package/dist/azure/financialAuthorityViewValidation.d.ts.map +1 -1
  144. package/dist/azure/financialAuthorityViewValidation.js +273 -2
  145. package/dist/azure/financialAuthorityViewValidation.js.map +1 -1
  146. package/dist/azure/financialChargeComposition.d.ts +81 -0
  147. package/dist/azure/financialChargeComposition.d.ts.map +1 -0
  148. package/dist/azure/financialChargeComposition.js +41 -0
  149. package/dist/azure/financialChargeComposition.js.map +1 -0
  150. package/dist/azure/financialChargeCompositionKernel.d.ts +3 -0
  151. package/dist/azure/financialChargeCompositionKernel.d.ts.map +1 -0
  152. package/dist/azure/financialChargeCompositionKernel.js +53 -0
  153. package/dist/azure/financialChargeCompositionKernel.js.map +1 -0
  154. package/dist/azure/financialChargeCompositionValidation.d.ts +8 -0
  155. package/dist/azure/financialChargeCompositionValidation.d.ts.map +1 -0
  156. package/dist/azure/financialChargeCompositionValidation.js +164 -0
  157. package/dist/azure/financialChargeCompositionValidation.js.map +1 -0
  158. package/dist/azure/financialChargePolicy.d.ts +215 -0
  159. package/dist/azure/financialChargePolicy.d.ts.map +1 -0
  160. package/dist/azure/financialChargePolicy.js +488 -0
  161. package/dist/azure/financialChargePolicy.js.map +1 -0
  162. package/dist/azure/financialCurrentSpendSurfaceProjection.d.ts +76 -0
  163. package/dist/azure/financialCurrentSpendSurfaceProjection.d.ts.map +1 -0
  164. package/dist/azure/financialCurrentSpendSurfaceProjection.js +6 -0
  165. package/dist/azure/financialCurrentSpendSurfaceProjection.js.map +1 -0
  166. package/dist/azure/financialCurrentSpendSurfaceProjectionValidation.d.ts +10 -0
  167. package/dist/azure/financialCurrentSpendSurfaceProjectionValidation.d.ts.map +1 -0
  168. package/dist/azure/financialCurrentSpendSurfaceProjectionValidation.js +196 -0
  169. package/dist/azure/financialCurrentSpendSurfaceProjectionValidation.js.map +1 -0
  170. package/dist/azure/financialDataflow.d.ts +45 -2
  171. package/dist/azure/financialDataflow.d.ts.map +1 -1
  172. package/dist/azure/financialDataflow.js.map +1 -1
  173. package/dist/azure/financialDataflowKernel.d.ts +31 -0
  174. package/dist/azure/financialDataflowKernel.d.ts.map +1 -0
  175. package/dist/azure/financialDataflowKernel.js +170 -0
  176. package/dist/azure/financialDataflowKernel.js.map +1 -0
  177. package/dist/azure/financialDataflowValidation.d.ts +5 -2
  178. package/dist/azure/financialDataflowValidation.d.ts.map +1 -1
  179. package/dist/azure/financialDataflowValidation.js +203 -30
  180. package/dist/azure/financialDataflowValidation.js.map +1 -1
  181. package/dist/azure/financialEvidenceAssessmentValidation.d.ts.map +1 -1
  182. package/dist/azure/financialEvidenceAssessmentValidation.js +7 -0
  183. package/dist/azure/financialEvidenceAssessmentValidation.js.map +1 -1
  184. package/dist/azure/financialEvidenceCoverage.d.ts +36 -0
  185. package/dist/azure/financialEvidenceCoverage.d.ts.map +1 -0
  186. package/dist/azure/financialEvidenceCoverage.js +111 -0
  187. package/dist/azure/financialEvidenceCoverage.js.map +1 -0
  188. package/dist/azure/financialPolicy.d.ts +19 -3
  189. package/dist/azure/financialPolicy.d.ts.map +1 -1
  190. package/dist/azure/financialPolicy.js.map +1 -1
  191. package/dist/azure/financialPolicyDelivery.d.ts +75 -1
  192. package/dist/azure/financialPolicyDelivery.d.ts.map +1 -1
  193. package/dist/azure/financialPolicyDelivery.js +5 -1
  194. package/dist/azure/financialPolicyDelivery.js.map +1 -1
  195. package/dist/azure/financialPolicyDeliveryValidation.d.ts +16 -2
  196. package/dist/azure/financialPolicyDeliveryValidation.d.ts.map +1 -1
  197. package/dist/azure/financialPolicyDeliveryValidation.js +238 -5
  198. package/dist/azure/financialPolicyDeliveryValidation.js.map +1 -1
  199. package/dist/azure/financialPolicyKernel.d.ts +38 -0
  200. package/dist/azure/financialPolicyKernel.d.ts.map +1 -0
  201. package/dist/azure/financialPolicyKernel.js +232 -0
  202. package/dist/azure/financialPolicyKernel.js.map +1 -0
  203. package/dist/azure/financialPolicyValidation.d.ts +1 -0
  204. package/dist/azure/financialPolicyValidation.d.ts.map +1 -1
  205. package/dist/azure/financialPolicyValidation.js +111 -16
  206. package/dist/azure/financialPolicyValidation.js.map +1 -1
  207. package/dist/azure/financialProjection.d.ts +11 -1
  208. package/dist/azure/financialProjection.d.ts.map +1 -1
  209. package/dist/azure/financialProjection.js.map +1 -1
  210. package/dist/azure/financialProjectionValidation.d.ts.map +1 -1
  211. package/dist/azure/financialProjectionValidation.js +43 -3
  212. package/dist/azure/financialProjectionValidation.js.map +1 -1
  213. package/dist/azure/financialResourceSurfaceProjection.d.ts +66 -0
  214. package/dist/azure/financialResourceSurfaceProjection.d.ts.map +1 -0
  215. package/dist/azure/financialResourceSurfaceProjection.js +6 -0
  216. package/dist/azure/financialResourceSurfaceProjection.js.map +1 -0
  217. package/dist/azure/financialResourceSurfaceProjectionValidation.d.ts +16 -0
  218. package/dist/azure/financialResourceSurfaceProjectionValidation.d.ts.map +1 -0
  219. package/dist/azure/financialResourceSurfaceProjectionValidation.js +252 -0
  220. package/dist/azure/financialResourceSurfaceProjectionValidation.js.map +1 -0
  221. package/dist/azure/financialSavingsAuthority.d.ts +68 -4
  222. package/dist/azure/financialSavingsAuthority.d.ts.map +1 -1
  223. package/dist/azure/financialSavingsAuthority.js +2 -1
  224. package/dist/azure/financialSavingsAuthority.js.map +1 -1
  225. package/dist/azure/financialSavingsAuthorityValidation.d.ts +6 -2
  226. package/dist/azure/financialSavingsAuthorityValidation.d.ts.map +1 -1
  227. package/dist/azure/financialSavingsAuthorityValidation.js +188 -2
  228. package/dist/azure/financialSavingsAuthorityValidation.js.map +1 -1
  229. package/dist/azure/financialSavingsChargePolicyKernel.d.ts +12 -0
  230. package/dist/azure/financialSavingsChargePolicyKernel.d.ts.map +1 -0
  231. package/dist/azure/financialSavingsChargePolicyKernel.js +34 -0
  232. package/dist/azure/financialSavingsChargePolicyKernel.js.map +1 -0
  233. package/dist/azure/financialSavingsCoordinateValidation.d.ts.map +1 -1
  234. package/dist/azure/financialSavingsCoordinateValidation.js +98 -19
  235. package/dist/azure/financialSavingsCoordinateValidation.js.map +1 -1
  236. package/dist/azure/financialSavingsPercentageKernel.d.ts +20 -0
  237. package/dist/azure/financialSavingsPercentageKernel.d.ts.map +1 -0
  238. package/dist/azure/financialSavingsPercentageKernel.js +49 -0
  239. package/dist/azure/financialSavingsPercentageKernel.js.map +1 -0
  240. package/dist/azure/financialSavingsSurfaceProjection.d.ts +82 -3
  241. package/dist/azure/financialSavingsSurfaceProjection.d.ts.map +1 -1
  242. package/dist/azure/financialSavingsSurfaceProjection.js +3 -1
  243. package/dist/azure/financialSavingsSurfaceProjection.js.map +1 -1
  244. package/dist/azure/financialSavingsSurfaceProjectionKernel.d.ts +26 -0
  245. package/dist/azure/financialSavingsSurfaceProjectionKernel.d.ts.map +1 -0
  246. package/dist/azure/financialSavingsSurfaceProjectionKernel.js +435 -0
  247. package/dist/azure/financialSavingsSurfaceProjectionKernel.js.map +1 -0
  248. package/dist/azure/financialSavingsSurfaceProjectionValidation.d.ts.map +1 -1
  249. package/dist/azure/financialSavingsSurfaceProjectionValidation.js +199 -13
  250. package/dist/azure/financialSavingsSurfaceProjectionValidation.js.map +1 -1
  251. package/dist/azure/financialScope.d.ts +14 -0
  252. package/dist/azure/financialScope.d.ts.map +1 -1
  253. package/dist/azure/financialScope.js +14 -0
  254. package/dist/azure/financialScope.js.map +1 -1
  255. package/dist/azure/financialScopeBaseline.d.ts +11 -3
  256. package/dist/azure/financialScopeBaseline.d.ts.map +1 -1
  257. package/dist/azure/financialScopeBaseline.js +14 -1
  258. package/dist/azure/financialScopeBaseline.js.map +1 -1
  259. package/dist/azure/financialScopeBaselineIdentity.d.ts.map +1 -1
  260. package/dist/azure/financialScopeBaselineIdentity.js +24 -4
  261. package/dist/azure/financialScopeBaselineIdentity.js.map +1 -1
  262. package/dist/azure/financialScopeBaselineValidation.d.ts.map +1 -1
  263. package/dist/azure/financialScopeBaselineValidation.js +21 -4
  264. package/dist/azure/financialScopeBaselineValidation.js.map +1 -1
  265. package/dist/azure/financialScopeEvidence.d.ts +1 -1
  266. package/dist/azure/financialScopeEvidence.d.ts.map +1 -1
  267. package/dist/azure/governance.d.ts +145 -0
  268. package/dist/azure/governance.d.ts.map +1 -1
  269. package/dist/azure/governance.js +2 -1
  270. package/dist/azure/governance.js.map +1 -1
  271. package/dist/azure/metrics.d.ts +2 -2
  272. package/dist/azure/metrics.d.ts.map +1 -1
  273. package/dist/azure/payloads.d.ts +55 -1
  274. package/dist/azure/payloads.d.ts.map +1 -1
  275. package/dist/azure/prices.d.ts +41 -12
  276. package/dist/azure/prices.d.ts.map +1 -1
  277. package/dist/azure/recommendationLifecycleOverlayValidation.d.ts +5 -0
  278. package/dist/azure/recommendationLifecycleOverlayValidation.d.ts.map +1 -0
  279. package/dist/azure/recommendationLifecycleOverlayValidation.js +82 -0
  280. package/dist/azure/recommendationLifecycleOverlayValidation.js.map +1 -0
  281. package/dist/azure/recommendationState.d.ts +1 -1
  282. package/dist/azure/recommendationState.d.ts.map +1 -1
  283. package/dist/azure/recommendations.d.ts +141 -5
  284. package/dist/azure/recommendations.d.ts.map +1 -1
  285. package/dist/azure/recommendations.js +3 -1
  286. package/dist/azure/recommendations.js.map +1 -1
  287. package/dist/azure/relationships.d.ts +1 -1
  288. package/dist/azure/relationships.d.ts.map +1 -1
  289. package/dist/azure/reportDailySpend.d.ts +48 -0
  290. package/dist/azure/reportDailySpend.d.ts.map +1 -0
  291. package/dist/azure/reportDailySpend.js +6 -0
  292. package/dist/azure/reportDailySpend.js.map +1 -0
  293. package/dist/azure/reportDailySpendValidation.d.ts +3 -0
  294. package/dist/azure/reportDailySpendValidation.d.ts.map +1 -0
  295. package/dist/azure/reportDailySpendValidation.js +72 -0
  296. package/dist/azure/reportDailySpendValidation.js.map +1 -0
  297. package/dist/azure/reportEvidence.d.ts +615 -0
  298. package/dist/azure/reportEvidence.d.ts.map +1 -0
  299. package/dist/azure/reportEvidence.js +25 -0
  300. package/dist/azure/reportEvidence.js.map +1 -0
  301. package/dist/azure/reportEvidenceCatalogueValidation.d.ts +5 -0
  302. package/dist/azure/reportEvidenceCatalogueValidation.d.ts.map +1 -0
  303. package/dist/azure/reportEvidenceCatalogueValidation.js +109 -0
  304. package/dist/azure/reportEvidenceCatalogueValidation.js.map +1 -0
  305. package/dist/azure/reportEvidenceValidation.d.ts +7 -0
  306. package/dist/azure/reportEvidenceValidation.d.ts.map +1 -0
  307. package/dist/azure/reportEvidenceValidation.js +421 -0
  308. package/dist/azure/reportEvidenceValidation.js.map +1 -0
  309. package/dist/azure/reportEvidenceValidationHelpers.d.ts +27 -0
  310. package/dist/azure/reportEvidenceValidationHelpers.d.ts.map +1 -0
  311. package/dist/azure/reportEvidenceValidationHelpers.js +134 -0
  312. package/dist/azure/reportEvidenceValidationHelpers.js.map +1 -0
  313. package/dist/azure/reportSavingsContributionValidation.d.ts +5 -0
  314. package/dist/azure/reportSavingsContributionValidation.d.ts.map +1 -0
  315. package/dist/azure/reportSavingsContributionValidation.js +37 -0
  316. package/dist/azure/reportSavingsContributionValidation.js.map +1 -0
  317. package/dist/azure/reportSpend.d.ts +87 -0
  318. package/dist/azure/reportSpend.d.ts.map +1 -0
  319. package/dist/azure/reportSpend.js +5 -0
  320. package/dist/azure/reportSpend.js.map +1 -0
  321. package/dist/azure/reportSpendValidation.d.ts +7 -0
  322. package/dist/azure/reportSpendValidation.d.ts.map +1 -0
  323. package/dist/azure/reportSpendValidation.js +197 -0
  324. package/dist/azure/reportSpendValidation.js.map +1 -0
  325. package/dist/azure/reportSpendValidationHelpers.d.ts +7 -0
  326. package/dist/azure/reportSpendValidationHelpers.d.ts.map +1 -0
  327. package/dist/azure/reportSpendValidationHelpers.js +31 -0
  328. package/dist/azure/reportSpendValidationHelpers.js.map +1 -0
  329. package/dist/azure/reports.d.ts +32 -10
  330. package/dist/azure/reports.d.ts.map +1 -1
  331. package/dist/azure/reports.js.map +1 -1
  332. package/dist/azure/resources.d.ts +24 -12
  333. package/dist/azure/resources.d.ts.map +1 -1
  334. package/dist/azure/serviceRetirement.d.ts +33 -2
  335. package/dist/azure/serviceRetirement.d.ts.map +1 -1
  336. package/dist/azure/storage-inventory.d.ts +44 -0
  337. package/dist/azure/storage-inventory.d.ts.map +1 -1
  338. package/dist/azure/subscriptions.d.ts +57 -11
  339. package/dist/azure/subscriptions.d.ts.map +1 -1
  340. package/dist/azure/subscriptions.js +35 -0
  341. package/dist/azure/subscriptions.js.map +1 -1
  342. package/dist/azure/views.d.ts +86 -22
  343. package/dist/azure/views.d.ts.map +1 -1
  344. package/dist/azure/views.js +8 -1
  345. package/dist/azure/views.js.map +1 -1
  346. package/dist/azure/vmPatchManagement.d.ts +109 -0
  347. package/dist/azure/vmPatchManagement.d.ts.map +1 -0
  348. package/dist/azure/vmPatchManagement.js +7 -0
  349. package/dist/azure/vmPatchManagement.js.map +1 -0
  350. package/dist/common/provider.d.ts +53 -0
  351. package/dist/common/provider.d.ts.map +1 -1
  352. package/dist/common/provider.js.map +1 -1
  353. package/dist/company/company.d.ts +1 -0
  354. package/dist/company/company.d.ts.map +1 -1
  355. package/dist/environment/canonicalization.d.ts +12 -0
  356. package/dist/environment/canonicalization.d.ts.map +1 -0
  357. package/dist/environment/canonicalization.js +40 -0
  358. package/dist/environment/canonicalization.js.map +1 -0
  359. package/dist/environment/contracts.d.ts +472 -0
  360. package/dist/environment/contracts.d.ts.map +1 -0
  361. package/dist/environment/contracts.js +73 -0
  362. package/dist/environment/contracts.js.map +1 -0
  363. package/dist/environment/index.d.ts +6 -0
  364. package/dist/environment/index.d.ts.map +1 -0
  365. package/dist/environment/index.js +22 -0
  366. package/dist/environment/index.js.map +1 -0
  367. package/dist/environment/internal.d.ts +21 -0
  368. package/dist/environment/internal.d.ts.map +1 -0
  369. package/dist/environment/internal.js +113 -0
  370. package/dist/environment/internal.js.map +1 -0
  371. package/dist/environment/references.d.ts +24 -0
  372. package/dist/environment/references.d.ts.map +1 -0
  373. package/dist/environment/references.js +243 -0
  374. package/dist/environment/references.js.map +1 -0
  375. package/dist/environment/tenant.d.ts +128 -0
  376. package/dist/environment/tenant.d.ts.map +1 -0
  377. package/dist/environment/tenant.js +203 -0
  378. package/dist/environment/tenant.js.map +1 -0
  379. package/dist/environment/validation.d.ts +34 -0
  380. package/dist/environment/validation.d.ts.map +1 -0
  381. package/dist/environment/validation.js +655 -0
  382. package/dist/environment/validation.js.map +1 -0
  383. package/dist/esm/accounts/accounts.js +1 -0
  384. package/dist/esm/accounts/azureManualOnboarding.js +8 -0
  385. package/dist/esm/accounts/azureSpSetup.js +14 -1
  386. package/dist/esm/accounts/azureSpSetupDurable.js +27 -1
  387. package/dist/esm/accounts/index.js +1 -0
  388. package/dist/esm/ai/conversationHistory.js +6 -0
  389. package/dist/esm/ai/grounding.js +80 -0
  390. package/dist/esm/ai/index.js +10 -1
  391. package/dist/esm/ai/workspaceArtifacts.js +158 -0
  392. package/dist/esm/aws/commitments-planning.js +5 -0
  393. package/dist/esm/aws/estates.js +7 -1
  394. package/dist/esm/aws/index.js +5 -0
  395. package/dist/esm/aws/organizationCommitments.js +48 -0
  396. package/dist/esm/aws/organizationCommitmentsApiValidation.js +220 -0
  397. package/dist/esm/aws/organizationCommitmentsValidation.js +224 -0
  398. package/dist/esm/aws/portalOrganizationCommitmentsPlanningPublicArtifactValidation.js +402 -0
  399. package/dist/esm/aws/portalOrganizationCommitmentsPlanningPublicArtifacts.js +2 -0
  400. package/dist/esm/aws/requests.js +1 -1
  401. package/dist/esm/azure/activityLogAnalysis.js +64 -0
  402. package/dist/esm/azure/activityLogAnalysisPublicValidation.js +360 -0
  403. package/dist/esm/azure/activityLogAnalysisPublicValidationHelpers.js +172 -0
  404. package/dist/esm/azure/activityLogAnalysisValidation.js +365 -0
  405. package/dist/esm/azure/billingPlots.js +45 -4
  406. package/dist/esm/azure/common.js +28 -1
  407. package/dist/esm/azure/costComposition.js +80 -0
  408. package/dist/esm/azure/financialAnalyticsDelivery.js +5 -0
  409. package/dist/esm/azure/financialAnalyticsDeliveryValidation.js +184 -11
  410. package/dist/esm/azure/financialAnalyticsDisplayKernel.js +139 -0
  411. package/dist/esm/azure/financialAnalyticsValidation.js +101 -19
  412. package/dist/esm/azure/financialAuthorityProjectionKernel.js +263 -0
  413. package/dist/esm/azure/financialAuthorityViewValidation.js +271 -1
  414. package/dist/esm/azure/financialChargeComposition.js +36 -0
  415. package/dist/esm/azure/financialChargeCompositionKernel.js +48 -0
  416. package/dist/esm/azure/financialChargeCompositionValidation.js +155 -0
  417. package/dist/esm/azure/financialChargePolicy.js +473 -0
  418. package/dist/esm/azure/financialCurrentSpendSurfaceProjection.js +2 -0
  419. package/dist/esm/azure/financialCurrentSpendSurfaceProjectionValidation.js +184 -0
  420. package/dist/esm/azure/financialDataflowKernel.js +164 -0
  421. package/dist/esm/azure/financialDataflowValidation.js +199 -29
  422. package/dist/esm/azure/financialEvidenceAssessmentValidation.js +7 -0
  423. package/dist/esm/azure/financialEvidenceCoverage.js +106 -0
  424. package/dist/esm/azure/financialPolicyDelivery.js +4 -0
  425. package/dist/esm/azure/financialPolicyDeliveryValidation.js +227 -7
  426. package/dist/esm/azure/financialPolicyKernel.js +225 -0
  427. package/dist/esm/azure/financialPolicyValidation.js +110 -16
  428. package/dist/esm/azure/financialProjectionValidation.js +43 -3
  429. package/dist/esm/azure/financialResourceSurfaceProjection.js +2 -0
  430. package/dist/esm/azure/financialResourceSurfaceProjectionValidation.js +243 -0
  431. package/dist/esm/azure/financialSavingsAuthority.js +1 -0
  432. package/dist/esm/azure/financialSavingsAuthorityValidation.js +186 -2
  433. package/dist/esm/azure/financialSavingsChargePolicyKernel.js +29 -0
  434. package/dist/esm/azure/financialSavingsCoordinateValidation.js +98 -19
  435. package/dist/esm/azure/financialSavingsPercentageKernel.js +44 -0
  436. package/dist/esm/azure/financialSavingsSurfaceProjection.js +2 -0
  437. package/dist/esm/azure/financialSavingsSurfaceProjectionKernel.js +427 -0
  438. package/dist/esm/azure/financialSavingsSurfaceProjectionValidation.js +199 -13
  439. package/dist/esm/azure/financialScope.js +14 -0
  440. package/dist/esm/azure/financialScopeBaseline.js +12 -0
  441. package/dist/esm/azure/financialScopeBaselineIdentity.js +24 -4
  442. package/dist/esm/azure/financialScopeBaselineValidation.js +21 -4
  443. package/dist/esm/azure/governance.js +1 -0
  444. package/dist/esm/azure/recommendationLifecycleOverlayValidation.js +75 -0
  445. package/dist/esm/azure/recommendations.js +2 -0
  446. package/dist/esm/azure/reportDailySpend.js +2 -0
  447. package/dist/esm/azure/reportDailySpendValidation.js +67 -0
  448. package/dist/esm/azure/reportEvidence.js +21 -0
  449. package/dist/esm/azure/reportEvidenceCatalogueValidation.js +103 -0
  450. package/dist/esm/azure/reportEvidenceValidation.js +413 -0
  451. package/dist/esm/azure/reportEvidenceValidationHelpers.js +106 -0
  452. package/dist/esm/azure/reportSavingsContributionValidation.js +30 -0
  453. package/dist/esm/azure/reportSpend.js +1 -0
  454. package/dist/esm/azure/reportSpendValidation.js +189 -0
  455. package/dist/esm/azure/reportSpendValidationHelpers.js +22 -0
  456. package/dist/esm/azure/subscriptions.js +33 -1
  457. package/dist/esm/azure/views.js +8 -1
  458. package/dist/esm/azure/vmPatchManagement.js +3 -0
  459. package/dist/esm/entries/commitments-planning.js +2 -2
  460. package/dist/esm/entries/environment.js +3 -0
  461. package/dist/esm/environment/canonicalization.js +34 -0
  462. package/dist/esm/environment/contracts.js +69 -0
  463. package/dist/esm/environment/index.js +5 -0
  464. package/dist/esm/environment/internal.js +97 -0
  465. package/dist/esm/environment/references.js +230 -0
  466. package/dist/esm/environment/tenant.js +190 -0
  467. package/dist/esm/environment/validation.js +635 -0
  468. package/dist/esm/identity/index.js +1 -0
  469. package/dist/esm/identity/microsoftSignInAdminConsent.js +1 -0
  470. package/dist/esm/index.js +13 -0
  471. package/dist/esm/index.vite.js +11 -0
  472. package/dist/esm/scheduler/bastionSchedule.js +1 -0
  473. package/dist/esm/scheduler/bastionScheduleProfile.js +206 -0
  474. package/dist/esm/scheduler/bastionScheduleValidation.js +401 -0
  475. package/dist/esm/scheduler/index.js +3 -0
  476. package/dist/events/alertDefinitionRun.d.ts +4 -0
  477. package/dist/events/alertDefinitionRun.d.ts.map +1 -1
  478. package/dist/events/baseAlert.d.ts +1 -0
  479. package/dist/events/baseAlert.d.ts.map +1 -1
  480. package/dist/events/cost.d.ts +4 -0
  481. package/dist/events/cost.d.ts.map +1 -1
  482. package/dist/events/quickAlerts.d.ts +13 -4
  483. package/dist/events/quickAlerts.d.ts.map +1 -1
  484. package/dist/events/quickAlerts.js.map +1 -1
  485. package/dist/features-and-permissions/access.d.ts +79 -0
  486. package/dist/features-and-permissions/access.d.ts.map +1 -1
  487. package/dist/identity/index.d.ts +1 -0
  488. package/dist/identity/index.d.ts.map +1 -1
  489. package/dist/identity/index.js +1 -0
  490. package/dist/identity/index.js.map +1 -1
  491. package/dist/identity/microsoftSignInAdminConsent.d.ts +59 -0
  492. package/dist/identity/microsoftSignInAdminConsent.d.ts.map +1 -0
  493. package/dist/identity/microsoftSignInAdminConsent.js +3 -0
  494. package/dist/identity/microsoftSignInAdminConsent.js.map +1 -0
  495. package/dist/index.d.ts +13 -0
  496. package/dist/index.d.ts.map +1 -1
  497. package/dist/index.js +19 -0
  498. package/dist/index.js.map +1 -1
  499. package/dist/index.vite.d.ts +11 -0
  500. package/dist/index.vite.d.ts.map +1 -1
  501. package/dist/index.vite.js +15 -0
  502. package/dist/index.vite.js.map +1 -1
  503. package/dist/portfolio/portfolioOperations.d.ts +1 -1
  504. package/dist/portfolio/portfolioOperations.d.ts.map +1 -1
  505. package/dist/scheduler/bastionSchedule.d.ts +113 -0
  506. package/dist/scheduler/bastionSchedule.d.ts.map +1 -0
  507. package/dist/scheduler/bastionSchedule.js +3 -0
  508. package/dist/scheduler/bastionSchedule.js.map +1 -0
  509. package/dist/scheduler/bastionScheduleProfile.d.ts +24 -0
  510. package/dist/scheduler/bastionScheduleProfile.d.ts.map +1 -0
  511. package/dist/scheduler/bastionScheduleProfile.js +210 -0
  512. package/dist/scheduler/bastionScheduleProfile.js.map +1 -0
  513. package/dist/scheduler/bastionScheduleValidation.d.ts +10 -0
  514. package/dist/scheduler/bastionScheduleValidation.d.ts.map +1 -0
  515. package/dist/scheduler/bastionScheduleValidation.js +412 -0
  516. package/dist/scheduler/bastionScheduleValidation.js.map +1 -0
  517. package/dist/scheduler/index.d.ts +3 -0
  518. package/dist/scheduler/index.d.ts.map +1 -1
  519. package/dist/scheduler/index.js +3 -0
  520. package/dist/scheduler/index.js.map +1 -1
  521. package/dist/scheduler/scheduler.d.ts +14 -10
  522. package/dist/scheduler/scheduler.d.ts.map +1 -1
  523. package/package.json +20 -3
@@ -2,7 +2,8 @@ import { sha256Utf8 } from '../common/sha256.js';
2
2
  import { FINANCIAL_SAVINGS_AUTHORITY_CONTRACT_VERSION_V1, FINANCIAL_SAVINGS_AUTHORITY_SCHEMA_VERSION_V1, } from './financialSavingsAuthority.js';
3
3
  import { validateFinancialEligibilityAssessmentV1, validateFinancialEligibilityBaselineV1, } from './financialEligibilityAssessmentValidation.js';
4
4
  import { validateFinancialSavingsCoordinateEnvelopeV1 } from './financialSavingsCoordinateValidation.js';
5
- import { canonicalizeFinancialSavingsJsonValue, hasExactFinancialSavingsFields, isFinancialSavingsHash, isFinancialSavingsRecord, } from './financialSavingsAuthorityValidationPrimitives.js';
5
+ import { isFinancialChargeInclusionPolicyRefV1 } from './financialChargeCompositionValidation.js';
6
+ import { canonicalizeFinancialSavingsJsonValue, hasExactFinancialSavingsFields, haveSameFinancialSavingsSet, isFinancialSavingsHash, isFinancialSavingsIdentity, isFinancialSavingsIsoInstant, isFinancialSavingsMinorUnits, isFinancialSavingsRecord, sumFinancialSavingsMinorUnits, } from './financialSavingsAuthorityValidationPrimitives.js';
6
7
  export { canonicalizeFinancialEligibilityAssessmentIdentityV1, createFinancialEligibilityAssessmentIdV1, } from './financialEligibilityAssessmentValidation.js';
7
8
  export { canonicalizeFinancialSavingsActivationIdentityV1, canonicalizeFinancialSavingsAllocationIdentityV1, canonicalizeFinancialSavingsDenominatorIdentityV1, createFinancialSavingsActivationIdV1, createFinancialSavingsAllocationIdV1, createFinancialSavingsDenominatorIdV1, } from './financialSavingsCoordinateValidation.js';
8
9
  export const canonicalizeFinancialSavingsAuthorityIdentityV1 = (value) => JSON.stringify(canonicalizeFinancialSavingsJsonValue({
@@ -28,7 +29,7 @@ export const canonicalizeFinancialSavingsAuthorityIdentityV1 = (value) => JSON.s
28
29
  .map(allocation => ({
29
30
  ...allocation,
30
31
  billableComponentIds: [...allocation.billableComponentIds].sort(),
31
- eligibility: allocation.eligibility.kind === 'not-applicable'
32
+ eligibility: allocation.eligibility.kind !== 'mapped'
32
33
  ? allocation.eligibility
33
34
  : {
34
35
  ...allocation.eligibility,
@@ -39,6 +40,9 @@ export const canonicalizeFinancialSavingsAuthorityIdentityV1 = (value) => JSON.s
39
40
  resourceContributions: [...coordinate.resourceContributions]
40
41
  .sort((left, right) => left.ownerScopeId.localeCompare(right.ownerScopeId))
41
42
  .map(contribution => ({ ...contribution, allocationIds: [...contribution.allocationIds].sort() })),
43
+ recommendationContributions: [...coordinate.recommendationContributions]
44
+ .sort((left, right) => `${left.ownerScopeId}\u0000${left.recommendationId}`.localeCompare(`${right.ownerScopeId}\u0000${right.recommendationId}`))
45
+ .map(contribution => ({ ...contribution, allocationIds: [...contribution.allocationIds].sort() })),
42
46
  aggregate: { ...coordinate.aggregate, allocationIds: [...coordinate.aggregate.allocationIds].sort() },
43
47
  }),
44
48
  }));
@@ -112,3 +116,183 @@ export const isFinancialSavingsAuthorityBoundToFinancialAuthorityV1 = (value, au
112
116
  const { savingsAuthorityId: _savingsAuthorityId, ...identity } = savingsAuthority;
113
117
  return savingsAuthority.savingsAuthorityId === createFinancialSavingsAuthorityIdV1(identity);
114
118
  };
119
+ const RESOURCE_PROJECTION_UNAVAILABLE_REASONS = new Set([
120
+ 'scenario-coverage-unproven',
121
+ 'unmigrated-scenario-producer',
122
+ 'projection-unavailable',
123
+ 'activation-unavailable',
124
+ 'allocation-unavailable',
125
+ ]);
126
+ const RESOURCE_PROJECTION_CURRENCY = /^[A-Z]{3}$/;
127
+ const normalizeResourceScope = (value) => value.trim().toLowerCase().replace(/\/+$/, '');
128
+ const isResourceContribution = (value, scopeId) => isFinancialSavingsRecord(value) &&
129
+ hasExactFinancialSavingsFields(value, ['ownerScopeId', 'allocationIds', 'savingsMinorUnits']) &&
130
+ isFinancialSavingsIdentity(value.ownerScopeId) &&
131
+ normalizeResourceScope(value.ownerScopeId) === scopeId &&
132
+ Array.isArray(value.allocationIds) &&
133
+ value.allocationIds.length > 0 &&
134
+ value.allocationIds.length <= 20000 &&
135
+ value.allocationIds.every(isFinancialSavingsHash) &&
136
+ new Set(value.allocationIds).size === value.allocationIds.length &&
137
+ isFinancialSavingsMinorUnits(value.savingsMinorUnits);
138
+ const isRecommendationContribution = (value, scopeId) => isFinancialSavingsRecord(value) &&
139
+ hasExactFinancialSavingsFields(value, ['ownerScopeId', 'recommendationId', 'allocationIds', 'savingsMinorUnits']) &&
140
+ isFinancialSavingsIdentity(value.ownerScopeId) &&
141
+ normalizeResourceScope(value.ownerScopeId) === scopeId &&
142
+ isFinancialSavingsIdentity(value.recommendationId) &&
143
+ Array.isArray(value.allocationIds) &&
144
+ value.allocationIds.length > 0 &&
145
+ value.allocationIds.length <= 20000 &&
146
+ value.allocationIds.every(isFinancialSavingsHash) &&
147
+ new Set(value.allocationIds).size === value.allocationIds.length &&
148
+ isFinancialSavingsMinorUnits(value.savingsMinorUnits);
149
+ const isSavingsResourceCoordinate = (value, scopeId) => {
150
+ if (!isFinancialSavingsRecord(value) || !isFinancialSavingsHash(value.coordinateId))
151
+ return false;
152
+ if (value.status === 'unavailable') {
153
+ return (hasExactFinancialSavingsFields(value, ['status', 'coordinateId', 'unavailableReason'], ['currentAggregateBaselineId', 'chargeInclusionPolicyRef']) &&
154
+ (value.currentAggregateBaselineId === undefined || isFinancialSavingsHash(value.currentAggregateBaselineId)) &&
155
+ (value.chargeInclusionPolicyRef === undefined || isFinancialChargeInclusionPolicyRefV1(value.chargeInclusionPolicyRef)) &&
156
+ typeof value.unavailableReason === 'string' &&
157
+ RESOURCE_PROJECTION_UNAVAILABLE_REASONS.has(value.unavailableReason));
158
+ }
159
+ const partial = value.status === 'partial';
160
+ if (value.status !== 'available' &&
161
+ !partial)
162
+ return false;
163
+ if (!hasExactFinancialSavingsFields(value, [
164
+ 'status',
165
+ 'coordinateId',
166
+ 'currentAggregateBaselineId',
167
+ 'accountingCurrencyCode',
168
+ 'minorUnitScale',
169
+ 'roundingMode',
170
+ 'recommendationContributions',
171
+ ...(partial ? ['unavailableScenarioIds'] : []),
172
+ ], [
173
+ 'resourceContribution',
174
+ 'chargeInclusionPolicyRef',
175
+ 'displayMemberResourceContributions',
176
+ 'displayMemberRecommendationContributions',
177
+ ]) ||
178
+ !isFinancialSavingsHash(value.currentAggregateBaselineId) ||
179
+ (value.chargeInclusionPolicyRef !== undefined && !isFinancialChargeInclusionPolicyRefV1(value.chargeInclusionPolicyRef)) ||
180
+ typeof value.accountingCurrencyCode !== 'string' ||
181
+ !RESOURCE_PROJECTION_CURRENCY.test(value.accountingCurrencyCode) ||
182
+ !Number.isSafeInteger(value.minorUnitScale) ||
183
+ Number(value.minorUnitScale) < 0 ||
184
+ Number(value.minorUnitScale) > 6 ||
185
+ value.roundingMode !== 'half-away-from-zero' ||
186
+ (value.resourceContribution !== undefined && !isResourceContribution(value.resourceContribution, scopeId)) ||
187
+ !Array.isArray(value.recommendationContributions) ||
188
+ value.recommendationContributions.length > 20000 ||
189
+ !value.recommendationContributions.every(contribution => isRecommendationContribution(contribution, scopeId)) ||
190
+ (value.displayMemberResourceContributions !== undefined &&
191
+ (!Array.isArray(value.displayMemberResourceContributions) ||
192
+ value.displayMemberResourceContributions.length === 0 ||
193
+ value.displayMemberResourceContributions.length > 20000 ||
194
+ !value.displayMemberResourceContributions.every(contribution => isFinancialSavingsRecord(contribution) &&
195
+ isResourceContribution(contribution, normalizeResourceScope(String(contribution.ownerScopeId))) &&
196
+ normalizeResourceScope(String(contribution.ownerScopeId)) !== scopeId))) ||
197
+ (value.displayMemberRecommendationContributions !== undefined &&
198
+ (!Array.isArray(value.displayMemberRecommendationContributions) ||
199
+ value.displayMemberRecommendationContributions.length === 0 ||
200
+ value.displayMemberRecommendationContributions.length > 20000 ||
201
+ !value.displayMemberRecommendationContributions.every(contribution => isFinancialSavingsRecord(contribution) &&
202
+ isRecommendationContribution(contribution, normalizeResourceScope(String(contribution.ownerScopeId))) &&
203
+ normalizeResourceScope(String(contribution.ownerScopeId)) !== scopeId))) ||
204
+ (partial &&
205
+ (!Array.isArray(value.unavailableScenarioIds) ||
206
+ value.unavailableScenarioIds.length === 0 ||
207
+ value.unavailableScenarioIds.length > 20000 ||
208
+ !value.unavailableScenarioIds.every(isFinancialSavingsIdentity) ||
209
+ new Set(value.unavailableScenarioIds).size !== value.unavailableScenarioIds.length)))
210
+ return false;
211
+ const recommendationIds = value.recommendationContributions.map(contribution => contribution.recommendationId);
212
+ const allocationIds = value.recommendationContributions.flatMap(contribution => contribution.allocationIds);
213
+ const contributionSum = sumFinancialSavingsMinorUnits(value.recommendationContributions.map(contribution => contribution.savingsMinorUnits));
214
+ const resourceContribution = value.resourceContribution;
215
+ const primaryValid = new Set(recommendationIds).size === recommendationIds.length &&
216
+ new Set(allocationIds).size === allocationIds.length &&
217
+ contributionSum !== undefined &&
218
+ (resourceContribution === undefined
219
+ ? allocationIds.length === 0 && contributionSum === 0
220
+ : haveSameFinancialSavingsSet(allocationIds, resourceContribution.allocationIds) &&
221
+ contributionSum === resourceContribution.savingsMinorUnits);
222
+ if (!primaryValid)
223
+ return false;
224
+ const displayResourceContributions = (value.displayMemberResourceContributions ?? []);
225
+ const displayRecommendationContributions = (value.displayMemberRecommendationContributions ?? []);
226
+ const displayResourceByOwner = new Map(displayResourceContributions.map(contribution => [normalizeResourceScope(contribution.ownerScopeId), contribution]));
227
+ if (displayResourceByOwner.size !== displayResourceContributions.length)
228
+ return false;
229
+ const displayRecommendationKeys = displayRecommendationContributions.map(contribution => `${normalizeResourceScope(contribution.ownerScopeId)}\u0000${contribution.recommendationId}`);
230
+ if (new Set(displayRecommendationKeys).size !== displayRecommendationKeys.length)
231
+ return false;
232
+ const displayAllocationIds = displayRecommendationContributions.flatMap(contribution => contribution.allocationIds);
233
+ if (new Set(displayAllocationIds).size !== displayAllocationIds.length ||
234
+ displayAllocationIds.some(allocationId => allocationIds.includes(allocationId)))
235
+ return false;
236
+ for (const [ownerScopeId, contribution] of displayResourceByOwner) {
237
+ const recommendations = displayRecommendationContributions.filter(candidate => normalizeResourceScope(candidate.ownerScopeId) === ownerScopeId);
238
+ const recommendationAllocationIds = recommendations.flatMap(candidate => candidate.allocationIds);
239
+ const recommendationSavings = sumFinancialSavingsMinorUnits(recommendations.map(candidate => candidate.savingsMinorUnits));
240
+ if (recommendationSavings === undefined ||
241
+ recommendationSavings !== contribution.savingsMinorUnits ||
242
+ !haveSameFinancialSavingsSet(recommendationAllocationIds, contribution.allocationIds))
243
+ return false;
244
+ }
245
+ return displayRecommendationContributions.every(contribution => displayResourceByOwner.has(normalizeResourceScope(contribution.ownerScopeId)));
246
+ };
247
+ /** Strict structural and arithmetic validation for one bounded resource savings projection. */
248
+ export const isFinancialSavingsResourceProjectionV1 = (value) => {
249
+ if (!isFinancialSavingsRecord(value) ||
250
+ !hasExactFinancialSavingsFields(value, [
251
+ 'contractVersion',
252
+ 'savingsAuthorityId',
253
+ 'financialAuthorityId',
254
+ 'artifactGeneration',
255
+ 'scopeId',
256
+ 'coordinates',
257
+ ]) ||
258
+ value.contractVersion !== 'financial-savings-resource-projection/v1' ||
259
+ !isFinancialSavingsHash(value.savingsAuthorityId) ||
260
+ !isFinancialSavingsHash(value.financialAuthorityId) ||
261
+ !isFinancialSavingsRecord(value.artifactGeneration) ||
262
+ !hasExactFinancialSavingsFields(value.artifactGeneration, ['runId', 'generatedAt']) ||
263
+ !isFinancialSavingsIdentity(value.artifactGeneration.runId) ||
264
+ !isFinancialSavingsIsoInstant(value.artifactGeneration.generatedAt) ||
265
+ !isFinancialSavingsIdentity(value.scopeId) ||
266
+ value.scopeId !== normalizeResourceScope(value.scopeId) ||
267
+ !Array.isArray(value.coordinates) ||
268
+ value.coordinates.length === 0 ||
269
+ value.coordinates.length > 128)
270
+ return false;
271
+ const projection = value;
272
+ return (projection.coordinates.every(coordinate => isSavingsResourceCoordinate(coordinate, projection.scopeId)) &&
273
+ new Set(projection.coordinates.map(coordinate => coordinate.coordinateId)).size === projection.coordinates.length);
274
+ };
275
+ /** Verifies that the bounded savings projection is the exact companion of one bounded Financial Authority projection. */
276
+ export const isFinancialSavingsResourceProjectionBoundToFinancialProjectionV1 = (value, financialProjection) => {
277
+ if (!isFinancialSavingsResourceProjectionV1(value))
278
+ return false;
279
+ const financialCoordinateIds = financialProjection.coordinates.map(coordinate => coordinate.coordinateId);
280
+ const displayOwnerScopeIdsByCoordinate = new Map(financialProjection.coordinates.map(coordinate => [
281
+ coordinate.coordinateId,
282
+ new Set((coordinate.displayMemberBaselines ?? []).map(baseline => normalizeResourceScope(baseline.scopeId))),
283
+ ]));
284
+ return (value.financialAuthorityId === financialProjection.authorityId &&
285
+ normalizeResourceScope(value.scopeId) === normalizeResourceScope(financialProjection.scopeId) &&
286
+ value.artifactGeneration.runId === financialProjection.artifactGeneration.runId &&
287
+ value.artifactGeneration.generatedAt === financialProjection.artifactGeneration.generatedAt &&
288
+ haveSameFinancialSavingsSet(value.coordinates.map(coordinate => coordinate.coordinateId), financialCoordinateIds) &&
289
+ value.coordinates.every(coordinate => {
290
+ if (coordinate.status === 'unavailable')
291
+ return true;
292
+ const allowedDisplayOwners = displayOwnerScopeIdsByCoordinate.get(coordinate.coordinateId);
293
+ if (!allowedDisplayOwners)
294
+ return false;
295
+ return ((coordinate.displayMemberResourceContributions ?? []).every(contribution => allowedDisplayOwners.has(normalizeResourceScope(contribution.ownerScopeId))) &&
296
+ (coordinate.displayMemberRecommendationContributions ?? []).every(contribution => allowedDisplayOwners.has(normalizeResourceScope(contribution.ownerScopeId))));
297
+ }));
298
+ };
@@ -0,0 +1,29 @@
1
+ import { resolveFinancialChargeInclusionPolicyV1 } from './financialChargeComposition.js';
2
+ /**
3
+ * Classifies a savings allocation against one registered charge policy without
4
+ * splitting its money. A mixed or unknown affected-component set is
5
+ * unavailable because the allocation carries one reconciled delta, not a
6
+ * per-component delta that a consumer could apportion safely.
7
+ */
8
+ export const classifyFinancialSavingsAllocationForPolicyV1 = (chargeCompositionByBaselineId, allocation, policyRef) => {
9
+ const policy = resolveFinancialChargeInclusionPolicyV1(policyRef);
10
+ if (!policy || allocation.billableComponentIds.length === 0)
11
+ return 'unavailable';
12
+ const composition = chargeCompositionByBaselineId.get(allocation.baselineId);
13
+ if (!composition)
14
+ return 'unavailable';
15
+ const sourceByComponentId = new Map(composition.buckets.flatMap(bucket => bucket.componentIds.map(componentId => [componentId, bucket.chargeSource])));
16
+ const dispositions = new Set();
17
+ for (const componentId of allocation.billableComponentIds) {
18
+ const source = sourceByComponentId.get(componentId);
19
+ if (!source || policy.withholdSources.includes(source))
20
+ return 'unavailable';
21
+ if (policy.includeSources.includes(source))
22
+ dispositions.add('included');
23
+ else if (policy.excludeSources.includes(source))
24
+ dispositions.add('excluded');
25
+ else
26
+ return 'unavailable';
27
+ }
28
+ return dispositions.size === 1 ? [...dispositions][0] : 'unavailable';
29
+ };
@@ -23,8 +23,17 @@ const ACTIVATION_REASONS = new Set([
23
23
  'lifecycle-conflict',
24
24
  'unrecognized-lifecycle',
25
25
  'generation-mismatch',
26
+ 'projection-unavailable',
27
+ 'eligibility-unavailable',
28
+ ]);
29
+ const UNAVAILABLE_ACTIVATION_REASONS = new Set([
30
+ 'lifecycle-stale',
31
+ 'lifecycle-unavailable',
32
+ 'lifecycle-conflict',
33
+ 'generation-mismatch',
34
+ 'projection-unavailable',
35
+ 'eligibility-unavailable',
26
36
  ]);
27
- const UNAVAILABLE_ACTIVATION_REASONS = new Set(['lifecycle-stale', 'lifecycle-unavailable', 'lifecycle-conflict', 'generation-mismatch']);
28
37
  export const canonicalizeFinancialSavingsDenominatorIdentityV1 = (value) => JSON.stringify(canonicalizeFinancialSavingsJsonValue({
29
38
  kind: value.kind,
30
39
  baselineId: value.baselineId,
@@ -35,7 +44,8 @@ export const canonicalizeFinancialSavingsDenominatorIdentityV1 = (value) => JSON
35
44
  export const createFinancialSavingsDenominatorIdV1 = (value) => `sha256:${sha256Utf8(canonicalizeFinancialSavingsDenominatorIdentityV1(value))}`;
36
45
  export const canonicalizeFinancialSavingsActivationIdentityV1 = (value) => JSON.stringify(canonicalizeFinancialSavingsJsonValue({
37
46
  recommendationId: value.recommendationId,
38
- projectionId: value.projectionId,
47
+ scenarioId: value.scenarioId,
48
+ ...(value.projectionId === undefined ? {} : { projectionId: value.projectionId }),
39
49
  lifecycleState: value.lifecycleState,
40
50
  lifecycleVersion: value.lifecycleVersion,
41
51
  lifecycleEvidenceRefId: value.lifecycleEvidenceRefId,
@@ -49,10 +59,11 @@ export const canonicalizeFinancialSavingsAllocationIdentityV1 = (value) => JSON.
49
59
  ownerScopeId: value.ownerScopeId,
50
60
  billableComponentIds: [...value.billableComponentIds].sort(),
51
61
  recommendationId: value.recommendationId,
62
+ scenarioId: value.scenarioId,
52
63
  baselineId: value.baselineId,
53
64
  projectionId: value.projectionId,
54
65
  denominatorId: value.denominatorId,
55
- eligibility: value.eligibility.kind === 'not-applicable'
66
+ eligibility: value.eligibility.kind !== 'mapped'
56
67
  ? value.eligibility
57
68
  : {
58
69
  ...value.eligibility,
@@ -98,10 +109,23 @@ const isActivationDecision = (state, result, reason) => {
98
109
  return UNAVAILABLE_ACTIVATION_REASONS.has(reason);
99
110
  };
100
111
  const isEligibility = (value) => {
101
- if (!isFinancialSavingsRecord(value) || (value.kind !== 'not-applicable' && value.kind !== 'mapped'))
112
+ if (!isFinancialSavingsRecord(value) || !['not-applicable', 'unavailable', 'mapped'].includes(String(value.kind)))
102
113
  return false;
103
114
  if (value.kind === 'not-applicable')
104
115
  return Object.keys(value).length === 1;
116
+ if (value.kind === 'unavailable') {
117
+ return (Object.keys(value).length === 2 &&
118
+ typeof value.reason === 'string' &&
119
+ [
120
+ 'rule-evidence-unavailable',
121
+ 'eligibility-baseline-unavailable',
122
+ 'eligible-components-unavailable',
123
+ 'denominator-unavailable',
124
+ 'current-baseline-mapping-unavailable',
125
+ 'currency-conflict',
126
+ 'reconciliation-failure',
127
+ ].includes(value.reason));
128
+ }
105
129
  return (Object.keys(value).length === 5 &&
106
130
  isFinancialSavingsHash(value.eligibilityId) &&
107
131
  isFinancialSavingsHash(value.eligibilityBaselineId) &&
@@ -114,7 +138,7 @@ const isEligibility = (value) => {
114
138
  value.eligibilityComponentIds.every(isFinancialSavingsIdentity) &&
115
139
  new Set(value.eligibilityComponentIds).size === value.eligibilityComponentIds.length);
116
140
  };
117
- const validateAvailableCoordinate = (value, authorityCoordinate, eligibilityById, evidenceById, authorityGeneratedAt, authorityRunId) => {
141
+ const validateComposedCoordinate = (value, authorityCoordinate, eligibilityById, evidenceById, authorityGeneratedAt, authorityRunId) => {
118
142
  if (!hasExactFinancialSavingsFields(value, [
119
143
  'status',
120
144
  'coordinateId',
@@ -126,6 +150,7 @@ const validateAvailableCoordinate = (value, authorityCoordinate, eligibilityById
126
150
  'activations',
127
151
  'allocations',
128
152
  'resourceContributions',
153
+ 'recommendationContributions',
129
154
  'aggregate',
130
155
  ]) ||
131
156
  !isFinancialSavingsHash(value.currentAggregateBaselineId) ||
@@ -139,7 +164,7 @@ const validateAvailableCoordinate = (value, authorityCoordinate, eligibilityById
139
164
  value.roundingMode !== 'half-away-from-zero' ||
140
165
  !isFinancialSavingsRecord(value.scenarioCoverage) ||
141
166
  !hasExactFinancialSavingsFields(value.scenarioCoverage, ['status', 'evidenceRefId', 'scenarioIds']) ||
142
- value.scenarioCoverage.status !== 'complete' ||
167
+ value.scenarioCoverage.status !== (value.status === 'available' ? 'complete' : 'partial') ||
143
168
  !isFinancialSavingsHash(value.scenarioCoverage.evidenceRefId) ||
144
169
  !Array.isArray(value.scenarioCoverage.scenarioIds) ||
145
170
  value.scenarioCoverage.scenarioIds.length > 20000 ||
@@ -151,6 +176,8 @@ const validateAvailableCoordinate = (value, authorityCoordinate, eligibilityById
151
176
  value.allocations.length > 20000 ||
152
177
  !Array.isArray(value.resourceContributions) ||
153
178
  value.resourceContributions.length > 20000 ||
179
+ !Array.isArray(value.recommendationContributions) ||
180
+ value.recommendationContributions.length > 20000 ||
154
181
  !isFinancialSavingsRecord(value.aggregate) ||
155
182
  !hasExactFinancialSavingsFields(value.aggregate, ['allocationIds', 'savingsMinorUnits']) ||
156
183
  !Array.isArray(value.aggregate.allocationIds) ||
@@ -163,15 +190,17 @@ const validateAvailableCoordinate = (value, authorityCoordinate, eligibilityById
163
190
  Date.parse(scenarioCoverageEvidence.intrinsicTime.at) > Date.parse(authorityGeneratedAt))
164
191
  return false;
165
192
  const projectionById = new Map(authorityCoordinate.projections.flatMap(projection => (projection.status === 'available' ? [[projection.projectionId, projection]] : [])));
193
+ const availableProjectionScenarioIds = new Set(authorityCoordinate.projections.flatMap(projection => (projection.status === 'available' ? [projection.scenarioId] : [])));
194
+ const unavailableEligibilityScenarioIds = new Set([...eligibilityById.values()].flatMap(assessment => (assessment.status === 'unavailable' ? [assessment.scenarioId] : [])));
166
195
  const activationById = new Map();
167
- const activationByRecommendationId = new Map();
196
+ const activationByScenarioId = new Map();
168
197
  for (const activation of value.activations) {
169
198
  const lifecycleEvidence = evidenceById.get(activation.lifecycleEvidenceRefId);
170
199
  if (!isFinancialSavingsRecord(activation) ||
171
200
  !hasExactFinancialSavingsFields(activation, [
172
201
  'activationId',
202
+ 'scenarioId',
173
203
  'recommendationId',
174
- 'projectionId',
175
204
  'lifecycleState',
176
205
  'lifecycleVersion',
177
206
  'lifecycleEvidenceRefId',
@@ -179,19 +208,29 @@ const validateAvailableCoordinate = (value, authorityCoordinate, eligibilityById
179
208
  'reason',
180
209
  'evaluatedAt',
181
210
  'policyVersion',
182
- ]) ||
211
+ ], ['projectionId']) ||
183
212
  !isFinancialSavingsHash(activation.activationId) ||
184
213
  activationById.has(activation.activationId) ||
185
- activationByRecommendationId.has(activation.recommendationId) ||
214
+ activationByScenarioId.has(activation.scenarioId) ||
215
+ !isFinancialSavingsIdentity(activation.scenarioId) ||
186
216
  !isFinancialSavingsIdentity(activation.recommendationId) ||
187
- !isFinancialSavingsHash(activation.projectionId) ||
217
+ (activation.projectionId !== undefined && !isFinancialSavingsHash(activation.projectionId)) ||
188
218
  !isFinancialSavingsIdentity(activation.lifecycleVersion) ||
189
219
  !isFinancialSavingsHash(activation.lifecycleEvidenceRefId) ||
190
220
  !isActivationDecision(activation.lifecycleState, activation.result, activation.reason) ||
191
221
  !isFinancialSavingsIsoInstant(activation.evaluatedAt) ||
192
222
  Date.parse(activation.evaluatedAt) > Date.parse(authorityGeneratedAt) ||
193
223
  !isFinancialSavingsIdentity(activation.policyVersion) ||
194
- projectionById.get(activation.projectionId)?.scenarioId !== activation.recommendationId ||
224
+ (activation.result === 'included' &&
225
+ (activation.projectionId === undefined || projectionById.get(activation.projectionId)?.scenarioId !== activation.scenarioId)) ||
226
+ (activation.result === 'excluded' &&
227
+ activation.projectionId !== undefined &&
228
+ projectionById.get(activation.projectionId)?.scenarioId !== activation.scenarioId) ||
229
+ (activation.result === 'unavailable' &&
230
+ (activation.projectionId !== undefined ||
231
+ (activation.reason === 'projection-unavailable' && availableProjectionScenarioIds.has(activation.scenarioId)) ||
232
+ (activation.reason === 'eligibility-unavailable' &&
233
+ !unavailableEligibilityScenarioIds.has(activation.scenarioId)))) ||
195
234
  lifecycleEvidence?.role !== 'recommendation-lifecycle' ||
196
235
  lifecycleEvidence.revisionId !== activation.lifecycleVersion ||
197
236
  Date.parse(lifecycleEvidence.intrinsicTime.at) > Date.parse(authorityGeneratedAt))
@@ -200,12 +239,15 @@ const validateAvailableCoordinate = (value, authorityCoordinate, eligibilityById
200
239
  if (activation.activationId !== createFinancialSavingsActivationIdV1(activationIdentity))
201
240
  return false;
202
241
  activationById.set(activation.activationId, activation);
203
- activationByRecommendationId.set(activation.recommendationId, activation);
242
+ activationByScenarioId.set(activation.scenarioId, activation);
204
243
  }
205
244
  const coveredScenarioIds = new Set(value.scenarioCoverage.scenarioIds);
206
- const activatedScenarioIds = new Set(value.activations.map(activation => activation.recommendationId));
245
+ const activatedScenarioIds = new Set(value.activations.map(activation => activation.scenarioId));
207
246
  if (value.scenarioCoverage.scenarioIds.some(scenarioId => !activatedScenarioIds.has(scenarioId)) ||
208
- value.activations.some(activation => !coveredScenarioIds.has(activation.recommendationId)))
247
+ value.activations.some(activation => !coveredScenarioIds.has(activation.scenarioId)))
248
+ return false;
249
+ const hasUnavailableActivation = value.activations.some(activation => activation.result === 'unavailable');
250
+ if ((value.status === 'available' && hasUnavailableActivation) || (value.status === 'partial' && !hasUnavailableActivation))
209
251
  return false;
210
252
  const allocationById = new Map();
211
253
  const allocatedBaselineComponents = new Set();
@@ -215,7 +257,7 @@ const validateAvailableCoordinate = (value, authorityCoordinate, eligibilityById
215
257
  const eligibility = allocation.eligibility.kind === 'mapped' ? eligibilityById.get(allocation.eligibility.eligibilityId) : undefined;
216
258
  const expectedDenominatorId = allocation.eligibility.kind === 'mapped' && eligibility?.status === 'available'
217
259
  ? eligibility.denominator.denominatorId
218
- : projection
260
+ : allocation.eligibility.kind === 'not-applicable' && projection
219
261
  ? createFinancialSavingsDenominatorIdV1({
220
262
  kind: 'projection-affected-current',
221
263
  baselineId: projection.baselineId,
@@ -229,6 +271,7 @@ const validateAvailableCoordinate = (value, authorityCoordinate, eligibilityById
229
271
  'allocationId',
230
272
  'ownerScopeId',
231
273
  'billableComponentIds',
274
+ 'scenarioId',
232
275
  'recommendationId',
233
276
  'baselineId',
234
277
  'projectionId',
@@ -245,6 +288,7 @@ const validateAvailableCoordinate = (value, authorityCoordinate, eligibilityById
245
288
  allocation.billableComponentIds.length > 20000 ||
246
289
  !allocation.billableComponentIds.every(isFinancialSavingsIdentity) ||
247
290
  new Set(allocation.billableComponentIds).size !== allocation.billableComponentIds.length ||
291
+ !isFinancialSavingsIdentity(allocation.scenarioId) ||
248
292
  !isFinancialSavingsIdentity(allocation.recommendationId) ||
249
293
  !isFinancialSavingsHash(allocation.baselineId) ||
250
294
  !isFinancialSavingsHash(allocation.projectionId) ||
@@ -258,15 +302,17 @@ const validateAvailableCoordinate = (value, authorityCoordinate, eligibilityById
258
302
  projection.baselineId !== allocation.baselineId ||
259
303
  !haveSameFinancialSavingsSet(projection.affectedComponentIds, allocation.billableComponentIds) ||
260
304
  decimalToMinorUnits(projection.change.savings, value.minorUnitScale) !== allocation.savingsMinorUnits ||
305
+ projection.scenarioId !== allocation.scenarioId ||
261
306
  !activation ||
262
307
  activation.result !== 'included' ||
308
+ activation.scenarioId !== allocation.scenarioId ||
263
309
  activation.recommendationId !== allocation.recommendationId ||
264
310
  activation.projectionId !== allocation.projectionId ||
265
311
  (allocation.eligibility.kind === 'mapped' &&
266
312
  (!eligibility ||
267
313
  eligibility.status !== 'available' ||
268
314
  eligibility.scopeId !== allocation.ownerScopeId ||
269
- eligibility.scenarioId !== allocation.recommendationId ||
315
+ eligibility.scenarioId !== allocation.scenarioId ||
270
316
  eligibility.eligibilityBaselineId !== allocation.eligibility.eligibilityBaselineId ||
271
317
  eligibility.denominator.denominatorId !== allocation.denominatorId ||
272
318
  eligibility.currentBaselineMapping.currentBaselineId !== allocation.baselineId ||
@@ -307,8 +353,41 @@ const validateAvailableCoordinate = (value, authorityCoordinate, eligibilityById
307
353
  contributedAllocationIds.push(...contribution.allocationIds);
308
354
  }
309
355
  const allocationIds = [...allocationById.keys()];
356
+ const recommendationContributionAllocationIds = [];
357
+ const recommendationContributionKeys = new Set();
358
+ for (const contribution of value.recommendationContributions) {
359
+ if (!isFinancialSavingsRecord(contribution) ||
360
+ !hasExactFinancialSavingsFields(contribution, [
361
+ 'ownerScopeId',
362
+ 'recommendationId',
363
+ 'allocationIds',
364
+ 'savingsMinorUnits',
365
+ ]) ||
366
+ !isFinancialSavingsIdentity(contribution.ownerScopeId) ||
367
+ !isFinancialSavingsIdentity(contribution.recommendationId) ||
368
+ !Array.isArray(contribution.allocationIds) ||
369
+ contribution.allocationIds.length === 0 ||
370
+ contribution.allocationIds.length > 20000 ||
371
+ !contribution.allocationIds.every(isFinancialSavingsHash) ||
372
+ new Set(contribution.allocationIds).size !== contribution.allocationIds.length ||
373
+ !isFinancialSavingsMinorUnits(contribution.savingsMinorUnits))
374
+ return false;
375
+ const contributionKey = `${contribution.ownerScopeId}\u0000${contribution.recommendationId}`;
376
+ if (recommendationContributionKeys.has(contributionKey))
377
+ return false;
378
+ const allocations = contribution.allocationIds.map(id => allocationById.get(id));
379
+ if (allocations.some(allocation => !allocation ||
380
+ allocation.ownerScopeId !== contribution.ownerScopeId ||
381
+ allocation.recommendationId !== contribution.recommendationId) ||
382
+ sumFinancialSavingsMinorUnits(allocations.map(allocation => allocation.savingsMinorUnits)) !== contribution.savingsMinorUnits)
383
+ return false;
384
+ recommendationContributionKeys.add(contributionKey);
385
+ recommendationContributionAllocationIds.push(...contribution.allocationIds);
386
+ }
310
387
  return (haveSameFinancialSavingsSet(contributedAllocationIds, allocationIds) &&
311
388
  new Set(contributedAllocationIds).size === contributedAllocationIds.length &&
389
+ haveSameFinancialSavingsSet(recommendationContributionAllocationIds, allocationIds) &&
390
+ new Set(recommendationContributionAllocationIds).size === recommendationContributionAllocationIds.length &&
312
391
  haveSameFinancialSavingsSet(value.aggregate.allocationIds, allocationIds) &&
313
392
  new Set(value.aggregate.allocationIds).size === value.aggregate.allocationIds.length &&
314
393
  value.aggregate.savingsMinorUnits === sumFinancialSavingsMinorUnits(value.allocations.map(allocation => allocation.savingsMinorUnits)));
@@ -324,6 +403,6 @@ export const validateFinancialSavingsCoordinateEnvelopeV1 = (value, authorityCoo
324
403
  ? value.currentAggregateBaselineId === authorityCoordinate.aggregateBaseline.baselineId
325
404
  : value.currentAggregateBaselineId === undefined));
326
405
  }
327
- return (value.status === 'available' &&
328
- validateAvailableCoordinate(value, authorityCoordinate, eligibilityById, evidenceById, authorityGeneratedAt, authorityRunId));
406
+ return ((value.status === 'available' || value.status === 'partial') &&
407
+ validateComposedCoordinate(value, authorityCoordinate, eligibilityById, evidenceById, authorityGeneratedAt, authorityRunId));
329
408
  };
@@ -0,0 +1,44 @@
1
+ import { formatExactDecimalValue, sumCanonicalDecimals } from '../common/exactDecimal.js';
2
+ /**
3
+ * Composes one exact percentage from allocation-bound denominator evidence.
4
+ * Repeated denominator identities are counted once; conflicting or missing
5
+ * evidence fails closed so no consumer substitutes display-resource spend.
6
+ */
7
+ export const composeFinancialSavingsAllocationPercentageV1 = (allocations, minorUnitScale) => {
8
+ if (!Number.isSafeInteger(minorUnitScale) || minorUnitScale < 0 || minorUnitScale > 6 || allocations.length === 0) {
9
+ return undefined;
10
+ }
11
+ const denominators = new Map();
12
+ let savingsMinorUnits = 0n;
13
+ for (const allocation of allocations) {
14
+ if (!Number.isSafeInteger(allocation.savingsMinorUnits) || allocation.savingsMinorUnits < 0 || !allocation.denominator) {
15
+ return undefined;
16
+ }
17
+ savingsMinorUnits += BigInt(allocation.savingsMinorUnits);
18
+ const existing = denominators.get(allocation.denominator.denominatorId);
19
+ if (existing &&
20
+ (existing.amount !== allocation.denominator.amount || existing.currencyCode !== allocation.denominator.currencyCode)) {
21
+ return undefined;
22
+ }
23
+ denominators.set(allocation.denominator.denominatorId, {
24
+ amount: allocation.denominator.amount,
25
+ currencyCode: allocation.denominator.currencyCode,
26
+ });
27
+ }
28
+ if (savingsMinorUnits > BigInt(Number.MAX_SAFE_INTEGER))
29
+ return undefined;
30
+ const currencies = new Set([...denominators.values()].map(denominator => denominator.currencyCode));
31
+ if (currencies.size !== 1)
32
+ return undefined;
33
+ const denominatorAmount = formatExactDecimalValue(sumCanonicalDecimals([...denominators.values()].map(denominator => denominator.amount)));
34
+ const denominatorNumber = Number(denominatorAmount);
35
+ const savingsNumber = Number(savingsMinorUnits) / 10 ** minorUnitScale;
36
+ if (!Number.isFinite(denominatorNumber) || denominatorNumber <= 0 || !Number.isFinite(savingsNumber))
37
+ return undefined;
38
+ return {
39
+ denominatorIds: [...denominators.keys()].sort(),
40
+ denominatorAmount,
41
+ denominatorCurrencyCode: [...currencies][0],
42
+ percentage: (savingsNumber / denominatorNumber) * 100,
43
+ };
44
+ };
@@ -1,2 +1,4 @@
1
1
  export const FINANCIAL_SAVINGS_SURFACE_PROJECTION_SCHEMA_VERSION_V1 = 1;
2
2
  export const FINANCIAL_SAVINGS_SURFACE_PROJECTION_CONTRACT_VERSION_V1 = 'financial-savings-surface-projection/v1';
3
+ export const FINANCIAL_SAVINGS_QUERY_SELECTION_CONTRACT_VERSION_V1 = 'financial-savings-query-selection/v1';
4
+ export const FINANCIAL_SAVINGS_RESOURCE_QUERY_SELECTION_CONTRACT_VERSION_V1 = 'financial-savings-resource-query-selection/v1';