Skip to content
GitLab
Projects Groups Topics Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Register
  • Sign in
  • A Ahad Mobile
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributor statistics
    • Graph
    • Compare revisions
  • Issues 0
    • Issues 0
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 0
    • Merge requests 0
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Terraform modules
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • holatech
  • Ahad Mobile
  • Merge requests
  • !128

fix(loans): Supply MAX respects the per-user supply cap

  • Review changes

  • Download
  • Patches
  • Plain diff
Merged Hung Hoang requested to merge hunghoang/fix/loan-supply-max into develop Oct 16, 2026
  • Overview 0
  • Commits 3
  • Pipelines 3
  • Changes 19

Bug: https://hola-tech.sg.larksuite.com/record/BK5GrTh5SeDvk9cu5z4lhJncgWc

Problem: Supply screen (USD) showed MAX 19,955.33 (the wallet) but submitting it was refused with "You can supply up to 9,968.99 USD": the per-user FIAT supply cap (10,000) minus what is already supplied or in flight.

Fix
- BE: GET /lending/quotes/supply?asset= returns { capRemaining } (cap headroom floored to the market decimals, null when uncapped), computed by the same cappedSupplyBalance + supplyCapHeadroom the supply refusal uses.
- FE: on FIAT markets MAX = min(wallet, capRemaining); CRYPTO unchanged. The quote is re-asked after a supply, a close or a SUPPLY_EXCEEDS_CAP refusal, and falls back to the wallet if it fails.

Tests
- BE unit + http specs; Postgres fiat-rail.postgres.spec (a MAX of exactly the headroom is accepted with a supply in flight), which fails without the fix.
- FE jest 1349/1349, tsc clean.
- Maestro fe/.maestro/app/supply-max-under-cap.yaml on the iOS simulator against a local BE: MAX 9,968.99 (not 19,955.33), Confirm, Completed; rerun with cap 15,000: MAX 5,000.00, Completed.

Review follow-up — ade691d5
- Supply-cap quotes now refresh through the existing lending socket invalidation helper on settled/failed events. Mounted real-hook regressions cover another session supplying, CLOSE_SUPPLY releasing headroom, and a failed supply returning its reservation. No polling or client-side money calculation added.
- Maestro now requires Completed beside Status, Supply beside Type, and the exact expected USD value beside Amount. Navigation away from the form is no longer enough.

Fresh verification
- Node 20.20.0: full FE 144 suites / 1546 tests passed; typecheck passed; full ESLint 0 errors / 30 warnings. Five assertions failed before the socket fix; the focused tests pass afterward. Prettier, commitlint and whitespace checks passed.
- Actual Maestro CLI AND local stdio MCP on an isolated iOS simulator with a strict localhost mock API: correct Completed Supply 9,968.99 USD passed. Pending, missing-operation error, Failed, wrong amount and wrong type each reached a fresh receipt and were rejected by the intended new assertion, after the old success checks had already passed.
- Native source audit: 1093 production/flow files, zero unintended mismatches; tested YAML and critical source hashes match this commit. Follow-up code and architecture review found no remaining blockers.

Boundaries
- Native follow-up proves mock-backed UI/form/receipt assertions, not real backend cap enforcement, ledger settlement or native socket transport. Socket/query-cache behavior is covered by the mounted-hook tests.
- Existing backend contract, advisory quote behavior and API-error wallet fallback are unchanged. No project dependencies added.
- Owned simulator/services were cleaned up; existing BE, Metro, Postgres, Redis and simulators preserved. No real financial/provider operation was performed. CI on this commit remains required before merge; no merge performed.

Edited Oct 16, 2026 by Hung Hoang
Assignee
Assign to
Reviewers
Request review from
Time tracking
Source branch: hunghoang/fix/loan-supply-max