Money paste follow-ups: separator hint and symbol drift test - #3882
Conversation
Pasting "1,234" into a euro field wrote 1234. The money field now passes the selected currency's decimal separator to the paste parser, which uses it only when a single separator precedes exactly three digits. Refs we-promise#3395
The letter-free symbol list in parse_amount_paste.js is copied by hand from config/currencies.yml; fail CI when the two drift apart. Refs we-promise#3395
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Important Review skippedReview was skipped as selected files did not have any reviewable changes. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (1)
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthroughThe money field supplies the selected currency’s decimal separator to pasted-amount parsing. The parser applies the hint only to numbers with one separator followed by exactly three digits. Tests cover hinted and unhinted parsing, other separator patterns, and currency-symbol consistency. ChangesCurrency-aware paste parsing
Priority: ➖ Normal Estimated code review effort: 2 (Simple) | ~10 minutes Change: Bug fix Suggested reviewers: Merge Risk: ⚪ Minimal · up to The selected currency’s separator now guides ambiguous pastes when available. During a currency switch or failed fetch, the existing heuristic remains in use; no new material merge risk is evident. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The change improves currency-aware amount interpretation without adding privileges or widening access. No introduced security issue was established. Existing submission behavior during pending currency changes remains, but its final server-side validation was not verified. Retained concerns Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 5 files. (1 skipped: 1 unsupported.) ✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
jjmata
left a comment
There was a problem hiding this comment.
Single-pass review done without the Agent tool (no multi-agent fan-out / subagent verify pass ran) — two findings below, both self-checked against the diff and the surrounding code.
Generated by Claude Code
| // other shape already says which separator is the decimal one, so a separator | ||
| // hint is only applied here; forcing it onto "$1,234.56" pasted into a euro | ||
| // field would read 1.23456. | ||
| const AMBIGUOUS_SEPARATOR = /^[^.,]*[.,]\d{3}$/ |
There was a problem hiding this comment.
Minor: ambiguity detection is now duplicated between this file and parse_locale_float.js.
AMBIGUOUS_SEPARATOR (/^[^.,]*[.,]\d{3}$/) re-implements, with a slightly different scope, the same "single separator + exactly three digits" ambiguity check that parseLocaleFloat's heuristic branch already computes independently (lastDot === -1 && digitsAfterComma === 3 in app/javascript/utils/parse_locale_float.js). The two definitions happen to agree today, but nothing ties them together — if either the regex here or the heuristic there is tweaked later (e.g. to also treat 1,23 or multi-group cases as ambiguous), they can silently drift apart, and parseAmountPaste would gate the hint on a different notion of "ambiguous" than parseLocaleFloat uses when no hint is supplied. Not a current bug, but worth consolidating into one shared ambiguity check (or at least a comment cross-referencing the other file) to keep them from diverging.
Generated by Claude Code
There was a problem hiding this comment.
I added cross-reference comments in both files in b5c07a0. I kept the two checks separate because they answer different questions: the heuristic in parseLocaleFloat picks one reading when there's no hint (it only treats a comma before three digits as grouping), while AMBIGUOUS_SEPARATOR marks every shape a hint should settle, including 1.234. Nothing else passes a separator to parseLocaleFloat, so I didn't want to change its behaviour for the other callers.
While a currency switch is loading or after it fails, the separator still belongs to the previous currency, so pastes fall back to the heuristic.
Part of #3395 (follow-ups from #3300).
Problem
Pasting
1,234into a EUR money field wrote1234instead of1.234: without a hint, the paste parser reads a comma before exactly three digits as a thousands separator. Before #3300 the browser rejected that paste, so this could now be saved by an auto-submit form.Changes
1. Currency separator hint
data-money-field-separator-value) and passes it toparseAmountPaste.,or.followed by exactly three digits. Other pastes keep the current parsing, so$1,234.56pasted into a EUR field is still1234.56.1,2341.234$1,234.563. Symbol-list drift test
test/architecture/currency_paste_symbols_test.rbfails whenCURRENCY_SYMBOLinparse_amount_paste.jsdrifts from the letter-free symbols inconfig/currencies.yml..mjstest because CI doesn't runtest/javascript.Question on part 2 (lettered markers)
I've left
USD 500,kr 500,R$ 1.234,56falling through to the browser. The reason is already documented at the top ofparse_amount_paste.js. Would you prefer to keep it that way, or ship a server-provided marker list (possibly limited to the selected currency's own symbol and ISO code)? If the status quo is fine, this PR can close the issue.Validation
node --test test/javascript(13 new cases for the separator hint)bin/rails test: 10,331 runs, 0 failuresbin/rubocop,erb_lint,npm run lint,bin/brakeman: cleanSummary by CodeRabbit