@zeniai/client-epic-state 5.0.81-betaML3 → 5.0.81-betaRR0

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 (189) hide show
  1. package/lib/common/aiCfo/aiCfoSuggestedQuestionsPageContext.d.ts +1 -1
  2. package/lib/commonStateTypes/viewAndReport/viewAndReport.d.ts +2 -2
  3. package/lib/commonStateTypes/viewAndReport/viewAndReport.js +0 -2
  4. package/lib/entity/account/accountSelector.d.ts +0 -9
  5. package/lib/entity/account/accountSelector.js +1 -14
  6. package/lib/entity/account/accountState.d.ts +1 -1
  7. package/lib/entity/accountGroup/accountGroupState.d.ts +1 -1
  8. package/lib/entity/aiCfo/aiCfoPayload.d.ts +171 -1
  9. package/lib/entity/aiCfo/aiCfoReducer.d.ts +22 -2
  10. package/lib/entity/aiCfo/aiCfoReducer.js +291 -4
  11. package/lib/entity/aiCfo/aiCfoSelector.d.ts +3 -1
  12. package/lib/entity/aiCfo/aiCfoSelector.js +11 -1
  13. package/lib/entity/aiCfo/aiCfoState.d.ts +186 -4
  14. package/lib/entity/aiCfo/aiCfoState.js +23 -1
  15. package/lib/entity/cardPolicy/cardPolicyPayload.d.ts +277 -0
  16. package/lib/entity/cardPolicy/cardPolicyPayload.js +143 -0
  17. package/lib/entity/cardPolicy/cardPolicyReducer.d.ts +19 -0
  18. package/lib/entity/cardPolicy/cardPolicyReducer.js +256 -0
  19. package/lib/entity/cardPolicy/cardPolicySelector.d.ts +32 -0
  20. package/lib/entity/cardPolicy/cardPolicySelector.js +103 -0
  21. package/lib/entity/cardPolicy/cardPolicyState.d.ts +205 -0
  22. package/lib/entity/cardPolicy/cardPolicyState.js +14 -0
  23. package/lib/entity/cardPolicy/extractPolicyDocumentEpic.d.ts +18 -0
  24. package/lib/entity/cardPolicy/extractPolicyDocumentEpic.js +54 -0
  25. package/lib/entity/cardPolicy/fetchCardPolicyVendorOptionsEpic.d.ts +26 -0
  26. package/lib/entity/cardPolicy/fetchCardPolicyVendorOptionsEpic.js +47 -0
  27. package/lib/entity/cardPolicy/policyDocumentExtractionToRecommendationBridgeEpic.d.ts +25 -0
  28. package/lib/entity/cardPolicy/policyDocumentExtractionToRecommendationBridgeEpic.js +39 -0
  29. package/lib/entity/cardPolicy/policyRecommendationFromUploadEpic.d.ts +23 -0
  30. package/lib/entity/cardPolicy/policyRecommendationFromUploadEpic.js +92 -0
  31. package/lib/entity/class/classReducer.d.ts +4 -4
  32. package/lib/entity/class/classState.d.ts +1 -1
  33. package/lib/entity/forecast/forecastState.d.ts +1 -1
  34. package/lib/entity/jeSchedules/jeSchedulesTypes.d.ts +1 -1
  35. package/lib/entity/monthEndCloseChecks/monthEndCloseChecksState.d.ts +1 -1
  36. package/lib/entity/sectionAccountsView/sectionAccountsView.d.ts +1 -1
  37. package/lib/entity/sectionClassesViewV2/sectionClassesView.d.ts +1 -1
  38. package/lib/entity/sectionClassesViewV2/sectionClassesViewReducer.d.ts +2 -2
  39. package/lib/entity/sectionProjectView/sectionProjectView.d.ts +1 -1
  40. package/lib/entity/sectionProjectView/sectionProjectViewReducer.d.ts +2 -2
  41. package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
  42. package/lib/entity/snackbar/snackbarTypes.js +2 -1
  43. package/lib/entity/tenant/clearAllEpic.d.ts +6 -3
  44. package/lib/entity/tenant/clearAllEpic.js +8 -2
  45. package/lib/entity/transaction/payloadTypes/transactionPayload.d.ts +0 -4
  46. package/lib/entity/transaction/payloadTypes/transactionPayload.js +10 -18
  47. package/lib/entity/transaction/stateTypes/transaction.d.ts +0 -3
  48. package/lib/epic.d.ts +11 -3
  49. package/lib/epic.js +11 -3
  50. package/lib/esm/commonStateTypes/viewAndReport/viewAndReport.js +0 -2
  51. package/lib/esm/entity/account/accountSelector.js +0 -11
  52. package/lib/esm/entity/aiCfo/aiCfoReducer.js +291 -4
  53. package/lib/esm/entity/aiCfo/aiCfoSelector.js +10 -1
  54. package/lib/esm/entity/aiCfo/aiCfoState.js +20 -0
  55. package/lib/esm/entity/cardPolicy/cardPolicyPayload.js +130 -0
  56. package/lib/esm/entity/cardPolicy/cardPolicyReducer.js +252 -0
  57. package/lib/esm/entity/cardPolicy/cardPolicySelector.js +79 -0
  58. package/lib/esm/entity/cardPolicy/cardPolicyState.js +9 -0
  59. package/lib/esm/entity/cardPolicy/extractPolicyDocumentEpic.js +50 -0
  60. package/lib/esm/entity/cardPolicy/fetchCardPolicyVendorOptionsEpic.js +43 -0
  61. package/lib/esm/entity/cardPolicy/policyDocumentExtractionToRecommendationBridgeEpic.js +35 -0
  62. package/lib/esm/entity/cardPolicy/policyRecommendationFromUploadEpic.js +88 -0
  63. package/lib/esm/entity/snackbar/snackbarTypes.js +2 -1
  64. package/lib/esm/entity/tenant/clearAllEpic.js +8 -2
  65. package/lib/esm/entity/transaction/payloadTypes/transactionPayload.js +10 -18
  66. package/lib/esm/epic.js +11 -3
  67. package/lib/esm/index.js +26 -12
  68. package/lib/esm/reducer.js +12 -3
  69. package/lib/esm/view/aiCfoView/aiCfoViewReducer.js +6 -3
  70. package/lib/esm/view/aiCfoView/epics/createSessionAndSubmitEpic.js +5 -2
  71. package/lib/esm/view/aiCfoView/epics/createSessionEpic.js +2 -1
  72. package/lib/esm/view/aiCfoView/epics/fetchSuggestedQuestionsEpic.js +12 -2
  73. package/lib/esm/view/expenseAutomationView/reducers/transactionsViewReducer.js +1 -13
  74. package/lib/esm/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +1 -9
  75. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailReducer.js +70 -0
  76. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailSelector.js +22 -0
  77. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailState.js +1 -0
  78. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/fetchCardPolicyDetailEpic.js +56 -0
  79. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/updateCardPolicyEpic.js +49 -0
  80. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/archiveCardPolicyEpic.js +42 -0
  81. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListReducer.js +72 -0
  82. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListSelector.js +21 -0
  83. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListState.js +1 -0
  84. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/fetchCardPolicyListEpic.js +56 -0
  85. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyReducer.js +62 -0
  86. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicySelector.js +39 -0
  87. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyState.js +1 -0
  88. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyTemplateEpic.js +53 -0
  89. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/fetchCardPolicyMccCategoriesEpic.js +25 -0
  90. package/lib/esm/view/spendManagement/chargeCards/chargeCardList/chargeCardListSelector.js +25 -0
  91. package/lib/esm/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardEpic.js +2 -2
  92. package/lib/esm/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardReducer.js +16 -4
  93. package/lib/esm/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardSelector.js +38 -0
  94. package/lib/esm/view/transactionDetail/transactionDetailSelector.js +1 -6
  95. package/lib/index.d.ts +24 -12
  96. package/lib/index.js +147 -43
  97. package/lib/reducer.d.ts +12 -3
  98. package/lib/reducer.js +12 -3
  99. package/lib/view/aiCfoView/aiCfoViewReducer.d.ts +11 -2
  100. package/lib/view/aiCfoView/aiCfoViewReducer.js +6 -3
  101. package/lib/view/aiCfoView/epics/createSessionAndSubmitEpic.js +5 -2
  102. package/lib/view/aiCfoView/epics/createSessionEpic.js +2 -1
  103. package/lib/view/aiCfoView/epics/fetchSuggestedQuestionsEpic.d.ts +8 -1
  104. package/lib/view/aiCfoView/epics/fetchSuggestedQuestionsEpic.js +12 -2
  105. package/lib/view/auditReportView/auditReportViewState.d.ts +1 -1
  106. package/lib/view/billPayCard/billPayCardSelector.d.ts +1 -1
  107. package/lib/view/cardBalance/cardBalanceSelector.d.ts +1 -1
  108. package/lib/view/cashBalance/cashBalanceSelector.d.ts +1 -1
  109. package/lib/view/cashInCashOut/cashInCashOutSelector.d.ts +1 -1
  110. package/lib/view/cashPosition/cashPositionSelector.d.ts +1 -1
  111. package/lib/view/dashboard/dashboardReducer.d.ts +2 -2
  112. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  113. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.d.ts +1 -3
  114. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.js +2 -14
  115. package/lib/view/expenseAutomationView/selectorTypes/transactionsViewSelectorTypes.d.ts +1 -4
  116. package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.d.ts +0 -1
  117. package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +2 -11
  118. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.d.ts +1 -1
  119. package/lib/view/expenseAutomationView/types/missingReceiptsViewState.d.ts +2 -2
  120. package/lib/view/expenseAutomationView/types/reconciliationViewState.d.ts +1 -1
  121. package/lib/view/expenseAutomationView/types/transactionsViewState.d.ts +1 -1
  122. package/lib/view/financeStatement/financeStatementReducer.d.ts +1 -1
  123. package/lib/view/globalMerchantView/globalMerchantViewReducer.d.ts +2 -2
  124. package/lib/view/people/peopleTypes.d.ts +1 -1
  125. package/lib/view/reimbursementCard/reimbursementCardSelector.d.ts +1 -1
  126. package/lib/view/reportsResync/reportsResyncReducer.d.ts +2 -2
  127. package/lib/view/scheduleView/scheduleListView/scheduleListTypes.d.ts +1 -1
  128. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailReducer.d.ts +14 -0
  129. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailReducer.js +74 -0
  130. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailSelector.d.ts +21 -0
  131. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailSelector.js +28 -0
  132. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailState.d.ts +25 -0
  133. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailState.js +2 -0
  134. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/fetchCardPolicyDetailEpic.d.ts +19 -0
  135. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/fetchCardPolicyDetailEpic.js +60 -0
  136. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/updateCardPolicyEpic.d.ts +18 -0
  137. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/updateCardPolicyEpic.js +53 -0
  138. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/archiveCardPolicyEpic.d.ts +16 -0
  139. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/archiveCardPolicyEpic.js +46 -0
  140. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListReducer.d.ts +15 -0
  141. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListReducer.js +76 -0
  142. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListSelector.d.ts +21 -0
  143. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListSelector.js +27 -0
  144. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListState.d.ts +19 -0
  145. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListState.js +2 -0
  146. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/fetchCardPolicyListEpic.d.ts +19 -0
  147. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/fetchCardPolicyListEpic.js +60 -0
  148. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyReducer.d.ts +13 -0
  149. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyReducer.js +66 -0
  150. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicySelector.d.ts +32 -0
  151. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicySelector.js +46 -0
  152. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyState.d.ts +45 -0
  153. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyState.js +2 -0
  154. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyTemplateEpic.d.ts +25 -0
  155. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyTemplateEpic.js +57 -0
  156. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/fetchCardPolicyMccCategoriesEpic.d.ts +15 -0
  157. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/fetchCardPolicyMccCategoriesEpic.js +29 -0
  158. package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardList.d.ts +1 -1
  159. package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardListSelector.d.ts +14 -0
  160. package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardListSelector.js +27 -1
  161. package/lib/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardEpic.d.ts +2 -2
  162. package/lib/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardEpic.js +1 -1
  163. package/lib/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardReducer.d.ts +5 -1
  164. package/lib/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardReducer.js +17 -5
  165. package/lib/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardSelector.d.ts +27 -0
  166. package/lib/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardSelector.js +43 -1
  167. package/lib/view/spendManagement/chargeCards/issueChargeCard/issueChargeCardState.d.ts +2 -0
  168. package/lib/view/taskManager/taskListView/taskListReducer.d.ts +1 -1
  169. package/lib/view/tasksCard/tasksCardSelector.d.ts +1 -1
  170. package/lib/view/topEx/topExSelector.d.ts +1 -1
  171. package/lib/view/transactionDetail/transactionDetailPayload.d.ts +1 -1
  172. package/lib/view/transactionDetail/transactionDetailSelector.d.ts +1 -6
  173. package/lib/view/transactionDetail/transactionDetailSelector.js +1 -6
  174. package/package.json +1 -1
  175. package/lib/esm/view/createTransferEntry/createTransferEntryReducer.js +0 -82
  176. package/lib/esm/view/createTransferEntry/createTransferEntrySelector.js +0 -64
  177. package/lib/esm/view/createTransferEntry/createTransferEntryState.js +0 -17
  178. package/lib/esm/view/createTransferEntry/epics/createTransferEntryEpic.js +0 -130
  179. package/lib/esm/view/createTransferEntry/epics/fetchTransferAccountsEpic.js +0 -37
  180. package/lib/view/createTransferEntry/createTransferEntryReducer.d.ts +0 -32
  181. package/lib/view/createTransferEntry/createTransferEntryReducer.js +0 -86
  182. package/lib/view/createTransferEntry/createTransferEntrySelector.d.ts +0 -39
  183. package/lib/view/createTransferEntry/createTransferEntrySelector.js +0 -69
  184. package/lib/view/createTransferEntry/createTransferEntryState.d.ts +0 -30
  185. package/lib/view/createTransferEntry/createTransferEntryState.js +0 -20
  186. package/lib/view/createTransferEntry/epics/createTransferEntryEpic.d.ts +0 -11
  187. package/lib/view/createTransferEntry/epics/createTransferEntryEpic.js +0 -134
  188. package/lib/view/createTransferEntry/epics/fetchTransferAccountsEpic.d.ts +0 -14
  189. package/lib/view/createTransferEntry/epics/fetchTransferAccountsEpic.js +0 -41
