Feat/set row collapsing threshold#1127
Conversation
📝 WalkthroughWalkthroughA new persisted CSV collapse threshold setting is added, exposed in the Account page, updated through a new API route, and threaded into CSV download calls. ChangesCSV collapse threshold
Sequence Diagram(s)sequenceDiagram
participant AccountPage
participant CsvThresholdAPI
participant userService
participant PrismaDB
AccountPage->>CsvThresholdAPI: PUT csvCollapseThreshold
CsvThresholdAPI->>CsvThresholdAPI: setSession(req, res, true)
CsvThresholdAPI->>CsvThresholdAPI: validate body value
CsvThresholdAPI->>userService: updateCsvCollapseThreshold(userId, threshold)
userService->>PrismaDB: prisma.userProfile.update(...)
PrismaDB-->>userService: update result
userService-->>CsvThresholdAPI: resolved
CsvThresholdAPI-->>AccountPage: 200 success
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 OpenGrep (1.23.0)pages/api/user/csvCollapseThreshold/index.ts┌──────────────┐ �[32m✔�[39m �[1mOpengrep OSS�[0m [00.50][ERROR]: unable to find a config; path services/userService.ts┌──────────────┐ �[32m✔�[39m �[1mOpengrep OSS�[0m [00.25][ERROR]: unable to find a config; path tests/mockedObjects.ts┌──────────────┐ �[32m✔�[39m �[1mOpengrep OSS�[0m [00.30][ERROR]: unable to find a config; path 🔧 SQLFluff (4.2.2)prisma-local/migrations/20260317024924_csv_collapse_threshold/migration.sql🔧 Stylelint (17.13.0)components/Account/account.module.cssError: ENOENT: no such file or directory, open '/.stylelintrc.json' 🔧 ESLint
components/Account/account.module.cssParsing error: Unexpected token . Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (4)
services/userService.ts (1)
159-166: Add a small service-layer guard for invalid threshold values.This method currently trusts callers completely. Adding an integer/non-negative check here prevents bad writes from any non-API caller path.
Proposed hardening
export async function updateCsvCollapseThreshold (id: string, csvCollapseThreshold: number): Promise<void> { + if (!Number.isInteger(csvCollapseThreshold) || csvCollapseThreshold < 0) { + throw new Error(RESPONSE_MESSAGES.BAD_REQUEST_400.message) + } await prisma.userProfile.update({ where: { id }, data: { csvCollapseThreshold } }) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@services/userService.ts` around lines 159 - 166, The updateCsvCollapseThreshold service blindly writes any number; add a guard in updateCsvCollapseThreshold to validate the input is an integer and non-negative before calling prisma.userProfile.update: check Number.isInteger(csvCollapseThreshold) && csvCollapseThreshold >= 0 (or coerce/convert input and then validate), and if the check fails throw a descriptive error (e.g., InvalidArgumentError / new Error('csvCollapseThreshold must be a non-negative integer')) so bad values are rejected at the service layer rather than persisted by prisma.userProfile.update.tests/mockedObjects.ts (1)
531-533: Consider keeping base fixture defaults aligned with production defaults.Using
csvCollapseThreshold: 0in shared base profiles can silently alter CSV behavior in unrelated tests. Prefer1in base fixtures and override to0only in edge-case-specific tests.Fixture alignment tweak
- csvCollapseThreshold: 0 + csvCollapseThreshold: 1 ... - csvCollapseThreshold: 0 + csvCollapseThreshold: 1Also applies to: 547-549
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/mockedObjects.ts` around lines 531 - 533, Update the shared base fixture in tests/mockedObjects.ts so the csvCollapseThreshold default is aligned with production by setting csvCollapseThreshold to 1 (instead of 0) in the base profile object (the block that contains proUntil and csvCollapseThreshold), and only set csvCollapseThreshold: 0 in individual edge-case tests where collapsing must be disabled; adjust any other base-profile occurrences (e.g., the similar block around lines 547-549) to the same default to avoid silently changing CSV behavior across tests.components/Account/ChangeCsvCollapseThreshold.tsx (1)
39-41: Clear the success timer on unmount to avoid stale state updates.The timeout callback can run after unmount. Add timer cleanup for reliability.
Proposed fix
-import React, { ReactElement, useState } from 'react' +import React, { ReactElement, useEffect, useRef, useState } from 'react' @@ export default function ChangeCsvCollapseThreshold ({ csvCollapseThreshold }: IProps): ReactElement { + const successTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null) @@ + useEffect(() => { + return () => { + if (successTimerRef.current !== null) { + clearTimeout(successTimerRef.current) + } + } + }, []) @@ - setTimeout(() => { + if (successTimerRef.current !== null) clearTimeout(successTimerRef.current) + successTimerRef.current = setTimeout(() => { setSuccess('') }, 3000)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@components/Account/ChangeCsvCollapseThreshold.tsx` around lines 39 - 41, The success timeout in the ChangeCsvCollapseThreshold component currently calls setTimeout to clear setSuccess('') but doesn't clear it on unmount; modify the effect (or wherever setTimeout is called) to capture the timer id (const timer = window.setTimeout(...)) and return a cleanup that calls clearTimeout(timer) so the callback can't run after the component unmounts; ensure the timer id type matches the environment (use number from window.setTimeout or NodeJS.Timeout in server contexts) and set timer to null after clearing if using state/refs.pages/api/user/csvCollapseThreshold/index.ts (1)
26-27: Add a defensive guard for missingsession.userIdbefore Prisma update.If
sessionis unavailable, this currently falls through to a DB error path instead of a clear auth response.Proposed fix
if (req.method === 'PUT') { const session = req.session + if (!session?.userId) { + res.status(401).json({ message: 'Unauthorized' }) + return + } const { csvCollapseThreshold } = req.body @@ - await userService.updateCsvCollapseThreshold(session.userId, threshold) + await userService.updateCsvCollapseThreshold(session.userId, threshold) res.status(200).json({ success: true })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pages/api/user/csvCollapseThreshold/index.ts` around lines 26 - 27, Add a defensive guard that checks for a valid session and session.userId before calling userService.updateCsvCollapseThreshold; if session or session.userId is missing, immediately respond with an auth error (e.g., res.status(401).json({ success: false, error: 'Unauthorized' })) and return so you never call userService.updateCsvCollapseThreshold with an undefined id.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@components/Account/ChangeCsvCollapseThreshold.tsx`:
- Around line 18-19: The input parsing currently uses parseInt (e.g., in
ChangeCsvCollapseThreshold’s handling of inputValue) which silently truncates
decimals; replace parseInt usage with Number() to parse the value and then
validate using Number.isInteger(newThreshold) and newThreshold >= 0, rejecting
NaN or non-integer (decimal) values explicitly (apply the same change for the
other occurrence referenced at the second spot around the lines corresponding to
the existing parseInt usage), and update any validation/error paths to reflect
"must be a non-negative integer" instead of relying on parseInt truncation.
- Around line 74-80: Change the input in the ChangeCsvCollapseThreshold
component to be an accessible numeric control: replace type="text" with
type="number", add step="1" and keep min="0" so HTML5 numeric validation works,
and provide an associated label element referencing id="csvCollapseThreshold"
(or add aria-label if a visible label isn't desired) to ensure accessibility;
update any related handlers like handleInputChange to handle numeric values
(parseInt/Number) from the inputValue before using it.
In `@pages/api/user/csvCollapseThreshold/index.ts`:
- Around line 15-23: The current validation for csvCollapseThreshold (variable
csvCollapseThreshold and computed threshold) is too permissive; change it to
first reject empty or whitespace-only string inputs (if typeof
csvCollapseThreshold === 'string' check trim().length === 0) then parse to a
number and validate using Number.isFinite(threshold) and
Number.isInteger(threshold) and threshold >= 0; return 400 with an appropriate
message if any of these checks fail so decimals, Infinity/NaN, and blank inputs
are rejected before persisting the Int.
---
Nitpick comments:
In `@components/Account/ChangeCsvCollapseThreshold.tsx`:
- Around line 39-41: The success timeout in the ChangeCsvCollapseThreshold
component currently calls setTimeout to clear setSuccess('') but doesn't clear
it on unmount; modify the effect (or wherever setTimeout is called) to capture
the timer id (const timer = window.setTimeout(...)) and return a cleanup that
calls clearTimeout(timer) so the callback can't run after the component
unmounts; ensure the timer id type matches the environment (use number from
window.setTimeout or NodeJS.Timeout in server contexts) and set timer to null
after clearing if using state/refs.
In `@pages/api/user/csvCollapseThreshold/index.ts`:
- Around line 26-27: Add a defensive guard that checks for a valid session and
session.userId before calling userService.updateCsvCollapseThreshold; if session
or session.userId is missing, immediately respond with an auth error (e.g.,
res.status(401).json({ success: false, error: 'Unauthorized' })) and return so
you never call userService.updateCsvCollapseThreshold with an undefined id.
In `@services/userService.ts`:
- Around line 159-166: The updateCsvCollapseThreshold service blindly writes any
number; add a guard in updateCsvCollapseThreshold to validate the input is an
integer and non-negative before calling prisma.userProfile.update: check
Number.isInteger(csvCollapseThreshold) && csvCollapseThreshold >= 0 (or
coerce/convert input and then validate), and if the check fails throw a
descriptive error (e.g., InvalidArgumentError / new Error('csvCollapseThreshold
must be a non-negative integer')) so bad values are rejected at the service
layer rather than persisted by prisma.userProfile.update.
In `@tests/mockedObjects.ts`:
- Around line 531-533: Update the shared base fixture in tests/mockedObjects.ts
so the csvCollapseThreshold default is aligned with production by setting
csvCollapseThreshold to 1 (instead of 0) in the base profile object (the block
that contains proUntil and csvCollapseThreshold), and only set
csvCollapseThreshold: 0 in individual edge-case tests where collapsing must be
disabled; adjust any other base-profile occurrences (e.g., the similar block
around lines 547-549) to the same default to avoid silently changing CSV
behavior across tests.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 95c08745-b5d8-43aa-988d-626badf50bae
📒 Files selected for processing (10)
components/Account/ChangeCsvCollapseThreshold.tsxcomponents/Account/account.module.csspages/account/index.tsxpages/api/paybutton/download/transactions/[paybuttonId].tspages/api/payments/download/index.tspages/api/user/csvCollapseThreshold/index.tsprisma-local/migrations/20260317024924_csv_collapse_threshold/migration.sqlprisma-local/schema.prismaservices/userService.tstests/mockedObjects.ts
| const newThreshold = parseInt(inputValue, 10) | ||
| if (isNaN(newThreshold) || newThreshold < 0) { |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
git ls-files | grep -i "ChangeCsvCollapseThreshold"Repository: PayButton/paybutton-server
Length of output: 119
🏁 Script executed:
fd -i "changecsvcollapsethreshold" --type fRepository: PayButton/paybutton-server
Length of output: 119
🏁 Script executed:
cat -n components/Account/ChangeCsvCollapseThreshold.tsxRepository: PayButton/paybutton-server
Length of output: 3610
🏁 Script executed:
node <<'EOF'
// Verify parseInt behavior
console.log("parseInt('1.5', 10):", parseInt('1.5', 10));
console.log("parseInt('12abc', 10):", parseInt('12abc', 10));
console.log("parseInt('abc', 10):", parseInt('abc', 10));
console.log("isNaN(parseInt('abc', 10)):", isNaN(parseInt('abc', 10)));
console.log("isNaN(parseInt('1.5', 10)):", isNaN(parseInt('1.5', 10)));
console.log("Number.isInteger(Number('1.5')):", Number.isInteger(Number('1.5')));
console.log("Number.isInteger(Number('12')):", Number.isInteger(Number('12')));
EOFRepository: PayButton/paybutton-server
Length of output: 286
parseInt silently truncates decimal input; use strict integer validation instead.
Values like 1.5 are accepted by isNaN() and truncated to 1 without warning. Use Number() with Number.isInteger() to enforce strict integer validation and reject decimal input explicitly.
Proposed fix
- const newThreshold = parseInt(inputValue, 10)
- if (isNaN(newThreshold) || newThreshold < 0) {
+ const normalized = inputValue.trim()
+ const newThreshold = Number(normalized)
+ if (normalized === '' || !Number.isInteger(newThreshold) || newThreshold < 0) {
setError('Please enter a valid non-negative number')
return
}
@@
- const numValue = parseInt(value, 10)
- if (!isNaN(numValue) && numValue >= 0 && numValue !== threshold) {
+ const normalized = value.trim()
+ const numValue = Number(normalized)
+ if (normalized !== '' && Number.isInteger(numValue) && numValue >= 0 && numValue !== threshold) {
setDisabled(false)
setError('')Also applies to: lines 56-57
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@components/Account/ChangeCsvCollapseThreshold.tsx` around lines 18 - 19, The
input parsing currently uses parseInt (e.g., in ChangeCsvCollapseThreshold’s
handling of inputValue) which silently truncates decimals; replace parseInt
usage with Number() to parse the value and then validate using
Number.isInteger(newThreshold) and newThreshold >= 0, rejecting NaN or
non-integer (decimal) values explicitly (apply the same change for the other
occurrence referenced at the second spot around the lines corresponding to the
existing parseInt usage), and update any validation/error paths to reflect "must
be a non-negative integer" instead of relying on parseInt truncation.
| <input | ||
| id="csvCollapseThreshold" | ||
| type="text" | ||
| min="0" | ||
| required | ||
| value={inputValue} | ||
| onChange={handleInputChange} |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
fd "ChangeCsvCollapseThreshold.tsx" --type fRepository: PayButton/paybutton-server
Length of output: 119
🏁 Script executed:
wc -l components/Account/ChangeCsvCollapseThreshold.tsxRepository: PayButton/paybutton-server
Length of output: 122
🏁 Script executed:
cat -n components/Account/ChangeCsvCollapseThreshold.tsxRepository: PayButton/paybutton-server
Length of output: 3610
Add an accessible label and use a numeric input type.
The input currently lacks an accessible label and type="text" makes the min="0" attribute ineffective. With manual validation expecting an integer, type="number" is more semantically appropriate and enables proper HTML5 validation.
Proposed fix
<div className={style.threshold_row}>
+ <label htmlFor="csvCollapseThreshold">CSV collapse threshold</label>
<input
id="csvCollapseThreshold"
- type="text"
+ type="number"
min="0"
+ step="1"
+ inputMode="numeric"
required
value={inputValue}
onChange={handleInputChange}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@components/Account/ChangeCsvCollapseThreshold.tsx` around lines 74 - 80,
Change the input in the ChangeCsvCollapseThreshold component to be an accessible
numeric control: replace type="text" with type="number", add step="1" and keep
min="0" so HTML5 numeric validation works, and provide an associated label
element referencing id="csvCollapseThreshold" (or add aria-label if a visible
label isn't desired) to ensure accessibility; update any related handlers like
handleInputChange to handle numeric values (parseInt/Number) from the inputValue
before using it.
| if (csvCollapseThreshold === undefined || csvCollapseThreshold === null) { | ||
| res.status(400).json({ message: 'csvCollapseThreshold is required' }) | ||
| return | ||
| } | ||
|
|
||
| const threshold = Number(csvCollapseThreshold) | ||
| if (isNaN(threshold) || threshold < 0) { | ||
| res.status(400).json({ message: 'csvCollapseThreshold must be a non-negative number' }) | ||
| return |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify JS coercion edge-cases that affect current validation logic.
node - <<'NODE'
const inputs = ['', ' ', '1.5', 'Infinity', null, undefined, '12abc'];
for (const v of inputs) {
console.log(JSON.stringify(v), '=> Number:', Number(v), 'isFinite:', Number.isFinite(Number(v)));
}
NODERepository: PayButton/paybutton-server
Length of output: 330
🏁 Script executed:
find . -type f -name "*.ts" -path "*/pages/api/user/csvCollapseThreshold*" | head -20Repository: PayButton/paybutton-server
Length of output: 116
🏁 Script executed:
cat -n pages/api/user/csvCollapseThreshold/index.tsRepository: PayButton/paybutton-server
Length of output: 1301
🏁 Script executed:
# Check the userService to understand what updateCsvCollapseThreshold expects
find . -type f -name "userService.ts" | head -5Repository: PayButton/paybutton-server
Length of output: 95
🏁 Script executed:
cat -n services/userService.ts | head -100Repository: PayButton/paybutton-server
Length of output: 4017
🏁 Script executed:
# Search for the updateCsvCollapseThreshold function specifically
rg -A 15 "updateCsvCollapseThreshold" services/userService.tsRepository: PayButton/paybutton-server
Length of output: 520
🏁 Script executed:
# Check if there's a Prisma schema that defines csvCollapseThreshold type
find . -type f \( -name "schema.prisma" -o -name "*.prisma" \)Repository: PayButton/paybutton-server
Length of output: 98
🏁 Script executed:
rg -A 3 -B 3 "csvCollapseThreshold" ./prisma-local/schema.prismaRepository: PayButton/paybutton-server
Length of output: 275
🏁 Script executed:
# Also check the UserProfile model in the schema
rg -A 50 "model UserProfile" ./prisma-local/schema.prisma | head -80Repository: PayButton/paybutton-server
Length of output: 1930
Harden threshold validation to reject blank, non-finite, and non-integer values.
Current coercion accepts invalid inputs like empty strings, whitespace, decimals, and Infinity. Since csvCollapseThreshold is defined as an Int in the database schema, these invalid inputs could cause unintended behavior or persist incorrect values.
Proposed fix
- if (csvCollapseThreshold === undefined || csvCollapseThreshold === null) {
+ if (
+ csvCollapseThreshold === undefined ||
+ csvCollapseThreshold === null ||
+ (typeof csvCollapseThreshold === 'string' && csvCollapseThreshold.trim() === '')
+ ) {
res.status(400).json({ message: 'csvCollapseThreshold is required' })
return
}
- const threshold = Number(csvCollapseThreshold)
- if (isNaN(threshold) || threshold < 0) {
- res.status(400).json({ message: 'csvCollapseThreshold must be a non-negative number' })
+ const threshold = Number(csvCollapseThreshold)
+ if (!Number.isFinite(threshold) || !Number.isInteger(threshold) || threshold < 0) {
+ res.status(400).json({ message: 'csvCollapseThreshold must be a non-negative integer' })
return
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (csvCollapseThreshold === undefined || csvCollapseThreshold === null) { | |
| res.status(400).json({ message: 'csvCollapseThreshold is required' }) | |
| return | |
| } | |
| const threshold = Number(csvCollapseThreshold) | |
| if (isNaN(threshold) || threshold < 0) { | |
| res.status(400).json({ message: 'csvCollapseThreshold must be a non-negative number' }) | |
| return | |
| if ( | |
| csvCollapseThreshold === undefined || | |
| csvCollapseThreshold === null || | |
| (typeof csvCollapseThreshold === 'string' && csvCollapseThreshold.trim() === '') | |
| ) { | |
| res.status(400).json({ message: 'csvCollapseThreshold is required' }) | |
| return | |
| } | |
| const threshold = Number(csvCollapseThreshold) | |
| if (!Number.isFinite(threshold) || !Number.isInteger(threshold) || threshold < 0) { | |
| res.status(400).json({ message: 'csvCollapseThreshold must be a non-negative integer' }) | |
| return |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pages/api/user/csvCollapseThreshold/index.ts` around lines 15 - 23, The
current validation for csvCollapseThreshold (variable csvCollapseThreshold and
computed threshold) is too permissive; change it to first reject empty or
whitespace-only string inputs (if typeof csvCollapseThreshold === 'string' check
trim().length === 0) then parse to a number and validate using
Number.isFinite(threshold) and Number.isInteger(threshold) and threshold >= 0;
return 400 with an appropriate message if any of these checks fail so decimals,
Infinity/NaN, and blank inputs are rejected before persisting the Int.
56ef258 to
5c9d2f4
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@pages/api/payments/download/index.ts`:
- Line 65: The calls to downloadTxsFile are passing one argument too many, so
user.csvRowCollapsing is being dropped and collapseTransactions stays hardcoded.
Update the downloadTxsFile call in both the payments download handler and the
paybutton transactions handler to match the function’s 8-argument signature, and
pass user.csvRowCollapsing in the correct position so the collapsing behavior is
driven by the user setting.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: aead8a7b-7f60-45b9-99c5-ce485c2d7566
📒 Files selected for processing (10)
components/Account/ChangeCsvCollapseThreshold.tsxcomponents/Account/account.module.csspages/account/index.tsxpages/api/paybutton/download/transactions/[paybuttonId].tspages/api/payments/download/index.tspages/api/user/csvCollapseThreshold/index.tsprisma-local/migrations/20260317024924_csv_collapse_threshold/migration.sqlprisma-local/schema.prismaservices/userService.tstests/mockedObjects.ts
✅ Files skipped from review due to trivial changes (2)
- prisma-local/migrations/20260317024924_csv_collapse_threshold/migration.sql
- pages/api/user/csvCollapseThreshold/index.ts
🚧 Files skipped from review as they are similar to previous changes (7)
- pages/account/index.tsx
- pages/api/paybutton/download/transactions/[paybuttonId].ts
- components/Account/account.module.css
- services/userService.ts
- components/Account/ChangeCsvCollapseThreshold.tsx
- prisma-local/schema.prisma
- tests/mockedObjects.ts
| const transactions = await fetchAllPaymentsByUserId(userId, networkIdArray, buttonIds, years, startDate, endDate, timezone) | ||
|
|
||
| await downloadTxsFile(res, quoteSlug, timezone, transactions, userId, undefined, user.csvRowCollapsing) | ||
| await downloadTxsFile(res, quoteSlug, timezone, transactions, userId, undefined, true, user.csvCollapseThreshold, user.csvRowCollapsing) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🔴 Critical
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
ast-grep --pattern 'export const downloadTxsFile = async ($$$) => { $$$ }' utils/files.ts
rg -nP 'downloadTxsFile\s*\(' --type=ts -g '!utils/files.ts'Repository: PayButton/paybutton-server
Length of output: 164
Call at line 65 passes an incorrect argument count, dropping user.csvRowCollapsing.
Function downloadTxsFile accepts 8 arguments. The current call passes 9, causing the 9th argument (user.csvRowCollapsing) to be silently ignored and collapseTransactions to remain hardcoded as true.
<details>
<summary>Proposed fix</summary>
- await downloadTxsFile(res, quoteSlug, timezone, transactions, userId, undefined, true, user.csvCollapseThreshold, user.csvRowCollapsing)
+ await downloadTxsFile(res, quoteSlug, timezone, transactions, userId, undefined, user.csvRowCollapsing, user.csvCollapseThreshold)</details>
The same mismatch exists in pages/api/paybutton/download/transactions/[paybuttonId].ts.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| await downloadTxsFile(res, quoteSlug, timezone, transactions, userId, undefined, true, user.csvCollapseThreshold, user.csvRowCollapsing) | |
| await downloadTxsFile(res, quoteSlug, timezone, transactions, userId, undefined, user.csvRowCollapsing, user.csvCollapseThreshold) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@pages/api/payments/download/index.ts` at line 65, The calls to
downloadTxsFile are passing one argument too many, so user.csvRowCollapsing is
being dropped and collapseTransactions stays hardcoded. Update the
downloadTxsFile call in both the payments download handler and the paybutton
transactions handler to match the function’s 8-argument signature, and pass
user.csvRowCollapsing in the correct position so the collapsing behavior is
driven by the user setting.
Related to #953
Description
Allow users to adjust the CSV collapse threshold directly from account settings.
Added a
csvCollapseThresholdparameter to theUserProfileAdded an input field in account settings to configure
csvCollapseThresholdUpdated CSV generation logic to use the
csvCollapseThresholdvalue fromUserProfileTest plan
Summary by CodeRabbit
Release Notes