Skip to content

Add a11y, motion, rate limits, and API versioning - #1294

Merged
Junirezz merged 1 commit into
Junirezz:mainfrom
success-OG:feat/rate
Aug 26, 2026
Merged

Add a11y, motion, rate limits, and API versioning#1294
Junirezz merged 1 commit into
Junirezz:mainfrom
success-OG:feat/rate

Conversation

@success-OG

Copy link
Copy Markdown
Contributor

closes #1276
closes #1280
closes #1281
closes #1284

PR description

Summary

#1276 Keyboard navigation and accessibility

Keyboard and assistive-tech users can now reach primary UI without a pointer.

  • Skip links to #main-content and #primary-nav, revealed on focus.
  • Focus management: reusable focus trap for dialogs; page headings receive focus on route change (including Settings and Transaction Receipt).
  • Keyboard: tab order through skip links, buttons, and labeled inputs; tablist arrow keys; Escape closes the mobile nav.
  • Screen readers: polite route announcer, role="tab" on tabs, labeled brand/nav/pending-count controls, aria-invalid / aria-describedby on inputs, aria-busy on submit.
  • Tests: skip links, focus trap, keyboard nav, axe screen-reader checks.

#1280 Framer Motion animations

Transitions are animated, and they turn off when the user asks for reduced motion.

  • Added framer-motion.
  • MotionConfig reducedMotion="user" wraps the app.
  • Page transitions on pathname change (AnimatePresence).
  • Buttons: hover/tap scale; inputs: focus scale; skeletons: pulse in addition to the CSS shimmer.
  • Reduced-motion hook + CSS fallbacks.

#1281 Rate limiting

API abuse is limited per tier, per IP, and per API key, with visible quotas.

  • Existing tiered limiter (auth / reads / writes / admin / deposits) plus IP and API-key limiters composed as identityRateLimiter.
  • Responses include X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, and Retry-After.
  • Monitoring: in-memory allow/reject counts by tier, GET /admin/rate-limits, Prometheus rate_limit_events_total.
  • Test env raises IP/API-key ceilings so existing suites are not starved.

#1284 API versioning

Clients pin a contract without breaking when the next version ships.

  • Canonical prefix /api/v1/; preview /api/v2/.
  • Version routing middleware sets req.apiVersion and X-API-Version-Path.
  • Header negotiation (X-API-Version, Accept-Version, Accept;version=) still returns 406 for unknown versions.
  • Legacy unversioned paths keep Deprecation / Sunset / Link headers.
  • GET /api/versions discovery document.
  • Policy updates in docs/api/VERSIONING.md and backend/docs/API_VERSIONING.md.

Test plan

  • cd frontend && npm install then npm run test:run (skip links, keyboard nav, screen reader, page transition, reduced motion).
  • Tab through skip links → nav → main; Escape closes mobile menu; modal Tab cycles and restores focus.
  • Confirm animations on route change / button press, and none with prefers-reduced-motion: reduce.
  • cd backend && npm test -- rateLimiter.headers versionRouting versionNegotiation.
  • Hit an endpoint and check X-RateLimit-*; exceed a tight limiter and expect 429 + Retry-After.
  • GET /api/v1/vault/summary has no deprecation headers; GET /vault/summary does; GET /api/versions lists v1/v2; unsupported Accept-Version returns 406.
  • GET /admin/rate-limits (admin API key) returns the snapshot.

@drips-wave

drips-wave Bot commented Aug 26, 2026

Copy link
Copy Markdown

@success-OG 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

@Junirezz
Junirezz merged commit 70e96bd into Junirezz:main Aug 26, 2026
7 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants