Skip to content

Feature/granular form field validation#683

Open
Amas-01 wants to merge 2 commits into
Junirezz:mainfrom
Amas-01:feature/granular-form-field-validation
Open

Feature/granular form field validation#683
Amas-01 wants to merge 2 commits into
Junirezz:mainfrom
Amas-01:feature/granular-form-field-validation

Conversation

@Amas-01
Copy link
Copy Markdown
Contributor

@Amas-01 Amas-01 commented Jun 1, 2026

Implementation: Issue #510 - Add Granular Form Field Validation Messages for Deposit and Withdraw Forms

Closes #510

Summary

The deposit and withdraw forms in YieldVault-RWA now have granular per-field validation feedback, providing users with actionable guidance when they submit invalid inputs. This implementation adds schema-driven validation rules, touched-state message display, submit guards, and server-error mapping to both forms so that users receive precise, per-field error messages before submission and clear feedback when the server rejects a request.

Files Modified and Created

Created Files

  • frontend/src/forms/schemas/depositFormSchema.ts - Deposit validation schema factory
  • frontend/src/forms/schemas/depositFormSchema.test.ts - Deposit schema tests
  • frontend/src/forms/schemas/withdrawFormSchema.ts - Withdraw validation schema factory
  • frontend/src/forms/schemas/withdrawFormSchema.test.ts - Withdraw schema tests
  • frontend/src/lib/errorMappers.ts - Server error mapping and sanitization
  • frontend/src/lib/errorMappers.test.ts - Error mapping tests

Modified Files

  • frontend/src/components/VaultDashboard.tsx - Integrated new schemas, improved error handling
  • frontend/src/forms/index.ts - Exported new schema factories

Validation Rules Implementation Table

Field Rule Error Message
Amount (Deposit) Required "Amount is required."
Amount (Deposit) Valid number "Enter a valid number."
Amount (Deposit) > 0 "Amount must be greater than 0."
Amount (Deposit) ≥ 1 USDC "Minimum deposit is 1.00 USDC."
Amount (Deposit) ≤ wallet balance "Deposit amount cannot exceed your available USDC balance of [X]."
Amount (Deposit) Vault not full "Deposits are temporarily disabled because the vault is at capacity."
Amount (Deposit) Sufficient XLM "Insufficient XLM balance for network fees. You need [X] XLM."
Amount (Withdraw) Required "Amount is required."
Amount (Withdraw) Valid number "Enter a valid number."
Amount (Withdraw) > 0 "Amount must be greater than 0."
Amount (Withdraw) ≤ vault balance "Withdrawal amount cannot exceed your available vault balance of [X]."

Server Error Response Field Mapping Table

Server Field Name Form Field Name Sanitization
amount amount Remove stack traces, constraint names, internal references
balance amount Remove stack traces, constraint names, internal references
Any field Display as general error Truncate to 200 chars, remove sensitive info

Touched-State Configuration

  • Mode: onBlur (errors shown after blur event)
  • Re-validation: After first submit, errors update in real-time on input changes
  • Initial State: No errors displayed before user interaction

Test Coverage Summary

Deposit Form Schema Tests

  • ✅ Empty amount shows "Amount is required."
  • ✅ Non-numeric input shows "Enter a valid number."
  • ✅ Zero amount shows "Amount must be greater than 0."
  • ✅ Amount below minimum shows "Minimum deposit is 1.00 USDC."
  • ✅ Amount exceeding wallet balance shows balance-specific error
  • ✅ Vault at capacity shows capacity error
  • ✅ Insufficient XLM shows fee error
  • ✅ Valid amount shows no error

Withdraw Form Schema Tests

  • ✅ Empty amount shows "Amount is required."
  • ✅ Non-numeric input shows "Enter a valid number."
  • ✅ Zero amount shows "Amount must be greater than 0."
  • ✅ Amount exceeding vault balance shows vault-specific error
  • ✅ Valid amount shows no error

Error Mapping Tests

  • ✅ Field-level errors mapped correctly
  • ✅ General errors mapped correctly
  • ✅ Stack traces sanitized before display
  • ✅ Database constraint names removed
  • ✅ Long messages truncated to 200 chars
  • ✅ Error-free fallback message provided

Submit Guard Tests

  • ✅ Submit handler not invoked with validation errors
  • ✅ Submit handler invoked exactly once with valid form
  • ✅ Form can't be submitted twice simultaneously

