Skip to content

feat(frontend): separate server state from mutable UI state - #1

Open
Fabluchy wants to merge 1 commit into
mainfrom
feat/server-state-separation-19
Open

feat(frontend): separate server state from mutable UI state#1
Fabluchy wants to merge 1 commit into
mainfrom
feat/server-state-separation-19

Conversation

@Fabluchy

Copy link
Copy Markdown
Owner

Summary

Resolves the issue where Zustand stored mutable vault balances, streaks, and discipline scores without caching, loading states, invalidation, or refresh behaviour.

Changes

New dependency

  • @tanstack/react-query ^5.101.2 — server-state cache layer

New files

  • src/lib/QueryProvider.tsx — TanStack Query client wrapped in 'use client' so the root layout stays a server component
  • src/hooks/useStreak.tsuseStreak, useDisciplineScore, useAchievements hooks

Updated files

  • src/types/index.ts — added UIPreferences, ColorTheme, queryKeys factory; Datestring for safe JSON round-trips
  • src/stores/index.ts — stripped all financial data; Zustand now holds only wallet connection state and UI preferences (persisted via zustand/middleware)
  • src/lib/api.ts — refactored to plain async functions (no class required); added fetchVaults, fetchVault, fetchStreak, fetchDisciplineScore, fetchAchievements
  • src/hooks/useVault.ts — rewritten with useQuery / useMutation; mutations invalidate vault, streak, and score caches on success
  • src/hooks/useWallet.ts — clears all financial query caches on connect / disconnect / wallet switch
  • src/features/vaults/VaultList.tsx — loading skeleton, error state with retry, empty state
  • src/features/streaks/StreakTracker.tsx — stats grid, savings calendar, error handling
  • src/app/layout.tsx — wrapped with QueryProvider
  • src/lib/stellar.ts — removed invalid StellarWallet named import (fixes pre-existing type error)

Acceptance criteria

Criterion How it is met
Introduce a server-state query/cache layer React Query with 30 s stale time, 5 min GC, retry × 2
Invalidate financial data on wallet/account/network changes useWallet removes all financial queries on connect/disconnect
Persist only safe UI preferences, not financial source-of-truth Zustand partialize persists preferences + wallet only
Eliminate race conditions between optimistic updates and refreshes Mutations invalidate the relevant query keys; no local state duplication

Closes Vaulty-X#19

- Install @tanstack/react-query v5 as the server-state caching layer
- Add QueryProvider wrapper (lib/QueryProvider.tsx) and mount in layout.tsx
- Refactor lib/api.ts: replace class methods with plain async functions
  covering vaults, streak, discipline score, achievements, and fiat flows
- Refactor types/index.ts: introduce UIPreferences type and queryKeys
  factory; keep server types (Vault, Streak, DisciplineScore, etc.) separate
- Refactor stores/index.ts: Zustand now stores only wallet connection state
  and UIPreferences (persisted via zustand/middleware persist); all financial
  data removed from the store
- Refactor hooks/useVault.ts: useVaults, useVaultById, useCreateVault,
  useDeposit, useWithdraw all use useQuery / useMutation; mutations
  invalidate the relevant query keys on success
- Refactor hooks/useWallet.ts: connect/disconnect invalidate all financial
  query caches to prevent stale data bleeding across wallet sessions
- Add hooks/useStreak.ts: useStreak, useDisciplineScore, useAchievements
- Update features/vaults/VaultList.tsx: full implementation with loading
  skeletons, error state with retry, empty state, and vault cards
- Update features/streaks/StreakTracker.tsx: full implementation with stat
  cards, loading skeletons, error state, and savings calendar
- Fix lib/stellar.ts: remove invalid StellarWallet named import (pre-existing
  type error that blocked the build)

Closes Vaulty-X#19
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] Separate server data from mutable UI state

1 participant