@@ -20,8 +20,178 @@ export interface ChartVisualizationPayload {
20
20
  lines?: string[] | null;
21
21
  y_format?: YFormatPayload;
22
22
  }
23
+ export interface CardsCardOptionPayload {
24
+ id: string;
25
+ label: string;
26
+ description?: string | null;
27
+ }
28
+ /**
29
+ * Single AI-suggested card on the wire. The controller ships an array of
30
+ * these mixing vendor and department entries; entries with
31
+ * `is_suggested: true` seed step 1 of the form pre-checked, while entries
32
+ * with `is_suggested: false` are available in the step-2 Card dropdown and
33
+ * step-1 search but don't appear as initial rows.
34
+ */
35
+ export interface SuggestedCardPayload {
36
+ avg_spend: number;
37
+ card_name: string;
38
+ card_name_id: string;
39
+ card_type: 'vendor' | 'department';
40
+ credit_limit: number;
41
+ is_suggested: boolean;
42
+ owner_id: string;
43
+ }
44
+ /**
45
+ * Discriminated payload for the AI Card Creation interactive form. The wire
46
+ * format mirrors the FE-side `CardsCreationInitialData` field-for-field
47
+ * (with snake_case field names converted to camelCase by the reducer).
48
+ *
49
+ * - `review` (default): the AI suggests rows (vendors + departments);
50
+ * user reviews them in step 1, then configures cards in step 2. The wire
51
+ * format ships a flat `suggested_cards` array. Both suggested and
52
+ * not-suggested entries are included; the reducer splits them into seed
53
+ * rows vs. dropdown options. The legacy `team_rows` /
54
+ * `suggested_owner_user_id_by_team_id` shape is also accepted for
55
+ * backward compatibility with mocks and tests.
56
+ * - `create` (1-step): the AI has already chosen cards; user lands
57
+ * directly on the editable card table for confirmation.
58
+ */
59
+ export type CardsCreationInitialDataPayload = {
60
+ card_options: CardsCardOptionPayload[];
61
+ mode: 'review';
62
+ /**
63
+ * Preferred wire format: flat list of vendor/department cards with an
64
+ * `is_suggested` discriminator. The reducer derives `team_rows`,
65
+ * `suggested_owner_user_id_by_team_id`, and the full `cardNameOptions`
66
+ * universe from this single array.
67
+ */
68
+ suggested_cards?: SuggestedCardPayload[];
69
+ /**
70
+ * Legacy/test shape — pre-shaped seed rows. Mutually exclusive with
71
+ * `suggested_cards`; when both are present, `suggested_cards` wins.
72
+ */
73
+ suggested_owner_user_id_by_team_id?: Record<string, string | null>;
74
+ team_rows?: Array<{
75
+ avg_monthly_spend: string;
76
+ id: string;
77
+ label: string;
78
+ recommended_limit: string;
79
+ card_kind?: 'vendor' | 'class' | null;
80
+ recommended_limit_cadence?: string | null;
81
+ }>;
82
+ } | {
83
+ card_options: CardsCardOptionPayload[];
84
+ card_rows: Array<{
85
+ card_option_id: string;
86
+ id: string;
87
+ /**
88
+ * Optional team-derived display label rendered in the card cell
89
+ * trigger (e.g. "Engineering"). Drives the row's first-letter avatar
90
+ * in step 2.
91
+ */
92
+ label?: string | null;
93
+ recommended_limit?: number | null;
94
+ suggested_owner_user_id?: string | null;
95
+ }>;
96
+ mode: 'create';
97
+ };
98
+ /**
99
+ * Per-policy allow / block bucket on the wire. The two arrays are
100
+ * independent (a draft policy may populate both, only one, or neither).
101
+ */
102
+ export interface DraftPolicyEntityPayload {
103
+ category_codes: string[];
104
+ merchant_names: string[];
105
+ }
106
+ /**
107
+ * Spend-limit bucket per policy. `transaction` is the only cadence the
108
+ * BE ships today; left open-ended for future cadences (e.g.
109
+ * `monthly`, `quarterly`).
110
+ */
111
+ export interface DraftPolicySpendLimitsPayload {
112
+ transaction: number;
113
+ [cadence: string]: number | undefined;
114
+ }
115
+ /**
116
+ * Single draft policy on the wire. The controller emits one of these
117
+ * per recommended policy in `step_5_review.draft_policies`. Identity is
118
+ * positional (no stable `id` from the BE); the FE synthesizes one on
119
+ * decode.
120
+ */
121
+ export interface DraftPolicyPayload {
122
+ allowed_entity: DraftPolicyEntityPayload;
123
+ apply_to_cards: string[];
124
+ blocked_entity: DraftPolicyEntityPayload;
125
+ description: string;
126
+ /** Enforcement mode for the policy (e.g. `"strict"`). Carried into
127
+ * state for guided submit; ignored for `auto` / `upload`. */
128
+ mode: string;
129
+ name: string;
130
+ required_receipt_threshold: number;
131
+ spend_limits: DraftPolicySpendLimitsPayload;
132
+ }
133
+ /**
134
+ * `step_5_review` block — the only step in `wizard_plan` the FE reads.
135
+ * Steps 1–4 are intentionally not modeled.
136
+ */
137
+ export interface CardPolicyStep5ReviewPayload {
138
+ draft_policies: DraftPolicyPayload[];
139
+ /** Header text shown above the review list / wizard. */
140
+ prompt: string;
141
+ /** How the BE grouped the suggested policies. `"none"` today; may
142
+ * surface as a header banner in a future iteration. */
143
+ grouping_source?: string;
144
+ }
145
+ export interface CardPolicyWizardPlanPayload {
146
+ step_5_review: CardPolicyStep5ReviewPayload;
147
+ }
148
+ /**
149
+ * Upload-mode metadata that the `policy-recommendation-from-upload` API
150
+ * returns alongside the wizard plan. Absent on the initial controller
151
+ * response; populated after the file upload + recommendation chain.
152
+ */
153
+ export interface CardPolicyUploadSourcePayload {
154
+ confidence_score: number;
155
+ file_name: string;
156
+ low_confidence_fields: string[];
157
+ }
158
+ /**
159
+ * Discriminated payload for the AI Card Policy interactive form.
160
+ * All three modes share the same `wizard_plan.step_5_review.draft_policies`
161
+ * envelope; the FE renders different forms based on `mode`.
162
+ *
163
+ * - `auto` (1-step review): user reviews suggested policies and submits.
164
+ * - `guided` (5-step wizard): Steps 1–4 seeded from `draft_policies[0]`,
165
+ * Step 5 lists every draft policy.
166
+ * - `upload` (3-step): upload doc → pick cards → review. Controller
167
+ * responses for `mode === "upload"` arrive *before* the user uploads,
168
+ * so `wizard_plan` is optional; populated after the upload-recommendation
169
+ * API returns.
170
+ */
171
+ export type CardPolicyInitialDataPayload = {
172
+ mode: 'auto';
173
+ wizard_plan: CardPolicyWizardPlanPayload;
174
+ } | {
175
+ mode: 'guided';
176
+ wizard_plan: CardPolicyWizardPlanPayload;
177
+ } | {
178
+ mode: 'upload';
179
+ source?: CardPolicyUploadSourcePayload;
180
+ wizard_plan?: CardPolicyWizardPlanPayload;
181
+ };
182
+ /**
183
+ * Discriminated visualization payload. The FE narrows on `form_type` and
184
+ * casts `payload` to the matching shape.
185
+ */
186
+ export type InteractiveFormVisualizationPayload = {
187
+ form_type: 'cards_creation';
188
+ payload: CardsCreationInitialDataPayload;
189
+ } | {
190
+ form_type: 'card_policy';
191
+ payload: CardPolicyInitialDataPayload;
192
+ };
23
193
  export interface AiCfoVisualizationPayload {
24
- data: TableVisualizationPayload | ChartVisualizationPayload | null;
194
+ data: TableVisualizationPayload | ChartVisualizationPayload | InteractiveFormVisualizationPayload | null;
25
195
  type: string | null;
26
196
  }
