Background
While investigating a PAYG debt recovery issue, I noticed a debt recovery behavior that seems counterintuitive.
For PAYG users, debt status is currently calculated roughly as:
oweamount = Balance - DeductionBalance + UsableCredits
When a user enters debt, the current code calls ResumeBalance. If DeductionBalance > Balance, ResumeBalance normalizes DeductionBalance back to Balance.
Example:
Before debt processing:
Balance = 0
DeductionBalance = 500
UsableCredits = 0
oweamount = -500
After ResumeBalance:
Balance = 0
DeductionBalance = 0
UsableCredits = 0
oweamount = 0
Then if the user recharges only 10:
Balance = 10
DeductionBalance = 0
UsableCredits = 0
oweamount = 10
The user can recover from debt, even though the original unpaid usage was 500.
Proposal
I propose changing PAYG debt recovery semantics so that users must cover the outstanding debt before resources are resumed.
In other words, entering debt should not erase the debt gap from the recovery condition.
A possible model:
outstandingDebt = max(DeductionBalance - Balance - UsableCredits, 0)
When a user enters debt, we should persist this outstanding debt amount separately, for example on the Debt record or another account debt ledger table.
Then recovery should require:
Balance + UsableCredits >= outstandingDebt
or another explicit "debt fully covered" condition.
Why
The current behavior makes it possible for a PAYG user with a large unpaid usage amount to recover after a very small recharge.
This seems surprising from both an accounting perspective and an operator/debugging perspective:
- the original unpaid usage gap is normalized away from the main account fields;
- recovery no longer reflects the actual unpaid usage amount;
- later investigation has to rely on transaction/audit records such as
DebtResumeDeductionBalanceTransaction;
- the name
ResumeBalance is also easy to misread as resource recovery, while it actually mutates deduction balance.
Suggested Implementation Direction
- Keep
ResumeBalance only if we still need to normalize DeductionBalance for technical reasons.
- Persist the debt gap before normalization.
- Use the persisted debt gap as part of the recovery condition.
- Only patch resources to
Resume after the outstanding debt is fully covered.
- Add comments/docs around
ResumeBalance to clarify that it normalizes deduction balance and does not itself resume resources.
Open Questions
- Should outstanding PAYG debt be stored on the existing
Debt record or in a separate debt ledger?
- Should credits be allowed to cover outstanding PAYG debt?
- Should partial repayment reduce the outstanding debt immediately, or only affect recovery once fully covered?
- How should this interact with existing
DebtResumeDeductionBalanceTransaction records?
Background
While investigating a PAYG debt recovery issue, I noticed a debt recovery behavior that seems counterintuitive.
For PAYG users, debt status is currently calculated roughly as:
When a user enters debt, the current code calls
ResumeBalance. IfDeductionBalance > Balance,ResumeBalancenormalizesDeductionBalanceback toBalance.Example:
After
ResumeBalance:Then if the user recharges only 10:
The user can recover from debt, even though the original unpaid usage was 500.
Proposal
I propose changing PAYG debt recovery semantics so that users must cover the outstanding debt before resources are resumed.
In other words, entering debt should not erase the debt gap from the recovery condition.
A possible model:
When a user enters debt, we should persist this outstanding debt amount separately, for example on the
Debtrecord or another account debt ledger table.Then recovery should require:
or another explicit "debt fully covered" condition.
Why
The current behavior makes it possible for a PAYG user with a large unpaid usage amount to recover after a very small recharge.
This seems surprising from both an accounting perspective and an operator/debugging perspective:
DebtResumeDeductionBalanceTransaction;ResumeBalanceis also easy to misread as resource recovery, while it actually mutates deduction balance.Suggested Implementation Direction
ResumeBalanceonly if we still need to normalizeDeductionBalancefor technical reasons.Resumeafter the outstanding debt is fully covered.ResumeBalanceto clarify that it normalizes deduction balance and does not itself resume resources.Open Questions
Debtrecord or in a separate debt ledger?DebtResumeDeductionBalanceTransactionrecords?