Bug
https://hola-tech.sg.larksuite.com/record/Qxuhr9GoSew9VIcfcallSpGMg5e
Actual: tapping "Apply for a card" rapidly opens one /cardholder-apply form per tap; the stacked duplicate forms each submit their own application and the losers surface as the "Retry" error.
Expect: only one Apply tap is honored while the form opens.
Root cause
card.tsx wired the CTA to router.push('/cardholder-apply') with no re-entry guard. expo-router v5's router.navigate does NOT dedupe a rapid burst (navigation actions queue asynchronously) — verified live on device.
Fix
Synchronous ref lock around the push in CardsScreen: taps inside the 1 s open window are dropped; the lock auto-releases so a deliberate reopen still works. No visual/UX change otherwise; submit-time dedupe from !134 (merged) is untouched.
Verification
- New Maestro regression flow
fe/.maestro/card-create-single-flight/apply-single-tap.yaml(local fixture, no live API): 3-tap burst -> assert exactly one form via a single back press; deliberate reopen after the burst still opens the form. - Repro on unfixed code: flow fails — one back lands on a second "Card application" screen (screenshot: repro evidence kept).
- With the fix: full flow green.
-
pnpm tsc --noemitclean, eslint on touched file clean, related jest suites (cardholder-apply, cardholder-status, keysecure-cardholder): 97/97 pass. - Fixture tooling:
fixture.cjsreset accepts optionalinitialStatus(default unchanged) so the start view can be served;control.jsforwards it.