Skip to content

feat(credit): implement subscription credit system and account balance (#719)#797

Open
Yinklekay wants to merge 2 commits into
Smartdevs17:mainfrom
Yinklekay:feature/credit-system-719
Open

feat(credit): implement subscription credit system and account balance (#719)#797
Yinklekay wants to merge 2 commits into
Smartdevs17:mainfrom
Yinklekay:feature/credit-system-719

Conversation

@Yinklekay

Copy link
Copy Markdown

Pull Request: Implement subscription credit system and account balance (Closes #719)

Summary

Adds a complete, end-to-end subscription credit system that mirrors the existing subtrackr-credit Soroban contract shape and the mobile AccountCredit ledger store, exposing:

  • Per-user credit balances with oldest-first consumption and never-negative invariants.
  • Credit application to subscription payments at the invoice-close boundary, so downstream payments and dunning only ever see the net amount due.
  • Immutable history / audit trail with paginated queries by time and entry kind.
  • A dedicated credit analytics dashboard with projected-vs-committed outstanding liability, daily usage trend, expiry forecast, top accounts, and burn-rate / consumption latency.
  • Expiration management with a per-account after_secs policy and explicit expireAccount / expireAll mutations that produce auditable ledger entries.
  • Bidirectional credit transfer between accounts, capped at the sender's unexpired balance.
  • Credit reporting in CSV and JSON with multi-section ledger flow + wallet transaction history.

Closes #719

Acceptance Criteria

  • Credit balance per user — creditService.getBalance, getAccount; mobile + web stores unchanged.
  • Credit application to subscription payments — applyCreditToCharge (integrates at invoice close).
  • Credit history with audit trail — paginated getAuditTrail with time/kind filters + printReport history section.
  • Credit analytics dashboard — getGlobalBreakdown, getUsageTrend, getExpiryForecast, getAccountSummary, topAccountsByBalance; mobile 4-tab CreditBalanceScreen.tsx + app/stores/analyticsStore.ts snapshot.
  • Credit expiration management — setExpirationPolicy, expireAccount, expireAll, getExpiryForecast (filters past-due lots).
  • Credit transfer between users — transferCredit with sender/recipient ledger entries.
  • Credit reporting — printReport + exportReport(..., 'csv' | 'json').

Technical Scope

A backend/services/billing/creditTypes.ts (new)
A backend/services/billing/creditService.ts (new)
A backend/services/billing/tests/creditService.test.ts (new — 36 tests)
M backend/services/billing/interfaces.ts (added ICreditService)
M backend/services/billing/errors.ts (added credit error codes + factories)
M backend/services/billing/index.ts (exported CreditService / types / helpers)
M app/stores/creditStore.ts (fixed pre-existing compile error; behaviour-preserving rewrite)
M app/screens/CreditBalanceScreen.tsx (rebuilt: 4-tab analytics dashboard UI)
M app/stores/analyticsStore.ts (added CreditMetricSnapshot + aggregation)

Architecture

  • Ledger model is source of truth, mirroring the on-chain Soroban contract and the mobile AccountCredit store. A future contract-event replay integration is translation-free.
  • Read methods are strictly non-mutating via projectExpiry(). Mutating expiry surface is explicit (expireAccount / expireAll).
  • Downstream payments and dunning only see the net amount due via applyCreditToCharge.
  • Projected vs committed outstanding liability are both exposed so finance dashboards can show on-chain lag.

Test Plan

  • Backend Jest: 36/36 tests pass (npx jest -c jest.backend.config.js backend/services/billing/__tests__/creditService.test.ts).
  • Root tsc --noEmit: clean.
  • Backend tsc --noEmit -p tsconfig.json: clean for the credit files.
  • eslint --no-ignore on modified files: 0 errors (4 Array style warnings).

Risks / Notes

  • No persistence layer is added in this PR. The ICreditService interface makes a DB-backed repository a drop-in replacement.
  • Past-due amounts are surfaced as a single delta in the LAST bucket of getUsageTrend (a "now" signal). A future per-day historical expiry trend would be a separate projectExpiryTrend helper.
  • The on-chain Soroban contract (contracts/credit/src/lib.rs) already implements the same operation set and is not modified by this PR.

Reviewer Checklist

  • app/stores/creditStore.ts rewrite preserves the 8 existing tests.
  • creditService is class+instance with ICreditService re-exported.
  • All mutators throw typed BillingError with appropriate codes.
  • Read methods are strictly non-mutating.
  • CreditBucketBreakdown returns both projected and committed outstanding liability.
  • CSV report correctly escapes commas.
  • No new lint errors introduced.

Smartdevs17#719)

Adds an end-to-end subscription credit system mirroring the
subtrackr-credit Soroban contract and the mobile AccountCredit ledger
store, with:

  - per-user credit balances (never-negative, oldest-first consumption)
  - applyCreditToCharge integration at invoice close
  - paginated audit trail (filterable by time and entry kind)
  - Credit analytics: getAccountSummary, getGlobalBreakdown,
    getUsageTrend, getExpiryForecast, topAccountsByBalance
  - expiration management: setExpirationPolicy + expireAccount /
    expireAll mutations on a clone-first projection
  - bidirectional credit transfer
  - prepayment wallets (createWallet / deposit / withdraw / drawdown)
  - CSV/JSON credit reporting via printReport / exportReport

Fixes a pre-existing compile error in app/stores/creditStore.ts.
Wires a 4-tab credit balance dashboard into the mobile analytics
store. Surfaces projected-vs-committed outstanding liability so
finance dashboards can show the on-chain lag.

Closes Smartdevs17#719

Backend jest: 36/36 passing. Root tsc clean. Lint clean (4 style
warnings on existing Array<T> usage; safe to leave).
@drips-wave

drips-wave Bot commented Jul 25, 2026

Copy link
Copy Markdown

@Yinklekay Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Smartdevs17

Copy link
Copy Markdown
Owner

merge conflicts

@Yinklekay

Copy link
Copy Markdown
Author

done

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.

Implement subscription credit system and account balance

2 participants