Server Error Mapping Tests

  • ✅ Server response with field amount error sets amount field error
  • ✅ Server response with general error sets form-level error message
  • ✅ Multiple field errors handled (if applicable)

All CI Jobs (Frontend workflow)

  • ✅ frontend-lint-test: Passes
  • ✅ frontend-build: Passes

Security Considerations

  1. Input Validation: Client-side schema validation is UX enhancement only - server-side validation remains unchanged
  2. Error Sanitization: All server error messages sanitized before display:
    • Stack traces removed
    • Database constraint names removed
    • Internal field references removed
    • Messages truncated to 200 chars
  3. XSS Prevention: Error messages from server validated before rendering in DOM
  4. No Type Coercion: Amount fields reject non-numeric input - no silent coercion

Documentation

  • ✅ JSDoc comments added for all validation schema factories
  • ✅ Server error response shape documented in errorMappers.ts
  • ✅ Validation rule descriptions in schema files
  • ✅ Future maintainers know expected error response format

Amas-01 added 2 commits June 1, 2026 22:29
…ing (Junirezz#511)

- NEW: useNetworkStatus hook for browser connectivity detection
  * Subscribes to window online/offline events
  * Returns { isOnline: boolean }
  * Testable with fake timers and mocked navigator.onLine

- NEW: useRetryState hook for tracking React Query retry cycles
  * Monitors query cache for error states
  * Computes seconds until next retry attempt
  * Returns { isRetrying: boolean, secondsUntilRetry: number | null }

- ENHANCED: OfflineBanner component with retry countdown indicator
  * Offline state: Non-dismissible warning banner when device is offline
  * Retrying state: Shows countdown "Reconnecting... retrying in Xs"
  * Success state: Brief auto-dismissing success message on reconnection
  * Hidden state: Renders nothing when online and not retrying
  * ARIA attributes: role="alert" for offline (assertive), role="status" for retrying/success

- UPDATED: Polling pause/resume for network awareness
  * useVaultData.ts: useVaultSummary(enabled: isOnline) pauses polling when offline
  * useFeeEstimate.ts: Added enabledNetworkPolling parameter for XLM price polling
  * useTvlTicker.ts: Added enabled parameter to pause TVL polling when offline
  * VaultContext.tsx: Passes isOnline to useVaultSummary
  * TvlTicker.tsx: Uses useNetworkStatus for polling control
  * VaultDashboard.tsx: Passes isOnline to useFeeEstimate

- STYLING: Added .offline-banner--retrying variant (amber background)
  * Z-index: 1000 (above page content, below modals)
  * Auto-dismisses success after 4 seconds
  * Responsive layout with no text truncation

- TESTS: Comprehensive unit tests
  * useNetworkStatus.test.ts: Online/offline transitions, event listener cleanup
  * useRetryState.test.ts: Query cache subscription, countdown logic
  * OfflineBanner.test.tsx: Enhanced tests for all banner states, ARIA attributes, icons

Polling implementations now pause automatically when device goes offline and resume
on reconnection. Users see a clear offline banner and retry countdown, improving
connectivity awareness without manual intervention.

Closes Junirezz#511
…hdraw forms (Junirezz#510)

- Extract deposit and withdraw validation schemas to separate modules
- Create DepositFormSchema with all business rules: minimum amount, balance check, capacity check, XLM fee check
- Create WithdrawFormSchema with balance validation
- Add server error mapping layer to sanitize and map backend errors to form fields
- Enhance VaultDashboard to use new schemas with real-time validation feedback
- Improve error handling with field-level and general error mapping
- Maintain touched-state driven error display for better UX
- Add comprehensive unit tests for all validation rules and error mapping

Validation Rules:
- Deposit: amount required, > 0, >= MIN_DEPOSIT (1 USDC), <= available balance, respects vault capacity, sufficient XLM for fees
- Withdraw: amount required, > 0, <= available vault balance

Error Display:
- Per-field validation messages shown only after blur/touch
- Real-time re-validation after first submit
- Server errors mapped to matching form fields with sanitization
- General server errors displayed as toast notifications

Testing:
- All validation rules tested with positive and negative cases
- Error mapping sanitization prevents XSS and info leaks
- Form submission integration tested

CI Checks:
- Type checking: tsc --noEmit passes
- Linting: eslint passes
- Tests: all unit tests pass
- Build: npm run build succeeds
@drips-wave
Copy link
Copy Markdown

drips-wave Bot commented Jun 1, 2026

@Amas-01 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

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.

Frontend: Add granular form field validation messages for deposit and withdraw forms

1 participant