# Offline Functionality Guide

## Overview

The DESTRY mobile app now includes comprehensive offline support, allowing users to continue working even without an internet connection. All changes made offline are automatically synced when the connection is restored.

## Features

### ✅ Offline-First Architecture
- **Work Without Internet**: Create, update, delete, and complete tasks even when offline
- **Automatic Caching**: All API responses are cached locally for offline access
- **Smart Sync Queue**: Changes made offline are queued and synced when back online
- **Visual Indicators**: Network status bar shows connection state and pending sync count

### ✅ What Works Offline

**Task Management:**
- ✅ Create new tasks
- ✅ View existing tasks (from cache)
- ✅ Mark tasks as complete
- ✅ Delete tasks
- ✅ View task details

**Dashboard:**
- ✅ View dashboard stats (from cache)
- ✅ View today's tasks
- ✅ View habits status
- ✅ Access quick actions

**Data Persistence:**
- All offline changes are stored in MMKV (fast local storage)
- Data persists across app restarts
- Automatic cleanup of old cached data (7+ days)

### ✅ Automatic Sync

**When Sync Happens:**
1. **Network Restore**: Automatically syncs when internet connection is restored
2. **App Foreground**: Syncs when app comes back to foreground (if online)
3. **Manual Sync**: Tap the network status bar to manually trigger sync
4. **Background Sync**: Syncs pending changes in the background

**Sync Process:**
1. Detect network connection restored
2. Execute all queued mutations in order (create → update → delete → complete)
3. Retry failed operations (max 3 attempts)
4. Fetch latest data from server
5. Update all screens with fresh data
6. Show success notification

### ✅ Network Status Bar

**Status Indicators:**
- 🟢 **Online + Synced**: Status bar hidden (everything is up to date)
- 🟡 **Online + Pending**: Yellow bar showing "X pending • Tap to sync"
- 🟠 **Offline**: Orange bar showing "Offline • X pending"
- 🔄 **Syncing**: Blue bar showing "Syncing..."

**Interaction:**
- Tap the status bar when online to manually trigger sync
- Shows pending operation count
- Provides haptic feedback on sync completion

## Technical Implementation

### Core Components

**1. Offline Sync Manager** (`/lib/offlineSync.ts`)
- Manages mutation queue
- Handles network state detection
- Executes queued operations
- Manages offline data storage

**2. Network Store** (`/stores/networkStore.ts`)
- Zustand store for network state
- Tracks online/offline status
- Tracks pending sync count
- Notifies components of changes

**3. TanStack Query Configuration** (`/lib/queryClient.ts`)
- Offline-first query mode
- Automatic refetch on reconnect
- Cached data persistence

**4. Network Status Component** (`/components/ui/NetworkStatus.tsx`)
- Visual network status indicator
- Manual sync trigger
- Pending operation counter

### Storage Strategy

**MMKV Storage Keys:**
- `offline_mutation_queue`: Queued mutations waiting for sync
- `offline_data`: Cached API responses for offline access
- `theme`: User theme preference

**Data Structure:**
```typescript
// Queued Mutation
{
  id: string;
  type: 'CREATE' | 'UPDATE' | 'DELETE' | 'COMPLETE';
  endpoint: string;
  data?: any;
  timestamp: number;
  retryCount: number;
}

// Cached Data
{
  [key: string]: {
    data: any;
    timestamp: number;
  }
}
```

### Sync Logic

**Mutation Queue Processing:**
1. Retrieve all queued mutations from storage
2. Execute each mutation in order
3. On success: Remove from queue
4. On failure: Increment retry count
5. Discard after 3 failed attempts
6. Save remaining queue back to storage

**Retry Strategy:**
- Max 3 retry attempts per mutation
- Skip retries for 401 (unauthorized) and 404 (not found) errors
- 100ms delay between mutations to prevent server overload

## Usage Examples

### Creating Tasks Offline

```typescript
// User creates task while offline
const createMutation = useMutation({
  mutationFn: async (taskData) => {
    if (!isOnline) {
      // Queue for later sync
      offlineSyncManager.queueMutation({
        type: 'CREATE',
        endpoint: '/tasks',
        data: taskData,
      });
      return { offline: true, ...taskData };
    }
    return await api.post('/tasks', taskData);
  },
});

// User gets feedback
Alert.alert(
  'Saved Offline',
  'Your task will sync when you're back online.'
);
```

### Fetching Data with Offline Fallback

```typescript
const { data } = useQuery({
  queryKey: ['tasks'],
  queryFn: async () => {
    try {
      const response = await api.get('/tasks');
      // Save to offline storage
      offlineSyncManager.saveOfflineData('tasks', response.data);
      return response.data;
    } catch (error) {
      // If offline, return cached data
      if (!isOnline) {
        const cached = offlineSyncManager.getOfflineDataByKey('tasks');
        if (cached) return cached;
      }
      throw error;
    }
  },
});
```

### Manual Sync

```typescript
import { offlineSyncManager } from '@/lib/offlineSync';
import { useQueryClient } from '@tanstack/react-query';

const handleSync = async () => {
  // Sync pending mutations
  await offlineSyncManager.syncAll();
  
  // Refetch all queries
  await queryClient.refetchQueries();
  
  // Update pending count
  useNetworkStore.getState().updatePendingCount();
};
```

