fix: the dashboard asserted $0.00 before anything had ever looked - #202
Conversation
A brand-new user's first view of CashPilot was "Total Balance $0.00 / Today $0.00 / This Month $0.00" — stated as measurements, in the same typeface those cards will later carry real money in. The three cards rendered identically when collection had silently STOPPED: an expired cookie, deleted credentials, a wedged scheduler. Nothing in the payload let the page tell "nothing measured yet" from "measured, and it was zero", and the template shipped the zeroes hardcoded, so they were on screen before any request was even made. /api/earnings/summary now reports has_readings, computed from the earnings rows it was already fetching. The cards render an em dash and "Nothing collected yet" until something has actually been read; the topbar total gets the same treatment, since one of them saying $0.00 would undo the other. A service read at exactly 0.00 still counts as read. Folding a genuine measured zero back into "nothing yet" would replace one wrong answer with another, and a control pins it. This is the rule the codebase already follows for balances, costs and payout minimums — absent is not zero — applied to the first screen a new user sees. Negative control: dropping has_readings fails 3 tests; deriving it from the total instead of the rows fails 2; rendering currency unconditionally fails 1; restoring one hardcoded $0.00 fails 2. The renderer assertion was strengthened after the third control initially PASSED — it matched a string that also occurs on the note-toggling line, so it was proving nothing about the cards it named. Closes CashPilot-93t
|
Warning Review limit reached
Next review available in: 16 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
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 |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #202 +/- ##
=======================================
Coverage 95.07% 95.07%
=======================================
Files 46 46
Lines 5912 5913 +1
=======================================
+ Hits 5621 5622 +1
Misses 291 291
🚀 New features to boost your workflow:
|
The defect
A brand-new user's first view of CashPilot:
Stated as measurements, in the same typeface those cards will later carry real money in. Worse, the same three cards render identically when collection has silently stopped — an expired cookie, deleted credentials, a wedged scheduler.
Verified live on an empty install:
/api/earnings/summaryreturns{"total":0,"today":0.0,"month":0,...}with no field separating "no earnings rows exist" from "balances summed to zero". Anddashboard.htmlshipped the zeroes hardcoded, so they were on screen before any request was made.The fix
/api/earnings/summarynow reportshas_readings, computed from the earnings rows it was already fetching — no extra query. The cards render an em dash plus "Nothing collected yet" until something has actually been read. The topbar total gets the same treatment, since one of them saying $0.00 would undo the other.A service read at exactly 0.00 still counts as read. Folding a genuine measured zero back into "nothing yet" would replace one wrong answer with another, and a control pins it.
This is the rule the codebase already applies to balances, running costs and payout minimums — absent is not zero — applied to the first screen a new user ever sees.
Evidence
ruff check+ruff format --checkclean,node --checkclean, 95.12% coverage, 2644 passed.Negative control:
has_readings$0.00restored to the templateOne note worth recording: the third control initially passed. My renderer assertion matched
data.has_readings === falseanywhere in the file, and the note-toggling line satisfies it on its own — so it proved nothing about the three cards it named. Strengthened to pin the money path, and each card is now separately asserted to go through it.Closes CashPilot-93t