27
197
  export interface AiCfoAnswerPayload {
@@ -1,7 +1,8 @@
1
1
  import { ID } from '../../commonStateTypes/common';
2
2
  import { ZeniDate } from '../../zeniDayJS';
3
3
  import { AiCfoAnswerPayload, AiCfoVisualizationPayload, ChatSessionPayload, MessagePayload } from './aiCfoPayload';
4
- import { AiCfoState, AiCfoVisualization, FileAttachmentMetadata } from './aiCfoState';
4
+ import { AiCfoState, AiCfoVisualization, FileAttachmentMetadata, SyntheticAiCfoAnswerKind } from './aiCfoState';
5
+ import type { CardPolicyUploadSource, CardPolicyWizardPlan } from './aiCfoState';
5
6
  export declare const initialAiCfoState: AiCfoState;
6
7
  export declare const toAiCfoVisualization: (visualization: AiCfoVisualizationPayload) => AiCfoVisualization | undefined;
7
8
  export declare const setNewSession: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
@@ -41,6 +42,25 @@ export declare const setNewSession: import("@reduxjs/toolkit").ActionCreatorWith
41
42
  }, "aiCfo/addQuestionPayload">, clearAiCfo: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"aiCfo/clearAiCfo">, deleteQuestion: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
42
43
  chatSessionId: ID;
