Commit graph

153 commits

Author SHA1 Message Date
senke
b8460d5a0c scalability: implement infinite scroll for LibraryPage track list
- Converted from useQuery with pagination to useInfiniteQuery
- Removed page state (no longer needed)
- Flattened all pages into single filteredTracks array
- Integrated useInfiniteScroll hook with VirtualizedList
- Removed pagination component (replaced with infinite scroll)
- Added loading indicator when fetching next page
- Updated query invalidation to use correct query key
- Fixed batchUpdate to use tracksApi.batchUpdate
- Updated genres/formats extraction to use filteredTracks
- Action 6.3.1.3 complete
2026-01-15 21:06:09 +01:00
senke
b77902b6bd scalability: virtualize LibraryPage track list and verify package installation
- Verified @tanstack/react-virtual already installed (^3.13.12)
- VirtualizedList component already exists and is used in chat
- Replaced list view map() with VirtualizedList component
- Item height: 88px (estimated from padding + content)
- Container height: 600px
- Preserved all existing functionality (bulk mode, dropdowns, selection)
- Moved empty state outside virtualizer for better UX
- Actions 6.3.1.1 and 6.3.1.2 complete
2026-01-15 21:03:22 +01:00
senke
7c5532afbd scalability: confirm bundle optimization not needed
- Verified all bundle size metrics exceed industry standards
- Initial bundle: ~246KB (excellent, < 300KB standard)
- Total JS: 764KB (good, < 1MB standard)
- Page chunks: 4.5-8.5KB (excellent, < 50KB standard)
- Code splitting: Excellent (55 chunks, proper vendor isolation)
- All routes lazy-loaded with small chunks
- Vendor chunks properly isolated
- CSS properly split
- Conclusion: Bundle sizes are already optimal, no optimization required
- Action 6.2.1.8 complete (no changes needed)
2026-01-15 21:00:04 +01:00
senke
6b1e0c5bd1 scalability: measure and document bundle sizes after code splitting
- Created comprehensive bundle size report (BUNDLE_SIZE_REPORT.md)
- Total JavaScript: 764KB across 55 chunks
- Total CSS: 66KB
- Initial load: ~246KB (excellent)
- Average page chunk: 4.5-8.5KB (excellent lazy loading)
- Vendor chunks properly isolated (React core: 209KB)
- All routes lazy-loaded with small chunks
- Bundle sizes meet industry standards
- Action 6.2.1.7 complete
2026-01-15 20:58:52 +01:00
senke
d5a3a40396 scalability: verify loading states and error boundaries already implemented
- Verified Suspense boundaries with LoadingSpinner fallback in LazyComponent.tsx
- Verified LazyErrorBoundary wraps all lazy-loaded components
- Verified ErrorBoundary wraps all routes in router/index.tsx
- Confirmed loading states show during lazy load
- Confirmed error boundaries catch lazy loading and runtime errors
- All lazy components automatically include loading states and error boundaries
- Actions 6.2.1.5 and 6.2.1.6 complete (already implemented)
2026-01-15 20:56:22 +01:00
senke
662e4694a0 scalability: verify heavy components already use dynamic imports
- Verified EmojiPicker already lazy loaded in ChatInput and ChatMessage
- Verified ImageCropper already lazy loaded with React.lazy()
- Verified Toaster already lazy loaded via LazyToaster component
- Verified @dnd-kit is lazy loaded via route-level lazy loading (PlaylistDetailPage)
- Confirmed dompurify should remain in main bundle (security-critical)
- Chart components are lightweight (custom SVG), no dynamic imports needed
- Conclusion: All heavy components already optimized
- Action 6.2.1.4 complete (already implemented)
2026-01-15 20:55:19 +01:00
senke
17faccda11 scalability: audit heavy components for code splitting
- Created HEAVY_COMPONENTS_AUDIT.md documenting all heavy components
- Identified already lazy-loaded components: EmojiPicker, ImageCropper, Toaster
- Verified chart components are lightweight (custom SVG, no heavy libraries)
- Confirmed heavy libraries already in vendor chunks
- Documented feature chunks already configured
- Identified potential optimizations (@dnd-kit, dompurify) - low priority
- Conclusion: Most heavy components already optimized
- Action 6.2.1.3 complete
2026-01-15 20:50:51 +01:00
senke
46eb1ca3f1 scalability: verify vendor bundles already split
- Verified manualChunks configuration in vite.config.ts
- Confirmed vendor bundles split into separate chunks:
  - vendor-react-core, vendor-react-hook-form, vendor-toast
  - vendor-router, vendor-tanstack, vendor-icons
  - vendor-dates, vendor-validation, vendor-media
  - vendor-zustand, vendor-sentry, vendor-axios, vendor-scheduler
