62 lines
1.8 KiB
TypeScript
62 lines
1.8 KiB
TypeScript
import type { ProfileDashboardSummary } from '../../../packages/shared/src/contracts/runtime';
|
|
|
|
type ProfileWalletBalanceSource =
|
|
| Pick<ProfileDashboardSummary, 'walletBalance'>
|
|
| { walletBalance?: number | null }
|
|
| null
|
|
| undefined;
|
|
|
|
export function resolveProfileWalletBalance(
|
|
dashboard: ProfileWalletBalanceSource,
|
|
) {
|
|
const walletBalance = dashboard?.walletBalance;
|
|
return typeof walletBalance === 'number' && Number.isFinite(walletBalance)
|
|
? Math.max(0, Math.floor(walletBalance))
|
|
: 0;
|
|
}
|
|
|
|
export function adjustProfileDashboardWalletBalance(
|
|
dashboard: ProfileDashboardSummary | null,
|
|
delta: number,
|
|
): ProfileDashboardSummary | null {
|
|
if (!dashboard || !Number.isFinite(delta) || delta === 0) {
|
|
return dashboard;
|
|
}
|
|
|
|
return {
|
|
...dashboard,
|
|
walletBalance: Math.max(
|
|
0,
|
|
resolveProfileWalletBalance(dashboard) + Math.trunc(delta),
|
|
),
|
|
updatedAt: new Date().toISOString(),
|
|
};
|
|
}
|
|
|
|
export function reconcileProfileWalletLocalDeltaWithServerDashboard(
|
|
previousDashboard: ProfileDashboardSummary | null,
|
|
latestDashboard: ProfileDashboardSummary | null,
|
|
localDelta: number,
|
|
) {
|
|
if (
|
|
!previousDashboard ||
|
|
!latestDashboard ||
|
|
!Number.isFinite(localDelta) ||
|
|
localDelta === 0
|
|
) {
|
|
return Number.isFinite(localDelta) ? Math.trunc(localDelta) : 0;
|
|
}
|
|
|
|
const previousBalance = resolveProfileWalletBalance(previousDashboard);
|
|
const latestBalance = resolveProfileWalletBalance(latestDashboard);
|
|
const normalizedDelta = Math.trunc(localDelta);
|
|
|
|
if (normalizedDelta < 0) {
|
|
const reflectedDebit = Math.max(0, previousBalance - latestBalance);
|
|
return Math.min(0, normalizedDelta + reflectedDebit);
|
|
}
|
|
|
|
const reflectedCredit = Math.max(0, latestBalance - previousBalance);
|
|
return Math.max(0, normalizedDelta - reflectedCredit);
|
|
}
|