43
44
  questionAnswerId: ID;
44
- }, "aiCfo/deleteQuestion">;
45
+ }, "aiCfo/deleteQuestion">, updateAiCfoAnswerCardPolicyWizardPlan: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
46
+ answerId: ID;
47
+ chatSessionId: ID;
48
+ wizardPlan: CardPolicyWizardPlan;
49
+ source?: CardPolicyUploadSource;
50
+ }, "aiCfo/updateAiCfoAnswerCardPolicyWizardPlan">, appendSyntheticAiCfoAnswer: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
51
+ chatSessionId: ID;
52
+ createdAt: ZeniDate;
53
+ id: ID;
54
+ kind: SyntheticAiCfoAnswerKind;
55
+ entityIds?: ID[];
56
+ }, "aiCfo/appendSyntheticAiCfoAnswer">, updateSyntheticAiCfoAnswer: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
57
+ chatSessionId: ID;
58
+ id: ID;
59
+ kind: SyntheticAiCfoAnswerKind;
60
+ entityIds?: ID[];
61
+ }, "aiCfo/updateSyntheticAiCfoAnswer">, removeSyntheticAiCfoAnswer: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
62
+ chatSessionId: ID;
63
+ id: ID;
64
+ }, "aiCfo/removeSyntheticAiCfoAnswer">, clearSyntheticAiCfoAnswers: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "aiCfo/clearSyntheticAiCfoAnswers">;
45
65
  declare const _default: import("redux").Reducer<AiCfoState>;
