Update CBS Mobile App codebase

This commit is contained in:
Abin Toppo
2026-09-21 13:21:25 +05:30
parent 58af541536
commit 2dcb10775c
339 changed files with 26750 additions and 16767 deletions
+87 -35
View File
@@ -1,14 +1,34 @@
import type { Beneficiary } from '../../../types/app';
import { demoBeneficiaries } from '../../../constants/mockData';
import { endpoints } from '../../../services/api/endpoints';
import { apiClient } from '../../../services/api/apiClient';
import { baseApi } from '../../../services/api/baseApi';
import { resolveWithMock } from '../../../services/api/serviceHelpers';
import { endpoints } from '../../../services/api/endpoints';
import { resolveLive, resolveWithMock } from '../../../services/api/serviceHelpers';
import type { Beneficiary } from '../../../types/app';
import type {
BeneficiarySaveRequest,
BeneficiaryValidateRequest,
BeneficiaryValidateResult,
CbsBeneficiary,
} from '../../../types/cbs';
import { favoriteStore, toBeneficiary } from '../utils/beneficiaryMapper';
/**
* TEMPORARY — fixed payer account for payee validation.
*
* Every validate call goes out with this as the payer, overriding whichever
* account the customer selected on screen. The development CBS only recognises
* this account as a payer; the profile's own accounts come back
* `ACCOUNT_NOT_FOUND`, which reads on screen as the *payee* being unverifiable.
*
* Delete this and pass `request` through untouched once the backend accepts
* the profile's accounts. It must not ship: in production it would validate
* every payee against an account that is not the customer's.
*/
const HARDCODED_PAYER_ACCOUNT = '002002000100019';
export interface BankTransferRequest {
beneficiaryId: string;
amount: number;
transferType: 'IMPS' | 'NEFT' | 'RTGS';
transferType: 'IMPS' | 'NEFT' | 'RTGS' | 'Internal';
remarks?: string;
sourceAccountId: string;
}
@@ -20,37 +40,66 @@ export interface BankTransferResponse {
export const paymentsApi = baseApi.injectEndpoints({
endpoints: (builder) => ({
/** The customer's saved payees, newest first. */
getBeneficiaries: builder.query<Beneficiary[], void>({
queryFn: () =>
resolveWithMock({
mockData: demoBeneficiaries,
request: async () => {
// Real API implementation
// const response = await apiClient.get<Beneficiary[]>('/beneficiaries');
// return response.data;
return [] as Beneficiary[];
},
resolveLive(async () => {
const [response, favorites] = await Promise.all([
apiClient.get<CbsBeneficiary[]>(endpoints.beneficiaries.list),
favoriteStore.read(),
]);
const favoriteSet = new Set(favorites);
return (response.data ?? []).map((payee) => toBeneficiary(payee, favoriteSet));
}),
providesTags: ['Payments'],
providesTags: ['Beneficiaries'],
}),
addBeneficiary: builder.mutation<Beneficiary, Partial<Beneficiary>>({
queryFn: (newBen) =>
resolveWithMock({
mockData: {
id: `ben_${Date.now()}`,
name: newBen.name || 'Unknown',
bankName: newBen.bankName || 'Unknown Bank',
accountMasked: newBen.accountMasked || 'xxxx0000',
favorite: false,
} as Beneficiary,
request: async () => {
// const response = await apiClient.post('/beneficiaries/add', newBen);
// return response.data;
return {} as Beneficiary;
}
}),
invalidatesTags: ['Payments'],
/**
* Asks IMPS whether this payee exists, and who they are. Saves nothing.
*
* This is what the confirmation step shows, because a mistyped account
* number is the most common way money reaches the wrong person. Read
* `result` rather than the status code: the switch answers 200 whether or
* not it recognised the payee.
*/
validateBeneficiary: builder.mutation<BeneficiaryValidateResult, BeneficiaryValidateRequest>({
queryFn: (request) =>
resolveLive(async () => {
const response = await apiClient.post<BeneficiaryValidateResult>(
endpoints.beneficiaries.validate,
// See HARDCODED_PAYER_ACCOUNT — the caller's payer is discarded.
{ ...request, payer: { accountNumber: HARDCODED_PAYER_ACCOUNT } },
);
return response.data;
}),
}),
/**
* Saves the payee, resolved through the bank's CBS lookup.
*
* A different body and a different lookup from validate, which goes to
* IMPS — so the two can disagree, and this one's answer is what gets
* stored. Validate first regardless: the server does not enforce the
* order, which means nothing but the app stops a customer saving a payee
* nobody has confirmed.
*/
saveBeneficiary: builder.mutation<Beneficiary, BeneficiarySaveRequest>({
queryFn: (request) =>
resolveLive(async () => {
const response = await apiClient.post<CbsBeneficiary>(
endpoints.beneficiaries.save,
request,
);
return toBeneficiary(response.data);
}),
invalidatesTags: ['Beneficiaries'],
}),
/** No transfer endpoint exists yet, so this stays on fixtures. */
submitBankTransfer: builder.mutation<BankTransferResponse, BankTransferRequest>({
queryFn: (req) =>
resolveWithMock({
@@ -59,9 +108,7 @@ export const paymentsApi = baseApi.injectEndpoints({
status: req.transferType === 'NEFT' ? 'Process_Pending' : 'Process_Success',
}),
request: async () => {
// const response = await apiClient.post<BankTransferResponse>('/transactions/transfer', req);
// return response.data;
return { referenceId: '', status: 'Process_Success' };
throw new Error('Transfer submission is not implemented by the CBS API yet');
},
}),
invalidatesTags: ['Payments', 'Transactions'],
@@ -69,4 +116,9 @@ export const paymentsApi = baseApi.injectEndpoints({
}),
});
export const { useGetBeneficiariesQuery, useAddBeneficiaryMutation, useSubmitBankTransferMutation } = paymentsApi;
export const {
useGetBeneficiariesQuery,
useValidateBeneficiaryMutation,
useSaveBeneficiaryMutation,
useSubmitBankTransferMutation,
} = paymentsApi;