merge master into dev#110
Conversation
…rotection system for CommDesk
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…d filter utility, refactor avatar DOM anti-pattern, fix render purity
feat: enterprise-grade credit economy, wallet billing ledger & cost p…
There was a problem hiding this comment.
Code Review
This pull request introduces a comprehensive billing and credit management system, featuring a community wallet, transaction tracking, usage analytics with visualizations, and automated recharge capabilities. It also incorporates E2E testing with Playwright and refines several UI components. Feedback highlights a critical missing import for the BarChart3 icon and a naming collision for the useWalletTransactions hook. Additionally, improvements are suggested for the robustness of initials calculation, React key usage in charts, the timing of idempotency key generation to prevent duplicate payments, and the frequency logic of the auto-recharge system.
| CreditCard, | ||
| Users, | ||
| Settings, | ||
| Wallet as WalletIcon, |
| import type { PaginatedTransactions, TransactionFilters } from "../Billing.types"; | ||
| import { applyTransactionFilters } from "../utils/credits"; | ||
|
|
||
| export function useWalletTransactions(walletId: string | undefined, filters: TransactionFilters) { |
There was a problem hiding this comment.
| .map((part) => part[0]) | ||
| .join("") |
There was a problem hiding this comment.
The initials calculation can produce "undefined" strings if communityName contains multiple consecutive spaces, as part[0] on an empty string is undefined. Adding a filter to remove empty strings from the split result will make this more robust.
| .map((part) => part[0]) | |
| .join("") | |
| .split(" ") | |
| .filter(Boolean) | |
| .map((part) => part[0]) |
| {breakdown.map((_, i) => ( | ||
| <Cell key={i} fill={COLORS[i % COLORS.length]} /> | ||
| ))} |
There was a problem hiding this comment.
Using the array index as a key for Cell components is not recommended in React as it can lead to rendering issues if the data changes. Use a unique identifier from the data instead, such as item.category.
| {breakdown.map((_, i) => ( | |
| <Cell key={i} fill={COLORS[i % COLORS.length]} /> | |
| ))} | |
| {breakdown.map((item, i) => ( | |
| <Cell key={item.category} fill={COLORS[i % COLORS.length]} /> | |
| ))} |
| await addFunds.mutateAsync({ | ||
| amountRupees: amount, | ||
| paymentMethod, | ||
| idempotencyKey: `pay-${crypto.randomUUID()}`, |
There was a problem hiding this comment.
The idempotency key is generated inside the handlePay function. If the user clicks the "Pay" button multiple times before the request completes (and before the button is disabled), each click will generate a new UUID, resulting in multiple distinct payment attempts. To ensure true idempotency, the key should be generated once when the modal opens or when the payment intent is first formed, and then reused for any retries of that specific intent.
| if (!communityWallet.autoRechargeEnabled) return; | ||
| if (communityWallet.availableCredits > communityWallet.autoRechargeThreshold) return; | ||
|
|
||
| const idempotencyKey = `auto-recharge-${new Date().toISOString().slice(0, 10)}-${communityWallet.id}`; |
There was a problem hiding this comment.
The idempotency key for auto-recharge is based on the current date (YYYY-MM-DD). This implementation restricts auto-recharge to once per day per wallet. If a community consumes credits rapidly and needs multiple recharges in a single day, subsequent attempts will be blocked by the idempotency check. Consider using a more granular timestamp or a unique session ID to allow multiple recharges when necessary.
No description provided.