mirror of
https://github.com/coleam00/Archon.git
synced 2025-12-24 02:39:17 -05:00
* feat: Phase 3 - Fix optimistic updates with stable UUIDs and visual indicators - Replace timestamp-based temp IDs with stable nanoid UUIDs - Create shared optimistic utilities module with type-safe functions - Add visual indicators (OptimisticIndicator component) for pending items - Update all mutation hooks (tasks, projects, knowledge) to use new utilities - Add optimistic state styling to TaskCard, ProjectCard, and KnowledgeCard - Add comprehensive unit tests for optimistic utilities - All tests passing, validation complete * docs: Update optimistic updates documentation with Phase 3 patterns - Remove outdated optimistic_updates.md - Create new concise documentation with file references - Document shared utilities API and patterns - Include performance characteristics and best practices - Reference actual implementation files instead of code examples - Add testing checklist and migration notes * fix: resolve CodeRabbit review issues for Phase 3 optimistic updates Address systematic review feedback on optimistic updates implementation: **Knowledge Queries (useKnowledgeQueries.ts):** - Add missing createOptimisticEntity import for type-safe optimistic creation - Implement filter-aware cache updates for crawl/upload flows to prevent items appearing in wrong filtered views - Fix total count calculation in deletion to accurately reflect removed items - Replace manual optimistic item creation with createOptimisticEntity<KnowledgeItem>() **Project Queries (useProjectQueries.ts):** - Add proper TypeScript mutation typing with Awaited<ReturnType<>> - Ensure type safety for createProject mutation response handling **OptimisticIndicator Component:** - Fix React.ComponentType import to use direct import instead of namespace - Add proper TypeScript ComponentType import for HOC function - Apply consistent Biome formatting **Documentation:** - Update performance characteristics with accurate bundlephobia metrics - Improve nanoid benchmark references and memory usage details All unit tests passing (90/90). Integration test failures expected without backend. Co-Authored-By: CodeRabbit Review <noreply@coderabbit.ai> * Adjust polling interval and clean knowledge cache --------- Co-authored-by: CodeRabbit Review <noreply@coderabbit.ai>
4.9 KiB
4.9 KiB
Optimistic Updates Pattern Guide
Core Architecture
Shared Utilities Module
Location: src/features/shared/optimistic.ts
Provides type-safe utilities for managing optimistic state across all features:
createOptimisticId()- Generates stable UUIDs using nanoidcreateOptimisticEntity<T>()- Creates entities with_optimisticand_localIdmetadataisOptimistic()- Type guard for checking optimistic statereplaceOptimisticEntity()- Replaces optimistic items by_localId(race-condition safe)removeDuplicateEntities()- Deduplicates after replacementcleanOptimisticMetadata()- Strips optimistic fields when needed
TypeScript Interface
interface OptimisticEntity {
_optimistic: boolean;
_localId: string;
}
Implementation Patterns
Mutation Hooks Pattern
Reference: src/features/projects/tasks/hooks/useTaskQueries.ts:44-108
-
onMutate: Create optimistic entity with stable ID
- Use
createOptimisticEntity<T>()for type-safe creation - Store
optimisticIdin context for later replacement
- Use
-
onSuccess: Replace optimistic with server response
- Use
replaceOptimisticEntity()matching by_localId - Apply
removeDuplicateEntities()to prevent duplicates
- Use
-
onError: Rollback to previous state
- Restore snapshot from context
UI Component Pattern
References:
src/features/projects/tasks/components/TaskCard.tsx:39-40,160,186src/features/projects/components/ProjectCard.tsx:32-33,67,93src/features/knowledge/components/KnowledgeCard.tsx:49-50,176,244
- Check optimistic state:
const optimistic = isOptimistic(entity) - Apply conditional styling: Add opacity and ring effect when optimistic
- Display indicator: Use
<OptimisticIndicator>component for visual feedback
Visual Indicator Component
Location: src/features/ui/primitives/OptimisticIndicator.tsx
Reusable component showing:
- Spinning loader icon (Loader2 from lucide-react)
- "Saving..." text with pulse animation
- Configurable via props:
showSpinner,pulseAnimation
Feature Integration
Tasks
- Mutations:
src/features/projects/tasks/hooks/useTaskQueries.ts - UI:
src/features/projects/tasks/components/TaskCard.tsx - Creates tasks with
priority: "medium"default
Projects
- Mutations:
src/features/projects/hooks/useProjectQueries.ts - UI:
src/features/projects/components/ProjectCard.tsx - Handles
prd: null,data_schema: nullfor new projects
Knowledge
- Mutations:
src/features/knowledge/hooks/useKnowledgeQueries.ts - UI:
src/features/knowledge/components/KnowledgeCard.tsx - Uses
createOptimisticId()directly for progress tracking
Toasts
- Location:
src/features/ui/hooks/useToast.ts:43 - Uses
createOptimisticId()for unique toast IDs
Testing
Unit Tests
Location: src/features/shared/optimistic.test.ts
Covers all utility functions with 8 test cases:
- ID uniqueness and format validation
- Entity creation with metadata
- Type guard functionality
- Replacement logic
- Deduplication
- Metadata cleanup
Manual Testing Checklist
- Rapid Creation: Create 5+ items quickly - verify no duplicates
- Visual Feedback: Check optimistic indicators appear immediately
- ID Stability: Confirm nanoid-based IDs after server response
- Error Handling: Stop backend, attempt creation - verify rollback
- Race Conditions: Use browser console script for concurrent creates
Performance Characteristics
- Bundle Impact: ~130 bytes (nanoid v5, minified+gzipped) - build/environment dependent
- Update Speed: Typically snappy on modern devices; actual latency varies by device and workload
- ID Generation: Per nanoid benchmarks: secure sync ≈5M ops/s, non-secure ≈2.7M ops/s, async crypto ≈135k ops/s
- Memory: Minimal - only
_optimisticand_localIdmetadata added per optimistic entity
Migration Notes
From Timestamp-based IDs
Before: const tempId = \temp-${Date.now()}`**After**:const optimisticId = createOptimisticId()`
Key Differences
- No timestamp collisions during rapid creation
- Stable IDs survive re-renders
- Type-safe with full TypeScript inference
- ~60% code reduction through shared utilities
Best Practices
- Always use shared utilities - Don't implement custom optimistic logic
- Match by _localId - Never match by the entity's
idfield - Include deduplication - Always call
removeDuplicateEntities()after replacement - Show visual feedback - Users should see pending state clearly
- Handle errors gracefully - Always implement rollback in
onError
Dependencies
- nanoid: v5.0.9 - UUID generation
- @tanstack/react-query: v5.x - Mutation state management
- React: v18.x - UI components
- TypeScript: v5.x - Type safety
Last updated: Phase 3 implementation (PR #695)