## User Experience

### Offline Workflow

**Scenario: User Goes Offline**
1. User loses internet connection
2. Network status bar appears: "Offline"
3. User continues working (create/edit/delete tasks)
4. Each action queued with visual confirmation
5. Status bar updates: "Offline • 3 pending"

**Scenario: User Returns Online**
1. Internet connection restored
2. Status bar changes: "3 pending • Tap to sync"
3. Auto-sync begins automatically
4. Status bar shows: "Syncing..."
5. Sync completes successfully
6. Status bar disappears (all synced)
7. Haptic success feedback

**Scenario: Sync Fails**
1. Mutation fails (e.g., validation error)
2. Retry attempted (up to 3 times)
3. If still failing, operation discarded
4. User can view errors in console logs

## Testing Offline Mode

### Manual Testing Steps

**1. Test Offline Creation:**
- Turn on airplane mode
- Create a new task
- Verify "Saved Offline" message
- Check network status bar shows "1 pending"
- Turn off airplane mode
- Verify task syncs automatically

**2. Test Offline Completion:**
- Turn on airplane mode
- Swipe right to complete a task
- Verify task marked complete locally
- Check network status bar shows pending
- Turn off airplane mode
- Verify completion syncs to server

**3. Test Offline Deletion:**
- Turn on airplane mode
- Swipe left to delete a task
- Confirm deletion
- Check pending count increases
- Turn off airplane mode
- Verify deletion syncs

**4. Test Cache Retrieval:**
- Load tasks while online
- Turn on airplane mode
- Close and reopen app
- Verify tasks still visible from cache
- Pull to refresh (shows cached data)

**5. Test Manual Sync:**
- Create tasks offline (multiple)
- Return online
- Tap network status bar
- Verify manual sync triggers
- Check all tasks sync successfully

### Development Tools

**Debug Offline Sync:**
```typescript
// Check pending mutations
const pending = offlineSyncManager.getPendingCount();
console.log('Pending mutations:', pending);

// Get network status
const isOnline = offlineSyncManager.getNetworkStatus();
console.log('Network status:', isOnline);

// View queued mutations
const queue = offlineSyncManager.getQueue();
console.log('Queue:', queue);

// Clear queue (for testing)
offlineSyncManager.clearQueue();
```

## Limitations & Known Issues

### Current Limitations

1. **Conflict Resolution**: Last-write-wins strategy (no conflict detection)
2. **File Uploads**: Not supported offline (requires online connection)
3. **Real-time Features**: Notifications and live updates require online
4. **Large Datasets**: Cache limited by device storage
5. **Background Sync**: iOS background restrictions may delay sync

### Future Enhancements

- [ ] Conflict resolution UI
- [ ] Batch sync optimization
- [ ] Selective sync (user controls what syncs)
- [ ] Offline indicators on individual items
- [ ] Sync progress indicators
- [ ] Failed sync notification system
- [ ] Background sync with iOS limitations workaround

## Performance Considerations

### Storage Management

**MMKV Performance:**
- ⚡ 30x faster than AsyncStorage
- ⚡ Synchronous read/write
- ⚡ Encrypted by default
- ⚡ Efficient memory usage

**Cache Cleanup:**
- Automatic cleanup of data older than 7 days
- Manual cleanup available via settings
- Queue cleared after successful sync

### Network Efficiency

**Smart Caching:**
- Only fetch when data is stale (5 min)
- Cache responses for offline access
- Minimize API calls with query deduplication

**Batch Operations:**
- Queue multiple mutations
- Execute in order when online
- Prevent duplicate requests

## Security

**Offline Data Security:**
- ✅ JWT tokens stored in Expo SecureStore (encrypted)
- ✅ MMKV storage is encrypted by default
- ✅ Cached data automatically expires
- ✅ Queued mutations are user-specific
- ✅ No sensitive data logged

**Sync Security:**
- ✅ All sync operations use authenticated API calls
- ✅ JWT token validation on each request
- ✅ Expired tokens trigger logout
- ✅ Failed auth clears offline queue

## Troubleshooting

### Common Issues

**Issue: Sync Not Working**
- Check network connection
- Verify JWT token is valid
- Check console for errors
- Try manual sync via status bar

**Issue: Data Not Updating**
- Pull to refresh to force refetch
- Check if offline mode is active
- Verify sync queue is not full
- Clear app cache and re-login

**Issue: Duplicate Items**
- Clear offline queue: `offlineSyncManager.clearQueue()`
- Re-login to refresh data
- Contact support if persists

**Issue: Pending Count Stuck**
- Check console for failed mutations
- Mutations may have exceeded retry limit
- Clear queue and refetch data

## Support

For issues or questions about offline functionality:
- Check console logs for detailed error messages
- Review pending mutations in queue
- Test with airplane mode for reproducibility
- Contact development team with specific scenarios

---

**Version**: 1.0  
**Last Updated**: January 2025  
**Status**: ✅ Production Ready
