@zeniai/client-epic-state 5.0.65-betaML2 → 5.0.65-betaRR2

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 (121) hide show
  1. package/lib/common/aiCfo/aiCfoSuggestedQuestionsPageContext.d.ts +1 -1
  2. package/lib/entity/aiCfo/aiCfoPayload.d.ts +168 -1
  3. package/lib/entity/aiCfo/aiCfoReducer.js +186 -2
  4. package/lib/entity/aiCfo/aiCfoState.d.ts +164 -4
  5. package/lib/entity/aiCfo/aiCfoState.js +10 -1
  6. package/lib/entity/cardPolicy/cardPolicyPayload.d.ts +171 -0
  7. package/lib/entity/cardPolicy/cardPolicyPayload.js +112 -0
  8. package/lib/entity/cardPolicy/cardPolicyReducer.d.ts +13 -0
  9. package/lib/entity/cardPolicy/cardPolicyReducer.js +203 -0
  10. package/lib/entity/cardPolicy/cardPolicySelector.d.ts +28 -0
  11. package/lib/entity/cardPolicy/cardPolicySelector.js +86 -0
  12. package/lib/entity/cardPolicy/cardPolicyState.d.ts +162 -0
  13. package/lib/entity/cardPolicy/cardPolicyState.js +14 -0
  14. package/lib/entity/cardPolicy/extractPolicyDocumentEpic.d.ts +18 -0
  15. package/lib/entity/cardPolicy/extractPolicyDocumentEpic.js +54 -0
  16. package/lib/entity/cardPolicy/fetchCardPolicyVendorOptionsEpic.d.ts +26 -0
  17. package/lib/entity/cardPolicy/fetchCardPolicyVendorOptionsEpic.js +47 -0
  18. package/lib/entity/jeSchedules/jeSchedulesTypes.d.ts +1 -1
  19. package/lib/entity/monthEndCloseChecks/monthEndCloseChecksState.d.ts +1 -1
  20. package/lib/entity/tenant/clearAllEpic.d.ts +6 -2
  21. package/lib/entity/tenant/clearAllEpic.js +8 -0
  22. package/lib/epic.d.ts +9 -2
  23. package/lib/epic.js +9 -2
  24. package/lib/esm/entity/aiCfo/aiCfoReducer.js +187 -3
  25. package/lib/esm/entity/aiCfo/aiCfoState.js +7 -0
  26. package/lib/esm/entity/cardPolicy/cardPolicyPayload.js +101 -0
  27. package/lib/esm/entity/cardPolicy/cardPolicyReducer.js +199 -0
  28. package/lib/esm/entity/cardPolicy/cardPolicySelector.js +66 -0
  29. package/lib/esm/entity/cardPolicy/cardPolicyState.js +9 -0
  30. package/lib/esm/entity/cardPolicy/extractPolicyDocumentEpic.js +50 -0
  31. package/lib/esm/entity/cardPolicy/fetchCardPolicyVendorOptionsEpic.js +43 -0
  32. package/lib/esm/entity/tenant/clearAllEpic.js +8 -0
  33. package/lib/esm/epic.js +9 -2
  34. package/lib/esm/index.js +21 -7
  35. package/lib/esm/reducer.js +12 -0
  36. package/lib/esm/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +1 -21
  37. package/lib/esm/view/expenseAutomationView/reducers/transactionsViewReducer.js +14 -117
  38. package/lib/esm/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +0 -28
  39. package/lib/esm/view/recommendation/recommendationHelper.js +0 -29
  40. package/lib/esm/view/recommendation/recommendationReducer.js +1 -36
  41. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailReducer.js +70 -0
  42. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailSelector.js +22 -0
  43. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailState.js +1 -0
  44. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/fetchCardPolicyDetailEpic.js +44 -0
  45. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/updateCardPolicyEpic.js +49 -0
  46. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/archiveCardPolicyEpic.js +42 -0
  47. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListReducer.js +72 -0
  48. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListSelector.js +21 -0
  49. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListState.js +1 -0
  50. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/fetchCardPolicyListEpic.js +46 -0
  51. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyReducer.js +50 -0
  52. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicySelector.js +6 -0
  53. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyState.js +1 -0
  54. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyTemplateEpic.js +34 -0
  55. package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/fetchCardPolicyMccCategoriesEpic.js +17 -0
  56. package/lib/esm/view/transactionDetail/transactionDetailReducer.js +1 -110
  57. package/lib/esm/view/transactionDetail/transactionDetailSelector.js +0 -22
  58. package/lib/index.d.ts +20 -8
  59. package/lib/index.js +119 -35
  60. package/lib/reducer.d.ts +12 -0
  61. package/lib/reducer.js +12 -0
  62. package/lib/view/companyHealthMetricView/companyHealthMetricViewSelector.d.ts +1 -1
  63. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +0 -1
  64. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.js +2 -23
  65. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.d.ts +1 -14
  66. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.js +14 -117
  67. package/lib/view/expenseAutomationView/selectorTypes/transactionsViewSelectorTypes.d.ts +0 -2
  68. package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.d.ts +0 -3
  69. package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +0 -29
  70. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.d.ts +1 -1
  71. package/lib/view/expenseAutomationView/types/missingReceiptsViewState.d.ts +2 -2
  72. package/lib/view/expenseAutomationView/types/transactionsViewState.d.ts +1 -2
  73. package/lib/view/onboardingView/cockpitView/types/onboardingCockpitViewTypes.d.ts +1 -1
  74. package/lib/view/people/peopleTypes.d.ts +1 -1
  75. package/lib/view/recommendation/recommendationHelper.d.ts +0 -9
  76. package/lib/view/recommendation/recommendationHelper.js +1 -31
  77. package/lib/view/recommendation/recommendationReducer.d.ts +1 -18
  78. package/lib/view/recommendation/recommendationReducer.js +2 -37
  79. package/lib/view/scheduleView/scheduleListView/scheduleListTypes.d.ts +1 -1
  80. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailReducer.d.ts +14 -0
  81. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailReducer.js +74 -0
  82. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailSelector.d.ts +21 -0
  83. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailSelector.js +28 -0
  84. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailState.d.ts +25 -0
  85. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/cardPolicyDetailState.js +2 -0
  86. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/fetchCardPolicyDetailEpic.d.ts +19 -0
  87. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/fetchCardPolicyDetailEpic.js +48 -0
  88. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/updateCardPolicyEpic.d.ts +18 -0
  89. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyDetail/updateCardPolicyEpic.js +53 -0
  90. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/archiveCardPolicyEpic.d.ts +16 -0
  91. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/archiveCardPolicyEpic.js +46 -0
  92. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListReducer.d.ts +15 -0
  93. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListReducer.js +76 -0
  94. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListSelector.d.ts +21 -0
  95. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListSelector.js +27 -0
  96. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListState.d.ts +19 -0
  97. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/cardPolicyListState.js +2 -0
  98. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/fetchCardPolicyListEpic.d.ts +19 -0
  99. package/lib/view/spendManagement/chargeCards/cardPolicy/cardPolicyList/fetchCardPolicyListEpic.js +50 -0
  100. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyReducer.d.ts +12 -0
  101. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyReducer.js +54 -0
  102. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicySelector.d.ts +4 -0
  103. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicySelector.js +10 -0
  104. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyState.d.ts +15 -0
  105. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyState.js +2 -0
  106. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyTemplateEpic.d.ts +8 -0
  107. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyTemplateEpic.js +38 -0
  108. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/fetchCardPolicyMccCategoriesEpic.d.ts +15 -0
  109. package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/fetchCardPolicyMccCategoriesEpic.js +21 -0
  110. package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardList.d.ts +1 -1
  111. package/lib/view/taskManager/taskListView/taskListReducer.d.ts +1 -1
  112. package/lib/view/transactionDetail/transactionDetailReducer.d.ts +1 -11
  113. package/lib/view/transactionDetail/transactionDetailReducer.js +2 -111
  114. package/lib/view/transactionDetail/transactionDetailSelector.d.ts +0 -2
  115. package/lib/view/transactionDetail/transactionDetailSelector.js +1 -24
  116. package/lib/view/transactionDetail/transactionDetailTypes.d.ts +0 -1
  117. package/package.json +1 -1
  118. package/lib/esm/view/recommendation/fetchEntityRecommendationsForLineUpdateEpic.js +0 -88
  119. package/lib/tsconfig.typecheck.tsbuildinfo +0 -1
  120. package/lib/view/recommendation/fetchEntityRecommendationsForLineUpdateEpic.d.ts +0 -9
  121. package/lib/view/recommendation/fetchEntityRecommendationsForLineUpdateEpic.js +0 -92