46
66
  export default _default;
@@ -1,13 +1,14 @@
1
1
  "use strict";
2
2
  var _a;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.deleteQuestion = exports.clearAiCfo = exports.addQuestionPayload = exports.upsertOrAddQuestionAnswerPayload = exports.upsertAnswerPayload = exports.setChatHistory = exports.setSessions = exports.clearSession = exports.setNewSession = exports.toAiCfoVisualization = exports.initialAiCfoState = void 0;
4
+ exports.clearSyntheticAiCfoAnswers = exports.removeSyntheticAiCfoAnswer = exports.updateSyntheticAiCfoAnswer = exports.appendSyntheticAiCfoAnswer = exports.updateAiCfoAnswerCardPolicyWizardPlan = exports.deleteQuestion = exports.clearAiCfo = exports.addQuestionPayload = exports.upsertOrAddQuestionAnswerPayload = exports.upsertAnswerPayload = exports.setChatHistory = exports.setSessions = exports.clearSession = exports.setNewSession = exports.toAiCfoVisualization = exports.initialAiCfoState = void 0;
5
5
  const toolkit_1 = require("@reduxjs/toolkit");
6
6
  const zeniDayJS_1 = require("../../zeniDayJS");
7
7
  const aiCfoState_1 = require("./aiCfoState");
8
8
  exports.initialAiCfoState = {
9
9
  aiCfoByChatSessionId: {},
10
10
  partialQuestionAnswers: {},
11
+ syntheticAnswersByChatSessionId: {},
11
12
  };
12
13
  // Utility: Merge two arrays of Q&A pairs, combining responses for the same question
13
14
  function mergeQuestionAnswerPairs(existing, newQAs) {
@@ -139,12 +140,188 @@ const toAiCfoVisualization = (visualization) => {
139
140
  if (visualization.type == null || visualization.data == null) {
140
141
  return undefined;
141
142
  }
143
+ const normalizedType = (0, aiCfoState_1.toAiCfoVisualizationTypeStrict)(visualization.type) ?? 'table';
142
144
  return {
143
- type: (0, aiCfoState_1.toAiCfoVisualizationTypeStrict)(visualization.type) ?? 'table',
144
- data: toAiCfoVisualizationData(visualization.data),
145
+ type: normalizedType,
146
+ data: normalizedType === 'interactive_form'
147
+ ? toInteractiveFormVisualization(visualization.data)
148
+ : toAiCfoVisualizationData(visualization.data),
145
149
  };
146
150
  };
147
151
  exports.toAiCfoVisualization = toAiCfoVisualization;
152
+ const toInteractiveFormVisualization = (data) => {
153
+ const formType = (0, aiCfoState_1.toInteractiveFormTypeStrict)(data.form_type) ?? 'cards_creation';
154
+ if (formType === 'card_policy') {
155
+ return {
156
+ formType: 'card_policy',
157
+ payload: toCardPolicyInitialData(data.payload),
158
+ };
159
+ }
160
+ return {
161
+ formType: 'cards_creation',
162
+ payload: toCardsCreationInitialData(data.payload),
163
+ };
164
+ };
165
+ const toCardsCreationInitialData = (payload) => {
166
+ const cardOptions = (payload.card_options ?? []).map((option) => ({
167
+ id: option.id,
168
+ label: option.label,
169
+ description: option.description ?? undefined,
170
+ }));
171
+ if (payload.mode === 'create') {
172
+ return {
173
+ mode: 'create',
174
+ cardOptions,
175
+ cardRows: (payload.card_rows ?? []).map((row) => ({
176
+ cardOptionId: row.card_option_id,
177
+ id: row.id,
178
+ label: row.label ?? undefined,
179
+ recommendedLimit: row.recommended_limit ?? undefined,
180
+ suggestedOwnerUserId: row.suggested_owner_user_id ?? undefined,
181
+ })),
182
+ };
183
+ }
184
+ // Preferred wire format: a flat `suggested_cards` array with an
185
+ // `is_suggested` discriminator. The adapter splits it into seed rows,
186
+ // owner map, and the full dropdown universe.
187
+ if (payload.suggested_cards != null) {
188
+ return fromSuggestedCards(payload.suggested_cards, cardOptions);
189
+ }
190
+ // Legacy / test shape: backend already pre-shapes seeds. Synthesize an
191
+ // empty `cardNameOptions` (step 2 dropdown still works via row-self ids).
192
+ const teamRows = (payload.team_rows ?? []).map((row) => ({
193
+ avgMonthlySpend: row.avg_monthly_spend,
194
+ cardKind: (row.card_kind ?? 'vendor'),
195
+ id: row.id,
196
+ label: row.label,
197
+ recommendedLimit: row.recommended_limit,
198
+ recommendedLimitCadence: row.recommended_limit_cadence ?? undefined,
199
+ }));
200
+ return {
201
+ mode: 'review',
202
+ cardOptions,
203
+ cardNameOptions: teamRows.map((row) => ({
204
+ id: row.id,
205
+ kind: row.cardKind,
206
+ label: row.label,
207
+ })),
208
+ suggestedOwnerUserIdByTeamId: Object.fromEntries(Object.entries(payload.suggested_owner_user_id_by_team_id ?? {}).map(([teamId, userId]) => [teamId, userId ?? undefined])),
209
+ teamRows,
210
+ };
211
+ };
212
+ const CURRENCY_FORMATTER = new Intl.NumberFormat('en-US', {
213
+ style: 'currency',
214
+ currency: 'USD',
215
+ maximumFractionDigits: 0,
216
+ });
217
+ const fromSuggestedCards = (suggestedCards, cardOptions) => {
218
+ const ordered = [...suggestedCards].sort((a, b) => {
219
+ if (a.card_type === b.card_type) {
220
+ return 0;
221
+ }
222
+ return a.card_type === 'vendor' ? -1 : 1;
223
+ });
224
+ const withUniqueIds = withSynthesizedIds(ordered);
225
+ const teamRows = withUniqueIds
226
+ .filter(({ card }) => card.is_suggested)
227
+ .map(({ card, uniqueId }) => ({
228
+ avgMonthlySpend: CURRENCY_FORMATTER.format(card.avg_spend),
229
+ cardKind: card.card_type === 'department'
230
+ ? 'class'
231
+ : 'vendor',
232
+ id: uniqueId,
233
+ label: card.card_name,
234
+ recommendedLimit: CURRENCY_FORMATTER.format(card.credit_limit),
235
+ recommendedLimitCadence: 'Monthly',
236
+ }));
237
+ const suggestedOwnerUserIdByTeamId = Object.fromEntries(withUniqueIds
238
+ .filter(({ card }) => card.is_suggested)
239
+ .map(({ card, uniqueId }) => [uniqueId, card.owner_id]));
240
+ const cardNameOptions = withUniqueIds.map(({ card, uniqueId }) => ({
241
+ id: uniqueId,
242
+ kind: card.card_type === 'department'
243
+ ? 'class'
244
+ : 'vendor',
245
+ label: card.card_name,
246
+ }));
247
+ return {
248
+ mode: 'review',
249
+ cardOptions,
250
+ cardNameOptions,
251
+ suggestedOwnerUserIdByTeamId,
252
+ teamRows,
253
+ };
254
+ };
255
+ /**
256
+ * Stamp each suggested card with a stable unique id derived from its
257
+ * `card_name_id`. If two cards in the same payload share the same
258
+ * `card_name_id` (which happens in the current sample payload where
259
+ * `card_name_id` is the literal `"vendor_uuid"`), fall back to a
260
+ * synthesized id `${kind}__${card_name_id}__${index}` so RHF row keying
261
+ * stays unique.
262
+ */
263
+ const withSynthesizedIds = (cards) => {
264
+ const seen = new Set();
265
+ return cards.map((card, index) => {
266
+ const preferred = card.card_name_id;
267
+ if (preferred != null && preferred !== '' && !seen.has(preferred)) {
268
+ seen.add(preferred);
269
+ return { card, uniqueId: preferred };
270
+ }
271
+ const synthesized = `${card.card_type}__${preferred ?? 'unknown'}__${index}`;
272
+ seen.add(synthesized);
273
+ return { card, uniqueId: synthesized };
274
+ });
275
+ };
276
+ const toCardPolicyDraftPolicy = (payload, index) => ({
277
+ id: `draft-${index}`,
278
+ name: payload.name,
279
+ description: payload.description ?? '',
280
+ mode: payload.mode,
281
+ allowedEntity: {
282
+ categoryCodes: payload.allowed_entity?.category_codes ?? [],
283
+ merchantNames: payload.allowed_entity?.merchant_names ?? [],
284
+ },
285
+ blockedEntity: {
286
+ categoryCodes: payload.blocked_entity?.category_codes ?? [],
287
+ merchantNames: payload.blocked_entity?.merchant_names ?? [],
288
+ },
289
+ applyToCards: payload.apply_to_cards ?? [],
290
+ requiredReceiptThreshold: payload.required_receipt_threshold ?? 0,
291
+ spendLimits: {
292
+ transaction: payload.spend_limits?.transaction ?? 0,
293
+ },
294
+ });
295
+ const toCardPolicyStep5Review = (payload) => ({
296
+ draftPolicies: (payload.draft_policies ?? []).map(toCardPolicyDraftPolicy),
297
+ groupingSource: payload.grouping_source ?? 'none',
298
+ prompt: payload.prompt ?? '',
299
+ });
300
+ const toCardPolicyWizardPlan = (payload) => ({
301
+ step5Review: toCardPolicyStep5Review(payload.step_5_review),
302
+ });
303
+ const toCardPolicyUploadSource = (payload) => ({
304
+ confidenceScore: payload.confidence_score,
305
+ fileName: payload.file_name,
306
+ lowConfidenceFields: payload.low_confidence_fields ?? [],
307
+ });
308
+ const toCardPolicyInitialData = (payload) => {
309
+ if (payload.mode === 'upload') {
310
+ return {
311
+ policyKind: 'upload',
312
+ wizardPlan: payload.wizard_plan != null
313
+ ? toCardPolicyWizardPlan(payload.wizard_plan)
314
+ : undefined,
315
+ source: payload.source != null
316
+ ? toCardPolicyUploadSource(payload.source)
317
+ : undefined,
318
+ };
319
+ }
320
+ return {
321
+ policyKind: payload.mode,
322
+ wizardPlan: toCardPolicyWizardPlan(payload.wizard_plan),
323
+ };
324
+ };
148
325
  const toAiCfoVisualizationData = (data) => {
149
326
  if ('x' in data && 'y' in data) {
150
327
  // Normalize y to always be an array
@@ -458,9 +635,118 @@ const aiCfo = (0, toolkit_1.createSlice)({
458
635
  session.questionAnswers.push(qa);
459
636
  }
460
637
  },
638
+ /**
639
+ * Patch the `card_policy` interactive-form payload for a specific
640
+ * answer in a chat session to merge in the wizard plan + upload
641
+ * source metadata returned by
642
+ * `POST /cards/1.0/ai-cfo/policy-recommendation-from-upload`.
643
+ *
644
+ * Dispatched by the recommendation epic after a successful response;
645
+ * the wizard re-renders Steps 2 + 3 of the upload variant once the
646
+ * payload becomes a populated `CardPolicyInitialData` with
647
+ * `policyKind: "upload"` + `wizardPlan` + `source`.
648
+ *
649
+ * No-op when the target answer / chat session / form payload is
650
+ * missing or isn't an upload-mode card-policy interactive form —
651
+ * the bridge epic is best-effort and silently drops in edge cases
652
+ * (e.g. the user closed the chat before recommendation returned).
653
+ */
654
+ updateAiCfoAnswerCardPolicyWizardPlan(draft, action) {
655
+ const { answerId, chatSessionId, source, wizardPlan } = action.payload;
656
+ const session = draft.aiCfoByChatSessionId[chatSessionId];
657
+ if (session == null) {
658
+ return;
659
+ }
660
+ const qa = session.questionAnswers.find((entry) => entry.questionAnswerId === answerId);
661
+ if (qa == null) {
662
+ return;
663
+ }
664
+ for (const response of Object.values(qa.responses)) {
665
+ const visualization = response?.content.visualization;
666
+ if (visualization == null ||
667
+ visualization.type !== 'interactive_form') {
668
+ continue;
669
+ }
670
+ const data = visualization.data;
671
+ if (data.formType !== 'card_policy' ||
672
+ data.payload.policyKind !== 'upload') {
673
+ continue;
674
+ }
675
+ data.payload = {
676
+ ...data.payload,
677
+ wizardPlan,
678
+ source: source ?? data.payload.source,
679
+ };
680
+ }
681
+ },
682
+ /**
683
+ * Append a client-synthesized answer bubble to a chat session. Used by
684
+ * the AI CFO cards/policy create flow to render a "Creating…" placeholder
685
+ * in the drawer while the underlying mutation runs.
686
+ *
687
+ * The caller is responsible for generating a stable `id` (so the same
688
+ * bubble can later be updated in place via `updateSyntheticAiCfoAnswer`
689
+ * once the mutation completes) and a `createdAt` timestamp so the
690
+ * renderer can interleave synthetic bubbles with streamed Q&A pairs in
691
+ * chronological order.
692
+ */
693
+ appendSyntheticAiCfoAnswer(draft, action) {
694
+ const { chatSessionId, id, kind, createdAt, entityIds } = action.payload;
695
+ if (draft.syntheticAnswersByChatSessionId[chatSessionId] == null) {
696
+ draft.syntheticAnswersByChatSessionId[chatSessionId] = [];
697
+ }
698
+ draft.syntheticAnswersByChatSessionId[chatSessionId].push({
699
+ id,
700
+ kind,
701
+ entityIds: entityIds ?? [],
702
+ createdAt,
703
+ });
704
+ },
705
+ /**
706
+ * Update an existing synthetic answer bubble in place. Typically called
707
+ * when the create mutation completes: the screen transitions the bubble
708
+ * from `creating_*` to `created_*` and populates `entityIds` with the
709
+ * newly created cards / policy templates.
710
+ *
711
+ * No-op when the target bubble is missing (e.g. the session was cleared
712
+ * before the mutation returned).
713
+ */
714
+ updateSyntheticAiCfoAnswer(draft, action) {
715
+ const { chatSessionId, id, kind, entityIds } = action.payload;
716
+ const list = draft.syntheticAnswersByChatSessionId[chatSessionId];
717
+ if (list == null) {
718
+ return;
719
+ }
720
+ const entry = list.find((item) => item.id === id);
721
+ if (entry == null) {
722
+ return;
723
+ }
724
+ entry.kind = kind;
725
+ if (entityIds != null) {
726
+ entry.entityIds = entityIds;
727
+ }
728
+ },
729
+ /**
730
+ * Remove a single synthetic answer bubble (e.g. when the user manually
731
+ * dismisses it or the mutation errors out and we want to fall back to
732
+ * an inline error snackbar).
733
+ */
734
+ removeSyntheticAiCfoAnswer(draft, action) {
735
+ const { chatSessionId, id } = action.payload;
736
+ const list = draft.syntheticAnswersByChatSessionId[chatSessionId];
737
+ if (list == null) {
738
+ return;
739
+ }
740
+ draft.syntheticAnswersByChatSessionId[chatSessionId] = list.filter((item) => item.id !== id);
741
+ },
742
+ /** Clear every synthetic bubble for a session. */
743
+ clearSyntheticAiCfoAnswers(draft, action) {
744
+ delete draft.syntheticAnswersByChatSessionId[action.payload];
745
+ },
461
746
  clearSession(draft, action) {
462
747
  const sessionId = action.payload;
463
748
  delete draft.aiCfoByChatSessionId[sessionId];
749
+ delete draft.syntheticAnswersByChatSessionId[sessionId];
464
750
  // Clear partial Q&A if it belongs to the cleared session
465
751
  if (draft.partialQuestionAnswers?.[sessionId] != null) {
466
752
  draft.partialQuestionAnswers[sessionId] = undefined;
@@ -469,6 +755,7 @@ const aiCfo = (0, toolkit_1.createSlice)({
469
755
  clearAiCfo(draft) {
470
756
  draft.aiCfoByChatSessionId = {};
471
757
  draft.partialQuestionAnswers = {};
758
+ draft.syntheticAnswersByChatSessionId = {};
472
759
  },
473
760
  deleteQuestion(draft, action) {
474
761
  const { chatSessionId, questionAnswerId } = action.payload;
@@ -493,5 +780,5 @@ const toChatSession = (chatSessionPayload) => {
493
780
  createdAt: (0, zeniDayJS_1.date)(created_at),
494
781
  };
495
782
  };
496
- _a = aiCfo.actions, exports.setNewSession = _a.setNewSession, exports.clearSession = _a.clearSession, exports.setSessions = _a.setSessions, exports.setChatHistory = _a.setChatHistory, exports.upsertAnswerPayload = _a.upsertAnswerPayload, exports.upsertOrAddQuestionAnswerPayload = _a.upsertOrAddQuestionAnswerPayload, exports.addQuestionPayload = _a.addQuestionPayload, exports.clearAiCfo = _a.clearAiCfo, exports.deleteQuestion = _a.deleteQuestion;
783
+ _a = aiCfo.actions, exports.setNewSession = _a.setNewSession, exports.clearSession = _a.clearSession, exports.setSessions = _a.setSessions, exports.setChatHistory = _a.setChatHistory, exports.upsertAnswerPayload = _a.upsertAnswerPayload, exports.upsertOrAddQuestionAnswerPayload = _a.upsertOrAddQuestionAnswerPayload, exports.addQuestionPayload = _a.addQuestionPayload, exports.clearAiCfo = _a.clearAiCfo, exports.deleteQuestion = _a.deleteQuestion, exports.updateAiCfoAnswerCardPolicyWizardPlan = _a.updateAiCfoAnswerCardPolicyWizardPlan, exports.appendSyntheticAiCfoAnswer = _a.appendSyntheticAiCfoAnswer, exports.updateSyntheticAiCfoAnswer = _a.updateSyntheticAiCfoAnswer, exports.removeSyntheticAiCfoAnswer = _a.removeSyntheticAiCfoAnswer, exports.clearSyntheticAiCfoAnswers = _a.clearSyntheticAiCfoAnswers;
497
784
  exports.default = aiCfo.reducer;
@@ -1,13 +1,15 @@
1
1
  import { ID } from '../../commonStateTypes/common';
2
- import { AiCfoQuestionWithAnswer, AiCfoState, ChatSession } from './aiCfoState';
2
+ import { AiCfoQuestionWithAnswer, AiCfoState, ChatSession, SyntheticAiCfoAnswer } from './aiCfoState';
3
3
  export declare function getAllQuestionAnswersForChatSession(state: AiCfoState, chatSessionId: ID): AiCfoQuestionWithAnswer[];
4
4
  export declare function getQuestionAnswerByIdForChatSession(state: AiCfoState, chatSessionId: ID, questionAnswerId: ID): AiCfoQuestionWithAnswer | undefined;
5
5
  export declare function getAllQuestionsForChatSession(state: AiCfoState, chatSessionId: ID): string[];
6
6
  export interface AiCfoSelectorView {
7
7
  allSessionsWithOrderedQuestionAnswers: ChatSessionWithOrderedQuestionAnswers[];
8
+ syntheticAnswersByChatSessionId: Record<ID, SyntheticAiCfoAnswer[]>;
8
9
  }
9
10
  export interface ChatSessionWithOrderedQuestionAnswers {
10
11
  chatSession: ChatSession;
11
12
  questionAnswers: AiCfoQuestionWithAnswer[];
12
13
  }
13
14
  export declare function getAiCfoSelectorView(state: AiCfoState): AiCfoSelectorView;
15
+ export declare function getSyntheticAiCfoAnswersForChatSession(state: AiCfoState, chatSessionId: ID): SyntheticAiCfoAnswer[];
@@ -4,6 +4,7 @@ exports.getAllQuestionAnswersForChatSession = getAllQuestionAnswersForChatSessio
4
4
  exports.getQuestionAnswerByIdForChatSession = getQuestionAnswerByIdForChatSession;
5
5
  exports.getAllQuestionsForChatSession = getAllQuestionsForChatSession;
6
6
  exports.getAiCfoSelectorView = getAiCfoSelectorView;
7
+ exports.getSyntheticAiCfoAnswersForChatSession = getSyntheticAiCfoAnswersForChatSession;
7
8
  function getAllQuestionAnswersForChatSession(state, chatSessionId) {
8
9
  const arr = state.aiCfoByChatSessionId[chatSessionId]?.questionAnswers ?? [];
9
10
  return arr
@@ -38,5 +39,14 @@ function getAiCfoSelectorView(state) {
38
39
  : [],
39
40
  }))
40
41
  .sort((a, b) => b.chatSession.createdAt.valueOf() - a.chatSession.createdAt.valueOf());
41
- return { allSessionsWithOrderedQuestionAnswers };
42
+ return {
43
+ allSessionsWithOrderedQuestionAnswers,
44
+ syntheticAnswersByChatSessionId: state.syntheticAnswersByChatSessionId ?? {},
45
+ };
46
+ }
47
+ function getSyntheticAiCfoAnswersForChatSession(state, chatSessionId) {
48
+ const arr = state.syntheticAnswersByChatSessionId?.[chatSessionId] ?? [];
49
+ return arr
50
+ .slice()
51
+ .sort((a, b) => a.createdAt.valueOf() - b.createdAt.valueOf());
42
52
  }