- Feature chunks configured for player, upload, chat, studio
- Chunk file naming configured for proper caching
- Action 6.2.1.2 complete (already implemented)
2026-01-15 20:49:04 +01:00
senke
854e020c34 scalability: verify routes already use lazy loading
- Verified all routes in router/index.tsx use Lazy* components
- Confirmed LazyComponent.tsx implements React.lazy() with Suspense
- All page components are dynamically imported
- Error boundaries and loading states already in place
- Action 6.2.1.1 complete (already implemented)
2026-01-15 20:48:12 +01:00
senke
a8decaf5f5 scalability: audit feature API files for obsolescence
- Audited all feature API files in features/*/api/
- Verified usage of each file:
  - features/tracks/api/trackApi.ts: Used by services/api/tracks.ts
  - features/auth/api/authApi.ts: Re-export for backward compatibility
  - features/webhooks/api/webhookApi.ts: Used by WebhooksPage
  - features/sessions/api/sessionsApi.ts: Used by SessionsPage
  - features/admin/api/auditService.ts: Used by AdminDashboardPage
- Conclusion: No obsolete files found - all serve a purpose
- Action 6.1.1.11 complete
2026-01-15 20:47:13 +01:00
senke
7d6ecca3ab scalability: update feature API files to use service layer
- Updated features/auth/api/authApi.ts to re-export from services/api/auth.ts
- Added deprecation comments to features/tracks/api/trackApi.ts
- Added documentation comments to webhooks, sessions, and admin API files
- All feature API files now document their relationship to the service layer
- Maintains backward compatibility
- No breaking changes
- Action 6.1.1.10 complete
2026-01-15 20:45:59 +01:00
senke
5e34c82495 scalability: create unified index file for API services
- Updated apps/web/src/services/api/index.ts to export all API services
- Exports apiClient and utilities from './client'
- Exports authApi and types from './auth'
- Exports tracksApi and types from './tracks'
- Exports usersApi and types from './users'
- Exports playlistsApi and types from './playlists'
- Removed duplicate apiClient export from './auth'
- Added documentation comments for each service section
- All services properly exported and accessible via barrel export
- No TypeScript errors
- Action 6.1.1.9 complete
2026-01-15 20:42:09 +01:00
senke
81e89aadc3 scalability: replace direct auth API calls with authApi service
- Replaced imports in VerifyEmailPage.tsx (verifyEmail, resendVerificationEmail → authApi.verifyEmail, authApi.resendVerification)
- Replaced imports in useUsernameAvailability.ts (checkUsernameAvailability → authApi.checkUsername with response.available extraction)
- Replaced imports in usePasswordReset.ts (requestPasswordReset, resetPassword → authApi.requestPasswordReset, authApi.resetPassword)
- Replaced imports in RegisterPage.tsx (resendVerificationEmail → authApi.resendVerification)
- All function calls updated to use authApi methods with proper request object wrapping
- Test files still use direct imports (acceptable - tests can use implementation details)
- AuthContext.tsx uses services/authService (legacy service, separate from features/auth/services/authService)
- No TypeScript errors related to authApi
- Action 6.1.1.8 complete
2026-01-15 20:40:46 +01:00
senke
491b129bfa scalability: replace direct playlist API calls with playlistsApi service
- Replaced imports in UserProfilePage.tsx (listPlaylists → playlistsApi.list)
- Replaced imports in PlaylistDetailPage.tsx (getCollaborators → playlistsApi.getCollaborators)
- Replaced imports in CreatePlaylistDialog.tsx (createPlaylist → playlistsApi.create)
- Replaced imports in PlaylistList.tsx (searchPlaylists → playlistsApi.search)
- Replaced imports in CollaboratorManagement.tsx (getCollaborators → playlistsApi.getCollaborators)
- Replaced imports in PlaylistSearch.tsx (searchPlaylists → playlistsApi.search)
- Replaced imports in unifiedSearchService.ts (searchPlaylists → playlistsApi.search)
- Replaced imports in GlobalSearchBar.tsx (searchPlaylists → playlistsApi.search)
- Fixed type imports in services/api/playlists.ts (types from types.ts, not playlistService.ts)
- All function calls updated to use playlistsApi methods
- Test files and hooks still use direct imports (acceptable - tests can use implementation details, hooks will be updated in Action 6.1.1.10)
- No TypeScript errors related to playlistsApi
- Action 6.1.1.7 complete
2026-01-15 20:38:09 +01:00
senke
9cfacdcc9a scalability: replace direct user API calls with usersApi service
- Replaced imports in UserProfilePage.tsx (getProfileByUsername → usersApi.getProfileByUsername)
- Replaced imports in SettingsPage.tsx (getSettings, updateSettings → usersApi.getSettings, usersApi.updateSettings)
- Replaced imports in ProfileForm.tsx (calculateProfileCompletion → usersApi.calculateProfileCompletion)
- Replaced dynamic imports in avatar-upload.tsx (uploadAvatar, deleteAvatar → usersApi.uploadAvatar, usersApi.deleteAvatar)
- All function calls updated to use usersApi methods
- Test files still use direct imports (acceptable - tests can use implementation details)
- No TypeScript errors related to usersApi
- Action 6.1.1.6 complete
2026-01-15 20:34:58 +01:00
senke
66479e5524 scalability: create unified auth API service
- Updated apps/web/src/services/api/auth.ts to export unified authApi object
- Wraps core auth functions: login, register, logout, getMe (with token storage logic)
- Wraps token management: refresh
- Wraps email verification: verifyEmail, resendVerification
- Wraps password management: requestPasswordReset, resetPassword
- Wraps username checking: checkUsername
- Wraps OAuth methods: getOAuthProviders, initiateOAuth
- Wraps 2FA methods: setup2FA, verify2FA, disable2FA, get2FAStatus
- Re-exports all related types for convenience
- Updated services/api/index.ts to export authApi
- No TypeScript errors
- Follows existing service layer pattern (similar to tracks.ts, users.ts, playlists.ts)
- Preserves existing token storage logic in login/register/logout
- Action 6.1.1.5 complete
2026-01-15 20:32:55 +01:00
senke
c880ca8631 scalability: create playlists API service
- Created apps/web/src/services/api/playlists.ts
- Wraps CRUD functions: create, get, update, delete, list
- Wraps track management: addTrack, removeTrack, reorderTracks
- Wraps collaboration functions: addCollaborator, removeCollaborator, updateCollaboratorPermission, getCollaborators
- Wraps social functions: follow, unfollow, getFollowStatus
- Wraps utility functions: search, createShareLink, getRecommendations
- Re-exports all related types for convenience
- Added to services/api/index.ts for barrel export
- No TypeScript errors
- Follows existing service layer pattern (similar to tracks.ts and users.ts)
- Action 6.1.1.4 complete
2026-01-15 20:30:38 +01:00
senke
5d5836effb scalability: create users API service
- Created apps/web/src/services/api/users.ts
- Wraps profile functions: getProfile, getProfileByUsername, updateProfile, calculateProfileCompletion
- Wraps social functions: follow, unfollow, getFollowers, getFollowing
- Wraps settings functions: getSettings, updateSettings
- Wraps avatar functions: uploadAvatar, deleteAvatar
- Re-exports all related types for convenience
- Added to services/api/index.ts for barrel export
- No TypeScript errors
- Follows existing service layer pattern (similar to tracks.ts)
- Action 6.1.1.3 complete
2026-01-15 20:28:50 +01:00
senke
7b51247e97 scalability: replace direct track API calls with tracksApi service
- Replaced imports in UploadModal.tsx (uploadTrack → tracksApi.create)
- Replaced imports in ShareDialog.tsx (createTrackShare → tracksApi.createShare)
- Replaced imports in LibraryPage.tsx (getTracks, batchDeleteTracks, batchUpdateTracks → tracksApi.list, tracksApi.batchDelete, tracksApi.batchUpdate)
- Replaced imports in UserProfilePage.tsx (getTracks → tracksApi.list)
- All function calls updated to use tracksApi methods
- Types re-exported from tracksApi for convenience
- No direct imports from @/features/tracks/api/trackApi remain in feature components
- Test files still use direct imports (acceptable - tests can use implementation details)
- No TypeScript errors related to tracksApi
- Action 6.1.1.2 complete
2026-01-15 20:27:02 +01:00
senke
f206a14126 scalability: create tracks API service layer
- Created apps/web/src/services/api/tracks.ts with tracksApi object
- Exports: list, get, create, update, delete, getStats, getHistory, download, like, unlike, getLikes, createShare
- Includes chunked upload methods: initiateChunkedUpload, uploadChunk, completeChunkedUpload
- Includes batch operations: batchDelete, batchUpdate
- Wraps existing track API functions from features/tracks/api/trackApi.ts
- Includes getTrack from features/tracks/services/trackService.ts for single track retrieval
- Re-exports all related types for convenience
- Added to services/api/index.ts for barrel export
- No TypeScript errors
- Follows existing service layer pattern (similar to auth.ts)
- Action 6.1.1.1 complete
2026-01-15 20:22:43 +01:00
senke
2f1f228ea7 security: implement proactive token refresh every 4 minutes
- Added PROACTIVE_REFRESH_INTERVAL_MS constant (4 minutes)
- Reduced PROACTIVE_REFRESH_BUFFER_MS to 1 minute (tokens expire in 5 min)
- Added proactiveRefreshInterval variable to track periodic refresh
- Created startPeriodicRefresh() function that sets up interval to refresh every 4 minutes
- Updated scheduleProactiveRefresh() to call startPeriodicRefresh()
- Updated cancelProactiveRefresh() to also clear the interval
- Periodic refresh checks token validity before refreshing
- Stops periodic refresh if token is expired or missing
- No TypeScript errors
- Works with existing token refresh infrastructure
- Action 5.1.1.5 complete
2026-01-15 20:19:13 +01:00
senke
bd47e7030a security: reduce access token expiry to 5 minutes
- Changed default AccessTokenTTL from 15 minutes to 5 minutes in jwt_service.go
- Updated test mock in mocks_test.go to match new default
- All references to AccessTokenTTL automatically use new value
- Tests pass successfully
- No breaking changes - frontend already handles token refresh
- Action 5.1.1.4 complete
2026-01-15 20:15:45 +01:00
senke
22737c4be0 security: integrate useFormValidation into all RegisterForm and LoginForm components
- Integrated useFormValidation into features/auth/components/RegisterForm.tsx
- Integrated useFormValidation into features/auth/components/LoginForm.tsx
- Integrated useFormValidation into components/forms/RegisterForm.tsx
- Integrated useFormValidation into components/forms/LoginForm.tsx
- All forms now use backend pre-validation with debouncing (300ms)
- Backend validation errors displayed alongside client-side errors
- Note: Other forms require backend validation types to be added first
- Action 5.2.1.4 complete
2026-01-15 20:13:34 +01:00
senke
9ca8739c19 security: add pre-validation to RegisterForm and LoginForm
- Integrated useFormValidation hook into RegisterForm
- Integrated useFormValidation hook into LoginForm
- Validation triggers on form data change (debounced 300ms)
- Backend validation errors displayed alongside client-side errors
- Errors mapped to correct form fields
- Uses watch() from react-hook-form to monitor form changes
- Handles field name mapping (password_confirm vs password_confirmation)
- No TypeScript errors
- Action 5.2.1.2 complete
2026-01-15 20:11:22 +01:00
senke
aad9461515 security: create useFormValidation hook for pre-validation
- Created useFormValidation hook with validate function
- Accepts validation type (e.g., "RegisterRequest", "LoginRequest")
- Calls /api/v1/validate endpoint with type and data
- Returns validation state: isValidating, errors, isValid, error
- Provides clear() function to reset validation state
- Handles both wrapped and direct API response formats
- Uses parseApiError for consistent error handling
- Exported from hooks/index.ts with types
- No TypeScript errors
- Follows existing hook patterns
- Action 5.2.1.3 complete
2026-01-15 20:06:30 +01:00
senke
79d93bee02 security: create /api/v1/validate endpoint for pre-validation
- Created ValidateHandler with Validate method
- Endpoint accepts POST /api/v1/validate with type and data
- Supports RegisterRequest and LoginRequest validation types
- Uses existing validator from CommonHandler
- Returns ValidateResponse with valid flag and errors array
- Public endpoint (no auth required)
- Route registered in setupValidateRoutes
- Code compiles successfully
- Follows existing handler patterns
- Action 5.2.1.1 complete
2026-01-15 20:04:16 +01:00
senke
d264b3ebf9 security: disable mutation buttons when rate limited
- Created useIsRateLimited() hook to check rate limit state
- Updated CommentSection submit button to disable when rate limited
- Updated LikeButton to disable when rate limited
- Updated PlaylistForm submit button to disable when rate limited
- Updated ChatInput send button to disable when rate limited
- Updated UploadModal upload button to disable when rate limited
- All buttons check isLimited from rate limit store
- Hook uses Zustand selector for efficient re-renders
- Pattern established for future mutation buttons
- Action 5.4.1.4 complete
2026-01-15 20:01:47 +01:00
senke
71e731f66e security: mark rate limit timer and store integration as complete
- Action 5.4.1.5: Countdown timer already implemented in RateLimitIndicator
- Action 5.4.1.7: Store integration already implemented via useRateLimitStore()
- Both actions were completed as part of Action 5.4.1.2
2026-01-15 19:58:45 +01:00
senke
04f8d76885 security: add rate limit indicator to header
- Added RateLimitIndicator component to Header
- Placed after NotificationMenu for visibility
- Component automatically shows/hides based on rate limit state
- No TypeScript errors
- Action 5.4.1.3 complete
2026-01-15 19:58:02 +01:00
senke
1320f8e88a security: create rate limit indicator component
- Created RateLimitIndicator component to display rate limit status
- Shows when user is rate limited or when remaining < 20% of limit
- Displays remaining requests (e.g., "50/100 requests")
- Shows countdown timer until reset (formatted as "5m 30s" or "1h 15m")
- Uses AlertTriangle and Clock icons from lucide-react
- Color-coded: red for critical (rate limited), gold for warning (< 20% remaining)
- Updates timer every second using useEffect
- Returns null when no rate limit data or not limited
- Follows existing component patterns (similar to OfflineIndicator)
- Action 5.4.1.2 complete
2026-01-15 19:56:32 +01:00
senke
1c1f0c7938 security: parse rate limit headers and create rate limit store
- Created rate limit store (apps/web/src/stores/rateLimit.ts) to store parsed headers
- Added header parsing in success response interceptor:
  - X-RateLimit-Limit: Maximum requests allowed
  - X-RateLimit-Remaining: Requests remaining
  - X-RateLimit-Reset: Unix timestamp when limit resets
- Added header parsing in error response interceptor:
  - Includes Retry-After header for 429 errors
  - All rate limit headers parsed from both lowercase and uppercase variants
- Store automatically updated on every API response
- Store includes isLimited flag calculated from remaining/retryAfter
- Uses Zustand with persistence for cross-tab state
- Actions 5.4.1.1 and 5.4.1.6 complete
2026-01-15 19:54:49 +01:00
senke
423cc5c882 security: add copy request ID button to ErrorDisplay
- Added "Copy Request ID" button that copies request ID to clipboard
- Button appears for server errors when request_id is available
- Uses modern Clipboard API with fallback to execCommand
- Shows success toast when copied
- Added alongside existing "Report Issue" button
- Fixed TypeScript error in isServerError calculation
- Action 5.3.1.2 complete
2026-01-15 19:52:48 +01:00
senke
eb0ac57db5 security: remove dev-only check for request ID in error messages
- Removed development-only check for request ID in formatErrorMessage function
- Request ID now always included when includeRequestId parameter is true
- Improves error correlation in production environments
- Updated comment to reflect change
- Action 5.3.1.1 complete
2026-01-15 19:50:41 +01:00
senke
3e21bc750c state-ownership: add optimistic updates to remaining mutations
- Added optimistic updates to notification mutations:
  - markAsReadMutation: Optimistically marks notification as read
  - markAllAsReadMutation: Optimistically marks all notifications as read
  - Updated in both NotificationsPage and NotificationMenu
- Added optimistic updates to share link mutations:
  - createShareMutation: Optimistically adds share link to local state
  - revokeShareMutation: Optimistically removes share link from local state
- Added optimistic updates to chat mutations:
  - leaveRoomMutation: Optimistically removes conversation from list
  - deleteRoomMutation: Optimistically removes conversation from list
- Added optimistic update to reorder mutation:
  - useReorderPlaylistTracks: Optimistically reorders tracks in playlist
- All mutations include:
  - onMutate: Cancel queries, snapshot previous state, apply optimistic update
  - onError: Rollback to previous state
  - onSuccess: Invalidate queries for consistency
- Action 4.4.1.5 complete (18 mutations with optimistic updates)
2026-01-15 19:48:47 +01:00
senke
1d4fb8f69c state-utilities: update stateInvalidation to work with React Query
- Created QueryClient singleton (queryClientSingleton.ts):
  - Provides global access to QueryClient for state invalidation
  - Set in main.tsx after QueryClient creation
- Updated invalidateQueries() to use QueryClient directly:
  - Replaced custom event system with direct QueryClient.invalidateQueries()
  - Added query key mapping for all resource types
  - Event system kept as fallback if QueryClient not available
- Updated invalidateStore() for Library Store:
  - Removed clearItems() call (method doesn't exist, domain data migrated to React Query)
  - Library Store now only contains UI state (filters)
  - React Query cache invalidation handles refetching
- Query keys mapped:
  - tracks: ['tracks'], ['track'], ['library']
  - playlists: ['playlists'], ['playlist']
  - users: ['users'], ['user'], ['auth'], ['userProfile']
  - conversations: ['conversations'], ['conversation'], ['chat'], ['chatConversations']
  - roles: ['roles'], ['role']
  - library: ['library'], ['tracks'], ['favorites'], ['libraryItems']
  - auth: ['auth'], ['user']
- Action 4.6.1.5 complete
2026-01-15 19:38:47 +01:00
senke
6d1382520a state-utilities: remove unused stateMiddleware utility
- Removed stateMiddleware utility (431 lines):
  - Deleted apps/web/src/utils/stateMiddleware.ts
  - Deleted apps/web/src/utils/stateMiddleware.test.ts (251 lines)
  - Completely unused in production code (only used in test file)
  - Previously removed from Library Store in Action 4.1.2.7
- Library Store now only contains UI state (filters), no middleware needed
- Created audit documentation: apps/web/src/docs/STATEMIDDLEWARE_UTILITY_AUDIT.md
- Action 4.6.1.4 complete
2026-01-15 19:36:45 +01:00
senke
8ed1b44658 state-utilities: remove unused undoRedo and stateNormalization utilities
- Removed undoRedo utility (8587 bytes):
  - Deleted apps/web/src/utils/undoRedo.ts
  - Removed WithUndoRedo<T> type from stores/types.ts
  - Removed WithUndoRedo export from stores/index.ts
  - Completely unused (confirmed in Action 4.6.1.9 audit)
- Removed stateNormalization utility (6321 bytes):
  - Deleted apps/web/src/utils/stateNormalization.ts
  - Updated stores.test.ts to remove outdated tests:
    - Removed createEmptyNormalized import
    - Removed outdated Library Store tests (items/favorites)
    - Updated Library Store tests to test current structure (filters only)
    - Updated Chat Store tests to use feature store
    - Updated Auth Store tests (user data migrated to React Query)
    - Fixed beforeEach to not call non-existent methods
  - Only used in outdated test file (confirmed in Action 4.6.1.11 audit)
- Both utilities made obsolete by React Query migration
- Actions 4.6.1.10 and 4.6.1.12 complete
2026-01-15 19:35:37 +01:00
senke
d86c3a4090 state-utilities: audit undoRedo and stateNormalization utilities
- Audited undoRedo utility: completely unused (no imports found)
  - Only type exports remain (WithUndoRedo) but also unused
  - Previously removed from Library Store in Action 4.1.2.5
  - Safe to remove (Action 4.6.1.10)
- Audited stateNormalization utility: only used in outdated test
  - Only createEmptyNormalized used in stores.test.ts
  - Tests check obsolete Library Store structure (items/favorites)
  - Library Store migrated to React Query in Action 4.1.2.6
  - Safe to remove after updating test file (Action 4.6.1.12)
- Created audit documentation:
  - apps/web/src/docs/UNDOREDO_UTILITY_AUDIT.md
  - apps/web/src/docs/STATENORMALIZATION_UTILITY_AUDIT.md
- Actions 4.6.1.9 and 4.6.1.11 complete
2026-01-15 19:33:39 +01:00
senke
547ca1e489 state-ownership: consolidate chat stores to feature store
- Removed duplicate stores/chat.ts (old store)
- Consolidated to features/chat/store/chatStore.ts (active store)
- Updated ChatMessages.tsx to use feature store (currentConversationId + lookup)
- Updated storeSelectors.ts to use feature store and export only existing methods
- Updated stateHydration.ts to skip chat hydration (uses React Query)
- Updated stateInvalidation.ts to not call fetchConversations (React Query handles it)
- Updated stores/index.ts to export feature store
- Updated documentation
- Test files still reference old store (separate update needed)
- Action 4.5.1.5 complete
2026-01-15 19:31:40 +01:00
senke
a03587b422 state-ownership: delete unused optimisticStoreUpdates.ts file
- Deleted apps/web/src/utils/optimisticStoreUpdates.ts (unused file)
- File was unused - no imports found in codebase
- Mutations already use React Query's onMutate pattern
- No TypeScript errors after deletion
- Actions 4.4.1.2 and 4.4.1.3 complete
2026-01-15 19:26:53 +01:00
senke
6cf41bdbea state-ownership: extend broadcastSync to invalidate React Query cache
- Added optional onStateSync callback to BroadcastSyncOptions
- Callback is called when state is updated locally or synced from another tab
- Callback receives new state and previous state as parameters
- Error handling prevents callback errors from breaking sync
- Stores can opt-in by providing callback that invalidates React Query queries
- No breaking changes - callback is optional
- Action 4.2.1.1 complete
2026-01-15 19:25:13 +01:00
senke
0922f98c41 state-ownership: remove _refreshUserPromise field from authStore
- Removed _refreshUserPromise from AuthState interface
- Removed _refreshUserPromise from initial state
- Field no longer needed - React Query handles deduplication automatically
- No references to field remain in codebase
- Action 4.3.1.3 complete
2026-01-15 18:11:41 +01:00
senke
224287e34f state-ownership: simplify refreshUser using React Query deduplication
- Removed manual promise deduplication logic (_refreshUserPromise usage)
- Removed promise creation and storage
- Simplified to direct async function that calls getMe()
- React Query's useUser hook handles deduplication automatically
- Preserved all error handling and state preservation logic
- Function simplified from 83 lines to 58 lines
- Action 4.3.1.2 complete
2026-01-15 18:10:39 +01:00
senke
27f65d9497 state-ownership: remove user field from authStore, keep only isAuthenticated
- Removed user field from AuthState interface
- Removed all user assignments in login, register, logout, refreshUser, checkAuthStatus
- Updated refreshUser to verify auth via getMe() but not store user (React Query handles that)
- Updated checkAuthStatus to verify auth via getMe() but not store user
- Updated persist partialize to not store user (only isAuthenticated)
- Updated broadcastSync shouldSync to only check isAuthenticated
- Removed User import
- Store now only manages isAuthenticated boolean
- User data exclusively managed by React Query (useUser hook)
- All production code already migrated (Actions 4.1.1.3-4.1.1.4 complete)
- Action 4.1.1.5 complete
2026-01-15 18:08:31 +01:00
senke
c4555c3bea api-contracts: mark backend response format tests as complete
- Tests already exist in response_test.go
- All tests passing (verified with go test)
- Tests cover all response helper functions
- Tests verify wrapped format for success and error responses
- Action 1.3.2.5 complete
2026-01-15 18:03:54 +01:00
senke
28b6a438af data-flow: integrate offline queue UI with OfflineIndicator
- Added state to manage queue manager dialog visibility
- Added 'View Queue' button in offline mode banner (when queueSize > 0)
- Added 'View Queue' button in processing mode banner (when queueSize > 0)
- Button opens OfflineQueueManager dialog when clicked
- Button styled appropriately for each banner variant
- Users can now view and manage queued requests directly from the indicator
- Action 2.5.1.5 complete
2026-01-15 18:02:40 +01:00
senke
67c285fc15 data-flow: add UI for offline queue management
- Created OfflineQueueManager component to display queued requests
- Shows request details: method, URL, timestamp, priority, retry count
- Allows removing individual requests
- Allows clearing entire queue
- Auto-updates queue every second while dialog is open
- Priority badges with color coding
- Empty state when no requests queued
- Uses Dialog component for modal display
- Action 2.5.1.4 complete
2026-01-15 18:01:22 +01:00
senke
414e533f5b data-flow: mark message deduplication as complete (already implemented)
- Action 2.3.1.4 was already implemented in Action 2.3.1.1
- Message deduplication uses processedMessages Set to track message IDs
- Prevents duplicate cache updates from same message
- Includes cleanup of old processed message IDs
- Action 2.3.1.4 complete
2026-01-15 17:59:21 +01:00
senke
b005d0a087 data-flow: handle broadcastSync message conflicts with React Query sync
- Added documentation explaining coexistence of Zustand and React Query sync
- Added type guards in broadcastSync.ts to verify message format before processing
- Added type guards in reactQuerySync.ts to verify message format before processing
- Both sync mechanisms use different channel names (no direct conflicts)
- Both sync mechanisms use different message formats (no cross-processing)
- Type guards ensure handlers only process their own message types
- Prevents accidental cross-processing of messages between sync mechanisms
- Both syncs can coexist safely without conflicts
- Action 2.3.1.3 complete
2026-01-15 17:58:49 +01:00
senke
2cf5fd5659 data-flow: integrate React Query sync into query client setup
- Added useQueryClient hook to App component
- Added setupReactQuerySync import and initialization
- Initialize sync on App mount with cleanup on unmount
- React Query cache synchronization now active across browser tabs
- Multi-tab updates work when mutations succeed or queries are invalidated
- Action 2.3.1.2 complete
2026-01-15 17:56:26 +01:00