Repository navigation
fix(ops): derive the month flow counters from type, not from a sign no writer produces - #191
Merged
Merged
Conversation
…o writer produces
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The operator dashboard's 「点数流入 / 点数流出」 pair (
GET /api/ops/runtime) was computed with a sign filter —WHERE pts > 0for inflow andWHERE pts < 0for outflow — over a ledger that is type-keyed: every production writer stores a positivepts(billing.rsconsume/earn,gift.rs,raise.rs,admin.rs,ops.rs), and the direction lives in thetypecolumn.Consequences:
month_outmatched no rows at all ⇒ the 「点数流出」 card rendered-0permanently.month_insummed every row, crediting consumption as inflow.Runtime evidence through the real writers (
POST /api/ops/credits+billing::settle, rowstopup 100/consume 7/earn 6.3): the endpoint returnedmonth_in = 113.3,month_out = 0.0before this fix — the correct pair is106.3 / 7.0. Injecting one negative-ptsrow mademonth_outbecome2.0, proving the query was alive and that no writer emits a negativepts.Related Issue
No linked issue — none exists for this defect. Recorded empty on purpose (verified via GraphQL
closingIssuesReferences).Changes
src/routes/ops.rs:month_innow filterstype IN ('earn', 'topup', 'gift');month_outnow filterstype IN ('consume', 'withdraw'). This mirrors the convention already used bywallet.rs's 7-day net series (CASE WHEN type IN ('earn','topup','gift') THEN pts ELSE -pts END) and the ops.mocksub-labels (收益 / 充值 / 赠送vs消费 / 提现).ABS()dropped on the out side: no writer stores a negative magnitude, soSUM(pts)is correct.Tests
cargo test— 180 passed (baseline 179, +1)cargo fmt --checkcargo clippy --all-targets -- -D warningsops_runtime_month_flow_is_type_baseddrives the real writers (POST /api/ops/credits+billing::settle) and assertsmonth_in == 100 + round5(7 * 0.9)andmonth_out == 7.0(expectations derived from the fixture + production constants, not hard-coded), plus a positive control: a month containing only a consume row ⇒ inflow must be0.0.Checklist
fix/…)fix(ops): …)Severity: display-only. The ops runtime pane is reachable only with
role = ops(the host) and no money path readsmonth_in/month_out— this is a permanently-wrong dashboard metric, not a billing bug.A/B evidence. Reverting only the two
WHEREclauses to the sign form turns exactly the new test red (observedmonth_in = 113.3,month_out = 0.0) while the other 179 stay green.