Skip to content

fix: reopen 2:3 share splits as 2:3, not 1:1.5 (port of upstream #774) - #35

Merged
KMKoushik merged 1 commit into
mainfrom
hq/port-774
Oct 16, 2026
Merged

KMKoushik merged 1 commit into
mainfrom
hq/port-774

Conversation

@KMKoushik

@KMKoushik KMKoushik commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Port of upstream oss-apps/split-pro#774 (fixes upstream #727), adapted to how this repo rebuilds split inputs.

Problem

splitpro.app already keeps the cents unchanged when an expense is reopened. But the split inputs it rebuilds can look different from what was entered:

  • A 2:3 share split reopens as 1 : 1.5. 4:6 also reopens as 1 : 1.5.
  • Percentages can drift into hundredths, e.g. 43/57 of 7.03 reopens as 42.96/57.04, and 25/50/25 of 12.34 as 25.04/50/24.96.

Change (src/store/addStore.ts, calculateSplitShareBasedOnAmount)

Upstream added a separate bigint recovery module. Here I added new candidates to the existing pick order instead. pick still uses a candidate only if it gives back exactly the stored cents, so it can't move money.

  • SHARE: first try the smallest whole numbers. Each try gives the smallest share one more (1, 2, … 100), as long as every share stays at most 100. After that come the existing 2-decimal shares relative to the smallest share, then the exact ratio. This replaces the old GCD whole-share candidate, which it fully covers.
  • PERCENTAGE: try whole percentages, then tenths, then hundredths (each adjusted to add up to exactly 100%), then the exact ratio.

Trade-off, the same one upstream makes: on small amounts, a decimal share input can reopen as whole shares that give the same cents. For example, 1 : 1.37 on 77.93 reopens as 27:37. On 779.30 it stays 1 : 1.37. Halves become equivalent whole numbers (1 : 1.5 → 2:3).

Testing

  • Added a test to src/tests/splitRoundTrip.test.ts. It opens a stored expense through getEditFormState three times in a row and checks two things: the shown inputs (2:3, 4:6→2:3, refunds, 3 people, zero share, halves, 43/57, 25/50/25, 37.5/62.5, 33.33/33.33/33.34), and that the cents never change.
  • The existing randomized round-trip tests still pass: 400 seeds through every split type plus edit-and-save. pnpm test: 202 passed, 0 failed (42 DB integration tests skipped).
  • npx tsc --noEmit -p . passes. pnpm lint reports nothing in the changed files.

Summary by CodeRabbit

  • Bug Fixes

    • Improved how percentage and share splits are displayed when reopening and saving, while preserving participant amounts to the cent across repeated saves.
  • Tests

    • Added coverage for split values across positive, negative, zero, and decimal amounts.

Port of oss-apps/split-pro#774, adapted to the cloud's pick order: a 2:3
share split reopened as 1:1.5, and 43% of 7.03 reopened as 42.96%. Smallest
whole shares (up to 100) and whole, then tenth percentages are now tried
first, and still only used when they give back exactly the stored cents.
@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: bce848ef-0fbb-46af-a6ba-96ef1d211ac0
📥 Commits

Reviewing files that changed from the base of the PR and between c2ae7ed and 34d160c.

📒 Files selected for processing: 2
  • src/store/addStore.ts
  • src/tests/splitRoundTrip.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📝 Walkthrough

The split reconstruction logic now searches bounded whole-share and percentage candidates. Regression tests cover repeated form reconstruction and verify that participant amounts remain unchanged to the cent.

Changes: Split reconstruction

Layer / File(s) Summary
Bounded split candidate reconstruction
src/store/addStore.ts, src/tests/splitRoundTrip.test.ts
The candidate search tries whole, one-decimal, and two-decimal percentage representations, and progressively scaled whole-number share ratios capped at 100. Regression cases verify expected displayed inputs and unchanged participant amounts through three reconstruction cycles.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~15 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 34d16

This change makes reopened split expenses show simpler share and percentage inputs while keeping each participant's amount unchanged to the cent. No merge-blocking risk was identified.

Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly identifies the main change: preserving 2:3 share splits when reopening expenses. The upstream port reference is accurate and does not obscure the primary change.
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 2 files.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@KMKoushik
KMKoushik merged commit 2a6d405 into main Oct 16, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant