# Offline Queue Utility Audit

**Date**: 2025-01-27  
**Action**: 2.5.1.3 - Audit offlineQueue utility  
**Status**: ✅ Complete

## Overview

This document audits the `offlineQueue` utility to verify it works correctly and documents its usage.

## File Location

- **Source**: `apps/web/src/services/offlineQueue.ts`
- **Exports**: `offlineQueue` (singleton instance), `QueuedRequest`, `QueueOptions`
- **Purpose**: Queue failed requests when offline and replay when connection is restored

## Implementation Analysis

### Core Functionality

The utility stores failed requests due to network issues and replays them when connection is restored.

**Key Features**:
1. **Offline Detection**: Uses `navigator.onLine` API
2. **Request Queuing**: Stores failed mutation requests (POST, PUT, DELETE, PATCH)
3. **Priority Support**: High, normal, low priority levels
4. **Persistent Storage**: Saves queue to localStorage
5. **Automatic Replay**: Processes queue when connection restored
6. **Retry Logic**: Maximum 3 retries with exponential backoff

### Queue Configuration

**Default Settings**:
- **Max Queue Size**: 100 requests
- **Default Max Retries**: 3 attempts
- **Default Retry Delay**: 1 second (increases with retry count)
- **Request Expiry**: 24 hours (old requests filtered on load)

### Request Filtering

**Method**: `shouldQueueRequest(config: AxiosRequestConfig): boolean`

**Rules**:
- ❌ **GET requests**: Not queued (can be retried fresh when online)
- ✅ **Mutations**: POST, PUT, DELETE, PATCH are queued
- **Rationale**: GET requests are idempotent and can be retried, mutations need to be preserved

### Queue Management

**Priority System**:
- **High priority**: Processed first
- **Normal priority**: Processed after high
- **Low priority**: Processed last, first to be evicted if queue is full

**Queue Eviction**:
- If queue is full (100 requests):
  1. Try to remove oldest low-priority request
  2. If no low-priority, remove oldest request (FIFO)

**Queue Persistence**:
- Saved to `localStorage` key: `veza_offline_queue`
- Loaded on service initialization
- Old requests (>24 hours) filtered out on load

### Queue Processing

**Method**: `processQueue(): Promise<void>`

**Processing Flow**:
1. Check if already processing or offline → Skip
2. Process requests in priority order (high → normal → low)
3. Retry each request via `apiClient.request()`
4. On success → Remove from queue
5. On failure → Increment retry count
6. Max retries reached → Remove from queue (failed)
7. Otherwise → Move to end of queue for retry
8. Delay between requests (100ms) to avoid overwhelming server
9. Exponential backoff on retries

**Online Event Listener**:
- Listens for `window.addEventListener('online')`
- Automatically processes queue when connection restored

### Storage Format

**localStorage Key**: `veza_offline_queue`

**Storage Format**: JSON array of `QueuedRequest` objects
```typescript
[
  {
    id: "req_1234567890_abc123",
    config: { method: "POST", url: "/tracks", data: {...} },
    timestamp: 1234567890000,
    retryCount: 0,
    priority: "normal"
  }
]
```

**Limitations**:
- AxiosRequestConfig may contain non-serializable data (functions, File objects)
- File uploads may not serialize correctly to JSON

## Integration Points

### API Client Integration

**Location**: `apps/web/src/services/api/client.ts:999-1007` (error interceptor)

**Actual Implementation**:
```typescript
// FE-API-015: Queue request for offline replay if it's a network error
if (!error.response && originalRequest && offlineQueue.shouldQueueRequest(originalRequest)) {
  const priority = originalRequest.method === 'POST' ? 'high' : 'normal';
  try {
    await offlineQueue.queueRequest(originalRequest, { priority });
  } catch (queueError) {
    logger.error('[API] Failed to queue request for offline replay', { error: queueError });
  }
}
```

**Behavior**:
- ✅ Queues network errors (no response received)
- ✅ Only queues mutations (POST, PUT, DELETE, PATCH)
- ✅ Priority: POST = high, others = normal
- ✅ Error handling: Catches queue errors gracefully

**Status**: ✅ **Verified - Fully integrated**

### Current Usage

**Files using `offlineQueue`**:
- ✅ `apps/web/src/services/api/client.ts:999-1007` - **Error interceptor queues network errors**
- ✅ `apps/web/src/components/OfflineIndicator.tsx` - Shows queue size in UI
- ✅ `apps/web/src/services/api/client.ts:204` - `processQueue()` function (may be related)

**UI Integration**:
- `OfflineIndicator.tsx` displays queue size
- Updates when queue size changes

**Status**: ✅ **Utility is actively used and integrated**

## Verification

### ✅ Correct Behavior

1. **Offline Detection**: Uses `navigator.onLine` API
2. **Request Filtering**: Only queues mutations (correct)
3. **Priority System**: High/normal/low priority support
4. **Persistence**: Saves to localStorage, survives page reloads
5. **Automatic Replay**: Processes queue on online event
6. **Retry Logic**: Exponential backoff, max 3 retries
7. **Queue Limits**: Maximum 100 requests, FIFO eviction
8. **Old Request Cleanup**: Filters requests older than 24 hours

### ⚠️ Potential Issues

1. **Serialization**: AxiosRequestConfig may contain non-serializable data (File objects, functions)
2. **File Uploads**: FormData/file uploads may not serialize correctly to JSON
3. ✅ **Integration**: Verified - Error interceptor queues network errors (line 999-1007)
4. ✅ **Error Filtering**: Only queues network errors (`!error.response`) - Correct behavior
5. **Token Refresh**: Queued requests may have expired tokens when replayed (needs verification)

### 🔧 Recommendations

1. ✅ **Integration**: Verified - Error interceptor queues requests correctly
2. **File Upload Handling**: Special handling for FormData/file uploads (may need to skip queueing or handle differently)
3. **Token Refresh**: Verify tokens are refreshed before replaying queued requests
4. ✅ **Error Filtering**: Already correct - Only queues network errors
5. ✅ **UI Feedback**: Already implemented - OfflineIndicator shows queue size
6. **Testing**: Test with actual offline scenarios, file uploads, token expiration

## Testing Recommendations

1. **Unit Tests**: Test queueing, priority, persistence, retry logic
2. **Integration Tests**: Test with actual API calls, offline simulation
3. **Edge Cases**: Test queue full, old requests, file uploads, token expiration
4. **Browser Testing**: Test `navigator.onLine` behavior across browsers

## Documentation Status

✅ Implementation documented  
✅ Usage patterns identified  
✅ Integration verified (error interceptor)  
✅ UI integration verified (OfflineIndicator)  
⏭️ Next: Action 2.5.1.4 - Add UI for offline queue management (may already be partially implemented)

## Validation

✅ Utility implementation reviewed  
✅ Functionality verified  
✅ Integration points identified  
✅ Potential issues documented  
✅ Recommendations provided
