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
  • !86

feat(fe): move card screens from reap to keysecure card account

  • Review changes

  • Download
  • Patches
  • Plain diff
Merged Khanh Pham requested to merge feat/keysecure-sp4b-card-screens into develop Oct 01, 2026
  • Overview 0
  • Commits 17
  • Pipelines 1
  • Changes 136

Summary

The app's card features now run on the KeySecure card account (/card-account). No app code calls the legacy /cards/*, /reap/* or /chats/external-transfer routes. FE only; no backend changes.

  • API layer: hand-written fe/src/api/card-account/: summary, cards, card, entries, consumptions, deposit, issue card, freeze/unfreeze, and error classification. While a card is APPLYING (less than 2 minutes old), the app polls it.
  • Card tab (approved cardholder):
    • One card-account balance plus the pending amount.
    • Card stack drawn from last4 / status / designSlug.
    • Issue card, guarded against double taps.
    • Purchases (consumptions) and Activity (entries) history.
  • Card detail: Add fund, Freeze/Unfreeze, and "Card details" disabled with a "Coming soon" hint. PAN/CVV reveal is SP4b-2, which needs the KeySecure iframe SDK in a WebView.
  • Funding:
    • Transfer posts POST /card-account/deposit with the amount normalised to 2 decimals, and has no card picker.
    • The Add-fund chooser offers Transfer only.
  • Convert (minimal):
    • cardId is dropped from the quote, and the Reap card-balance call is removed.
    • Another branch reworks Convert into crypto ↔ fiat wallet. The leftovers belong to that rework: the cardReceive prop, the convert.noCardAdded, selectCard and cardSend keys, and isCardFunding.
  • Removed:
    • The chat money flows (send money, split equally, request money) and the card-funded Send path. Send is now crypto only.
    • The Reap-only screens: add-card, billing/shipping address, card settings, PIN, limit, add-current-card.
    • api/cards, the card stores, orphaned card components, hooks and translation keys.

Testing

  • pnpm type-check is clean. pnpm jest passes 111 suites and 1018 tests. eslint on the changed files shows 0 errors.
  • The grep gate for legacy routes and hooks prints nothing.
  • Simulator against a local BE, 6/6 pass:
    • Card tab and the Issue card error toast.
    • History tabs.
    • A Transfer deposit of 5 USD to the card account.
    • Add fund shows Transfer only.
    • Chat has no money actions.
    • Card detail freeze/unfreeze and details disabled.
  • Card issuance in the sandbox is still blocked: /card/apply returns 3008 until the reserve is funded.

Notes / follow-ups

  • Backend: POST /card-account/cards returns 400 with no code when the wallet cannot cover the issue fee. Swagger documents 422 INSUFFICIENT_BALANCE. The app handles it, but the backend should be fixed.
  • Issue fee: not shown in the app; the only fee route is the legacy /cards/issue-fee.
  • Local env: a local BE needs KEYSECURE_CARD_PACKAGE_NO, otherwise Issue card returns 503 KEYSECURE_NOT_CONFIGURED.
  • Polling: an APPLYING card stops polling after 2 minutes. The backend sweeper only resolves older cards (every 5 minutes), so a 202 card can show "Processing" until the screen is reopened.
  • Cardholder status: a CARDHOLDER_NOT_APPROVED error while loading the balance does not refresh the cardholder status (the Issue path does).
  • Dead code:
    • send/confirm.tsx keeps a crypto chat branch and group-member plumbing that are now unreachable.
    • detail-card/card-action-button.tsx and utils/format-card-number.ts were already unused before this branch.
  • UI polish:
    • The card face shows a Mastercard logo for a Visa BIN.
    • The Transfer fee row reads "0 PRV".
    • The confirm sheet shows the raw typed amount ("5.").

🤖 Generated with Claude Code

Assignee
Assign to
Reviewers
Request review from
Time tracking
Source branch: feat/keysecure-sp4b-card-screens