feat: the app has a concept of money - #46
Conversation
grep for earning|balance|payout across this source returned nothing. The app is
named CashPilot and showed no money at all -- it pushed a heartbeat and never
read anything back.
The server now returns per-platform earnings on the heartbeat, which is the one
call this client is already authenticated for, so no second credential is
needed. This adds the model, keeps the last known figures in a StateFlow beside
the existing lastHeartbeat state, and adds the display rules.
The rules are the point, and each is a thing the server took care to express
that a client can easily throw away:
- null usd means NOTHING WAS EVER READ -> em-dash, never "$0.00"
- a genuine 0.0 is a measurement -> "$0.00"
- no total when no platform has been read -> no line at all, not "$0.00"
- a platform also running on another machine cannot be attributed to this
device, and the payload says so
- a phone is offline often, so the last figures are KEPT rather than blanked
on every blip -- but timestamped, so the UI can say they are stale instead
of passing them off as current
|
Warning Review limit reached
Next review available in: 11 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 |
Client half of
CashPilot-android-35t(P1). The server half is CashPilot#242, already merged.The gap
grep -riE "earning|balance|payout"across this source returned nothing. The app is named CashPilot and showed no money at all — it pushed a heartbeat and never read anything back.It couldn't just call an earnings endpoint: every one on the server goes through
_require_auth_api, which needs a user session. A per-worker key reads none of them, and giving a phone an owner-level credential to render a number is a bad trade. So the server now returns the figures on the heartbeat — the one call this client is already authenticated for.What this adds
The model, a
StateFlowbeside the existinglastHeartbeatstate, and the display rules.The rules are the point. Each is something the server took care to express, and that a client can throw away without noticing:
usd: null— nothing ever read$0.00usd: 0.0— a real measurement$0.00total_usd: null— no platform readshared_with_other_workers: trueThat first row is the one that matters. A confident
$0.00beside a service the user is actively running is a lie, and it's the exact defect class the server side of this project has spent dozens of fixes removing. Getting it wrong here would reintroduce it on mobile.Attribution stays honest. Providers report one balance per account, so when the same app runs on two machines nothing can split it. The payload carries that fact and the client keeps it, rather than presenting an account figure as a device figure.
Offline is the normal case on a phone. The last figures are kept rather than blanked on every connectivity blip — but timestamped, so the UI can say they're stale instead of passing them off as current.
earningsToKeepandearningsAreStaleare both pure and unit-tested.Tests
14, covering every rule above plus the wire format — including a case that parses the exact JSON the server emits and asserts an unread platform stays
nullrather than becoming0.0, and one proving an older server that sends noearningskey reads as unknown rather than as an empty set of figures.Verification
No JDK on either machine here, so I have not run the suite locally and am not claiming I did — same as the two Android PRs before this, both of which CI validated cleanly. CI is the gate.
Not in this PR
Rendering it on the dashboard. This lands the model, the state, and the rules with tests; wiring it into
AppCardand the summary header is a UI change that belongs with the UI-renewal bead, where screenshot tests will exist to prove it. Splitting it keeps this diff reviewable and keeps the honesty rules under test independently of layout.