@zeniai/client-epic-state 5.0.65-betaRR5 → 5.0.65-betaRR7
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.
- package/lib/entity/aiCfo/aiCfoPayload.d.ts +67 -64
- package/lib/entity/aiCfo/aiCfoReducer.d.ts +7 -1
- package/lib/entity/aiCfo/aiCfoReducer.js +87 -56
- package/lib/entity/aiCfo/aiCfoState.d.ts +58 -59
- package/lib/entity/cardPolicy/cardPolicyPayload.d.ts +106 -5
- package/lib/entity/cardPolicy/cardPolicyPayload.js +35 -4
- package/lib/entity/cardPolicy/cardPolicyReducer.d.ts +9 -3
- package/lib/entity/cardPolicy/cardPolicyReducer.js +57 -4
- package/lib/entity/cardPolicy/cardPolicySelector.d.ts +4 -0
- package/lib/entity/cardPolicy/cardPolicySelector.js +17 -0
- package/lib/entity/cardPolicy/cardPolicyState.d.ts +33 -0
- package/lib/entity/cardPolicy/policyDocumentExtractionToRecommendationBridgeEpic.d.ts +25 -0
- package/lib/entity/cardPolicy/policyDocumentExtractionToRecommendationBridgeEpic.js +39 -0
- package/lib/entity/cardPolicy/policyRecommendationFromUploadEpic.d.ts +23 -0
- package/lib/entity/cardPolicy/policyRecommendationFromUploadEpic.js +92 -0
- package/lib/epic.d.ts +3 -1
- package/lib/epic.js +3 -1
- package/lib/esm/entity/aiCfo/aiCfoReducer.js +86 -55
- package/lib/esm/entity/cardPolicy/cardPolicyPayload.js +32 -3
- package/lib/esm/entity/cardPolicy/cardPolicyReducer.js +56 -3
- package/lib/esm/entity/cardPolicy/cardPolicySelector.js +13 -0
- package/lib/esm/entity/cardPolicy/policyDocumentExtractionToRecommendationBridgeEpic.js +35 -0
- package/lib/esm/entity/cardPolicy/policyRecommendationFromUploadEpic.js +88 -0
- package/lib/esm/epic.js +4 -2
- package/lib/esm/index.js +10 -9
- package/lib/esm/view/aiCfoView/aiCfoViewReducer.js +6 -3
- package/lib/esm/view/aiCfoView/epics/createSessionAndSubmitEpic.js +5 -2
- package/lib/esm/view/aiCfoView/epics/createSessionEpic.js +2 -1
- package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyReducer.js +22 -13
- package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicySelector.js +26 -1
- package/lib/esm/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyTemplateEpic.js +27 -8
- package/lib/esm/view/spendManagement/chargeCards/chargeCardList/chargeCardListSelector.js +25 -0
- package/lib/index.d.ts +10 -10
- package/lib/index.js +29 -15
- package/lib/view/aiCfoView/aiCfoViewReducer.d.ts +4 -2
- package/lib/view/aiCfoView/aiCfoViewReducer.js +6 -3
- package/lib/view/aiCfoView/epics/createSessionAndSubmitEpic.js +5 -2
- package/lib/view/aiCfoView/epics/createSessionEpic.js +2 -1
- package/lib/view/companyHealthMetricView/companyHealthMetricViewSelector.d.ts +1 -1
- package/lib/view/onboardingView/cockpitView/types/onboardingCockpitViewTypes.d.ts +1 -1
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyReducer.d.ts +4 -3
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyReducer.js +23 -14
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicySelector.d.ts +22 -0
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicySelector.js +28 -1
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyState.d.ts +29 -8
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyTemplateEpic.d.ts +20 -3
- package/lib/view/spendManagement/chargeCards/cardPolicy/createCardPolicy/createCardPolicyTemplateEpic.js +27 -8
- package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardList.d.ts +1 -1
- package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardListSelector.d.ts +14 -0
- package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardListSelector.js +27 -1
- package/package.json +1 -1
|
@@ -96,85 +96,88 @@ export type CardsCreationInitialDataPayload = {
|
|
|
96
96
|
mode: 'cards-only';
|
|
97
97
|
};
|
|
98
98
|
/**
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* items omit it.
|
|
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).
|
|
102
101
|
*/
|
|
103
|
-
export interface
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
label: string;
|
|
107
|
-
optional_code?: string | null;
|
|
102
|
+
export interface DraftPolicyEntityPayload {
|
|
103
|
+
category_codes: string[];
|
|
104
|
+
merchant_names: string[];
|
|
108
105
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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;
|
|
113
114
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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;
|
|
128
132
|
}
|
|
129
133
|
/**
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
* the expandable policy card; the FE classifies them visually via the
|
|
133
|
-
* `chip_kind` discriminator.
|
|
134
|
+
* `step_5_review` block — the only step in `wizard_plan` the FE reads.
|
|
135
|
+
* Steps 1–4 are intentionally not modeled.
|
|
134
136
|
*/
|
|
135
|
-
export interface
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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;
|
|
139
144
|
}
|
|
140
|
-
export interface
|
|
141
|
-
|
|
142
|
-
id: string;
|
|
143
|
-
label: string;
|
|
145
|
+
export interface CardPolicyWizardPlanPayload {
|
|
146
|
+
step_5_review: CardPolicyStep5ReviewPayload;
|
|
144
147
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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[];
|
|
150
157
|
}
|
|
151
158
|
/**
|
|
152
|
-
* Discriminated payload for the AI Card Policy interactive form.
|
|
153
|
-
* the
|
|
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`.
|
|
154
162
|
*
|
|
155
|
-
* - `
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
* optional suggested-policy seed.
|
|
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.
|
|
163
170
|
*/
|
|
164
171
|
export type CardPolicyInitialDataPayload = {
|
|
165
|
-
|
|
166
|
-
|
|
172
|
+
mode: 'auto';
|
|
173
|
+
wizard_plan: CardPolicyWizardPlanPayload;
|
|
167
174
|
} | {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
default_limits: CardPolicyLimitRowSeedPayload[];
|
|
171
|
-
policy_kind: 'full-builder';
|
|
172
|
-
suggested_policies: CardPolicySuggestedPolicyPayload[];
|
|
173
|
-
vendors: CardPolicyTagSeedPayload[];
|
|
175
|
+
mode: 'guided';
|
|
176
|
+
wizard_plan: CardPolicyWizardPlanPayload;
|
|
174
177
|
} | {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
+
mode: 'upload';
|
|
179
|
+
source?: CardPolicyUploadSourcePayload;
|
|
180
|
+
wizard_plan?: CardPolicyWizardPlanPayload;
|
|
178
181
|
};
|
|
179
182
|
/**
|
|
180
183
|
* Discriminated visualization payload. The FE narrows on `form_type` and
|
|
@@ -2,6 +2,7 @@ import { ID } from '../../commonStateTypes/common';
|
|
|
2
2
|
import { ZeniDate } from '../../zeniDayJS';
|
|
3
3
|
import { AiCfoAnswerPayload, AiCfoVisualizationPayload, ChatSessionPayload, MessagePayload } from './aiCfoPayload';
|
|
4
4
|
import { AiCfoState, AiCfoVisualization, FileAttachmentMetadata } 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,11 @@ 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">;
|
|
45
51
|
declare const _default: import("redux").Reducer<AiCfoState>;
|
|
46
52
|
export default _default;
|
|
@@ -1,7 +1,7 @@
|
|
|
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.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");
|
|
@@ -268,67 +268,55 @@ const withSynthesizedIds = (cards) => {
|
|
|
268
268
|
return { card, uniqueId: synthesized };
|
|
269
269
|
});
|
|
270
270
|
};
|
|
271
|
+
const toCardPolicyDraftPolicy = (payload, index) => ({
|
|
272
|
+
id: `draft-${index}`,
|
|
273
|
+
name: payload.name,
|
|
274
|
+
description: payload.description ?? '',
|
|
275
|
+
mode: payload.mode,
|
|
276
|
+
allowedEntity: {
|
|
277
|
+
categoryCodes: payload.allowed_entity?.category_codes ?? [],
|
|
278
|
+
merchantNames: payload.allowed_entity?.merchant_names ?? [],
|
|
279
|
+
},
|
|
280
|
+
blockedEntity: {
|
|
281
|
+
categoryCodes: payload.blocked_entity?.category_codes ?? [],
|
|
282
|
+
merchantNames: payload.blocked_entity?.merchant_names ?? [],
|
|
283
|
+
},
|
|
284
|
+
applyToCards: payload.apply_to_cards ?? [],
|
|
285
|
+
requiredReceiptThreshold: payload.required_receipt_threshold ?? 0,
|
|
286
|
+
spendLimits: {
|
|
287
|
+
transaction: payload.spend_limits?.transaction ?? 0,
|
|
288
|
+
},
|
|
289
|
+
});
|
|
290
|
+
const toCardPolicyStep5Review = (payload) => ({
|
|
291
|
+
draftPolicies: (payload.draft_policies ?? []).map(toCardPolicyDraftPolicy),
|
|
292
|
+
groupingSource: payload.grouping_source ?? 'none',
|
|
293
|
+
prompt: payload.prompt ?? '',
|
|
294
|
+
});
|
|
295
|
+
const toCardPolicyWizardPlan = (payload) => ({
|
|
296
|
+
step5Review: toCardPolicyStep5Review(payload.step_5_review),
|
|
297
|
+
});
|
|
298
|
+
const toCardPolicyUploadSource = (payload) => ({
|
|
299
|
+
confidenceScore: payload.confidence_score,
|
|
300
|
+
fileName: payload.file_name,
|
|
301
|
+
lowConfidenceFields: payload.low_confidence_fields ?? [],
|
|
302
|
+
});
|
|
271
303
|
const toCardPolicyInitialData = (payload) => {
|
|
272
|
-
|
|
273
|
-
id: policy.id,
|
|
274
|
-
isChecked: policy.is_checked,
|
|
275
|
-
name: policy.name,
|
|
276
|
-
chipGroups: (policy.chip_groups ?? []).map((group) => ({
|
|
277
|
-
id: group.id,
|
|
278
|
-
label: group.label,
|
|
279
|
-
chips: (group.chips ?? []).map((chip) => ({
|
|
280
|
-
id: chip.id,
|
|
281
|
-
label: chip.label,
|
|
282
|
-
chipKind: chip.chip_kind,
|
|
283
|
-
})),
|
|
284
|
-
})),
|
|
285
|
-
}));
|
|
286
|
-
if (payload.policy_kind === 'review-only') {
|
|
287
|
-
return {
|
|
288
|
-
policyKind: 'review-only',
|
|
289
|
-
suggestedPolicies,
|
|
290
|
-
};
|
|
291
|
-
}
|
|
292
|
-
const toCardRowSeed = (card) => ({
|
|
293
|
-
cardName: card.card_name,
|
|
294
|
-
id: card.id,
|
|
295
|
-
isChecked: card.is_checked,
|
|
296
|
-
last4: card.last4,
|
|
297
|
-
limitAmount: card.limit_amount,
|
|
298
|
-
limitCadence: card.limit_cadence ?? undefined,
|
|
299
|
-
owner: {
|
|
300
|
-
userId: card.owner.user_id,
|
|
301
|
-
displayName: card.owner.display_name,
|
|
302
|
-
roleLabel: card.owner.role_label ?? undefined,
|
|
303
|
-
},
|
|
304
|
-
utilizationAmount: card.utilization_amount,
|
|
305
|
-
});
|
|
306
|
-
if (payload.policy_kind === 'doc-upload') {
|
|
304
|
+
if (payload.mode === 'upload') {
|
|
307
305
|
return {
|
|
308
|
-
policyKind: '
|
|
309
|
-
|
|
310
|
-
|
|
306
|
+
policyKind: 'upload',
|
|
307
|
+
wizardPlan: payload.wizard_plan != null
|
|
308
|
+
? toCardPolicyWizardPlan(payload.wizard_plan)
|
|
309
|
+
: undefined,
|
|
310
|
+
source: payload.source != null
|
|
311
|
+
? toCardPolicyUploadSource(payload.source)
|
|
312
|
+
: undefined,
|
|
311
313
|
};
|
|
312
314
|
}
|
|
313
315
|
return {
|
|
314
|
-
policyKind:
|
|
315
|
-
|
|
316
|
-
vendors: (payload.vendors ?? []).map(toCardPolicyTagSeed),
|
|
317
|
-
categories: (payload.categories ?? []).map(toCardPolicyTagSeed),
|
|
318
|
-
cards: (payload.cards ?? []).map(toCardRowSeed),
|
|
319
|
-
defaultLimits: (payload.default_limits ?? []).map((row) => ({
|
|
320
|
-
id: row.id,
|
|
321
|
-
isEnabled: row.is_enabled,
|
|
322
|
-
amount: row.amount ?? undefined,
|
|
323
|
-
})),
|
|
316
|
+
policyKind: payload.mode,
|
|
317
|
+
wizardPlan: toCardPolicyWizardPlan(payload.wizard_plan),
|
|
324
318
|
};
|
|
325
319
|
};
|
|
326
|
-
const toCardPolicyTagSeed = (tag) => ({
|
|
327
|
-
id: tag.id,
|
|
328
|
-
isSelected: tag.is_selected,
|
|
329
|
-
label: tag.label,
|
|
330
|
-
optionalCode: tag.optional_code ?? undefined,
|
|
331
|
-
});
|
|
332
320
|
const toAiCfoVisualizationData = (data) => {
|
|
333
321
|
if ('x' in data && 'y' in data) {
|
|
334
322
|
// Normalize y to always be an array
|
|
@@ -642,6 +630,49 @@ const aiCfo = (0, toolkit_1.createSlice)({
|
|
|
642
630
|
session.questionAnswers.push(qa);
|
|
643
631
|
}
|
|
644
632
|
},
|
|
633
|
+
/**
|
|
634
|
+
* Patch the `card_policy` interactive-form payload for a specific
|
|
635
|
+
* answer in a chat session to merge in the wizard plan + upload
|
|
636
|
+
* source metadata returned by
|
|
637
|
+
* `POST /cards/1.0/ai-cfo/policy-recommendation-from-upload`.
|
|
638
|
+
*
|
|
639
|
+
* Dispatched by the recommendation epic after a successful response;
|
|
640
|
+
* the wizard re-renders Steps 2 + 3 of the upload variant once the
|
|
641
|
+
* payload becomes a populated `CardPolicyInitialData` with
|
|
642
|
+
* `policyKind: "upload"` + `wizardPlan` + `source`.
|
|
643
|
+
*
|
|
644
|
+
* No-op when the target answer / chat session / form payload is
|
|
645
|
+
* missing or isn't an upload-mode card-policy interactive form —
|
|
646
|
+
* the bridge epic is best-effort and silently drops in edge cases
|
|
647
|
+
* (e.g. the user closed the chat before recommendation returned).
|
|
648
|
+
*/
|
|
649
|
+
updateAiCfoAnswerCardPolicyWizardPlan(draft, action) {
|
|
650
|
+
const { answerId, chatSessionId, source, wizardPlan } = action.payload;
|
|
651
|
+
const session = draft.aiCfoByChatSessionId[chatSessionId];
|
|
652
|
+
if (session == null) {
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
const qa = session.questionAnswers.find((entry) => entry.questionAnswerId === answerId);
|
|
656
|
+
if (qa == null) {
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
659
|
+
for (const response of Object.values(qa.responses)) {
|
|
660
|
+
const visualization = response?.content.visualization;
|
|
661
|
+
if (visualization == null || visualization.type !== 'interactive_form') {
|
|
662
|
+
continue;
|
|
663
|
+
}
|
|
664
|
+
const data = visualization.data;
|
|
665
|
+
if (data.formType !== 'card_policy' ||
|
|
666
|
+
data.payload.policyKind !== 'upload') {
|
|
667
|
+
continue;
|
|
668
|
+
}
|
|
669
|
+
data.payload = {
|
|
670
|
+
...data.payload,
|
|
671
|
+
wizardPlan,
|
|
672
|
+
source: source ?? data.payload.source,
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
},
|
|
645
676
|
clearSession(draft, action) {
|
|
646
677
|
const sessionId = action.payload;
|
|
647
678
|
delete draft.aiCfoByChatSessionId[sessionId];
|
|
@@ -677,5 +708,5 @@ const toChatSession = (chatSessionPayload) => {
|
|
|
677
708
|
createdAt: (0, zeniDayJS_1.date)(created_at),
|
|
678
709
|
};
|
|
679
710
|
};
|
|
680
|
-
_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;
|
|
711
|
+
_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;
|
|
681
712
|
exports.default = aiCfo.reducer;
|
|
@@ -126,80 +126,79 @@ export type CardsCreationInitialData = {
|
|
|
126
126
|
mode: 'cards-only';
|
|
127
127
|
};
|
|
128
128
|
/**
|
|
129
|
-
*
|
|
130
|
-
* `
|
|
131
|
-
* items omit it.
|
|
129
|
+
* Per-policy allow / block bucket. CamelCase mirror of
|
|
130
|
+
* `DraftPolicyEntityPayload`.
|
|
132
131
|
*/
|
|
133
|
-
export interface
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
label: string;
|
|
137
|
-
optionalCode?: string;
|
|
132
|
+
export interface CardPolicyDraftPolicyEntity {
|
|
133
|
+
categoryCodes: string[];
|
|
134
|
+
merchantNames: string[];
|
|
138
135
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
cardName: string;
|
|
146
|
-
id: string;
|
|
147
|
-
isChecked: boolean;
|
|
148
|
-
last4: string;
|
|
149
|
-
limitAmount: number;
|
|
150
|
-
owner: CardPolicyOwnerSeed;
|
|
151
|
-
utilizationAmount: number;
|
|
152
|
-
limitCadence?: string;
|
|
136
|
+
/**
|
|
137
|
+
* Spend-limit bucket per policy. `transaction` is the only cadence the
|
|
138
|
+
* BE ships today.
|
|
139
|
+
*/
|
|
140
|
+
export interface CardPolicySpendLimits {
|
|
141
|
+
transaction: number;
|
|
153
142
|
}
|
|
154
|
-
|
|
143
|
+
/**
|
|
144
|
+
* Single draft policy in FE state. Identity is positional — the reducer
|
|
145
|
+
* synthesizes a stable `id` (`draft-0`, `draft-1`, ...) at decode time
|
|
146
|
+
* since the BE doesn't ship one today.
|
|
147
|
+
*/
|
|
148
|
+
export interface CardPolicyDraftPolicy {
|
|
149
|
+
allowedEntity: CardPolicyDraftPolicyEntity;
|
|
150
|
+
applyToCards: string[];
|
|
151
|
+
blockedEntity: CardPolicyDraftPolicyEntity;
|
|
152
|
+
description: string;
|
|
155
153
|
id: string;
|
|
156
|
-
|
|
157
|
-
|
|
154
|
+
/** Enforcement mode (e.g. `"strict"`). Carried for guided submit;
|
|
155
|
+
* ignored by auto / upload submit. */
|
|
156
|
+
mode: string;
|
|
157
|
+
name: string;
|
|
158
|
+
requiredReceiptThreshold: number;
|
|
159
|
+
spendLimits: CardPolicySpendLimits;
|
|
158
160
|
}
|
|
159
|
-
export interface
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
161
|
+
export interface CardPolicyStep5Review {
|
|
162
|
+
draftPolicies: CardPolicyDraftPolicy[];
|
|
163
|
+
groupingSource: string;
|
|
164
|
+
prompt: string;
|
|
163
165
|
}
|
|
164
|
-
export interface
|
|
165
|
-
|
|
166
|
-
id: string;
|
|
167
|
-
label: string;
|
|
166
|
+
export interface CardPolicyWizardPlan {
|
|
167
|
+
step5Review: CardPolicyStep5Review;
|
|
168
168
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
169
|
+
/**
|
|
170
|
+
* Upload-mode metadata returned by the
|
|
171
|
+
* `policy-recommendation-from-upload` API alongside the wizard plan.
|
|
172
|
+
*/
|
|
173
|
+
export interface CardPolicyUploadSource {
|
|
174
|
+
confidenceScore: number;
|
|
175
|
+
fileName: string;
|
|
176
|
+
lowConfidenceFields: string[];
|
|
174
177
|
}
|
|
175
178
|
/**
|
|
176
179
|
* Initial data for the AI Card Policy interactive form. Discriminated on
|
|
177
|
-
* `policyKind
|
|
180
|
+
* `policyKind`. All three modes consume the same `wizardPlan.step5Review`
|
|
181
|
+
* envelope; the wizard renders different surfaces per mode.
|
|
178
182
|
*
|
|
179
|
-
* - `
|
|
180
|
-
* policy
|
|
181
|
-
* - `
|
|
182
|
-
*
|
|
183
|
-
* - `
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
* the user picks which cards the policy applies to in Step 2.
|
|
183
|
+
* - `auto` (1-step review): chip groups built directly from each draft
|
|
184
|
+
* policy. Submit omits `mode` + `spend_limits` + `required_receipt_threshold`.
|
|
185
|
+
* - `guided` (5-step wizard): Steps 1–4 seeded from `draftPolicies[0]`,
|
|
186
|
+
* Step 5 lists every draft. Submit includes all keys.
|
|
187
|
+
* - `upload` (3-step): upload → cards → review. `wizardPlan` is
|
|
188
|
+
* `undefined` until the upload-recommendation API succeeds, then
|
|
189
|
+
* populated alongside `source` metadata. Submit includes
|
|
190
|
+
* `spend_limits` + `required_receipt_threshold`; omits `mode`.
|
|
188
191
|
*/
|
|
189
192
|
export type CardPolicyInitialData = {
|
|
190
|
-
policyKind: '
|
|
191
|
-
|
|
193
|
+
policyKind: 'auto';
|
|
194
|
+
wizardPlan: CardPolicyWizardPlan;
|
|
192
195
|
} | {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
defaultLimits: CardPolicyLimitRowSeed[];
|
|
196
|
-
policyKind: 'full-builder';
|
|
197
|
-
suggestedPolicies: CardPolicySuggestedPolicy[];
|
|
198
|
-
vendors: CardPolicyTagSeed[];
|
|
196
|
+
policyKind: 'guided';
|
|
197
|
+
wizardPlan: CardPolicyWizardPlan;
|
|
199
198
|
} | {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
199
|
+
policyKind: 'upload';
|
|
200
|
+
source?: CardPolicyUploadSource;
|
|
201
|
+
wizardPlan?: CardPolicyWizardPlan;
|
|
203
202
|
};
|
|
204
203
|
/**
|
|
205
204
|
* Visualization variant rendered as an interactive RHF form (in lieu of a
|
|
@@ -52,9 +52,12 @@ interface CardPolicyTemplateSpendLimitsPayload {
|
|
|
52
52
|
transaction: number | null;
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
55
|
+
* Per-template request shape. `POST /cards/1.0/policy-templates` now
|
|
56
|
+
* accepts a bulk wrapper (`CreateCardPolicyTemplatesRequest`); this
|
|
57
|
+
* interface describes a single entry inside the `templates` array.
|
|
58
|
+
*
|
|
59
|
+
* `PUT /cards/1.0/policy-templates/{id}` (update) still consumes this
|
|
60
|
+
* shape directly — see `UpdateCardPolicyTemplateRequest` below.
|
|
58
61
|
*/
|
|
59
62
|
export interface CreateCardPolicyTemplateRequest {
|
|
60
63
|
allowedEntity: CardPolicyTemplateEntityList;
|
|
@@ -81,6 +84,24 @@ export interface CreateCardPolicyTemplateRequestBody {
|
|
|
81
84
|
required_receipt_threshold: number | null;
|
|
82
85
|
spend_limits: CardPolicyTemplateSpendLimitsPayload;
|
|
83
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Bulk request for `POST /cards/1.0/policy-templates`. The single-policy
|
|
89
|
+
* create flow wraps its one request in a length-1 `templates` array;
|
|
90
|
+
* future multi-policy submit (AI CFO review step) sends N entries in a
|
|
91
|
+
* single round-trip.
|
|
92
|
+
*
|
|
93
|
+
* `sourceChatSessionId` ties the submit back to an AI CFO chat session so
|
|
94
|
+
* the BE can attribute the created templates to it. Manual create-page
|
|
95
|
+
* callers omit it.
|
|
96
|
+
*/
|
|
97
|
+
export interface CreateCardPolicyTemplatesRequest {
|
|
98
|
+
templates: CreateCardPolicyTemplateRequest[];
|
|
99
|
+
sourceChatSessionId?: string;
|
|
100
|
+
}
|
|
101
|
+
export interface CreateCardPolicyTemplatesRequestBody {
|
|
102
|
+
templates: CreateCardPolicyTemplateRequestBody[];
|
|
103
|
+
source_chat_session_id?: string;
|
|
104
|
+
}
|
|
84
105
|
export interface CardPolicyTemplatePayload {
|
|
85
106
|
allowed_entity: CardPolicyTemplateEntityListPayload;
|
|
86
107
|
applied_cards: ID[];
|
|
@@ -99,11 +120,55 @@ export interface CardPolicyTemplatePayload {
|
|
|
99
120
|
tenant_id: ID;
|
|
100
121
|
updated_at: string;
|
|
101
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* Per-template response envelope. Still returned by `PUT /policy-templates/{id}`,
|
|
125
|
+
* `GET /policy-templates/{id}`, and (as the row payload) the list endpoint.
|
|
126
|
+
* Also nested inside `CreateCardPolicyTemplatesResponseData.templates_created`.
|
|
127
|
+
*/
|
|
102
128
|
export interface CreateCardPolicyTemplateResponseData {
|
|
103
129
|
cards_applied: number;
|
|
104
130
|
template: CardPolicyTemplatePayload;
|
|
105
131
|
}
|
|
106
132
|
export type CreateCardPolicyTemplateResponse = ZeniAPIResponse<CreateCardPolicyTemplateResponseData>;
|
|
133
|
+
/**
|
|
134
|
+
* Per-item error returned by the bulk POST when one or more templates in
|
|
135
|
+
* the request fail validation / persistence. The exact field shape is
|
|
136
|
+
* **TBD** with the BE — `message` is the only guaranteed field today; the
|
|
137
|
+
* rest are best-effort placeholders that callers should not assume to be
|
|
138
|
+
* present.
|
|
139
|
+
*
|
|
140
|
+
* TODO: lock down the shape (`index`, `name`, `code`) once the BE
|
|
141
|
+
* documents it. See plan §"Open question to resolve with BE".
|
|
142
|
+
*/
|
|
143
|
+
export interface BulkCreateCardPolicyTemplateErrorPayload {
|
|
144
|
+
message: string;
|
|
145
|
+
code?: string;
|
|
146
|
+
index?: number;
|
|
147
|
+
name?: string;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Wire shape returned by the bulk `POST /cards/1.0/policy-templates`.
|
|
151
|
+
* Partial success is allowed — `templates_created` holds the successfully
|
|
152
|
+
* created rows (each in the same envelope as the single endpoint), and
|
|
153
|
+
* `errors` holds per-item failures for the rest. `status.message` follows
|
|
154
|
+
* the "N of M templates created" convention.
|
|
155
|
+
*/
|
|
156
|
+
export interface CreateCardPolicyTemplatesResponseData {
|
|
157
|
+
errors: BulkCreateCardPolicyTemplateErrorPayload[];
|
|
158
|
+
templates_created: CreateCardPolicyTemplateResponseData[];
|
|
159
|
+
}
|
|
160
|
+
export type CreateCardPolicyTemplatesResponse = ZeniAPIResponse<CreateCardPolicyTemplatesResponseData>;
|
|
161
|
+
/**
|
|
162
|
+
* Camel-cased mirror of `BulkCreateCardPolicyTemplateErrorPayload` stored
|
|
163
|
+
* on the create-card-policy view slice so the UI can render a partial-success
|
|
164
|
+
* banner without re-touching the wire types.
|
|
165
|
+
*/
|
|
166
|
+
export interface BulkCreateCardPolicyTemplateError {
|
|
167
|
+
message: string;
|
|
168
|
+
code?: string;
|
|
169
|
+
index?: number;
|
|
170
|
+
name?: string;
|
|
171
|
+
}
|
|
107
172
|
export type UpdateCardPolicyTemplateRequest = CreateCardPolicyTemplateRequest;
|
|
108
173
|
export type UpdateCardPolicyTemplateRequestBody = CreateCardPolicyTemplateRequestBody;
|
|
109
174
|
export type UpdateCardPolicyTemplateResponseData = CreateCardPolicyTemplateResponseData;
|
|
@@ -138,10 +203,26 @@ export declare const toCardPolicyStats: (payload: CardPolicyStatsPayload) => Car
|
|
|
138
203
|
export declare const toCardPolicyTemplateList: (data: ListCardPolicyTemplatesResponseData) => CardPolicyTemplate[];
|
|
139
204
|
export declare const toCardPolicyTemplate: (payload: CardPolicyTemplatePayload) => CardPolicyTemplate;
|
|
140
205
|
/**
|
|
141
|
-
* Re-shape a camelCase create request into the snake_case wire
|
|
142
|
-
* Used by the
|
|
206
|
+
* Re-shape a single camelCase create request into the snake_case wire
|
|
207
|
+
* body. Used by the bulk-create mapper to build each entry of the
|
|
208
|
+
* `templates` array, and directly by the update epic (PUT) since the
|
|
209
|
+
* update endpoint still consumes a single object.
|
|
143
210
|
*/
|
|
144
211
|
export declare const toCreateCardPolicyTemplateRequestBody: (request: CreateCardPolicyTemplateRequest) => CreateCardPolicyTemplateRequestBody;
|
|
212
|
+
/**
|
|
213
|
+
* Re-shape a bulk create request into the snake_case wire body for
|
|
214
|
+
* `POST /cards/1.0/policy-templates`. Maps each entry through
|
|
215
|
+
* `toCreateCardPolicyTemplateRequestBody` and only emits
|
|
216
|
+
* `source_chat_session_id` when the camelCase counterpart is defined,
|
|
217
|
+
* so manual-create callers don't ship a stray `undefined` over the wire.
|
|
218
|
+
*/
|
|
219
|
+
export declare const toCreateCardPolicyTemplatesRequestBody: (request: CreateCardPolicyTemplatesRequest) => CreateCardPolicyTemplatesRequestBody;
|
|
220
|
+
/**
|
|
221
|
+
* Map a single bulk-response error payload to its camelCased view shape.
|
|
222
|
+
* Defensive against missing optional fields (see `BulkCreateCardPolicyTemplateErrorPayload`
|
|
223
|
+
* docstring — the BE contract isn't fully locked yet).
|
|
224
|
+
*/
|
|
225
|
+
export declare const toBulkCreateCardPolicyTemplateError: (payload: BulkCreateCardPolicyTemplateErrorPayload) => BulkCreateCardPolicyTemplateError;
|
|
145
226
|
export declare const toUpdateCardPolicyTemplateRequestBody: (request: CreateCardPolicyTemplateRequest) => CreateCardPolicyTemplateRequestBody;
|
|
146
227
|
/**
|
|
147
228
|
* Seed an edit-form draft (`CreateCardPolicyTemplateRequest`) from an
|
|
@@ -173,4 +254,24 @@ export interface PolicyDocumentExtractResponseData {
|
|
|
173
254
|
}
|
|
174
255
|
export type PolicyDocumentExtractResponse = ZeniAPIResponse<PolicyDocumentExtractResponseData>;
|
|
175
256
|
export declare const toExtractedCardPolicyRules: (payload: ExtractedCardPolicyRulesPayload) => ExtractedCardPolicyRules;
|
|
257
|
+
/**
|
|
258
|
+
* Wire shape returned by `POST /cards/1.0/ai-cfo/policy-recommendation-from-upload`.
|
|
259
|
+
* Chained after `extractPolicyDocument` succeeds in the AI CFO `upload`
|
|
260
|
+
* flow: the FE forwards the just-returned `extracted_rules` and the BE
|
|
261
|
+
* synthesizes a wizard plan + upload source metadata.
|
|
262
|
+
*
|
|
263
|
+
* The response mirrors the same `mode`-discriminated envelope the
|
|
264
|
+
* controller API ships for `auto` / `guided`, but always with `mode:
|
|
265
|
+
* "upload"` and a populated `wizard_plan.step_5_review`. The FE merges
|
|
266
|
+
* the returned `wizard_plan` + `source` into the in-flight AI CFO
|
|
267
|
+
* answer's `CardPolicyInitialData` via
|
|
268
|
+
* `updateAiCfoAnswerCardPolicyWizardPlan`.
|
|
269
|
+
*/
|
|
270
|
+
export interface CardPolicyRecommendationFromUploadResponseData {
|
|
271
|
+
mode: 'upload';
|
|
272
|
+
source: import('../aiCfo/aiCfoPayload').CardPolicyUploadSourcePayload;
|
|
273
|
+
tenant_id: string;
|
|
274
|
+
wizard_plan: import('../aiCfo/aiCfoPayload').CardPolicyWizardPlanPayload;
|
|
275
|
+
}
|
|
276
|
+
export type CardPolicyRecommendationFromUploadResponse = ZeniAPIResponse<CardPolicyRecommendationFromUploadResponseData>;
|
|
176
277
|
export {};
|