@@ -0,0 +1,171 @@
1
+ import { ID } from '../../commonStateTypes/common';
2
+ import { ZeniAPIResponse } from '../../responsePayload';
3
+ import { CardPolicyStats, CardPolicyTemplate, CardPolicyTemplateEntityList, CardPolicyTemplateMode, CardPolicyTemplateSpendLimits, ExtractedCardPolicyRules, MccCategory } from './cardPolicyState';
4
+ export interface MccCategoryPayload {
5
+ count: number;
6
+ mcc_codes: string[];
7
+ name: string;
8
+ }
9
+ /**
10
+ * Wire shape for `GET /cards/1.0/cards/mcc-codes`. Beyond the universe of
11
+ * MCC categories used to populate the category search dropdown, the
12
+ * endpoint also ships **suggested** allow / block merchants and categories
13
+ * that the chip-pickers seed into their cloud body before the user starts
14
+ * editing.
15
+ *
16
+ * Field spellings (`*_catagories`) preserve the BE wire format verbatim;
17
+ * the camelCase mapper below corrects to `Categories`.
18
+ */
19
+ export interface CardPolicyMccCategoriesPayload {
20
+ categories: MccCategoryPayload[];
21
+ suggested_allow_catagories?: MccCategoryPayload[];
22
+ suggested_allow_merchants?: string[];
23
+ suggested_block_catagories?: MccCategoryPayload[];
24
+ suggested_block_merchants?: string[];
25
+ }
26
+ export type CardPolicyMccCategoriesResponse = ZeniAPIResponse<CardPolicyMccCategoriesPayload>;
27
+ export declare const toMccCategory: (payload: MccCategoryPayload) => MccCategory;
28
+ /**
29
+ * Vendor row returned by `/accounting/1.0/vendors`. The card-policy
30
+ * vendor search dropdown only needs `vendor_id` + `vendor_name`; we
31
+ * deliberately ignore the rest of the payload to keep this slice
32
+ * independent of the heavy `vendor` entity store.
33
+ */
34
+ export interface CardPolicyVendorSearchVendorPayload {
35
+ vendor_id: string;
36
+ vendor_name: string;
37
+ }
38
+ export interface CardPolicyVendorSearchData {
39
+ vendors: CardPolicyVendorSearchVendorPayload[];
40
+ }
41
+ export type CardPolicyVendorSearchResponse = ZeniAPIResponse<CardPolicyVendorSearchData>;
42
+ export interface CardPolicyVendorSearchOption {
43
+ name: string;
44
+ vendorId: string;
45
+ }
46
+ export declare const toCardPolicyVendorSearchOption: (payload: CardPolicyVendorSearchVendorPayload) => CardPolicyVendorSearchOption;
47
+ interface CardPolicyTemplateEntityListPayload {
48
+ category_codes: string[];
49
+ merchant_names: string[];
50
+ }
51
+ interface CardPolicyTemplateSpendLimitsPayload {
52
+ transaction: number;
53
+ }
54
+ /**
55
+ * Request body for `POST /cards/1.0/policy-templates`. Consumers pass the
56
+ * already-camelCased payload to the action creator; the epic re-maps it to
57
+ * the snake_case wire format before sending.
58
+ */
59
+ export interface CreateCardPolicyTemplateRequest {
60
+ allowedEntity: CardPolicyTemplateEntityList;
61
+ applyToCards: ID[];
62
+ blockedEntity: CardPolicyTemplateEntityList;
63
+ description: string;
64
+ mode: CardPolicyTemplateMode;
65
+ name: string;
66
+ requiredReceiptThreshold: number;
67
+ spendLimits: CardPolicyTemplateSpendLimits;
68
+ }
69
+ export interface CreateCardPolicyTemplateRequestBody {
70
+ allowed_entity: CardPolicyTemplateEntityListPayload;
71
+ apply_to_cards: ID[];
72
+ blocked_entity: CardPolicyTemplateEntityListPayload;
73
+ description: string;
74
+ mode: string;
75
+ name: string;
76
+ required_receipt_threshold: number;
77
+ spend_limits: CardPolicyTemplateSpendLimitsPayload;
78
+ }
79
+ export interface CardPolicyTemplatePayload {
80
+ allowed_entity: CardPolicyTemplateEntityListPayload;
81
+ applied_cards: ID[];
82
+ blocked_entity: CardPolicyTemplateEntityListPayload;
83
+ cards_count: number;
84
+ category_restrictions: unknown[];
85
+ created_at: string;
86
+ created_by: ID;
87
+ description: string;
88
+ mode: string;
89
+ name: string;
90
+ required_receipt_threshold: number;
91
+ spend_limits: CardPolicyTemplateSpendLimitsPayload;
92
+ status: string;
93
+ template_id: ID;
94
+ tenant_id: ID;
95
+ updated_at: string;
96
+ }
97
+ export interface CreateCardPolicyTemplateResponseData {
98
+ cards_applied: number;
99
+ template: CardPolicyTemplatePayload;
100
+ }
101
+ export type CreateCardPolicyTemplateResponse = ZeniAPIResponse<CreateCardPolicyTemplateResponseData>;
102
+ export type UpdateCardPolicyTemplateRequest = CreateCardPolicyTemplateRequest;
103
+ export type UpdateCardPolicyTemplateRequestBody = CreateCardPolicyTemplateRequestBody;
104
+ export type UpdateCardPolicyTemplateResponseData = CreateCardPolicyTemplateResponseData;
105
+ export type UpdateCardPolicyTemplateResponse = CreateCardPolicyTemplateResponse;
106
+ export type CardPolicyDetailResponseData = CreateCardPolicyTemplateResponseData;
107
+ export type CardPolicyDetailResponse = CreateCardPolicyTemplateResponse;
108
+ /**
109
+ * Aggregate counters returned alongside the templates list. Stored on
110
+ * the entity slice (alongside `cardPolicyTemplateById`) so any list
111
+ * surface can read it without re-fetching.
112
+ */
113
+ export interface CardPolicyStatsPayload {
114
+ active_policies: number;
115
+ total_cards: number;
116
+ total_templates: number;
117
+ }
118
+ /**
119
+ * Each list row is wrapped in the same `{cards_applied, template}`
120
+ * envelope the create endpoint returns. Only the `template` portion is
121
+ * stored on the entity slice; `cards_applied` is a one-shot summary
122
+ * carried over from create and not surfaced in the list state today.
123
+ */
124
+ export interface CardPolicyListRowPayload {
125
+ data: CreateCardPolicyTemplateResponseData;
126
+ }
127
+ export interface ListCardPolicyTemplatesResponseData {
128
+ stats: CardPolicyStatsPayload;
129
+ templates: CardPolicyListRowPayload[];
130
+ }
131
+ export type ListCardPolicyTemplatesResponse = ZeniAPIResponse<ListCardPolicyTemplatesResponseData>;
132
+ export declare const toCardPolicyStats: (payload: CardPolicyStatsPayload) => CardPolicyStats;
133
+ export declare const toCardPolicyTemplateList: (data: ListCardPolicyTemplatesResponseData) => CardPolicyTemplate[];
134
+ export declare const toCardPolicyTemplate: (payload: CardPolicyTemplatePayload) => CardPolicyTemplate;
135
+ /**
136
+ * Re-shape a camelCase create request into the snake_case wire body.
137
+ * Used by the epic at request time.
138
+ */
139
+ export declare const toCreateCardPolicyTemplateRequestBody: (request: CreateCardPolicyTemplateRequest) => CreateCardPolicyTemplateRequestBody;
140
+ export declare const toUpdateCardPolicyTemplateRequestBody: (request: CreateCardPolicyTemplateRequest) => CreateCardPolicyTemplateRequestBody;
141
+ /**
142
+ * Seed an edit-form draft (`CreateCardPolicyTemplateRequest`) from an
143
+ * existing camelCased `CardPolicyTemplate`. Used by the detail-fetch
144
+ * epic so the edit page can render with the saved values pre-populated.
145
+ */
146
+ export declare const toCardPolicyEditFormDraft: (template: CardPolicyTemplate) => CreateCardPolicyTemplateRequest;
147
+ /**
148
+ * Wire shape returned by `POST /cards/1.0/policy-documents/extract`.
149
+ * The backend OCRs / parses an uploaded policy document (PDF, image, etc.)
150
+ * and returns a best-effort set of policy rules + a confidence score.
151
+ *
152
+ * Consumers (manual `CardPolicyCreatePage` + AI CFO `CardPolicyInteractiveForm`)
153
+ * use `toExtractedCardPolicyRules` to map this onto the camelCase FE shape
154
+ * and then feed the result through `applyExtractedPolicyRulesToFormValues`
155
+ * (`@zeniai/web-components`) to seed the RHF form.
156
+ */
157
+ export interface ExtractedCardPolicyRulesPayload {
158
+ allowed_entity: CardPolicyTemplateEntityListPayload;
159
+ blocked_entity: CardPolicyTemplateEntityListPayload;
160
+ confidence_score: number;
161
+ policy_name: string;
162
+ required_receipt_threshold: number;
163
+ transaction_limit: number;
164
+ }
165
+ export interface PolicyDocumentExtractResponseData {
166
+ extracted_rules: ExtractedCardPolicyRulesPayload;
167
+ message: string;
168
+ }
169
+ export type PolicyDocumentExtractResponse = ZeniAPIResponse<PolicyDocumentExtractResponseData>;
170
+ export declare const toExtractedCardPolicyRules: (payload: ExtractedCardPolicyRulesPayload) => ExtractedCardPolicyRules;
171
+ export {};
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toExtractedCardPolicyRules = exports.toCardPolicyEditFormDraft = exports.toUpdateCardPolicyTemplateRequestBody = exports.toCreateCardPolicyTemplateRequestBody = exports.toCardPolicyTemplate = exports.toCardPolicyTemplateList = exports.toCardPolicyStats = exports.toCardPolicyVendorSearchOption = exports.toMccCategory = void 0;
4
+ const zeniDayJS_1 = require("../../zeniDayJS");
5
+ const cardPolicyState_1 = require("./cardPolicyState");
6
+ const toMccCategory = (payload) => ({
7
+ count: payload.count,
8
+ mccCodes: payload.mcc_codes ?? [],
9
+ name: payload.name,
10
+ });
11
+ exports.toMccCategory = toMccCategory;
12
+ const toCardPolicyVendorSearchOption = (payload) => ({
13
+ vendorId: payload.vendor_id,
14
+ name: payload.vendor_name,
15
+ });
16
+ exports.toCardPolicyVendorSearchOption = toCardPolicyVendorSearchOption;
17
+ const toCardPolicyStats = (payload) => ({
18
+ activePolicies: payload.active_policies,
19
+ totalCards: payload.total_cards,
20
+ totalTemplates: payload.total_templates,
21
+ });
22
+ exports.toCardPolicyStats = toCardPolicyStats;
23
+ const toCardPolicyTemplateList = (data) => (data.templates ?? []).map((row) => (0, exports.toCardPolicyTemplate)(row.data.template));
24
+ exports.toCardPolicyTemplateList = toCardPolicyTemplateList;
25
+ const toCardPolicyTemplateEntityList = (payload) => ({
26
+ categoryCodes: payload.category_codes ?? [],
27
+ merchantNames: payload.merchant_names ?? [],
28
+ });
29
+ const toCardPolicyTemplate = (payload) => ({
30
+ allowedEntity: toCardPolicyTemplateEntityList(payload.allowed_entity),
31
+ appliedCards: payload.applied_cards ?? [],
32
+ blockedEntity: toCardPolicyTemplateEntityList(payload.blocked_entity),
33
+ cardsCount: payload.cards_count,
34
+ categoryRestrictions: payload.category_restrictions ?? [],
35
+ createdAt: (0, zeniDayJS_1.date)(payload.created_at),
36
+ createdBy: payload.created_by,
37
+ description: payload.description,
38
+ mode: (0, cardPolicyState_1.toCardPolicyTemplateMode)(payload.mode),
39
+ name: payload.name,
40
+ requiredReceiptThreshold: payload.required_receipt_threshold,
41
+ spendLimits: {
42
+ transaction: payload.spend_limits.transaction,
43
+ },
44
+ status: (0, cardPolicyState_1.toCardPolicyTemplateStatus)(payload.status),
45
+ templateId: payload.template_id,
46
+ tenantId: payload.tenant_id,
47
+ updatedAt: (0, zeniDayJS_1.date)(payload.updated_at),
48
+ });
49
+ exports.toCardPolicyTemplate = toCardPolicyTemplate;
50
+ /**
51
+ * Re-shape a camelCase create request into the snake_case wire body.
52
+ * Used by the epic at request time.
53
+ */
54
+ const toCreateCardPolicyTemplateRequestBody = (request) => ({
55
+ allowed_entity: {
56
+ category_codes: request.allowedEntity.categoryCodes,
57
+ merchant_names: request.allowedEntity.merchantNames,
58
+ },
59
+ apply_to_cards: request.applyToCards,
60
+ blocked_entity: {
61
+ category_codes: request.blockedEntity.categoryCodes,
62
+ merchant_names: request.blockedEntity.merchantNames,
63
+ },
64
+ description: request.description,
65
+ mode: request.mode ?? 'strict',
66
+ name: request.name,
67
+ required_receipt_threshold: request.requiredReceiptThreshold,
68
+ spend_limits: {
69
+ transaction: request.spendLimits.transaction,
70
+ },
71
+ });
72
+ exports.toCreateCardPolicyTemplateRequestBody = toCreateCardPolicyTemplateRequestBody;
73
+ // Update body uses the exact same wire shape as create — the PUT
74
+ // endpoint is a full replace.
75
+ exports.toUpdateCardPolicyTemplateRequestBody = exports.toCreateCardPolicyTemplateRequestBody;
76
+ /**
77
+ * Seed an edit-form draft (`CreateCardPolicyTemplateRequest`) from an
78
+ * existing camelCased `CardPolicyTemplate`. Used by the detail-fetch
79
+ * epic so the edit page can render with the saved values pre-populated.
80
+ */
81
+ const toCardPolicyEditFormDraft = (template) => ({
82
+ allowedEntity: {
83
+ categoryCodes: [...template.allowedEntity.categoryCodes],
84
+ merchantNames: [...template.allowedEntity.merchantNames],
85
+ },
86
+ applyToCards: [...template.appliedCards],
87
+ blockedEntity: {
88
+ categoryCodes: [...template.blockedEntity.categoryCodes],
89
+ merchantNames: [...template.blockedEntity.merchantNames],
90
+ },
91
+ description: template.description,
92
+ mode: template.mode,
93
+ name: template.name,
94
+ requiredReceiptThreshold: template.requiredReceiptThreshold,
95
+ spendLimits: { transaction: template.spendLimits.transaction },
96
+ });
97
+ exports.toCardPolicyEditFormDraft = toCardPolicyEditFormDraft;
98
+ const toExtractedCardPolicyRules = (payload) => ({
99
+ allowedEntity: {
100
+ categoryCodes: payload.allowed_entity?.category_codes ?? [],
101
+ merchantNames: payload.allowed_entity?.merchant_names ?? [],
102
+ },
103
+ blockedEntity: {
104
+ categoryCodes: payload.blocked_entity?.category_codes ?? [],
105
+ merchantNames: payload.blocked_entity?.merchant_names ?? [],
106
+ },
107
+ confidenceScore: payload.confidence_score,
108
+ policyName: payload.policy_name,
109
+ requiredReceiptThreshold: payload.required_receipt_threshold,
110
+ transactionLimit: payload.transaction_limit,
111
+ });
112
+ exports.toExtractedCardPolicyRules = toExtractedCardPolicyRules;
@@ -0,0 +1,13 @@
1
+ import { ZeniAPIStatus } from '../../responsePayload';
2
+ import { CardPolicyMccCategoriesPayload, CardPolicyTemplatePayload, CardPolicyVendorSearchData, ExtractedCardPolicyRulesPayload } from './cardPolicyPayload';
3
+ import { CardPolicyState, CardPolicyStats, CardPolicyTemplate } from './cardPolicyState';
4
+ export declare const initialState: CardPolicyState;
5
+ export declare const fetchCardPolicyMccCategories: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"cardPolicy/fetchCardPolicyMccCategories">, fetchCardPolicyVendorOptions: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[searchString?: string | undefined], {
6
+ searchString: string;
7
+ }, "cardPolicy/fetchCardPolicyVendorOptions", never, never>, updateCardPolicyMccCategories: import("@reduxjs/toolkit").ActionCreatorWithPayload<CardPolicyMccCategoriesPayload, "cardPolicy/updateCardPolicyMccCategories">, updateCardPolicyMccCategoriesFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "cardPolicy/updateCardPolicyMccCategoriesFailure">, updateCardPolicyVendorOptions: import("@reduxjs/toolkit").ActionCreatorWithPayload<CardPolicyVendorSearchData, "cardPolicy/updateCardPolicyVendorOptions">, updateCardPolicyVendorOptionsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "cardPolicy/updateCardPolicyVendorOptionsFailure">, updateCreatedCardPolicyTemplate: import("@reduxjs/toolkit").ActionCreatorWithPayload<CardPolicyTemplatePayload, "cardPolicy/updateCreatedCardPolicyTemplate">, updateCardPolicyTemplates: import("@reduxjs/toolkit").ActionCreatorWithPayload<CardPolicyTemplate[], "cardPolicy/updateCardPolicyTemplates">, removeCardPolicyTemplate: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "cardPolicy/removeCardPolicyTemplate">, updateCardPolicyStats: import("@reduxjs/toolkit").ActionCreatorWithPayload<CardPolicyStats, "cardPolicy/updateCardPolicyStats">, extractPolicyDocument: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[files: File[]], {
8
+ files: File[];
9
+ }, "cardPolicy/extractPolicyDocument", never, {
10
+ uploadedFileName: string;
11
+ }>, updatePolicyDocumentExtractionSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<ExtractedCardPolicyRulesPayload, "cardPolicy/updatePolicyDocumentExtractionSuccess">, updatePolicyDocumentExtractionFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "cardPolicy/updatePolicyDocumentExtractionFailure">, clearPolicyDocumentExtraction: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"cardPolicy/clearPolicyDocumentExtraction">, clearCardPolicy: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"cardPolicy/clearCardPolicy">;
12
+ declare const _default: import("redux").Reducer<CardPolicyState>;
13
+ export default _default;
@@ -0,0 +1,203 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.clearCardPolicy = exports.clearPolicyDocumentExtraction = exports.updatePolicyDocumentExtractionFailure = exports.updatePolicyDocumentExtractionSuccess = exports.extractPolicyDocument = exports.updateCardPolicyStats = exports.removeCardPolicyTemplate = exports.updateCardPolicyTemplates = exports.updateCreatedCardPolicyTemplate = exports.updateCardPolicyVendorOptionsFailure = exports.updateCardPolicyVendorOptions = exports.updateCardPolicyMccCategoriesFailure = exports.updateCardPolicyMccCategories = exports.fetchCardPolicyVendorOptions = exports.fetchCardPolicyMccCategories = exports.initialState = void 0;
5
+ const toolkit_1 = require("@reduxjs/toolkit");
6
+ const cardPolicyPayload_1 = require("./cardPolicyPayload");
7
+ /**
8
+ * Defensive predicate for vendor / merchant names that flow into
9
+ * `buildVendorChipId(name)` (in `@zeniai/web-components`). That helper
10
+ * calls `name.trim().toLowerCase()`, so a null / undefined / whitespace-
11
+ * only value would throw at render time, and an empty string would
12
+ * collapse every nameless row into a single colliding `vendor-` chip-id.
13
+ * Used at the redux ingestion boundary for both the vendor-search results
14
+ * and the BE-suggested merchant seed arrays.
15
+ */
16
+ const isUsableMerchantName = (name) => typeof name === 'string' && name.trim() !== '';
17
+ const initialPolicyDocumentExtractionState = {
18
+ fetchState: 'Not-Started',
19
+ error: undefined,
20
+ extractedRules: undefined,
21
+ uploadedFileName: undefined,
22
+ };
23
+ const initialVendorSearchState = {
24
+ fetchState: 'Not-Started',
25
+ searchString: '',
26
+ vendors: [],
27
+ error: undefined,
28
+ };
29
+ exports.initialState = {
30
+ cardPolicyTemplateById: {},
31
+ mccCategories: [],
32
+ mccCategoriesError: undefined,
33
+ mccCategoriesFetchState: 'Not-Started',
34
+ policyDocumentExtraction: initialPolicyDocumentExtractionState,
35
+ suggestedAllowCategories: [],
36
+ suggestedAllowMerchants: [],
37
+ suggestedBlockCategories: [],
38
+ suggestedBlockMerchants: [],
39
+ vendorSearch: initialVendorSearchState,
40
+ cardPolicyStats: undefined,
41
+ };
42
+ const cardPolicy = (0, toolkit_1.createSlice)({
43
+ name: 'cardPolicy',
44
+ initialState: exports.initialState,
45
+ reducers: {
46
+ fetchCardPolicyMccCategories(draft) {
47
+ draft.mccCategoriesFetchState = 'In-Progress';
48
+ draft.mccCategoriesError = undefined;
49
+ },
50
+ updateCardPolicyMccCategories(draft, action) {
51
+ draft.mccCategories = (action.payload.categories ?? []).map(cardPolicyPayload_1.toMccCategory);
52
+ // Persist BE-suggested allow / block seeds alongside the universe.
53
+ // Both flows (manual create page + AI CFO interactive form) read
54
+ // these to pre-populate the chip cloud body before the user edits.
55
+ // Drop empty / nullish merchant names defensively — they feed
56
+ // `buildVendorChipId(name)` (in @zeniai/web-components) which calls
57
+ // `.trim().toLowerCase()` and would crash the chip-picker render
58
+ // path if any entry slipped through as undefined / "".
59
+ draft.suggestedAllowMerchants = (action.payload.suggested_allow_merchants ?? []).filter(isUsableMerchantName);
60
+ draft.suggestedBlockMerchants = (action.payload.suggested_block_merchants ?? []).filter(isUsableMerchantName);
61
+ draft.suggestedAllowCategories = (action.payload.suggested_allow_catagories ?? []).map(cardPolicyPayload_1.toMccCategory);
62
+ draft.suggestedBlockCategories = (action.payload.suggested_block_catagories ?? []).map(cardPolicyPayload_1.toMccCategory);
63
+ draft.mccCategoriesFetchState = 'Completed';
64
+ draft.mccCategoriesError = undefined;
65
+ },
66
+ updateCardPolicyMccCategoriesFailure(draft, action) {
67
+ draft.mccCategoriesFetchState = 'Error';
68
+ draft.mccCategoriesError = action.payload;
69
+ },
70
+ /**
71
+ * Store a newly-created (or refreshed) card-policy template keyed by
72
+ * `templateId`. Dispatched by the create / list / get epics; consumed
73
+ * by both manual and AI-CFO policy flows via `getCardPolicyTemplateById`.
74
+ */
75
+ updateCreatedCardPolicyTemplate(draft, action) {
76
+ const template = (0, cardPolicyPayload_1.toCardPolicyTemplate)(action.payload);
77
+ draft.cardPolicyTemplateById[template.templateId] = template;
78
+ },
79
+ /**
80
+ * Replace the entity store's `cardPolicyTemplateById` map with the
81
+ * full list returned by the templates-list endpoint. Full replace is
82
+ * intentional — templates that no longer exist on the server should be
83
+ * dropped from local state too. The view slice keeps the server-order
84
+ * ID list separately for stable list rendering.
85
+ */
86
+ updateCardPolicyTemplates(draft, action) {
87
+ const byId = {};
88
+ for (const template of action.payload) {
89
+ byId[template.templateId] = template;
90
+ }
91
+ draft.cardPolicyTemplateById = byId;
92
+ },
93
+ /**
94
+ * Drop a single template from the entity map. Dispatched by the
95
+ * archive (DELETE) epic on success; also usable by any future flow
96
+ * that needs to evict a template (e.g. AI-CFO rejection).
97
+ */
98
+ removeCardPolicyTemplate(draft, action) {
99
+ delete draft.cardPolicyTemplateById[action.payload];
100
+ },
101
+ /**
102
+ * Replace the tenant-wide policy stats. Dispatched alongside
103
+ * `updateCardPolicyTemplates` from the list epic, but lives on the
104
+ * entity slice so any consumer can read it without re-fetching the
105
+ * list.
106
+ */
107
+ updateCardPolicyStats(draft, action) {
108
+ draft.cardPolicyStats = action.payload;
109
+ },
110
+ /**
111
+ * Kick off the `POST /cards/1.0/policy-documents/extract` request.
112
+ *
113
+ * Synchronously flips the sub-slice to `In-Progress` and captures the
114
+ * first uploaded file's name (used by the manual `CardPolicyCreatePage`
115
+ * to render the "Policy.pdf ×" pill once the request completes) so
116
+ * downstream callers don't have to keep their own file refs.
117
+ *
118
+ * The accompanying `extractPolicyDocumentEpic` listens for this action,
119
+ * POSTs multipart form-data to the cards micro-service, and dispatches
120
+ * either `updatePolicyDocumentExtractionSuccess` or
121
+ * `updatePolicyDocumentExtractionFailure`.
122
+ *
123
+ * Designed to be dispatched from both the manual create page and a
124
+ * future AI CFO composer/upload surface — selectors return a single
125
+ * source of truth.
126
+ */
127
+ extractPolicyDocument: {
128
+ reducer(draft, action) {
129
+ draft.policyDocumentExtraction.fetchState = 'In-Progress';
130
+ draft.policyDocumentExtraction.error = undefined;
131
+ draft.policyDocumentExtraction.extractedRules = undefined;
132
+ draft.policyDocumentExtraction.uploadedFileName =
133
+ action.meta.uploadedFileName;
134
+ },
135
+ prepare(files) {
136
+ return {
137
+ payload: { files },
138
+ meta: { uploadedFileName: files[0]?.name },
139
+ };
140
+ },
141
+ },
142
+ updatePolicyDocumentExtractionSuccess(draft, action) {
143
+ draft.policyDocumentExtraction.fetchState = 'Completed';
144
+ draft.policyDocumentExtraction.error = undefined;
145
+ draft.policyDocumentExtraction.extractedRules =
146
+ (0, cardPolicyPayload_1.toExtractedCardPolicyRules)(action.payload);
147
+ },
148
+ updatePolicyDocumentExtractionFailure(draft, action) {
149
+ draft.policyDocumentExtraction.fetchState = 'Error';
150
+ draft.policyDocumentExtraction.error = action.payload;
151
+ draft.policyDocumentExtraction.extractedRules = undefined;
152
+ },
153
+ clearPolicyDocumentExtraction(draft) {
154
+ draft.policyDocumentExtraction = {
155
+ ...initialPolicyDocumentExtractionState,
156
+ };
157
+ },
158
+ /**
159
+ * Kick off `GET /accounting/1.0/vendors` (card-policy mode). When
160
+ * `searchString` is empty the BE returns the top vendors sorted by
161
+ * year-to-date spend; with a non-empty value it filters server-side.
162
+ *
163
+ * The accompanying `fetchCardPolicyVendorOptionsEpic` listens for
164
+ * this action, builds the `query` JSON (matching `fetchVendorsList`'s
165
+ * `view: "vendor_list"` shape) and dispatches success / failure.
166
+ *
167
+ * Designed to be dispatched from both the manual `CardPolicyCreate /
168
+ * EditScreen` (on mount + on every chip-picker keystroke, debounced)
169
+ * and the AI CFO interactive form's vendor step.
170
+ */
171
+ fetchCardPolicyVendorOptions: {
172
+ reducer(draft, action) {
173
+ draft.vendorSearch.fetchState = 'In-Progress';
174
+ draft.vendorSearch.searchString = action.payload.searchString;
175
+ draft.vendorSearch.error = undefined;
176
+ },
177
+ prepare(searchString) {
178
+ return { payload: { searchString: searchString ?? '' } };
179
+ },
180
+ },
181
+ updateCardPolicyVendorOptions(draft, action) {
182
+ // Drop rows with no usable name. The chip-picker keys vendors by
183
+ // `buildVendorChipId(name)` (in @zeniai/web-components), which calls
184
+ // `name.trim().toLowerCase()`. A null / undefined / whitespace-only
185
+ // name would either throw at render time or collapse every nameless
186
+ // row into a single colliding `vendor-` chip-id.
187
+ draft.vendorSearch.vendors = (action.payload.vendors ?? [])
188
+ .map(cardPolicyPayload_1.toCardPolicyVendorSearchOption)
189
+ .filter((vendor) => isUsableMerchantName(vendor.name));
190
+ draft.vendorSearch.fetchState = 'Completed';
191
+ draft.vendorSearch.error = undefined;
192
+ },
193
+ updateCardPolicyVendorOptionsFailure(draft, action) {
194
+ draft.vendorSearch.fetchState = 'Error';
195
+ draft.vendorSearch.error = action.payload;
196
+ },
197
+ clearCardPolicy(draft) {
198
+ Object.assign(draft, exports.initialState);
199
+ },
200
+ },
201
+ });
202
+ _a = cardPolicy.actions, exports.fetchCardPolicyMccCategories = _a.fetchCardPolicyMccCategories, exports.fetchCardPolicyVendorOptions = _a.fetchCardPolicyVendorOptions, exports.updateCardPolicyMccCategories = _a.updateCardPolicyMccCategories, exports.updateCardPolicyMccCategoriesFailure = _a.updateCardPolicyMccCategoriesFailure, exports.updateCardPolicyVendorOptions = _a.updateCardPolicyVendorOptions, exports.updateCardPolicyVendorOptionsFailure = _a.updateCardPolicyVendorOptionsFailure, exports.updateCreatedCardPolicyTemplate = _a.updateCreatedCardPolicyTemplate, exports.updateCardPolicyTemplates = _a.updateCardPolicyTemplates, exports.removeCardPolicyTemplate = _a.removeCardPolicyTemplate, exports.updateCardPolicyStats = _a.updateCardPolicyStats, exports.extractPolicyDocument = _a.extractPolicyDocument, exports.updatePolicyDocumentExtractionSuccess = _a.updatePolicyDocumentExtractionSuccess, exports.updatePolicyDocumentExtractionFailure = _a.updatePolicyDocumentExtractionFailure, exports.clearPolicyDocumentExtraction = _a.clearPolicyDocumentExtraction, exports.clearCardPolicy = _a.clearCardPolicy;
203
+ exports.default = cardPolicy.reducer;
@@ -0,0 +1,28 @@
1
+ import { FetchState, ID } from '../../commonStateTypes/common';
2
+ import { ZeniAPIStatus } from '../../responsePayload';
3
+ import { CardPolicyState, CardPolicyStats, CardPolicyTemplate, CardPolicyVendorSearchEntry, ExtractedCardPolicyRules, MccCategory } from './cardPolicyState';
4
+ export declare function getCardPolicyMccCategories(state: CardPolicyState): MccCategory[];
5
+ export declare function getCardPolicyMccCategoriesFetchState(state: CardPolicyState): FetchState;
6
+ export declare function getCardPolicyMccCategoriesError(state: CardPolicyState): ZeniAPIStatus | undefined;
7
+ export declare function getCardPolicyTemplateById(state: CardPolicyState, templateId: ID): CardPolicyTemplate | undefined;
8
+ export declare function getAllCardPolicyTemplates(state: CardPolicyState): CardPolicyTemplate[];
9
+ /**
10
+ * Resolve an ordered list of `templateId`s against the entity store and
11
+ * return the corresponding `CardPolicyTemplate[]` in the same order.
12
+ * Missing IDs (e.g. stale local state during a refetch) are silently
13
+ * dropped. Pair with `getCardPolicyTemplateIds` from the view slice to
14
+ * render the Policy List page in server order.
15
+ */
16
+ export declare function getCardPolicyTemplatesByIds(state: CardPolicyState, templateIds: ID[]): CardPolicyTemplate[];
17
+ export declare function getCardPolicyStats(state: CardPolicyState): CardPolicyStats | undefined;
18
+ export declare function getPolicyDocumentExtractionFetchState(state: CardPolicyState): FetchState;
19
+ export declare function getPolicyDocumentExtractionError(state: CardPolicyState): ZeniAPIStatus | undefined;
20
+ export declare function getExtractedCardPolicyRules(state: CardPolicyState): ExtractedCardPolicyRules | undefined;
21
+ export declare function getUploadedPolicyDocumentFileName(state: CardPolicyState): string | undefined;
22
+ export declare function getCardPolicySuggestedAllowMerchants(state: CardPolicyState): string[];
23
+ export declare function getCardPolicySuggestedBlockMerchants(state: CardPolicyState): string[];
24
+ export declare function getCardPolicySuggestedAllowCategories(state: CardPolicyState): MccCategory[];
25
+ export declare function getCardPolicySuggestedBlockCategories(state: CardPolicyState): MccCategory[];
26
+ export declare function getCardPolicyVendorSearchOptions(state: CardPolicyState): CardPolicyVendorSearchEntry[];
27
+ export declare function getCardPolicyVendorSearchFetchState(state: CardPolicyState): FetchState;
28
+ export declare function getCardPolicyVendorSearchString(state: CardPolicyState): string;
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCardPolicyMccCategories = getCardPolicyMccCategories;
4
+ exports.getCardPolicyMccCategoriesFetchState = getCardPolicyMccCategoriesFetchState;
5
+ exports.getCardPolicyMccCategoriesError = getCardPolicyMccCategoriesError;
6
+ exports.getCardPolicyTemplateById = getCardPolicyTemplateById;
7
+ exports.getAllCardPolicyTemplates = getAllCardPolicyTemplates;
8
+ exports.getCardPolicyTemplatesByIds = getCardPolicyTemplatesByIds;
9
+ exports.getCardPolicyStats = getCardPolicyStats;
10
+ exports.getPolicyDocumentExtractionFetchState = getPolicyDocumentExtractionFetchState;
11
+ exports.getPolicyDocumentExtractionError = getPolicyDocumentExtractionError;
12
+ exports.getExtractedCardPolicyRules = getExtractedCardPolicyRules;
13
+ exports.getUploadedPolicyDocumentFileName = getUploadedPolicyDocumentFileName;
14
+ exports.getCardPolicySuggestedAllowMerchants = getCardPolicySuggestedAllowMerchants;
15
+ exports.getCardPolicySuggestedBlockMerchants = getCardPolicySuggestedBlockMerchants;
16
+ exports.getCardPolicySuggestedAllowCategories = getCardPolicySuggestedAllowCategories;
17
+ exports.getCardPolicySuggestedBlockCategories = getCardPolicySuggestedBlockCategories;
18
+ exports.getCardPolicyVendorSearchOptions = getCardPolicyVendorSearchOptions;
19
+ exports.getCardPolicyVendorSearchFetchState = getCardPolicyVendorSearchFetchState;
20
+ exports.getCardPolicyVendorSearchString = getCardPolicyVendorSearchString;
21
+ function getCardPolicyMccCategories(state) {
22
+ return state.mccCategories;
23
+ }
24
+ function getCardPolicyMccCategoriesFetchState(state) {
25
+ return state.mccCategoriesFetchState;
26
+ }
27
+ function getCardPolicyMccCategoriesError(state) {
28
+ return state.mccCategoriesError;
29
+ }
30
+ function getCardPolicyTemplateById(state, templateId) {
31
+ return state.cardPolicyTemplateById[templateId];
32
+ }
33
+ function getAllCardPolicyTemplates(state) {
34
+ return Object.values(state.cardPolicyTemplateById);
35
+ }
36
+ /**
37
+ * Resolve an ordered list of `templateId`s against the entity store and
38
+ * return the corresponding `CardPolicyTemplate[]` in the same order.
39
+ * Missing IDs (e.g. stale local state during a refetch) are silently
40
+ * dropped. Pair with `getCardPolicyTemplateIds` from the view slice to
41
+ * render the Policy List page in server order.
42
+ */
43
+ function getCardPolicyTemplatesByIds(state, templateIds) {
44
+ return templateIds
45
+ .map((id) => state.cardPolicyTemplateById[id])
46
+ .filter((template) => template != null);
47
+ }
48
+ function getCardPolicyStats(state) {
49
+ return state.cardPolicyStats;
50
+ }
51
+ // ── Policy document extraction ───────────────────────────────────────
52
+ function getPolicyDocumentExtractionFetchState(state) {
53
+ return state.policyDocumentExtraction.fetchState;
54
+ }
55
+ function getPolicyDocumentExtractionError(state) {
56
+ return state.policyDocumentExtraction.error;
57
+ }
58
+ function getExtractedCardPolicyRules(state) {
59
+ return state.policyDocumentExtraction.extractedRules;
60
+ }
61
+ function getUploadedPolicyDocumentFileName(state) {
62
+ return state.policyDocumentExtraction.uploadedFileName;
63
+ }
64
+ // ── Suggested allow / block seeds (shipped alongside MCC categories) ─
65
+ function getCardPolicySuggestedAllowMerchants(state) {
66
+ return state.suggestedAllowMerchants;
67
+ }
68
+ function getCardPolicySuggestedBlockMerchants(state) {
69
+ return state.suggestedBlockMerchants;
70
+ }
71
+ function getCardPolicySuggestedAllowCategories(state) {
72
+ return state.suggestedAllowCategories;
73
+ }
74
+ function getCardPolicySuggestedBlockCategories(state) {
75
+ return state.suggestedBlockCategories;
76
+ }
77
+ // ── Vendor search dropdown ───────────────────────────────────────────
78
+ function getCardPolicyVendorSearchOptions(state) {
79
+ return state.vendorSearch.vendors;
80
+ }
81
+ function getCardPolicyVendorSearchFetchState(state) {
82
+ return state.vendorSearch.fetchState;
83
+ }
84
+ function getCardPolicyVendorSearchString(state) {
85
+ return state.vendorSearch.searchString;
86
+ }